浏览代码

答题项目注册页面

李志伟 3 年前
父节点
当前提交
917417230b
共有 6 个文件被更改,包括 639 次插入19 次删除
  1. 21
    0
      src/api/signup.js
  2. 2
    2
      src/permission.js
  3. 14
    0
      src/router/index.js
  4. 261
    0
      src/views/login/forgotPassword.vue
  5. 12
    17
      src/views/login/index.vue
  6. 329
    0
      src/views/login/register.vue

+ 21
- 0
src/api/signup.js 查看文件

@@ -0,0 +1,21 @@
1
+import request from '@/utils/request'
2
+
3
+/**
4
+* 注册账号
5
+* @param {*} data
6
+* @returns
7
+*/
8
+export const signUp = (data) => request({
9
+  url: '/admin/signup',
10
+  method: 'post',
11
+  data
12
+})
13
+
14
+/**
15
+ * 获取验证码
16
+ * @param {*} params
17
+ * @returns
18
+ */
19
+export const getCaptcha = (params) => request({
20
+  url: '/admin/captcha', params
21
+})

+ 2
- 2
src/permission.js 查看文件

@@ -8,14 +8,14 @@ import getPageTitle from '@/utils/get-page-title'
8 8
 
9 9
 NProgress.configure({ showSpinner: false }) // NProgress Configuration
10 10
 
11
-const whiteList = ['/login'] // no redirect whitelist
11
+const whiteList = ['/login', '/login/forgotPassword', '/login/register'] // no redirect whitelist
12 12
 
