feat:登录
Showing
24 changed files
with
0 additions
and
484 deletions
... | @@ -17,7 +17,6 @@ import router from './router' | ... | @@ -17,7 +17,6 @@ import router from './router' |
17 | import _ from 'lodash' | 17 | import _ from 'lodash' |
18 | 18 | ||
19 | import './icons' // icon | 19 | import './icons' // icon |
20 | import './permission' // permission control | ||
21 | import * as filters from './filters' // global filters | 20 | import * as filters from './filters' // global filters |
22 | Vue.use(lbTable); | 21 | Vue.use(lbTable); |
23 | 22 | ... | ... |
... | @@ -21,16 +21,6 @@ export const constantRoutes = [ | ... | @@ -21,16 +21,6 @@ export const constantRoutes = [ |
21 | ] | 21 | ] |
22 | }, | 22 | }, |
23 | { | 23 | { |
24 | path: '/login', | ||
25 | component: () => import('@/views/login/login'), | ||
26 | hidden: true | ||
27 | }, | ||
28 | { | ||
29 | path: '/auth-redirect', | ||
30 | component: () => import('@/views/login/auth-redirect'), | ||
31 | hidden: true | ||
32 | }, | ||
33 | { | ||
34 | path: '/', | 24 | path: '/', |
35 | component: Layout, | 25 | component: Layout, |
36 | redirect: '/home', | 26 | redirect: '/home', | ... | ... |
src/views/login/auth-redirect.vue
deleted
100644 → 0
1 | <script> | ||
2 | export default { | ||
3 | name: 'AuthRedirect', | ||
4 | created() { | ||
5 | const hash = window.location.search.slice(1) | ||
6 | if (window.localStorage) { | ||
7 | window.localStorage.setItem('x-admin-oauth-code', hash) | ||
8 | window.close() | ||
9 | } | ||
10 | }, | ||
11 | render: function(h) { | ||
12 | return h() // avoid warning message | ||
13 | } | ||
14 | } | ||
15 | </script> |
1 | <template> | ||
2 | <div class="jc-component__range"> | ||
3 | <div v-loading="loading" class="jc-range" :class="rangeStatus ? 'success' : ''"> | ||
4 | <i @mousedown="rangeMove" :class="rangeStatus ? successIcon : startIcon"></i> | ||
5 | {{ rangeStatus ? successText : startText }} | ||
6 | </div> | ||
7 | </div> | ||
8 | </template> | ||
9 | |||
10 | <script> | ||
11 | import * as login from '@/api/login' | ||
12 | export default { | ||
13 | props: { | ||
14 | // 成功之后的函数 | ||
15 | successFun: { | ||
16 | type: Function, | ||
17 | }, | ||
18 | //成功图标 | ||
19 | successIcon: { | ||
20 | type: String, | ||
21 | default: 'el-icon-check', | ||
22 | }, | ||
23 | //成功文字 | ||
24 | successText: { | ||
25 | type: String, | ||
26 | default: '验证成功', | ||
27 | }, | ||
28 | //开始的图标 | ||
29 | startIcon: { | ||
30 | type: String, | ||
31 | default: 'el-icon-right', | ||
32 | }, | ||
33 | //开始的文字 | ||
34 | startText: { | ||
35 | type: String, | ||
36 | default: '请按住滑块,拖动到最右边', | ||
37 | }, | ||
38 | //失败之后的函数 | ||
39 | errorFun: { | ||
40 | type: Function, | ||
41 | }, | ||
42 | //或者用值来进行监听 | ||
43 | status: { | ||
44 | type: String, | ||
45 | }, | ||
46 | }, | ||
47 | data () { | ||
48 | return { | ||
49 | loading: false, | ||
50 | disX: 0, | ||
51 | rangeStatus: false, | ||
52 | str: {}, | ||
53 | } | ||
54 | }, | ||
55 | methods: { | ||
56 | moveFn (e) { | ||
57 | let ele = e.target | ||
58 | ele.style.transition = '.5s all' | ||
59 | ele.style.transform = 'translateX(0)' | ||
60 | this.rangeStatus = false | ||
61 | // 执行成功的函数 | ||
62 | this.errorFun() | ||
63 | }, | ||
64 | //滑块移动 | ||
65 | rangeMove (e) { | ||
66 | this.str = e | ||
67 | let ele = e.target | ||
68 | let startX = e.clientX | ||
69 | let eleWidth = ele.offsetWidth | ||
70 | let parentWidth = ele.parentElement.offsetWidth | ||
71 | let MaxX = parentWidth - eleWidth | ||
72 | |||
73 | if (this.rangeStatus) { | ||
74 | //不运行 | ||
75 | return false | ||
76 | } | ||
77 | document.onmousemove = (e) => { | ||
78 | let endX = e.clientX | ||
79 | this.disX = endX - startX | ||
80 | if (this.disX <= 0) { | ||
81 | this.disX = 0 | ||
82 | } | ||
83 | if (this.disX >= MaxX - eleWidth) { | ||
84 | //减去滑块的宽度,体验效果更好 | ||
85 | this.disX = MaxX | ||
86 | } | ||
87 | ele.style.transition = '.1s all' | ||
88 | ele.style.background = 'red!important' | ||
89 | ele.style.transform = 'translateX(' + this.disX + 'px)' | ||
90 | e.preventDefault() | ||
91 | } | ||
92 | |||
93 | document.onmouseup = async () => { | ||
94 | |||
95 | if (this.disX !== MaxX) { | ||
96 | ele.style.transition = '.5s all' | ||
97 | ele.style.transform = 'translateX(0)' | ||
98 | // 执行成功的函数 | ||
99 | this.errorFun && this.errorFun() | ||
100 | } | ||
101 | else { | ||
102 | this.successFun && this.successFun() | ||
103 | this.rangeStatus = true | ||
104 | this.loading = true | ||
105 | if (this.status) { | ||
106 | this.$parent[this.status] = true | ||
107 | } | ||
108 | } | ||
109 | document.onmousemove = null | ||
110 | document.onmouseup = null | ||
111 | } | ||
112 | }, | ||
113 | }, | ||
114 | } | ||
115 | </script> | ||
116 | |||
117 | <style lang="scss" scoped> | ||
118 | @mixin jc-flex { | ||
119 | display: flex; | ||
120 | justify-content: center; | ||
121 | align-items: center; | ||
122 | } | ||
123 | |||
124 | .jc-component__range { | ||
125 | .jc-range { | ||
126 | background-color: #F7FAFE; | ||
127 | border: 1px solid #D8E0E9; | ||
128 | position: relative; | ||
129 | transition: 1s all; | ||
130 | user-select: none; | ||
131 | color: #9B9B9B; | ||
132 | display: flex; | ||
133 | // justify-content: center; | ||
134 | padding-left: 50px; | ||
135 | align-items: center; | ||
136 | height: 40px; | ||
137 | |||
138 | /*no*/ | ||
139 | &.success { | ||
140 | background-color: #D2F5EF; | ||
141 | color: #4caf50; | ||
142 | border: 1px solid #99D5D0; | ||
143 | font-size: 16px; | ||
144 | justify-content: center; | ||
145 | padding-left: 0px; | ||
146 | |||
147 | i { | ||
148 | color: #ffffff; | ||
149 | background-color: #51CCBF; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | i { | ||
154 | position: absolute; | ||
155 | left: 0; | ||
156 | width: 38px; | ||
157 | /*no*/ | ||
158 | height: 40px; | ||
159 | |||
160 | background-color: #fff; | ||
161 | border: 1px solid #d8d8d8; | ||
162 | cursor: pointer; | ||
163 | font-size: 14px; | ||
164 | color: #829ABA; | ||
165 | @include jc-flex; | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | </style> | ||
170 | <style lang="scss" scoped> | ||
171 | /deep/.el-loading-spinner { | ||
172 | top: 62%; | ||
173 | |||
174 | .circular { | ||
175 | height: 35px !important; | ||
176 | width: 30px !important; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /deep/.el-loading-mask { | ||
181 | background-color: rgba(255, 255, 255, 1); | ||
182 | } | ||
183 | </style> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
13.1 KB
729 KB
src/views/login/img/bazaaz.png
deleted
100644 → 0
2.58 MB
src/views/login/img/code.png
deleted
100644 → 0
8.19 KB
src/views/login/img/erweima.png
deleted
100644 → 0
65.2 KB
src/views/login/img/jiancelogo.png
deleted
100644 → 0
76.9 KB
src/views/login/img/jiarr.png
deleted
100644 → 0
2.68 KB
src/views/login/img/jieshao.png
deleted
100644 → 0
2.48 KB
src/views/login/img/login-title.png
deleted
100644 → 0
65.8 KB
11.6 KB
src/views/login/img/qiye.png
deleted
100644 → 0
4.13 KB
src/views/login/img/shichang.png
deleted
100644 → 0
4.46 KB
src/views/login/img/shichanglogo.png
deleted
100644 → 0
65.7 KB
src/views/login/img/xieyi.png
deleted
100644 → 0
2.53 KB
src/views/login/img/xinBg.png
deleted
100644 → 0
1.34 MB
src/views/login/img/xinlogo.png
deleted
100644 → 0
56.4 KB
src/views/login/img/yonghu.png
deleted
100644 → 0
4.84 KB
src/views/login/img/zhengfu.png
deleted
100644 → 0
4.27 KB
src/views/login/img/zhinan.png
deleted
100644 → 0
2.91 KB
src/views/login/login.vue
deleted
100644 → 0
1 | <template> | ||
2 | <div class="login"> | ||
3 | <div class="login-header-title"> | ||
4 | <img src="./img/login-title.png"> | ||
5 | </div> | ||
6 | <div class="login-content_code"> | ||
7 | <div class="hidden-bos"> | ||
8 | <img src='./img/72054ab975174650a84d0a975de6712.png' @click.stop="Codeclick('2')" alt=""> | ||
9 | </div> | ||
10 | <div class="login-form"> | ||
11 | <h3 class="login-title "> | ||
12 | <p>{{ activeName }}</p> | ||
13 | </h3> | ||
14 | <el-form :model="ruleForm" :rules="rules" size="large" ref="ruleForm"> | ||
15 | <el-form-item prop="username"> | ||
16 | <el-input type="text" placeholder="请输入账号/手机号" v-model="ruleForm.username"> | ||
17 | <svg-icon slot="prefix" icon-class="username" /> | ||
18 | </el-input> | ||
19 | </el-form-item> | ||
20 | <el-form-item prop="password"> | ||
21 | <el-input type="password" placeholder="请输入登录密码" v-model="ruleForm.password"> | ||
22 | <svg-icon slot="prefix" icon-class="password" /> | ||
23 | </el-input> | ||
24 | </el-form-item> | ||
25 | <el-form-item prop="code"> | ||
26 | <JcRange ref='jcrangeRef' :successFun="verificate_sucess" :errorFun="verificate_error"></JcRange> | ||
27 | </el-form-item> | ||
28 | <el-form-item class="login-button-form"> | ||
29 | <el-button type="primary" class="submit-button" @click="submitForm('ruleForm')">登录 | ||
30 | </el-button> | ||
31 | </el-form-item> | ||
32 | </el-form> | ||
33 | </div> | ||
34 | </div> | ||
35 | <div class="login-footer"> | ||
36 | Copyright © 2021-2025闽ICP备20013799号-2 | ||
37 | </div> | ||
38 | </div> | ||
39 | </template> | ||
40 | <script> | ||
41 | import * as login from '@/api/login' | ||
42 | import JcRange from './components/JcRange' | ||
43 | import dialogBox from '@/components/dialogBox/index'; | ||
44 | export default { | ||
45 | components: { | ||
46 | JcRange, | ||
47 | dialogBox | ||
48 | }, | ||
49 | data () { | ||
50 | return { | ||
51 | activeName: '登录', | ||
52 | ruleForm: { | ||
53 | username: '', | ||
54 | password: '', | ||
55 | location: '', | ||
56 | code: '' | ||
57 | }, | ||
58 | rules: { | ||
59 | username: [ | ||
60 | { required: true, message: '请输入账号/手机号', trigger: 'blur' }, | ||
61 | ], | ||
62 | password: [ | ||
63 | { | ||
64 | required: true, | ||
65 | message: '请输入登录密码', | ||
66 | trigger: 'blur' | ||
67 | } | ||
68 | ], | ||
69 | code: [ | ||
70 | { | ||
71 | required: true, | ||
72 | message: '请滑动完成验证', | ||
73 | trigger: 'blur' | ||
74 | } | ||
75 | ] | ||
76 | }, | ||
77 | loading: false, | ||
78 | redirect: undefined, | ||
79 | otherQuery: {} | ||
80 | } | ||
81 | }, | ||
82 | watch: { | ||
83 | $route: { | ||
84 | handler: function (route) { | ||
85 | const query = route.query | ||
86 | if (query) { | ||
87 | this.redirect = query.redirect | ||
88 | this.otherQuery = this.getOtherQuery(query) | ||
89 | } | ||
90 | }, | ||
91 | immediate: true | ||
92 | }, | ||
93 | |||
94 | }, | ||
95 | methods: { | ||
96 | async getcode () { | ||
97 | try { | ||
98 | const res = await login.verifyCode() | ||
99 | this.ruleForm.code = res | ||
100 | if (this.ruleForm.code !== '') { | ||
101 | this.$refs.jcrangeRef.loading = false | ||
102 | } | ||
103 | } catch (error) { | ||
104 | this.$refs.jcrangeRef.loading = true | ||
105 | this.$message.error('获取验证码失败') | ||
106 | } | ||
107 | }, | ||
108 | handleCode () { | ||
109 | this.getcode() | ||
110 | }, | ||
111 | submitForm (formName) { | ||
112 | this.$refs[formName].validate(async valid => { | ||
113 | if (valid) { | ||
114 | this.$store.dispatch('user/login', this.ruleForm).then((res) => { | ||
115 | this.$router.push({ | ||
116 | path: this.redirect || '/', | ||
117 | query: this.otherQuery | ||
118 | }) | ||
119 | }).catch(e => { | ||
120 | this.$refs.jcrangeRef.disX = 0 | ||
121 | this.$refs.jcrangeRef.moveFn(this.$refs.jcrangeRef.str) | ||
122 | }) | ||
123 | } else { | ||
124 | return false | ||
125 | } | ||
126 | }) | ||
127 | }, | ||
128 | getOtherQuery (query) { | ||
129 | return Object.keys(query).reduce((acc, cur) => { | ||
130 | if (cur !== 'redirect') { | ||
131 | acc[cur] = query[cur] | ||
132 | } | ||
133 | return acc | ||
134 | }, {}) | ||
135 | }, | ||
136 | |||
137 | // 验证码 | ||
138 | verificate_sucess () { | ||
139 | this.getcode() | ||
140 | }, | ||
141 | verificate_error () { | ||
142 | this.ruleForm.code = '' | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | </script> | ||
147 | <style lang="scss" scoped> | ||
148 | .login { | ||
149 | width: 100%; | ||
150 | height: 100%; | ||
151 | background: url("./img/xinBg.png") no-repeat; | ||
152 | background-size: 100% auto; | ||
153 | display: flex; | ||
154 | align-items: center; | ||
155 | flex-direction: column; | ||
156 | position: relative; | ||
157 | |||
158 | .login-header-title { | ||
159 | width: 40%; | ||
160 | margin: 5% 0 40px 0; | ||
161 | min-height: 65px; | ||
162 | |||
163 | img { | ||
164 | width: 100%; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | .login-content_code { | ||
169 | width: 25%; | ||
170 | background-color: #ffffff; | ||
171 | box-shadow: 0px 0px 30px 0px rgba(130, 154, 186, 0.2); | ||
172 | border-radius: 8px; | ||
173 | background-repeat: no-repeat; | ||
174 | background-position: top right; | ||
175 | position: relative; | ||
176 | |||
177 | .hidden-box { | ||
178 | text-align: right; | ||
179 | cursor: pointer; | ||
180 | position: absolute; | ||
181 | right: 0; | ||
182 | top: 0; | ||
183 | |||
184 | img { | ||
185 | width: 45%; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | .hidden-bos { | ||
190 | text-align: right; | ||
191 | cursor: pointer; | ||
192 | position: absolute; | ||
193 | right: 0; | ||
194 | top: 0; | ||
195 | |||
196 | img { | ||
197 | width: 45%; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | .login-form { | ||
202 | width: 100%; | ||
203 | min-height: 385px; | ||
204 | padding: 20px 30px 0 30px; | ||
205 | box-sizing: border-box; | ||
206 | |||
207 | .code-item { | ||
208 | display: flex; | ||
209 | align-items: center; | ||
210 | height: 40px; | ||
211 | width: 100%; | ||
212 | |||
213 | img { | ||
214 | width: 100px; | ||
215 | height: 40px; | ||
216 | float: right; | ||
217 | cursor: pointer; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /deep/.el-input__prefix { | ||
222 | display: flex; | ||
223 | align-items: center; | ||
224 | justify-content: center; | ||
225 | margin-left: 10px; | ||
226 | } | ||
227 | |||
228 | /deep/.el-input__prefix:after { | ||
229 | content: ""; | ||
230 | position: absolute; | ||
231 | right: -9px; | ||
232 | top: 13px; | ||
233 | height: 14px; | ||
234 | border-right: 1px solid #d9d9d9; | ||
235 | } | ||
236 | |||
237 | /deep/.el-input__inner { | ||
238 | padding-left: 50px; | ||
239 | } | ||
240 | |||
241 | .code-input { | ||
242 | position: relative; | ||
243 | |||
244 | /deep/.el-input__inner { | ||
245 | border-right: none; | ||
246 | } | ||
247 | |||
248 | .verification-code { | ||
249 | width: 96px; | ||
250 | height: 31px; | ||
251 | } | ||
252 | |||
253 | /deep/.el-input-group__append { | ||
254 | border-left: none; | ||
255 | background: none; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | .login-title { | ||
260 | margin-bottom: 20px; | ||
261 | text-align: center; | ||
262 | |||
263 | p { | ||
264 | font-size: 20px; | ||
265 | color: #8a8a8a; | ||
266 | width: 25%; | ||
267 | margin: 0 auto; | ||
268 | border-bottom: 2px solid #0f93f6; | ||
269 | padding-bottom: 10px; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | </style> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment