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.
Files changed (2) hide show
  1. package/le-login/src/main.vue +644 -157
  2. package/package.json +1 -1
@@ -1,83 +1,125 @@
1
1
  <template>
2
2
  <div class="login-wrapper">
3
3
  <div class="login-card">
4
- <!-- Logo区域 -->
5
- <div class="logo-section">
6
- <div class="logo-circle">
7
- <i class="el-icon-s-data"></i>
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
- <div class="form-container">
17
- <el-form
18
- ref="loginForm"
19
- :model="formdata"
20
- :rules="rules"
21
- label-position="top"
22
- class="login-form"
23
- @submit.native.prevent="handleLodin"
24
- >
25
- <!-- 用户名 -->
26
- <el-form-item label="用户名" prop="account" class="form-item">
27
- <el-input
28
- v-model="formdata.account"
29
- placeholder="请输入用户名"
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
- <span v-if="!loading">登录系统</span>
63
- <span v-if="loading">登录中...</span>
64
- </el-button>
65
- </el-form-item>
66
- </el-form>
67
- </div>
68
-
69
- <!-- 简化后的系统提示 -->
70
- <div class="system-tips">
71
- <p class="tip">
72
- <i class="el-icon-warning-outline"></i>
73
- 建议使用Chrome、Edge等现代浏览器
74
- </p>
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.$store.commit("setToken", data.token);
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: 420px;
316
+ max-width: 900px;
188
317
  margin: 0 auto;
189
318
  padding: 0 20px;
190
319
 
191
- @media (max-width: 480px) {
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: 16px;
200
- padding: 40px 36px;
201
- box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
202
- border: 1px solid rgba(255, 255, 255, 0.1);
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: 32px 28px;
206
- border-radius: 14px;
339
+ padding: 30px 25px;
340
+ border-radius: 16px;
207
341
  }
208
342
 
209
343
  @media (max-width: 480px) {
210
- padding: 28px 24px;
344
+ padding: 25px 20px;
211
345
  }
212
346
  }
213
347
 
214
- .logo-section {
215
- text-align: center;
216
- margin-bottom: 36px;
348
+ .login-layout {
349
+ display: flex;
350
+ min-height: 500px;
351
+ max-height: 500px;
217
352
 
218
353
  @media (max-width: 768px) {
219
- margin-bottom: 32px;
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: 72px;
224
- height: 72px;
389
+ width: 100px;
390
+ height: 100px;
225
391
  background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
226
- border-radius: 18px;
392
+ border-radius: 20px;
227
393
  display: flex;
228
394
  align-items: center;
229
395
  justify-content: center;
230
- margin: 0 auto 20px;
231
- box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3);
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: 36px;
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: 24px;
242
- font-weight: 600;
410
+ font-size: 28px;
411
+ font-weight: 700;
243
412
  color: #1e293b;
244
- margin: 0 0 6px 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: 14px;
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
- margin-bottom: 28px;
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: 22px;
504
+ margin-bottom: 28px;
262
505
 
263
506
  &:last-of-type {
264
- margin-bottom: 28px;
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: 500;
513
+ font-weight: 600;
271
514
  color: #475569;
272
- margin-bottom: 8px;
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: 48px;
288
- border-radius: 10px;
289
- border: 1.5px solid #e2e8f0;
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: 12px;
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: 18px;
677
+ font-size: 20px;
323
678
  }
324
679
  }
325
680
 
326
- // 密码显示/隐藏图标
327
681
  .el-input__suffix {
328
- right: 12px;
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: 18px;
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: 40px !important;
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: 48px;
709
+ height: 52px;
357
710
  font-size: 16px;
358
711
  font-weight: 600;
359
- border-radius: 10px;
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 10px 25px rgba(59, 130, 246, 0.4);
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
- .system-tips {
379
- padding-top: 24px;
380
- border-top: 1px solid #f1f5f9;
381
- text-align: center;
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
- .tip {
384
- display: inline-flex;
385
- align-items: center;
386
- font-size: 13px;
387
- color: #64748b;
388
- margin: 0;
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
- i {
391
- margin-right: 6px;
392
- font-size: 14px;
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
- @media (prefers-color-scheme: dark) {
400
- .login-card {
401
- background: rgba(30, 41, 59, 0.95);
402
- border-color: rgba(255, 255, 255, 0.05);
756
+ .logo-content .system-tips .tip {
757
+ color: #94a3b8;
758
+
759
+ i {
760
+ color: #64748b;
761
+ }
403
762
  }
404
763
 
405
- .logo-section .system-info {
406
- h2 {
764
+ .form-header {
765
+ h3 {
407
766
  color: #f1f5f9;
408
767
  }
409
768
 
410
- .subtitle {
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.7);
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
- .system-tips {
452
- border-top-color: #334155;
453
-
454
- .tip {
455
- color: #94a3b8;
811
+ .captcha-button {
812
+ background: linear-gradient(135deg, #047857 0%, #065f46 100%);
456
813
 
457
- i {
458
- color: #64748b;
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 fadeIn {
821
+ /* 动画效果 */
822
+ @keyframes fadeInLeft {
466
823
  from {
467
824
  opacity: 0;
468
- transform: translateY(10px);
825
+ transform: translateX(-20px);
469
826
  }
470
827
  to {
471
828
  opacity: 1;
472
- transform: translateY(0);
829
+ transform: translateX(0);
473
830
  }
474
831
  }
475
832
 
476
- .logo-section {
477
- animation: fadeIn 0.5s ease-out;
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
- .form-container {
481
- animation: fadeIn 0.5s ease-out 0.1s both;
844
+ .left-section {
845
+ animation: fadeInLeft 0.6s ease-out;
482
846
  }
483
847
 
484
- .login-btn-item {
485
- animation: fadeIn 0.5s ease-out 0.2s both;
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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leisure-core",
3
- "version": "0.6.19",
3
+ "version": "0.6.21",
4
4
  "description": "leisure-core是京心数据基于vue2.x开发的一套后台管理系统桌面端组件库,封装了大量实用的UI控件模板,非常方便开发者快速搭建前端应用",
5
5
  "private": false,
6
6
  "author": "北方乐逍遥(zcx7878)",