13 13
 router.beforeEach(async(to, from, next) => {
14 14
   // start progress bar
15 15
   NProgress.start()
16 16
 
17 17
   // set page title
18
-  document.title = getPageTitle(to.meta.title)
18
+  // document.title = getPageTitle(to.meta.title)
19 19
 
20 20
   // determine whether the user has logged in
21 21
   const hasToken = getToken()

+ 14
- 0
src/router/index.js 查看文件

@@ -144,6 +144,20 @@ export const constantRoutes = [
144 144
     hidden: true
145 145
   },
146 146
 
147
+  {
148
+    path: '/login/register',
149
+    component: () => import('@/views/login/register'),
150
+    hidden: true,
151
+    name: 'register'
152
+  },
153
+
154
+  {
155
+    path: '/login/forgotPassword',
156
+    component: () => import('@/views/login/forgotPassword'),
157
+    hidden: true,
158
+    name: 'forgotPassword'
159
+  },
160
+
147 161
   {
148 162
     path: '/404',
149 163
     component: () => import('@/views/404'),

+ 261
- 0
src/views/login/forgotPassword.vue 查看文件

@@ -0,0 +1,261 @@
1
+<template>
2
+  <div class="login-container">
3
+    <el-form
4
+      ref="regisiterForm"
5
+      :model="regisiterForm"
6
+      :rules="regisiterRules"
7
+      class="login-form"
8
+      auto-complete="on"
9
+      label-position="left"
10
+    >
11
+      <div class="title-container">
12
+        <h3 class="title">找回密码</h3>
13
+      </div>
14
+
15
+      <el-form-item prop="phone">
16
+        <span class="svg-container">
17
+          <svg-icon icon-class="password" />
18
+        </span>
19
+        <el-input
20
+          ref="phone"
21
+          v-model="regisiterForm.phone"
22
+          type="tel"
23
+          placeholder="手机号"
24
+          name="phone"
25
+          tabindex="1"
26
+        />
27
+      </el-form-item>
28
+
29
+      <el-form-item prop="captcha" style="width:65%">
30
+        <span class="svg-container">
31
+          <svg-icon icon-class="password" />
32
+        </span>
33
+        <el-input
34
+          ref="captcha"
35
+          v-model="regisiterForm.captcha"
36
+          type="text"
37
+          placeholder="验证码"
38
+          tabindex="2"
39
+          name="captcha"
40
+        />
41
+        <el-button style="position: absolute;right: -150px;top: 6px;" :disabled="disabled" @click="sendCode">{{ btnText }}</el-button>
42
+      </el-form-item>
43
+      <el-form-item prop="password">
44
+        <span class="svg-container">
45
+          <svg-icon icon-class="password" />
46
+        </span>
47
+        <el-input
48
+          ref="password"
49
+          v-model="regisiterForm.password"
50
+          type="text"
51
+          placeholder="密码"
52
+          name="password"
53
+          tabindex="3"
54
+          @keyup.enter.native="handleLogin"
55
+        />
56
+      </el-form-item>
57
+      <el-button
58
+        :loading="loading"
59
+        type="primary"
60
+        style="width: 100%; margin-bottom: 30px"
61
+        @click.native.prevent="handleLogin"
62
+      >找回密码</el-button>
63
+    </el-form>
64
+  </div>
65
+</template>
66
+<script>
67
+import { getCaptcha, signUp } from '@/api/signup'
68
+import md5 from 'js-md5'
69
+export default {
70
+  name: 'Login',
71
+  data() {
72
+    const validatePhone = (rule, value, callback) => {
73
+      if (!value) {
74
+        return callback(new Error('手机号不能为空'))
75
+      } else {
76
+        const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
77
+        if (reg.test(value)) {
78
+          callback()
79
+        } else {
80
+          return callback(new Error('请输入正确的手机号'))
81
+        }
82
+      }
83
+    }
84
+    return {
85
+      regisiterForm: {
86
+        password: '',
87
+        phone: undefined,
88
+        captcha: undefined
89
+      },
90
+      regisiterRules: {
91
+        password: [
92
+          { required: true, trigger: 'change', message: '请输入密码' }
93
+        ],
94
+        phone: [
95
+          { required: true, trigger: 'change', validator: validatePhone }
96
+        ],
97
+        captcha: [
98
+          { required: true, trigger: 'change', message: '请输入验证码' }
99
+        ]
100
+      },
101
+      disabled: false,
102
+      btnText: '发送验证码',
103
+      time: 0,
104
+      loading: false
105
+    }
106
+  },
107
+  methods: {
108
+    sendCode() {
109
+      this.disabled = true
110
+
111
+      this.$refs.regisiterForm.validateField('phone', (errorMessage) => {
112
+        if (errorMessage) {
113
+          this.$message.error(errorMessage)
114
+
115
+          this.disabled = false
116
+        } else {
117
+          getCaptcha({ phone: this.regisiterForm.phone })
118
+            .then((e) => {})
119
+            .catch((res) => {
120
+            })
121
+          this.time = 60
122
+          const timer = setInterval(() => {
123
+            this.time-- // 倒计时递减
124
+            this.btnText = `${this.time}s后重新发送`
125
+            if (this.time === 0) {
126
+              this.disabled = false
127
+              this.btnText = '重新发送'
128
+              this.time = this.countDown
129
+              clearInterval(timer)
130
+            }
131
+          }, 1000)
132
+        }
133
+      })
134
+    },
135
+    handleLogin() {
136
+      this.$refs.regisiterForm.validate((valid) => {
137
+        if (valid) {
138
+          this.regisiterForm.password = md5(this.regisiterForm.password)
139
+          // signUp(this.regisiterForm).then((res) => {
140
+          this.$message('修改密码成功')
141
+          this.$router.push({ path: '/login' })
142
+          // })
143
+        } else {
144
+          return false
145
+        }
146
+      })
147
+    }
148
+  }
149
+}
150
+</script>
151
+
152
+<style lang="scss">
153
+/* 修复input 背景不协调 和光标变色 */
154
+/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
155
+
156
+$bg: #283443;
157
+$light_gray: #fff;
158
+$cursor: #fff;
159
+
160
+@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
161
+  .login-container .el-input input {
162
+    color: $cursor;
163
+  }
164
+}
165
+
166
+/* reset element-ui css */
167
+.login-container {
168
+  .el-input {
169
+    display: inline-block;
170
+    height: 47px;
171
+    width: 85%;
172
+
173
+    input {
174
+      background: transparent;
175
+      border: 0px;
176
+      -webkit-appearance: none;
177
+      border-radius: 0px;
178
+      padding: 12px 5px 12px 15px;
179
+      color: $light_gray;
180
+      height: 47px;
181
+      caret-color: $cursor;
182
+
183
+      &:-webkit-autofill {
184
+        box-shadow: 0 0 0px 1000px $bg inset !important;
185
+        -webkit-text-fill-color: $cursor !important;
186
+      }
187
+    }
188
+  }
189
+
190
+  .el-form-item {
191
+    border: 1px solid rgba(255, 255, 255, 0.1);
192
+    background: rgba(0, 0, 0, 0.1);
193
+    border-radius: 5px;
194
+    color: #454545;
195
+  }
196
+}
197
+</style>
198
+
199
+<style lang="scss" scoped>
200
+$bg: #2d3a4b;
201
+$dark_gray: #889aa4;
202
+$light_gray: #eee;
203
+
204
+.login-container {
205
+  min-height: 100%;
206
+  width: 100%;
207
+  background-color: $bg;
208
+  overflow: hidden;
209
+
210
+  .login-form {
211
+    position: relative;
212
+    width: 520px;
213
+    max-width: 100%;
214
+    padding: 160px 35px 0;
215
+    margin: 0 auto;
216
+    overflow: hidden;
217
+  }
218
+
219
+  .tips {
220
+    font-size: 14px;
221
+    color: #fff;
222
+    margin-bottom: 10px;
223
+
224
+    span {
225
+      &:first-of-type {
226
+        margin-right: 16px;
227
+      }
228
+    }
229
+  }
230
+
231
+  .svg-container {
232
+    padding: 6px 5px 6px 15px;
233
+    color: $dark_gray;
234
+    vertical-align: middle;
235
+    width: 30px;
236
+    display: inline-block;
237
+  }
238
+
239
+  .title-container {
240
+    position: relative;
241
+
242
+    .title {
243
+      font-size: 26px;
244
+      color: $light_gray;
245
+      margin: 0px auto 40px auto;
246
+      text-align: center;
247
+      font-weight: bold;
248
+    }
249
+  }
250
+
251
+  .show-pwd {
252
+    position: absolute;
253
+    right: 10px;
254
+    top: 7px;
255
+    font-size: 16px;
256
+    color: $dark_gray;
257
+    cursor: pointer;
258
+    user-select: none;
259
+  }
260
+}
261
+</style>

+ 12
- 17
src/views/login/index.vue 查看文件

@@ -55,29 +55,24 @@
55 55
         style="width: 100%; margin-bottom: 30px"
56 56
         @click.native.prevent="handleLogin"
57 57
       >登录</el-button>
58
+      <el-link :underline="false" style="margin:0" type="primary">
59
+        <router-link
60
+          :to="{name: 'register'}"
61
+        >注册账号</router-link>
62
+      </el-link>
63
+      <el-link :underline="false" style="float:right" type="primary">
64
+        <router-link
65
+          :to="{name: 'forgotPassword'}"
66
+        >忘记密码</router-link>
67
+      </el-link>
58 68
     </el-form>
59 69
   </div>
60 70
 </template>
61 71
 <script>
62
-import { validUsername } from '@/utils/validate'
63 72
 import md5 from 'js-md5'
64 73
 export default {
65 74
   name: 'Login',
66 75
   data() {
67
-    const validateUsername = (rule, value, callback) => {
68
-      if (!validUsername(value)) {
69
-        callback(new Error('请输入用户名'))
70
-      } else {
71
-        callback()
72
-      }
73
-    }
74
-    const validatePassword = (rule, value, callback) => {
75
-      if (value.length < 6) {
76
-        callback(new Error('请输入密码'))
77
-      } else {
78
-        callback()
79
-      }
80
-    }
81 76
     return {
82 77
       loginForm: {
83 78
         userName: '',
@@ -85,10 +80,10 @@ export default {
85 80
       },
86 81
       loginRules: {
87 82
         userName: [
88
-          { required: true, trigger: 'blur', validator: validateUsername }
83
+          { required: true, message: '请输入用户名', trigger: 'change' }
89 84
         ],
90 85
         password: [
91
-          { required: true, trigger: 'blur', validator: validatePassword }
86
+          { required: true, trigger: 'change', message: '请输入密码' }
92 87
         ]
93 88
       },
94 89
       loading: false,

+ 329
- 0
src/views/login/register.vue 查看文件

@@ -0,0 +1,329 @@
1
+<template>
2
+  <div class="login-container">
3
+    <el-form
4
+      ref="regisiterForm"
5
+      :model="regisiterForm"
6
+      :rules="regisiterRules"
7
+      class="login-form"
8
+      auto-complete="on"
9
+      label-position="left"
10
+    >
11
+      <div class="title-container">
12
+        <h3 class="title">注册账号</h3>
13
+      </div>
14
+
15
+      <el-form-item prop="name">
16
+        <span class="svg-container">
17
+          <svg-icon icon-class="user" />
18
+        </span>
19
+        <el-input
20
+          ref="name"
21
+          v-model="regisiterForm.name"
22
+          placeholder="用户名"
23
+          name="name"
24
+          type="text"
25
+          tabindex="1"
26
+        />
27
+      </el-form-item>
28
+
29
+      <el-form-item prop="password">
30
+        <span class="svg-container">
31
+          <svg-icon icon-class="password" />
32
+        </span>
33
+        <el-input
34
+          :key="passwordType"
35
+          ref="password"
36
+          v-model="regisiterForm.password"
37
+          :type="passwordType"
38
+          placeholder="密码"
39
+          name="password"
40
+          tabindex="2"
41
+        />
42
+        <span class="show-pwd" @click="showPwd">
43
+          <svg-icon
44
+            :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
45
+          />
46
+        </span>
47
+      </el-form-item>
48
+      <el-form-item prop="password2">
49
+        <span class="svg-container">
50
+          <svg-icon icon-class="password" />
51
+        </span>
52
+        <el-input
53
+          ref="password2"
54
+          v-model="regisiterForm.password2"
55
+          type="text"
56
+          placeholder="确认密码"
57
+          name="password2"
58
+          tabindex="3"
59
+        />
60
+      </el-form-item>
61
+      <el-form-item prop="phone">
62
+        <span class="svg-container">
63
+          <svg-icon icon-class="password" />
64
+        </span>
65
+        <el-input
66
+          ref="phone"
67
+          v-model="regisiterForm.phone"
68
+          type="tel"
69
+          placeholder="手机号"
70
+          name="phone"
71
+          tabindex="4"
72
+        />
73
+      </el-form-item>
74
+
75
+      <el-form-item prop="captcha" style="width:65%">
76
+        <span class="svg-container">
77
+          <svg-icon icon-class="password" />
78
+        </span>
79
+        <el-input
80
+          ref="captcha"
81
+          v-model="regisiterForm.captcha"
82
+          type="text"
83
+          placeholder="验证码"
84
+          tabindex="5"
85
+          name="captcha"
86
+          @keyup.enter.native="handleLogin"
87
+        />
88
+        <el-button style="position: absolute;right: -150px;top: 6px;" :disabled="disabled" @click="sendCode">{{ btnText }}</el-button>
89
+      </el-form-item>
90
+
91
+      <el-button
92
+        :loading="loading"
93
+        type="primary"
94
+        style="width: 100%; margin-bottom: 30px"
95
+        @click.native.prevent="handleLogin"
96
+      >注册</el-button>
97
+      <el-link :underline="false" style="margin:0" type="primary">
98
+        <router-link
99
+          :to="{path: '/login'}"
100
+        >登录系统</router-link>
101
+      </el-link>
102
+      <el-link :underline="false" style="float:right" type="primary">
103
+        <router-link
104
+          :to="{name: 'forgotPassword'}"
105
+        >忘记密码</router-link>
106
+      </el-link>
107
+    </el-form>
108
+  </div>
109
+</template>
110
+<script>
111
+import { getCaptcha, signUp } from '@/api/signup'
112
+import md5 from 'js-md5'
113
+export default {
114
+  name: 'Login',
115
+  data() {
116
+    const validatePhone = (rule, value, callback) => {
117
+      if (!value) {
118
+        return callback(new Error('手机号不能为空'))
119
+      } else {
120
+        const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
121
+        if (reg.test(value)) {
122
+          callback()
123
+        } else {
124
+          return callback(new Error('请输入正确的手机号'))
125
+        }
126
+      }
127
+    }
128
+    return {
129
+      regisiterForm: {
130
+        name: undefined,
131
+        password: undefined,
132
+        phone: undefined,
133
+        captcha: '619400',
134
+        password2: undefined
135
+      },
136
+      regisiterRules: {
137
+        name: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
138
+        password: [
139
+          { required: true, trigger: 'change', message: '请输入密码' }
140
+        ],
141
+        password2: [
142
+          { required: true, trigger: 'change', message: '请再次输入密码' }
143
+        ],
144
+        phone: [
145
+          { required: true, trigger: 'change', validator: validatePhone }
146
+        ],
147
+        captcha: [
148
+          { required: true, trigger: 'change', message: '请输入验证码' }
149
+        ]
150
+      },
151
+      disabled: false,
152
+      btnText: '发送验证码',
153
+      time: 0,
154
+      loading: false,
155
+      passwordType: 'password'
156
+    }
157
+  },
158
+  methods: {
159
+    sendCode() {
160
+      this.disabled = true
161
+
162
+      this.$refs.regisiterForm.validateField('phone', (errorMessage) => {
163
+        if (errorMessage) {
164
+          this.$message.error(errorMessage)
165
+
166
+          this.disabled = false
167
+        } else {
168
+          getCaptcha({ phone: this.regisiterForm.phone })
169
+            .then((e) => {})
170
+            .catch((res) => {
171
+              // console.log(res)
172
+            })
173
+          this.time = 60
174
+          const timer = setInterval(() => {
175
+            this.time-- // 倒计时递减
176
+            this.btnText = `${this.time}s后重新发送`
177
+            if (this.time === 0) {
178
+              this.disabled = false
179
+              this.btnText = '重新发送'
180
+              this.time = this.countDown
181
+              clearInterval(timer)
182
+            }
183
+          }, 1000)
184
+        }
185
+      })
186
+    },
187
+    showPwd() {
188
+      if (this.passwordType === 'password') {
189
+        this.passwordType = ''
190
+      } else {
191
+        this.passwordType = 'password'
192
+      }
193
+      this.$nextTick(() => {
194
+        this.$refs.password.focus()
195
+      })
196
+    },
197
+    handleLogin() {
198
+      this.$refs.regisiterForm.validate((valid) => {
199
+        if (valid) {
200
+          if (this.regisiterForm.password !== this.regisiterForm.password2) {
201
+            this.$message('密码输入不一致请重新输入')
202
+            this.$refs.password2.focus()
203
+            return false
204
+          } else {
205
+            this.regisiterForm.password = md5(this.regisiterForm.password)
206
+            signUp(this.regisiterForm).then((res) => {
207
+              this.$message('注册成功')
208
+              this.$router.push({ path: '/login' })
209
+            })
210
+          }
211
+        } else {
212
+          return false
213
+        }
214
+      })
215
+    }
216
+  }
217
+}
218
+</script>
219
+
220
+<style lang="scss">
221
+/* 修复input 背景不协调 和光标变色 */
222
+/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
223
+
224
+$bg: #283443;
225
+$light_gray: #fff;
226
+$cursor: #fff;
227
+
228
+@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
229
+  .login-container .el-input input {
230
+    color: $cursor;
231
+  }
232
+}
233
+
234
+/* reset element-ui css */
235
+.login-container {
236
+  .el-input {
237
+    display: inline-block;
238
+    height: 47px;
239
+    width: 85%;
240
+
241
+    input {
242
+      background: transparent;
243
+      border: 0px;
244
+      -webkit-appearance: none;
245
+      border-radius: 0px;
246
+      padding: 12px 5px 12px 15px;
247
+      color: $light_gray;
248
+      height: 47px;
249
+      caret-color: $cursor;
250
+
251
+      &:-webkit-autofill {
252
+        box-shadow: 0 0 0px 1000px $bg inset !important;
253
+        -webkit-text-fill-color: $cursor !important;
254
+      }
255
+    }
256
+  }
257
+
258
+  .el-form-item {
259
+    border: 1px solid rgba(255, 255, 255, 0.1);
260
+    background: rgba(0, 0, 0, 0.1);
261
+    border-radius: 5px;
262
+    color: #454545;
263
+  }
264
+}
265
+</style>
266
+
267
+<style lang="scss" scoped>
268
+$bg: #2d3a4b;
269
+$dark_gray: #889aa4;
270
+$light_gray: #eee;
271
+
272
+.login-container {
273
+  min-height: 100%;
274
+  width: 100%;
275
+  background-color: $bg;
276
+  overflow: hidden;
277
+
278
+  .login-form {
279
+    position: relative;
280
+    width: 520px;
281
+    max-width: 100%;
282
+    padding: 160px 35px 0;
283
+    margin: 0 auto;
284
+    overflow: hidden;
285
+  }
286
+
287
+  .tips {
288
+    font-size: 14px;
289
+    color: #fff;
290
+    margin-bottom: 10px;
291
+
292
+    span {
293
+      &:first-of-type {
294
+        margin-right: 16px;
295
+      }
296
+    }
297
+  }
298
+
299
+  .svg-container {
300
+    padding: 6px 5px 6px 15px;
301
+    color: $dark_gray;
302
+    vertical-align: middle;
303
+    width: 30px;
304
+    display: inline-block;
305
+  }
306
+
307
+  .title-container {
308
+    position: relative;
309
+
310
+    .title {
311
+      font-size: 26px;
312
+      color: $light_gray;
313
+      margin: 0px auto 40px auto;
314
+      text-align: center;
315
+      font-weight: bold;
316
+    }
317
+  }
318
+
319
+  .show-pwd {
320
+    position: absolute;
321
+    right: 10px;
322
+    top: 7px;
323
+    font-size: 16px;
324
+    color: $dark_gray;
325
+    cursor: pointer;
326
+    user-select: none;
327
+  }
328
+}
329
+</style>