leisure-core 0.6.19 → 0.6.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/le-login/src/main.vue +644 -157
- package/package.json +1 -1
package/le-login/src/main.vue
CHANGED
|
@@ -1,83 +1,125 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="login-wrapper">
|
|
3
3
|
<div class="login-card">
|
|
4
|
-
<!--
|
|
5
|
-
<div class="
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
<!-- 左右布局容器 -->
|
|
5
|
+
<div class="login-layout">
|
|
6
|
+
<!-- 左侧Logo区域 -->
|
|
7
|
+
<div class="left-section">
|
|
8
|
+
<div class="logo-content">
|
|
9
|
+
<div class="logo-circle">
|
|
10
|
+
<i class="el-icon-s-data"></i>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="system-info">
|
|
13
|
+
<h2>{{ title }}</h2>
|
|
14
|
+
<p class="subtitle">{{ title1 }}</p>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<!-- 浏览器提示移到Logo区域 -->
|
|
18
|
+
<div class="system-tips">
|
|
19
|
+
<p class="tip">
|
|
20
|
+
<i class="el-icon-warning-outline"></i>
|
|
21
|
+
建议使用Chrome、Edge等现代浏览器
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<!-- 左侧装饰元素 -->
|
|
26
|
+
<div class="decorative-line"></div>
|
|
27
|
+
</div>
|
|
8
28
|
</div>
|
|
9
|
-
<div class="system-info">
|
|
10
|
-
<h2>{{ title }}</h2>
|
|
11
|
-
<p class="subtitle">{{ title1 }}</p>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
prefix-icon="el-icon-user"
|
|
31
|
-
class="custom-input"
|
|
32
|
-
@keydown.enter.native="nextFocus(0)"
|
|
33
|
-
autocomplete="username"
|
|
34
|
-
/>
|
|
35
|
-
</el-form-item>
|
|
36
|
-
|
|
37
|
-
<!-- 密码 -->
|
|
38
|
-
<el-form-item label="密码" prop="pwd" class="form-item">
|
|
39
|
-
<el-input
|
|
40
|
-
v-model="formdata.pwd"
|
|
41
|
-
type="password"
|
|
42
|
-
placeholder="请输入密码"
|
|
43
|
-
show-password
|
|
44
|
-
prefix-icon="el-icon-lock"
|
|
45
|
-
class="custom-input"
|
|
46
|
-
@keydown.enter.native="nextFocus(1)"
|
|
47
|
-
autocomplete="current-password"
|
|
48
|
-
/>
|
|
49
|
-
</el-form-item>
|
|
50
|
-
|
|
51
|
-
<!-- 验证码插槽 -->
|
|
52
|
-
<slot></slot>
|
|
53
|
-
|
|
54
|
-
<!-- 登录按钮 -->
|
|
55
|
-
<el-form-item class="login-btn-item">
|
|
56
|
-
<el-button
|
|
57
|
-
type="primary"
|
|
58
|
-
class="login-btn"
|
|
59
|
-
:loading="loading"
|
|
60
|
-
@click="handleLodin"
|
|
30
|
+
<!-- 右侧表单区域 -->
|
|
31
|
+
<div class="right-section">
|
|
32
|
+
<!-- 表单容器 -->
|
|
33
|
+
<div class="form-container">
|
|
34
|
+
<div class="form-header">
|
|
35
|
+
<h3>用户登录</h3>
|
|
36
|
+
<p>请输入您的账号信息</p>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<el-form
|
|
40
|
+
ref="loginForm"
|
|
41
|
+
:model="formdata"
|
|
42
|
+
:rules="rules"
|
|
43
|
+
class="login-form"
|
|
44
|
+
@submit.native.prevent="handleLodin"
|
|
61
45
|
>
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
46
|
+
<!-- 用户名 -->
|
|
47
|
+
<el-form-item label="用户名" prop="account" class="form-item">
|
|
48
|
+
<el-input
|
|
49
|
+
v-model="formdata.account"
|
|
50
|
+
placeholder="请输入用户名"
|
|
51
|
+
prefix-icon="el-icon-user"
|
|
52
|
+
class="custom-input"
|
|
53
|
+
@keydown.enter.native="nextFocus(0)"
|
|
54
|
+
autocomplete="username"
|
|
55
|
+
/>
|
|
56
|
+
</el-form-item>
|
|
57
|
+
|
|
58
|
+
<!-- 密码 -->
|
|
59
|
+
<el-form-item label="密码" prop="pwd" class="form-item">
|
|
60
|
+
<el-input
|
|
61
|
+
v-model="formdata.pwd"
|
|
62
|
+
type="password"
|
|
63
|
+
placeholder="请输入密码"
|
|
64
|
+
show-password
|
|
65
|
+
prefix-icon="el-icon-lock"
|
|
66
|
+
class="custom-input"
|
|
67
|
+
@keydown.enter.native="nextFocus(1)"
|
|
68
|
+
autocomplete="current-password"
|
|
69
|
+
/>
|
|
70
|
+
</el-form-item>
|
|
71
|
+
|
|
72
|
+
<!-- 验证码区域(移除label) -->
|
|
73
|
+
<el-form-item
|
|
74
|
+
prop="captcha"
|
|
75
|
+
class="captcha-item"
|
|
76
|
+
v-if="captchaRequired"
|
|
77
|
+
>
|
|
78
|
+
<div class="captcha-wrapper">
|
|
79
|
+
<el-input
|
|
80
|
+
v-model="formdata.captcha"
|
|
81
|
+
placeholder="请输入6位验证码"
|
|
82
|
+
class="captcha-input"
|
|
83
|
+
prefix-icon="el-icon-message"
|
|
84
|
+
maxlength="6"
|
|
85
|
+
@keydown.enter.native="handleLodin"
|
|
86
|
+
></el-input>
|
|
87
|
+
<el-button
|
|
88
|
+
class="captcha-button"
|
|
89
|
+
type="primary"
|
|
90
|
+
:disabled="isDis || isCounting"
|
|
91
|
+
@click="sendCaptcha"
|
|
92
|
+
:loading="sending"
|
|
93
|
+
>
|
|
94
|
+
<span class="button-text">
|
|
95
|
+
{{ isCounting ? `${retime}秒` : "获取验证码" }}
|
|
96
|
+
</span>
|
|
97
|
+
</el-button>
|
|
98
|
+
</div>
|
|
99
|
+
</el-form-item>
|
|
100
|
+
|
|
101
|
+
<!-- 登录按钮 -->
|
|
102
|
+
<el-form-item class="login-btn-item">
|
|
103
|
+
<el-button
|
|
104
|
+
type="primary"
|
|
105
|
+
class="login-btn"
|
|
106
|
+
:loading="loading"
|
|
107
|
+
@click="handleLodin"
|
|
108
|
+
>
|
|
109
|
+
<span v-if="!loading">登录系统</span>
|
|
110
|
+
<span v-else>登录中...</span>
|
|
111
|
+
</el-button>
|
|
112
|
+
</el-form-item>
|
|
113
|
+
</el-form>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
75
116
|
</div>
|
|
76
117
|
</div>
|
|
77
118
|
</div>
|
|
78
119
|
</template>
|
|
79
120
|
|
|
80
121
|
<script>
|
|
122
|
+
import { setToken } from "../../le-libs/js/tokens";
|
|
81
123
|
export default {
|
|
82
124
|
name: "le-login",
|
|
83
125
|
props: {
|
|
@@ -93,12 +135,18 @@ export default {
|
|
|
93
135
|
type: String,
|
|
94
136
|
default: "Wine Culture Museum Management System",
|
|
95
137
|
},
|
|
138
|
+
// 添加验证码相关props
|
|
139
|
+
captchaRequired: {
|
|
140
|
+
type: Boolean,
|
|
141
|
+
default: true,
|
|
142
|
+
},
|
|
96
143
|
},
|
|
97
144
|
data() {
|
|
98
145
|
return {
|
|
99
146
|
formdata: {
|
|
100
147
|
account: "",
|
|
101
148
|
pwd: "",
|
|
149
|
+
captcha: "",
|
|
102
150
|
},
|
|
103
151
|
rules: {
|
|
104
152
|
account: [
|
|
@@ -119,8 +167,25 @@ export default {
|
|
|
119
167
|
trigger: "blur",
|
|
120
168
|
},
|
|
121
169
|
],
|
|
170
|
+
captcha: this.captchaRequired
|
|
171
|
+
? [
|
|
172
|
+
{ required: true, message: "请输入验证码", trigger: "blur" },
|
|
173
|
+
{ len: 6, message: "验证码长度为6位", trigger: "blur" },
|
|
174
|
+
{
|
|
175
|
+
pattern: /^\d{6}$/,
|
|
176
|
+
message: "验证码必须是6位数字",
|
|
177
|
+
trigger: "blur",
|
|
178
|
+
},
|
|
179
|
+
]
|
|
180
|
+
: [],
|
|
122
181
|
},
|
|
123
182
|
loading: false,
|
|
183
|
+
// 验证码相关数据
|
|
184
|
+
sending: false, // 发送中状态
|
|
185
|
+
isCounting: false, // 是否正在倒计时
|
|
186
|
+
retime: 60, // 倒计时时间
|
|
187
|
+
isDis: false, // 按钮是否禁用
|
|
188
|
+
countdownTimer: null, // 倒计时定时器
|
|
124
189
|
};
|
|
125
190
|
},
|
|
126
191
|
mounted() {
|
|
@@ -131,6 +196,13 @@ export default {
|
|
|
131
196
|
firstInput.focus();
|
|
132
197
|
}
|
|
133
198
|
});
|
|
199
|
+
|
|
200
|
+
// 组件销毁前清除定时器
|
|
201
|
+
this.$once("hook:beforeDestroy", () => {
|
|
202
|
+
if (this.countdownTimer) {
|
|
203
|
+
clearInterval(this.countdownTimer);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
134
206
|
},
|
|
135
207
|
methods: {
|
|
136
208
|
nextFocus(index) {
|
|
@@ -149,6 +221,7 @@ export default {
|
|
|
149
221
|
{
|
|
150
222
|
account: this.formdata.account,
|
|
151
223
|
pwd: this.formdata.pwd,
|
|
224
|
+
captcha: this.captchaRequired ? this.formdata.captcha : undefined,
|
|
152
225
|
},
|
|
153
226
|
this.loginAfter,
|
|
154
227
|
this.nav2Home,
|
|
@@ -162,8 +235,12 @@ export default {
|
|
|
162
235
|
const code = res?.data?.code || "";
|
|
163
236
|
if (code === "10000") {
|
|
164
237
|
const data = res.data.data;
|
|
238
|
+
if (data && data.cid && data.cid.length > 0) {
|
|
239
|
+
this.$store.commit("setCid", data.cid);
|
|
240
|
+
}
|
|
165
241
|
this.$store.commit("setUserInfo", data);
|
|
166
|
-
this.$
|
|
242
|
+
this.$emit("loginAfter", data);
|
|
243
|
+
setToken(res.data.data.token);
|
|
167
244
|
this.$message.success("登录成功");
|
|
168
245
|
} else {
|
|
169
246
|
this.$message.error(res?.data?.msg || "登录失败");
|
|
@@ -177,6 +254,58 @@ export default {
|
|
|
177
254
|
getUserInfo() {
|
|
178
255
|
return this.formdata;
|
|
179
256
|
},
|
|
257
|
+
|
|
258
|
+
validatePhone(phone) {
|
|
259
|
+
const phoneRegex = /^1[3-9]\d{9}$/;
|
|
260
|
+
return phoneRegex.test(phone);
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
// 发送验证码
|
|
264
|
+
sendCaptcha() {
|
|
265
|
+
if (
|
|
266
|
+
!this.formdata.account ||
|
|
267
|
+
!this.validatePhone(this.formdata.account)
|
|
268
|
+
) {
|
|
269
|
+
this.$message.error("请输入正确的手机号码");
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// 验证密码
|
|
274
|
+
if (!this.formdata.pwd) {
|
|
275
|
+
this.$message.error("请输入密码");
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this.sending = true;
|
|
280
|
+
|
|
281
|
+
// 触发发送验证码事件,父组件可以监听这个事件来处理发送逻辑
|
|
282
|
+
this.$emit("sendCaptcha", {
|
|
283
|
+
account: this.formdata.account,
|
|
284
|
+
pwd: this.formdata.pwd,
|
|
285
|
+
success: this.startCountdown,
|
|
286
|
+
fail: () => {
|
|
287
|
+
this.sending = false;
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
// 开始倒计时
|
|
293
|
+
startCountdown() {
|
|
294
|
+
this.sending = false;
|
|
295
|
+
this.isCounting = true;
|
|
296
|
+
this.isDis = true;
|
|
297
|
+
this.retime = 60;
|
|
298
|
+
|
|
299
|
+
this.countdownTimer = setInterval(() => {
|
|
300
|
+
this.retime--;
|
|
301
|
+
if (this.retime <= 0) {
|
|
302
|
+
clearInterval(this.countdownTimer);
|
|
303
|
+
this.isCounting = false;
|
|
304
|
+
this.isDis = false;
|
|
305
|
+
this.retime = 60;
|
|
306
|
+
}
|
|
307
|
+
}, 1000);
|
|
308
|
+
},
|
|
180
309
|
},
|
|
181
310
|
};
|
|
182
311
|
</script>
|
|
@@ -184,11 +313,15 @@ export default {
|
|
|
184
313
|
<style lang="scss" scoped>
|
|
185
314
|
.login-wrapper {
|
|
186
315
|
width: 100%;
|
|
187
|
-
max-width:
|
|
316
|
+
max-width: 900px;
|
|
188
317
|
margin: 0 auto;
|
|
189
318
|
padding: 0 20px;
|
|
190
319
|
|
|
191
|
-
@media (max-width:
|
|
320
|
+
@media (max-width: 1024px) {
|
|
321
|
+
max-width: 800px;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@media (max-width: 768px) {
|
|
192
325
|
max-width: 100%;
|
|
193
326
|
padding: 0 15px;
|
|
194
327
|
}
|
|
@@ -196,101 +329,323 @@ export default {
|
|
|
196
329
|
|
|
197
330
|
.login-card {
|
|
198
331
|
background: rgba(255, 255, 255, 0.98);
|
|
199
|
-
border-radius:
|
|
200
|
-
padding: 40px
|
|
201
|
-
box-shadow: 0 20px
|
|
202
|
-
border: 1px solid rgba(255, 255, 255, 0.
|
|
332
|
+
border-radius: 20px;
|
|
333
|
+
padding: 40px;
|
|
334
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1), 0 8px 30px rgba(0, 0, 0, 0.08);
|
|
335
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
336
|
+
overflow: hidden;
|
|
203
337
|
|
|
204
338
|
@media (max-width: 768px) {
|
|
205
|
-
padding:
|
|
206
|
-
border-radius:
|
|
339
|
+
padding: 30px 25px;
|
|
340
|
+
border-radius: 16px;
|
|
207
341
|
}
|
|
208
342
|
|
|
209
343
|
@media (max-width: 480px) {
|
|
210
|
-
padding:
|
|
344
|
+
padding: 25px 20px;
|
|
211
345
|
}
|
|
212
346
|
}
|
|
213
347
|
|
|
214
|
-
.
|
|
215
|
-
|
|
216
|
-
|
|
348
|
+
.login-layout {
|
|
349
|
+
display: flex;
|
|
350
|
+
min-height: 500px;
|
|
351
|
+
max-height: 500px;
|
|
217
352
|
|
|
218
353
|
@media (max-width: 768px) {
|
|
219
|
-
|
|
354
|
+
flex-direction: column;
|
|
355
|
+
min-height: auto;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* 左侧Logo区域 */
|
|
360
|
+
.left-section {
|
|
361
|
+
flex: 1;
|
|
362
|
+
display: flex;
|
|
363
|
+
align-items: center;
|
|
364
|
+
justify-content: center;
|
|
365
|
+
padding: 40px;
|
|
366
|
+
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
367
|
+
border-radius: 16px 0 0 16px;
|
|
368
|
+
|
|
369
|
+
@media (max-width: 768px) {
|
|
370
|
+
padding: 30px 25px;
|
|
371
|
+
border-radius: 16px 16px 0 0;
|
|
372
|
+
margin-bottom: 20px;
|
|
220
373
|
}
|
|
221
374
|
|
|
375
|
+
@media (max-width: 480px) {
|
|
376
|
+
padding: 25px 20px;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.logo-content {
|
|
381
|
+
text-align: center;
|
|
382
|
+
max-width: 320px;
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-direction: column;
|
|
385
|
+
height: 100%;
|
|
386
|
+
justify-content: center;
|
|
387
|
+
|
|
222
388
|
.logo-circle {
|
|
223
|
-
width:
|
|
224
|
-
height:
|
|
389
|
+
width: 100px;
|
|
390
|
+
height: 100px;
|
|
225
391
|
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
|
226
|
-
border-radius:
|
|
392
|
+
border-radius: 20px;
|
|
227
393
|
display: flex;
|
|
228
394
|
align-items: center;
|
|
229
395
|
justify-content: center;
|
|
230
|
-
margin: 0 auto
|
|
231
|
-
box-shadow: 0
|
|
396
|
+
margin: 0 auto 30px;
|
|
397
|
+
box-shadow: 0 15px 35px rgba(59, 130, 246, 0.25),
|
|
398
|
+
0 5px 15px rgba(59, 130, 246, 0.15);
|
|
232
399
|
|
|
233
400
|
i {
|
|
234
|
-
font-size:
|
|
401
|
+
font-size: 48px;
|
|
235
402
|
color: white;
|
|
236
403
|
}
|
|
237
404
|
}
|
|
238
405
|
|
|
239
406
|
.system-info {
|
|
407
|
+
margin-bottom: 30px;
|
|
408
|
+
|
|
240
409
|
h2 {
|
|
241
|
-
font-size:
|
|
242
|
-
font-weight:
|
|
410
|
+
font-size: 28px;
|
|
411
|
+
font-weight: 700;
|
|
243
412
|
color: #1e293b;
|
|
244
|
-
margin: 0 0
|
|
413
|
+
margin: 0 0 15px 0;
|
|
245
414
|
line-height: 1.3;
|
|
415
|
+
letter-spacing: 0.5px;
|
|
246
416
|
}
|
|
247
417
|
|
|
248
418
|
.subtitle {
|
|
249
|
-
font-size:
|
|
419
|
+
font-size: 16px;
|
|
250
420
|
color: #64748b;
|
|
251
421
|
margin: 0;
|
|
252
422
|
font-weight: 400;
|
|
423
|
+
letter-spacing: 0.5px;
|
|
424
|
+
line-height: 1.5;
|
|
253
425
|
}
|
|
254
426
|
}
|
|
427
|
+
|
|
428
|
+
/* 左侧浏览器提示 */
|
|
429
|
+
.system-tips {
|
|
430
|
+
margin-top: auto;
|
|
431
|
+
padding-top: 20px;
|
|
432
|
+
text-align: center;
|
|
433
|
+
width: 100%;
|
|
434
|
+
|
|
435
|
+
.tip {
|
|
436
|
+
display: inline-flex;
|
|
437
|
+
align-items: center;
|
|
438
|
+
justify-content: center;
|
|
439
|
+
font-size: 12px;
|
|
440
|
+
color: #64748b;
|
|
441
|
+
margin: 0;
|
|
442
|
+
line-height: 1.5;
|
|
443
|
+
|
|
444
|
+
i {
|
|
445
|
+
margin-right: 6px;
|
|
446
|
+
font-size: 13px;
|
|
447
|
+
color: #94a3b8;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.decorative-line {
|
|
453
|
+
width: 60px;
|
|
454
|
+
height: 4px;
|
|
455
|
+
background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%);
|
|
456
|
+
border-radius: 2px;
|
|
457
|
+
margin: 20px auto 0;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* 右侧表单区域 */
|
|
462
|
+
.right-section {
|
|
463
|
+
flex: 1.2;
|
|
464
|
+
display: flex;
|
|
465
|
+
flex-direction: column;
|
|
466
|
+
padding: 40px 40px 40px 50px;
|
|
467
|
+
|
|
468
|
+
@media (max-width: 1024px) {
|
|
469
|
+
padding: 40px 40px 40px 40px;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
@media (max-width: 768px) {
|
|
473
|
+
padding: 0;
|
|
474
|
+
}
|
|
255
475
|
}
|
|
256
476
|
|
|
257
477
|
.form-container {
|
|
258
|
-
|
|
478
|
+
flex: 1;
|
|
479
|
+
display: flex;
|
|
480
|
+
flex-direction: column;
|
|
481
|
+
justify-content: center;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.form-header {
|
|
485
|
+
margin-bottom: 40px;
|
|
259
486
|
|
|
487
|
+
h3 {
|
|
488
|
+
font-size: 24px;
|
|
489
|
+
font-weight: 700;
|
|
490
|
+
color: #1e293b;
|
|
491
|
+
margin: 0 0 8px 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
p {
|
|
495
|
+
font-size: 14px;
|
|
496
|
+
color: #64748b;
|
|
497
|
+
margin: 0;
|
|
498
|
+
font-weight: 400;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.login-form {
|
|
260
503
|
.form-item {
|
|
261
|
-
margin-bottom:
|
|
504
|
+
margin-bottom: 28px;
|
|
262
505
|
|
|
263
506
|
&:last-of-type {
|
|
264
|
-
margin-bottom:
|
|
507
|
+
margin-bottom: 32px;
|
|
265
508
|
}
|
|
266
509
|
|
|
267
510
|
.el-form-item__label {
|
|
268
511
|
display: block;
|
|
269
512
|
font-size: 14px;
|
|
270
|
-
font-weight:
|
|
513
|
+
font-weight: 600;
|
|
271
514
|
color: #475569;
|
|
272
|
-
margin-bottom:
|
|
515
|
+
margin-bottom: 10px;
|
|
273
516
|
padding-bottom: 0;
|
|
274
517
|
}
|
|
275
518
|
}
|
|
519
|
+
|
|
520
|
+
/* 验证码区域 */
|
|
521
|
+
.captcha-item {
|
|
522
|
+
margin-bottom: 32px;
|
|
523
|
+
|
|
524
|
+
.captcha-wrapper {
|
|
525
|
+
display: flex;
|
|
526
|
+
gap: 12px;
|
|
527
|
+
align-items: center;
|
|
528
|
+
|
|
529
|
+
.captcha-input {
|
|
530
|
+
flex: 3; /* 增大输入框宽度比例 */
|
|
531
|
+
|
|
532
|
+
::v-deep .el-input__inner {
|
|
533
|
+
height: 52px;
|
|
534
|
+
border-radius: 12px;
|
|
535
|
+
border: 2px solid #e2e8f0;
|
|
536
|
+
font-size: 15px;
|
|
537
|
+
color: #334155;
|
|
538
|
+
padding-left: 48px !important;
|
|
539
|
+
padding-right: 16px;
|
|
540
|
+
transition: all 0.2s ease;
|
|
541
|
+
box-sizing: border-box;
|
|
542
|
+
|
|
543
|
+
&:hover {
|
|
544
|
+
border-color: #cbd5e1;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
&:focus {
|
|
548
|
+
border-color: #3b82f6;
|
|
549
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
550
|
+
outline: none;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
&::placeholder {
|
|
554
|
+
color: #94a3b8;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
::v-deep .el-input__prefix {
|
|
559
|
+
left: 16px;
|
|
560
|
+
display: flex;
|
|
561
|
+
align-items: center;
|
|
562
|
+
justify-content: center;
|
|
563
|
+
pointer-events: none;
|
|
564
|
+
|
|
565
|
+
.el-icon {
|
|
566
|
+
color: #94a3b8;
|
|
567
|
+
font-size: 20px;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.captcha-button {
|
|
573
|
+
flex: 1; /* 减小按钮宽度比例 */
|
|
574
|
+
min-width: 120px; /* 设置最小宽度 */
|
|
575
|
+
height: 52px;
|
|
576
|
+
border-radius: 12px;
|
|
577
|
+
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
|
578
|
+
border: none;
|
|
579
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
580
|
+
position: relative;
|
|
581
|
+
overflow: hidden;
|
|
582
|
+
|
|
583
|
+
&:hover:not(.is-disabled) {
|
|
584
|
+
transform: translateY(-2px);
|
|
585
|
+
box-shadow: 0 12px 30px rgba(16, 185, 129, 0.4);
|
|
586
|
+
background: linear-gradient(135deg, #059669 0%, #047857 100%);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
&:active {
|
|
590
|
+
transform: translateY(0);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
&:focus {
|
|
594
|
+
outline: none;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.button-text {
|
|
598
|
+
font-size: 14px;
|
|
599
|
+
font-weight: 600;
|
|
600
|
+
letter-spacing: 0.5px;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
&::after {
|
|
604
|
+
content: "";
|
|
605
|
+
position: absolute;
|
|
606
|
+
top: 50%;
|
|
607
|
+
left: 50%;
|
|
608
|
+
width: 5px;
|
|
609
|
+
height: 5px;
|
|
610
|
+
background: rgba(255, 255, 255, 0.5);
|
|
611
|
+
opacity: 0;
|
|
612
|
+
border-radius: 100%;
|
|
613
|
+
transform: scale(1, 1) translate(-50%);
|
|
614
|
+
transform-origin: 50% 50%;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
&:focus:not(:active)::after {
|
|
618
|
+
animation: ripple 1s ease-out;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
@keyframes ripple {
|
|
626
|
+
0% {
|
|
627
|
+
transform: scale(0, 0);
|
|
628
|
+
opacity: 0.5;
|
|
629
|
+
}
|
|
630
|
+
100% {
|
|
631
|
+
transform: scale(20, 20);
|
|
632
|
+
opacity: 0;
|
|
633
|
+
}
|
|
276
634
|
}
|
|
277
635
|
|
|
278
636
|
::v-deep .custom-input {
|
|
279
|
-
// 修复图标重叠的关键:确保图标区域有正确的padding
|
|
280
637
|
.el-input {
|
|
281
|
-
// 确保输入框内部布局正确
|
|
282
638
|
display: flex;
|
|
283
639
|
align-items: center;
|
|
284
640
|
}
|
|
285
641
|
|
|
286
642
|
.el-input__inner {
|
|
287
|
-
height:
|
|
288
|
-
border-radius:
|
|
289
|
-
border:
|
|
643
|
+
height: 52px;
|
|
644
|
+
border-radius: 12px;
|
|
645
|
+
border: 2px solid #e2e8f0;
|
|
290
646
|
font-size: 15px;
|
|
291
647
|
color: #334155;
|
|
292
|
-
|
|
293
|
-
padding-left: 40px !important;
|
|
648
|
+
padding-left: 48px !important;
|
|
294
649
|
padding-right: 16px;
|
|
295
650
|
transition: all 0.2s ease;
|
|
296
651
|
box-sizing: border-box;
|
|
@@ -311,27 +666,26 @@ export default {
|
|
|
311
666
|
}
|
|
312
667
|
|
|
313
668
|
.el-input__prefix {
|
|
314
|
-
left:
|
|
669
|
+
left: 16px;
|
|
315
670
|
display: flex;
|
|
316
671
|
align-items: center;
|
|
317
672
|
justify-content: center;
|
|
318
|
-
pointer-events: none;
|
|
673
|
+
pointer-events: none;
|
|
319
674
|
|
|
320
675
|
.el-icon {
|
|
321
676
|
color: #94a3b8;
|
|
322
|
-
font-size:
|
|
677
|
+
font-size: 20px;
|
|
323
678
|
}
|
|
324
679
|
}
|
|
325
680
|
|
|
326
|
-
// 密码显示/隐藏图标
|
|
327
681
|
.el-input__suffix {
|
|
328
|
-
right:
|
|
682
|
+
right: 16px;
|
|
329
683
|
display: flex;
|
|
330
684
|
align-items: center;
|
|
331
685
|
|
|
332
686
|
.el-icon {
|
|
333
687
|
color: #94a3b8;
|
|
334
|
-
font-size:
|
|
688
|
+
font-size: 20px;
|
|
335
689
|
cursor: pointer;
|
|
336
690
|
transition: color 0.2s ease;
|
|
337
691
|
|
|
@@ -341,9 +695,8 @@ export default {
|
|
|
341
695
|
}
|
|
342
696
|
}
|
|
343
697
|
|
|
344
|
-
// 修复密码输入框的显示/隐藏图标位置
|
|
345
698
|
&.el-input--suffix .el-input__inner {
|
|
346
|
-
padding-right:
|
|
699
|
+
padding-right: 48px !important;
|
|
347
700
|
}
|
|
348
701
|
}
|
|
349
702
|
|
|
@@ -353,17 +706,17 @@ export default {
|
|
|
353
706
|
|
|
354
707
|
.login-btn {
|
|
355
708
|
width: 100%;
|
|
356
|
-
height:
|
|
709
|
+
height: 52px;
|
|
357
710
|
font-size: 16px;
|
|
358
711
|
font-weight: 600;
|
|
359
|
-
border-radius:
|
|
712
|
+
border-radius: 12px;
|
|
360
713
|
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
|
361
714
|
border: none;
|
|
362
715
|
transition: all 0.2s ease;
|
|
363
716
|
|
|
364
717
|
&:hover {
|
|
365
718
|
transform: translateY(-2px);
|
|
366
|
-
box-shadow: 0
|
|
719
|
+
box-shadow: 0 12px 30px rgba(59, 130, 246, 0.3);
|
|
367
720
|
}
|
|
368
721
|
|
|
369
722
|
&:active {
|
|
@@ -375,39 +728,45 @@ export default {
|
|
|
375
728
|
}
|
|
376
729
|
}
|
|
377
730
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
731
|
+
/* 暗色主题适配 */
|
|
732
|
+
@media (prefers-color-scheme: dark) {
|
|
733
|
+
.login-card {
|
|
734
|
+
background: rgba(30, 41, 59, 0.95);
|
|
735
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
736
|
+
}
|
|
382
737
|
|
|
383
|
-
.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
738
|
+
.left-section {
|
|
739
|
+
background: linear-gradient(
|
|
740
|
+
135deg,
|
|
741
|
+
rgba(30, 41, 59, 0.8) 0%,
|
|
742
|
+
rgba(15, 23, 42, 0.9) 100%
|
|
743
|
+
);
|
|
744
|
+
}
|
|
389
745
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
746
|
+
.logo-content .system-info {
|
|
747
|
+
h2 {
|
|
748
|
+
color: #f1f5f9;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.subtitle {
|
|
393
752
|
color: #94a3b8;
|
|
394
753
|
}
|
|
395
754
|
}
|
|
396
|
-
}
|
|
397
755
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
756
|
+
.logo-content .system-tips .tip {
|
|
757
|
+
color: #94a3b8;
|
|
758
|
+
|
|
759
|
+
i {
|
|
760
|
+
color: #64748b;
|
|
761
|
+
}
|
|
403
762
|
}
|
|
404
763
|
|
|
405
|
-
.
|
|
406
|
-
|
|
764
|
+
.form-header {
|
|
765
|
+
h3 {
|
|
407
766
|
color: #f1f5f9;
|
|
408
767
|
}
|
|
409
768
|
|
|
410
|
-
|
|
769
|
+
p {
|
|
411
770
|
color: #94a3b8;
|
|
412
771
|
}
|
|
413
772
|
}
|
|
@@ -416,9 +775,10 @@ export default {
|
|
|
416
775
|
color: #cbd5e1;
|
|
417
776
|
}
|
|
418
777
|
|
|
419
|
-
::v-deep .custom-input
|
|
778
|
+
::v-deep .custom-input,
|
|
779
|
+
::v-deep .captcha-input {
|
|
420
780
|
.el-input__inner {
|
|
421
|
-
background: rgba(15, 23, 42, 0.
|
|
781
|
+
background: rgba(15, 23, 42, 0.5);
|
|
422
782
|
border-color: #475569;
|
|
423
783
|
color: #f1f5f9;
|
|
424
784
|
|
|
@@ -448,40 +808,167 @@ export default {
|
|
|
448
808
|
}
|
|
449
809
|
}
|
|
450
810
|
|
|
451
|
-
.
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
.tip {
|
|
455
|
-
color: #94a3b8;
|
|
811
|
+
.captcha-button {
|
|
812
|
+
background: linear-gradient(135deg, #047857 0%, #065f46 100%);
|
|
456
813
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
814
|
+
&:hover:not(.is-disabled) {
|
|
815
|
+
background: linear-gradient(135deg, #065f46 0%, #064e3b 100%);
|
|
816
|
+
box-shadow: 0 12px 30px rgba(6, 95, 70, 0.4);
|
|
460
817
|
}
|
|
461
818
|
}
|
|
462
819
|
}
|
|
463
820
|
|
|
464
|
-
|
|
465
|
-
@keyframes
|
|
821
|
+
/* 动画效果 */
|
|
822
|
+
@keyframes fadeInLeft {
|
|
466
823
|
from {
|
|
467
824
|
opacity: 0;
|
|
468
|
-
transform:
|
|
825
|
+
transform: translateX(-20px);
|
|
469
826
|
}
|
|
470
827
|
to {
|
|
471
828
|
opacity: 1;
|
|
472
|
-
transform:
|
|
829
|
+
transform: translateX(0);
|
|
473
830
|
}
|
|
474
831
|
}
|
|
475
832
|
|
|
476
|
-
|
|
477
|
-
|
|
833
|
+
@keyframes fadeInRight {
|
|
834
|
+
from {
|
|
835
|
+
opacity: 0;
|
|
836
|
+
transform: translateX(20px);
|
|
837
|
+
}
|
|
838
|
+
to {
|
|
839
|
+
opacity: 1;
|
|
840
|
+
transform: translateX(0);
|
|
841
|
+
}
|
|
478
842
|
}
|
|
479
843
|
|
|
480
|
-
.
|
|
481
|
-
animation:
|
|
844
|
+
.left-section {
|
|
845
|
+
animation: fadeInLeft 0.6s ease-out;
|
|
482
846
|
}
|
|
483
847
|
|
|
484
|
-
.
|
|
485
|
-
animation:
|
|
848
|
+
.right-section {
|
|
849
|
+
animation: fadeInRight 0.6s ease-out 0.1s both;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/* 响应式调整 */
|
|
853
|
+
@media (max-width: 768px) {
|
|
854
|
+
.login-wrapper {
|
|
855
|
+
max-width: 500px;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.login-layout {
|
|
859
|
+
min-height: auto;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
.left-section {
|
|
863
|
+
animation: none;
|
|
864
|
+
padding: 25px 20px;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.right-section {
|
|
868
|
+
animation: none;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.logo-content .logo-circle {
|
|
872
|
+
width: 80px;
|
|
873
|
+
height: 80px;
|
|
874
|
+
margin-bottom: 25px;
|
|
875
|
+
|
|
876
|
+
i {
|
|
877
|
+
font-size: 40px;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
.logo-content .system-info {
|
|
882
|
+
margin-bottom: 25px;
|
|
883
|
+
|
|
884
|
+
h2 {
|
|
885
|
+
font-size: 24px;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.subtitle {
|
|
889
|
+
font-size: 14px;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
.logo-content .system-tips {
|
|
894
|
+
margin-top: 20px;
|
|
895
|
+
padding-top: 15px;
|
|
896
|
+
|
|
897
|
+
.tip {
|
|
898
|
+
font-size: 11px;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.form-header {
|
|
903
|
+
margin-bottom: 30px;
|
|
904
|
+
|
|
905
|
+
h3 {
|
|
906
|
+
font-size: 22px;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
::v-deep .custom-input .el-input__inner,
|
|
911
|
+
::v-deep .captcha-input .el-input__inner {
|
|
912
|
+
height: 48px;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.captcha-button {
|
|
916
|
+
height: 48px;
|
|
917
|
+
min-width: 90px;
|
|
918
|
+
|
|
919
|
+
.button-text {
|
|
920
|
+
font-size: 13px;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.login-btn {
|
|
925
|
+
height: 48px;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
@media (max-width: 480px) {
|
|
930
|
+
.logo-content .logo-circle {
|
|
931
|
+
width: 70px;
|
|
932
|
+
height: 70px;
|
|
933
|
+
margin-bottom: 20px;
|
|
934
|
+
|
|
935
|
+
i {
|
|
936
|
+
font-size: 36px;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
.logo-content .system-info {
|
|
941
|
+
h2 {
|
|
942
|
+
font-size: 22px;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.form-header {
|
|
947
|
+
margin-bottom: 25px;
|
|
948
|
+
|
|
949
|
+
h3 {
|
|
950
|
+
font-size: 20px;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.login-form .form-item,
|
|
955
|
+
.login-form .captcha-item {
|
|
956
|
+
margin-bottom: 24px;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/* 移动端验证码区域垂直排列 */
|
|
960
|
+
.captcha-item .captcha-wrapper {
|
|
961
|
+
flex-direction: column;
|
|
962
|
+
gap: 12px;
|
|
963
|
+
|
|
964
|
+
.captcha-input {
|
|
965
|
+
width: 100%;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.captcha-button {
|
|
969
|
+
width: 100%;
|
|
970
|
+
min-width: 100%;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
486
973
|
}
|
|
487
974
|
</style>
|