inleft
2022-02-09 f1b087d45ded835ccd6c875086b1f2e2b847f15a
commit | author | age
9bcb19 1 <template>
I 2   <div class="main user-layout-register">
3     <h3><span>注册</span></h3>
4     <a-form ref="formRegister" :form="form" id="formRegister">
5       <a-form-item>
6         <a-input
7           size="large"
8           type="text"
9           placeholder="邮箱"
10           v-decorator="['email', {rules: [{ required: true, type: 'email', message: '请输入邮箱地址' }], validateTrigger: ['change', 'blur']}]"
11         ></a-input>
12       </a-form-item>
13
14       <a-popover
15         placement="rightTop"
16         :trigger="['focus']"
17         :getPopupContainer="(trigger) => trigger.parentElement"
18         v-model="state.passwordLevelChecked">
19         <template slot="content">
20           <div :style="{ width: '240px' }" >
21             <div :class="['user-register', passwordLevelClass]">强度:<span>{{ passwordLevelName }}</span></div>
22             <a-progress :percent="state.percent" :showInfo="false" :strokeColor=" passwordLevelColor " />
23             <div style="margin-top: 10px;">
24               <span>请至少输入 6 个字符。请不要使用容易被猜到的密码。</span>
25             </div>
26           </div>
27         </template>
28         <a-form-item>
29           <a-input
30             size="large"
31             type="password"
32             @click="handlePasswordInputClick"
33             autocomplete="false"
34             placeholder="至少6位密码,区分大小写"
35             v-decorator="['password', {rules: [{ required: true, message: '至少6位密码,区分大小写'}, { validator: this.handlePasswordLevel }], validateTrigger: ['change', 'blur']}]"
36           ></a-input>
37         </a-form-item>
38       </a-popover>
39
40       <a-form-item>
41         <a-input
42           size="large"
43           type="password"
44           autocomplete="false"
45           placeholder="确认密码"
46           v-decorator="['password2', {rules: [{ required: true, message: '至少6位密码,区分大小写' }, { validator: this.handlePasswordCheck }], validateTrigger: ['change', 'blur']}]"
47         ></a-input>
48       </a-form-item>
49
50       <a-form-item>
51         <a-input size="large" placeholder="11 位手机号" v-decorator="['mobile', {rules: [{ required: true, message: '请输入正确的手机号', pattern: /^1[3456789]\d{9}$/ }, { validator: this.handlePhoneCheck } ], validateTrigger: ['change', 'blur'] }]">
52           <a-select slot="addonBefore" size="large" defaultValue="+86">
53             <a-select-option value="+86">+86</a-select-option>
54             <a-select-option value="+87">+87</a-select-option>
55           </a-select>
56         </a-input>
57       </a-form-item>
58       <!--<a-input-group size="large" compact>
59             <a-select style="width: 20%" size="large" defaultValue="+86">
60               <a-select-option value="+86">+86</a-select-option>
61               <a-select-option value="+87">+87</a-select-option>
62             </a-select>
63             <a-input style="width: 80%" size="large" placeholder="11 位手机号"></a-input>
64           </a-input-group>-->
65
66       <a-row :gutter="16">
67         <a-col class="gutter-row" :span="16">
68           <a-form-item>
69             <a-input size="large" type="text" placeholder="验证码" v-decorator="['captcha', {rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}]">
70               <a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
71             </a-input>
72           </a-form-item>
73         </a-col>
74         <a-col class="gutter-row" :span="8">
75           <a-button
76             class="getCaptcha"
77             size="large"
78             :disabled="state.smsSendBtn"
79             @click.stop.prevent="getCaptcha"
80             v-text="!state.smsSendBtn && '获取验证码'||(state.time+' s')"></a-button>
81         </a-col>
82       </a-row>
83
84       <a-form-item>
85         <a-button
86           size="large"
87           type="primary"
88           htmlType="submit"
89           class="register-button"
90           :loading="registerBtn"
91           @click.stop.prevent="handleSubmit"
92           :disabled="registerBtn">注册
93         </a-button>
94         <router-link class="login" :to="{ name: 'login' }">使用已有账户登录</router-link>
95       </a-form-item>
96
97     </a-form>
98   </div>
99 </template>
100
101 <script>
102 import { mixinDevice } from '@/utils/mixin.js'
103 import { getSmsCaptcha } from '@/api/modular/system/loginManage'
104
105 const levelNames = {
106   0: '低',
107   1: '低',
108   2: '中',
109   3: '强'
110 }
111 const levelClass = {
112   0: 'error',
113   1: 'error',
114   2: 'warning',
115   3: 'success'
116 }
117 const levelColor = {
118   0: '#ff0000',
119   1: '#ff0000',
120   2: '#ff7e05',
121   3: '#52c41a'
122 }
123 export default {
124   name: 'Register',
125   components: {
126   },
127   mixins: [mixinDevice],
128   data () {
129     return {
130       form: this.$form.createForm(this),
131
132       state: {
133         time: 60,
134         smsSendBtn: false,
135         passwordLevel: 0,
136         passwordLevelChecked: false,
137         percent: 10,
138         progressColor: '#FF0000'
139       },
140       registerBtn: false
141     }
142   },
143   computed: {
144     passwordLevelClass () {
145       return levelClass[this.state.passwordLevel]
146     },
147     passwordLevelName () {
148       return levelNames[this.state.passwordLevel]
149     },
150     passwordLevelColor () {
151       return levelColor[this.state.passwordLevel]
152     }
153   },
154   methods: {
155     handlePasswordLevel (rule, value, callback) {
156       let level = 0
157
158       // 判断这个字符串中有没有数字
159       if (/[0-9]/.test(value)) {
160         level++
161       }
162       // 判断字符串中有没有字母
163       if (/[a-zA-Z]/.test(value)) {
164         level++
165       }
166       // 判断字符串中有没有特殊符号
167       if (/[^0-9a-zA-Z_]/.test(value)) {
168         level++
169       }
170       this.state.passwordLevel = level
171       this.state.percent = level * 30
172       if (level >= 2) {
173         if (level >= 3) {
174           this.state.percent = 100
175         }
176         callback()
177       } else {
178         if (level === 0) {
179           this.state.percent = 10
180         }
181         callback(new Error('密码强度不够'))
182       }
183     },
184
185     handlePasswordCheck (rule, value, callback) {
186       const password = this.form.getFieldValue('password')
187       console.log('value', value)
188       if (value === undefined) {
189         callback(new Error('请输入密码'))
190       }
191       if (value && password && value.trim() !== password.trim()) {
192         callback(new Error('两次密码不一致'))
193       }
194       callback()
195     },
196
197     handlePhoneCheck (rule, value, callback) {
198       console.log('handlePhoneCheck, rule:', rule)
199       console.log('handlePhoneCheck, value', value)
200       console.log('handlePhoneCheck, callback', callback)
201
202       callback()
203     },
204
205     handlePasswordInputClick () {
206       if (!this.isMobile()) {
207         this.state.passwordLevelChecked = true
208         return
209       }
210       this.state.passwordLevelChecked = false
211     },
212
213     handleSubmit () {
214       const { form: { validateFields }, state, $router } = this
215       validateFields({ force: true }, (err, values) => {
216         if (!err) {
217           state.passwordLevelChecked = false
218           $router.push({ name: 'registerResult', params: { ...values } })
219         }
220       })
221     },
222
223     getCaptcha (e) {
224       e.preventDefault()
225       const { form: { validateFields }, state, $message, $notification } = this
226
227       validateFields(['mobile'], { force: true },
228         (err, values) => {
229           if (!err) {
230             state.smsSendBtn = true
231
232             const interval = window.setInterval(() => {
233               if (state.time-- <= 0) {
234                 state.time = 60
235                 state.smsSendBtn = false
236                 window.clearInterval(interval)
237               }
238             }, 1000)
239
240             const hide = $message.loading('验证码发送中..', 0)
241
242             getSmsCaptcha({ mobile: values.mobile }).then(res => {
243               setTimeout(hide, 2500)
244               $notification['success']({
245                 message: '提示',
246                 description: '验证码获取成功,您的验证码为:' + res.result.captcha,
247                 duration: 8
248               })
249             }).catch(err => {
250               setTimeout(hide, 1)
251               clearInterval(interval)
252               state.time = 60
253               state.smsSendBtn = false
254               this.requestFailed(err)
255             })
256           }
257         }
258       )
259     },
260     requestFailed (err) {
261       this.$notification['error']({
262         message: '错误',
263         description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
264         duration: 4
265       })
266       this.registerBtn = false
267     }
268   },
269   watch: {
270     'state.passwordLevel' (val) {
271       console.log(val)
272     }
273   }
274 }
275 </script>
276 <style lang="less">
277   .user-register {
278
279     &.error {
280       color: #ff0000;
281     }
282
283     &.warning {
284       color: #ff7e05;
285     }
286
287     &.success {
288       color: #52c41a;
289     }
290
291   }
292
293   .user-layout-register {
294     .ant-input-group-addon:first-child {
295       background-color: #fff;
296     }
297   }
298 </style>
299 <style lang="less" scoped>
300   .user-layout-register {
301
302     & > h3 {
303       font-size: 16px;
304       margin-bottom: 20px;
305     }
306
307     .getCaptcha {
308       display: block;
309       width: 100%;
310       height: 40px;
311     }
312
313     .register-button {
314       width: 50%;
315     }
316
317     .login {
318       float: right;
319       line-height: 40px;
320     }
321   }
322 </style>