vue2-client 1.22.30 → 1.22.31

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.
@@ -0,0 +1,781 @@
1
+ <template>
2
+ <div class="scale-wrapper">
3
+ <div class="page-container">
4
+ <!-- 背景层 -->
5
+ <div class="bg-rect-685"></div>
6
+ <div class="bg-annotation3"></div>
7
+ <div class="decorative-stripes">
8
+ <div
9
+ v-for="n in 28"
10
+ :key="n"
11
+ class="stripe"
12
+ :class="{ 'stripe-no-blur': isNoBlurStripe(n) }"
13
+ :style="{ left: `calc(${n - 1} * (100% / 28))` }"
14
+ ></div>
15
+ </div>
16
+
17
+ <!-- 上下结构主体 -->
18
+ <div class="main-layout">
19
+ <!-- 上部区域 -->
20
+ <div class="top-section">
21
+ <div class="brand-group">
22
+ <img src="~@/assets/img/hisLogo.png" alt="芯蕊智能" class="brand-logo-img" />
23
+ </div>
24
+
25
+ <!-- 动态系统标题 + 下拉箭头 -->
26
+ <div class="his-system-title" @click="toggleHisDropdown">
27
+ {{ currentSystemName }}
28
+ <span class="his-dropdown-arrow">
29
+ <svg class="arrow-icon" viewBox="0 0 24 24" fill="none">
30
+ <path d="M9 6L15 12L9 18" stroke="#94979E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
31
+ </svg>
32
+ </span>
33
+ </div>
34
+ <div v-if="hisDropdownOpen" class="dropdown-menu his-dropdown-menu">
35
+ <div
36
+ v-for="sys in systemList"
37
+ :key="sys.code"
38
+ class="dropdown-item"
39
+ :class="{ active: currentSystem.code === sys.code }"
40
+ @click="selectSystem(sys)"
41
+ >
42
+ {{ sys.name }}
43
+ </div>
44
+ </div>
45
+
46
+ <div class="welcome-cn">欢迎使用芯蕊智能医疗系统</div>
47
+ <div class="welcome-en">Welcome to log in to Xinrui Intelligent Medical System</div>
48
+ <div class="divider-line"></div>
49
+ </div>
50
+
51
+ <!-- 下部区域(毛玻璃基底) -->
52
+ <div class="bottom-section">
53
+ <div class="rect-112"></div>
54
+
55
+ <!-- 登录卡片 -->
56
+ <div class="login-card">
57
+ <!-- 人员选择(高度 50px) -->
58
+ <div class="form-item" @click.stop="toggleUserDropdown">
59
+ <div class="select-box user-row">
60
+ <div class="user-avatar-mini" v-if="selectedUser">
61
+ <div class="avatar-circle" v-if="selectedUser.avatar">
62
+ <img :src="selectedUser.avatar" class="avatar-img" />
63
+ </div>
64
+ <div class="avatar-circle default-avatar" v-else></div>
65
+ <span class="online-dot"></span>
66
+ </div>
67
+ <span class="select-text">{{ selectedUser ? selectedUser.name : '请选择人员' }}</span>
68
+ <svg class="arrow-icon" viewBox="0 0 24 24" fill="none">
69
+ <path d="M9 6L15 12L9 18" stroke="#94979E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
70
+ </svg>
71
+ </div>
72
+ <div v-if="userDropdownOpen" class="dropdown-menu dropdown-relative">
73
+ <div
74
+ v-for="user in filteredUsers"
75
+ :key="user.code"
76
+ class="dropdown-item"
77
+ :class="{ active: selectedUser && selectedUser.code === user.code }"
78
+ @click.stop="selectUser(user)"
79
+ >
80
+ <div class="avatar-circle" v-if="user.avatar">
81
+ <img :src="user.avatar" class="dropdown-avatar" />
82
+ </div>
83
+ <div class="avatar-circle default-avatar-small" v-else></div>
84
+ {{ user.name }} - {{ user.title }}
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ <!-- 职位筛选(高度 32px) -->
90
+ <div class="form-item" @click.stop="togglePositionDropdown">
91
+ <div class="select-box">
92
+ <span class="select-label">职位</span>
93
+ <span class="select-text">{{ filterPosition || '全部' }}</span>
94
+ <svg class="arrow-icon" viewBox="0 0 24 24" fill="none">
95
+ <path d="M9 6L15 12L9 18" stroke="#94979E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
96
+ </svg>
97
+ </div>
98
+ <div v-if="positionDropdownOpen" class="dropdown-menu dropdown-relative">
99
+ <div class="dropdown-item" :class="{ active: !filterPosition }" @click.stop="setFilterPosition('')">全部</div>
100
+ <div
101
+ v-for="pos in positionList"
102
+ :key="pos"
103
+ class="dropdown-item"
104
+ :class="{ active: filterPosition === pos }"
105
+ @click.stop="setFilterPosition(pos)"
106
+ >
107
+ {{ pos }}
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- 科室筛选(高度 32px) -->
113
+ <div class="form-item" @click.stop="toggleDeptDropdown">
114
+ <div class="select-box">
115
+ <span class="select-label">科室选择</span>
116
+ <span class="select-text">{{ filterDept || '全部' }}</span>
117
+ <svg class="arrow-icon" viewBox="0 0 24 24" fill="none">
118
+ <path d="M9 6L15 12L9 18" stroke="#94979E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
119
+ </svg>
120
+ </div>
121
+ <div v-if="deptDropdownOpen" class="dropdown-menu dropdown-relative">
122
+ <div class="dropdown-item" :class="{ active: !filterDept }" @click.stop="setFilterDept('')">全部</div>
123
+ <div
124
+ v-for="dept in deptList"
125
+ :key="dept"
126
+ class="dropdown-item"
127
+ :class="{ active: filterDept === dept }"
128
+ @click.stop="setFilterDept(dept)"
129
+ >
130
+ {{ dept }}
131
+ </div>
132
+ </div>
133
+ </div>
134
+
135
+ <!-- 密码(高度 32px) -->
136
+ <div class="form-item password-item">
137
+ <input
138
+ :type="passwordVisible ? 'text' : 'password'"
139
+ :placeholder="passwordVisible ? '请输入密码' : '••••••••••'"
140
+ class="password-input"
141
+ v-model="actualPassword"
142
+ @focus="onPasswordFocus"
143
+ @blur="onPasswordBlur"
144
+ @keyup.enter="handleLogin"
145
+ />
146
+ <div class="password-toggle" @click.stop="togglePasswordVisibility">
147
+ <svg v-if="!passwordVisible" viewBox="0 0 24 24" fill="none">
148
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" stroke="#848484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
149
+ <circle cx="12" cy="12" r="3" stroke="#848484" stroke-width="2" />
150
+ </svg>
151
+ <svg v-else viewBox="0 0 24 24" fill="none">
152
+ <path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94" stroke="#848484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
153
+ <path d="M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19" stroke="#848484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
154
+ <line x1="1" y1="1" x2="23" y2="23" stroke="#848484" stroke-width="2" stroke-linecap="round" />
155
+ </svg>
156
+ </div>
157
+ </div>
158
+
159
+ <!-- 医师编码(高度 32px) -->
160
+ <div class="form-item doctor-code-row">
161
+ <span class="input-label">医师编码:</span>
162
+ <input
163
+ type="text"
164
+ class="disabled-input"
165
+ :value="selectedUser ? selectedUser.doctorCode : ''"
166
+ disabled
167
+ placeholder="自动回显"
168
+ />
169
+ </div>
170
+
171
+ <!-- 登录按钮 -->
172
+ <div class="login-btn-wrap" @click="handleLogin">
173
+ <div class="login-btn">
174
+ <span class="login-btn-text">登录</span>
175
+ </div>
176
+ </div>
177
+ </div>
178
+
179
+ <div class="copyright">©版权所有 2024-2026 XINRUI 芯蕊智能 . All Rights Reserved.</div>
180
+ </div>
181
+ </div>
182
+ </div>
183
+
184
+ <div v-if="toastMsg" class="toast">{{ toastMsg }}</div>
185
+ </div>
186
+ </template>
187
+
188
+ <script>
189
+ export default {
190
+ name: 'LoginPage',
191
+ data() {
192
+ return {
193
+ // 系统列表
194
+ systemList: [],
195
+ currentSystem: { code: '', name: 'HIS SYSTEM' },
196
+ // 用户相关
197
+ allUsers: [],
198
+ selectedUser: null,
199
+ filterPosition: '',
200
+ filterDept: '',
201
+ actualPassword: '',
202
+ passwordVisible: false,
203
+ // 下拉状态
204
+ hisDropdownOpen: false,
205
+ userDropdownOpen: false,
206
+ positionDropdownOpen: false,
207
+ deptDropdownOpen: false,
208
+ toastMsg: '',
209
+ isPasswordFocused: false
210
+ }
211
+ },
212
+ computed: {
213
+ currentSystemName() {
214
+ return this.currentSystem.name || 'HIS SYSTEM'
215
+ },
216
+ positionList() {
217
+ return [...new Set(this.allUsers.map(u => u.title))]
218
+ },
219
+ deptList() {
220
+ return [...new Set(this.allUsers.map(u => u.deptName))]
221
+ },
222
+ filteredUsers() {
223
+ let list = this.allUsers
224
+ if (this.filterPosition) {
225
+ list = list.filter(u => u.title === this.filterPosition)
226
+ }
227
+ if (this.filterDept) {
228
+ list = list.filter(u => u.deptName === this.filterDept)
229
+ }
230
+ return list
231
+ }
232
+ },
233
+ methods: {
234
+ isNoBlurStripe(index) {
235
+ return index === 9 || index === 12 || index === 17
236
+ },
237
+ // 获取系统列表(模拟,实际替换为 API)
238
+ async fetchSystems() {
239
+ // 示例:this.systemList = (await this.$http.get('/api/systems')).data
240
+ this.systemList = [
241
+ { code: 'his', name: 'HIS SYSTEM' },
242
+ { code: 'backup', name: '备用系统' }
243
+ ]
244
+ if (this.systemList.length) {
245
+ this.currentSystem = { ...this.systemList[0] }
246
+ }
247
+ },
248
+ // 选择系统
249
+ selectSystem(sys) {
250
+ this.currentSystem = { ...sys }
251
+ this.hisDropdownOpen = false
252
+ this.showToast(`已切换至: ${sys.name}`)
253
+ },
254
+ async fetchUsers() {
255
+ this.allUsers = [
256
+ {
257
+ name: '刘文军',
258
+ code: '1001',
259
+ title: '主任医师',
260
+ deptName: '心血管内科',
261
+ deptCode: 'D001',
262
+ doctorCode: '652106958140237',
263
+ avatar: 'http://192.168.50.67:31567/resource/af-system/images/17aa33361e4548988f72669756c7d965.jpg'
264
+ },
265
+ {
266
+ name: '张明华',
267
+ code: '1002',
268
+ title: '副主任医师',
269
+ deptName: '神经内科',
270
+ deptCode: 'D002',
271
+ doctorCode: '652106958140238',
272
+ avatar: 'http://192.168.50.67:31567/resource/af-system/images/17aa33361e4548988f72669756c7d965.jpg'
273
+ },
274
+ {
275
+ name: '李芳',
276
+ code: '1003',
277
+ title: '主治医师',
278
+ deptName: '心血管内科',
279
+ deptCode: 'D001',
280
+ doctorCode: '652106958140239',
281
+ avatar: 'http://192.168.50.67:31567/resource/af-system/images/17aa33361e4548988f72669756c7d965.jpg'
282
+ }
283
+ ]
284
+ },
285
+ selectUser(user) {
286
+ this.selectedUser = { ...user }
287
+ this.userDropdownOpen = false
288
+ },
289
+ setFilterPosition(pos) {
290
+ this.filterPosition = pos
291
+ this.positionDropdownOpen = false
292
+ this.selectedUser = null
293
+ },
294
+ setFilterDept(dept) {
295
+ this.filterDept = dept
296
+ this.deptDropdownOpen = false
297
+ this.selectedUser = null
298
+ },
299
+ toggleHisDropdown() {
300
+ this.closeOtherDropdowns('his')
301
+ this.hisDropdownOpen = !this.hisDropdownOpen
302
+ },
303
+ toggleUserDropdown() {
304
+ this.closeOtherDropdowns('user')
305
+ this.userDropdownOpen = !this.userDropdownOpen
306
+ },
307
+ togglePositionDropdown() {
308
+ this.closeOtherDropdowns('position')
309
+ this.positionDropdownOpen = !this.positionDropdownOpen
310
+ },
311
+ toggleDeptDropdown() {
312
+ this.closeOtherDropdowns('dept')
313
+ this.deptDropdownOpen = !this.deptDropdownOpen
314
+ },
315
+ closeAllDropdowns() {
316
+ this.hisDropdownOpen = false
317
+ this.userDropdownOpen = false
318
+ this.positionDropdownOpen = false
319
+ this.deptDropdownOpen = false
320
+ },
321
+ closeOtherDropdowns(type) {
322
+ if (type !== 'his') this.hisDropdownOpen = false
323
+ if (type !== 'user') this.userDropdownOpen = false
324
+ if (type !== 'position') this.positionDropdownOpen = false
325
+ if (type !== 'dept') this.deptDropdownOpen = false
326
+ },
327
+ togglePasswordVisibility() {
328
+ this.passwordVisible = !this.passwordVisible
329
+ },
330
+ onPasswordFocus() {
331
+ this.isPasswordFocused = true
332
+ },
333
+ onPasswordBlur() {
334
+ this.isPasswordFocused = false
335
+ },
336
+ handleLogin() {
337
+ if (!this.selectedUser) return this.showToast('请选择人员')
338
+ if (!this.actualPassword) return this.showToast('请输入密码')
339
+ this.showToast(`登录中... 人员编码: ${this.selectedUser.code}`)
340
+ },
341
+ showToast(msg) {
342
+ this.toastMsg = msg
343
+ setTimeout(() => { this.toastMsg = '' }, 2200)
344
+ },
345
+ handleClickOutside(e) {
346
+ const dropdowns = this.$el.querySelectorAll('.dropdown-menu')
347
+ let inside = false
348
+ dropdowns.forEach(menu => {
349
+ if (menu.contains(e.target)) inside = true
350
+ })
351
+ const triggers = this.$el.querySelectorAll('.select-box, .his-system-title')
352
+ triggers.forEach(el => {
353
+ if (el.contains(e.target)) inside = true
354
+ })
355
+ if (!inside) {
356
+ this.closeAllDropdowns()
357
+ }
358
+ }
359
+ },
360
+ mounted() {
361
+ this.fetchSystems()
362
+ this.fetchUsers()
363
+ document.addEventListener('click', this.handleClickOutside)
364
+ },
365
+ beforeUnmount() {
366
+ document.removeEventListener('click', this.handleClickOutside)
367
+ }
368
+ }
369
+ </script>
370
+
371
+ <style scoped>
372
+ * {
373
+ margin: 0;
374
+ padding: 0;
375
+ box-sizing: border-box;
376
+ }
377
+
378
+ .scale-wrapper {
379
+ width: 100vw;
380
+ height: 100vh;
381
+ overflow: hidden;
382
+ font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', sans-serif;
383
+ }
384
+
385
+ .page-container {
386
+ position: relative;
387
+ width: 100%;
388
+ height: 100%;
389
+ background: #f0f4fc;
390
+ overflow: hidden;
391
+ }
392
+
393
+ .bg-rect-685 {
394
+ position: absolute;
395
+ left: 0;
396
+ top: 0;
397
+ width: 100%;
398
+ height: 100%;
399
+ background: rgba(0, 87, 254, 0.3);
400
+ filter: blur(827px);
401
+ pointer-events: none;
402
+ }
403
+
404
+ .bg-annotation3 {
405
+ position: absolute;
406
+ left: calc(51 / 1920 * 100vw);
407
+ top: 0;
408
+ width: calc(1200 / 1920 * 100vw);
409
+ height: calc(938 / 1080 * 100vh);
410
+ background: url('~@/assets/img/80359c35a5465167cb25ff87bab49035d041a65558b35-YJOr3x.png') no-repeat;
411
+ background-size: 100% 100%;
412
+ pointer-events: none;
413
+ }
414
+
415
+ .decorative-stripes {
416
+ position: absolute;
417
+ left: 0;
418
+ top: 0;
419
+ width: 100%;
420
+ height: 100%;
421
+ pointer-events: none;
422
+ z-index: 1;
423
+ }
424
+
425
+ .stripe {
426
+ position: absolute;
427
+ width: calc(100% / 28);
428
+ height: 100%;
429
+ background: linear-gradient(92deg, rgba(255, 255, 255, 0.2) 15%, rgba(255, 255, 255, 0.05) 85%);
430
+ -webkit-backdrop-filter: blur(60px);
431
+ backdrop-filter: blur(60px);
432
+ }
433
+
434
+ .stripe-no-blur {
435
+ mix-blend-mode: normal;
436
+ -webkit-backdrop-filter: none;
437
+ backdrop-filter: none;
438
+ background: linear-gradient(92deg, rgba(255, 255, 255, 0.25) 12%, rgba(255, 255, 255, 0) 81%);
439
+ }
440
+
441
+ .main-layout {
442
+ position: relative;
443
+ display: flex;
444
+ flex-direction: column;
445
+ width: 100%;
446
+ height: 100%;
447
+ z-index: 2;
448
+ }
449
+
450
+ .top-section {
451
+ flex: 0 0 calc(597 / 1080 * 100vh);
452
+ position: relative;
453
+ }
454
+
455
+ .bottom-section {
456
+ flex: 0 0 calc(483 / 1080 * 100vh);
457
+ position: relative;
458
+ }
459
+
460
+ .rect-112 {
461
+ position: absolute;
462
+ left: calc(-17 / 1920 * 100vw);
463
+ top: 0;
464
+ width: calc(100% + (34 / 1920 * 100vw));
465
+ height: 100%;
466
+ background: rgba(255, 255, 255, 0.3);
467
+ -webkit-backdrop-filter: blur(245px);
468
+ backdrop-filter: blur(245px);
469
+ pointer-events: none;
470
+ }
471
+
472
+ /* 品牌标识 */
473
+ .brand-group {
474
+ position: absolute;
475
+ left: calc(103 / 1920 * 100vw);
476
+ top: calc(120 / 1080 * 100vh);
477
+ width: calc(163 / 1920 * 100vw);
478
+ height: calc(53.36 / 1080 * 100vh);
479
+ }
480
+
481
+ .brand-logo-img {
482
+ width: 100%;
483
+ height: 100%;
484
+ object-fit: contain;
485
+ }
486
+
487
+ /* 系统标题(整合箭头) */
488
+ .his-system-title {
489
+ position: absolute;
490
+ left: calc(1756 / 1920 * 100vw);
491
+ top: calc(38 / 1080 * 100vh);
492
+ font-size: calc(14 / 1920 * 100vw);
493
+ font-weight: 600;
494
+ letter-spacing: 0.08em;
495
+ color: #3a3a4a;
496
+ white-space: nowrap;
497
+ cursor: pointer;
498
+ display: flex;
499
+ align-items: center;
500
+ gap: 4px;
501
+ }
502
+
503
+ .his-dropdown-arrow {
504
+ display: flex;
505
+ align-items: center;
506
+ }
507
+
508
+ /* 箭头图标:11px,比标题略小 */
509
+ .arrow-icon {
510
+ width: calc(11 / 1920 * 100vw);
511
+ height: calc(11 / 1080 * 100vh);
512
+ transform: rotate(90deg);
513
+ transition: transform 0.2s;
514
+ }
515
+
516
+ .welcome-cn {
517
+ position: absolute;
518
+ left: calc(1328 / 1920 * 100vw);
519
+ top: calc(446 / 1080 * 100vh);
520
+ font-size: calc(28 / 1920 * 100vw);
521
+ font-weight: 700;
522
+ color: #0057FE;
523
+ }
524
+
525
+ .welcome-en {
526
+ position: absolute;
527
+ left: calc(1328 / 1920 * 100vw);
528
+ top: calc(491 / 1080 * 100vh);
529
+ font-size: calc(16 / 1920 * 100vw);
530
+ color: #0057FE;
531
+ }
532
+
533
+ .divider-line {
534
+ position: absolute;
535
+ left: calc(1118 / 1920 * 100vw);
536
+ top: calc(595 / 1080 * 100vh);
537
+ width: 41.77%;
538
+ height: 2px;
539
+ background: linear-gradient(90deg, #0057fe 0%, rgba(0, 87, 254, 0) 100%);
540
+ }
541
+
542
+ /* 登录卡片 */
543
+ .login-card {
544
+ position: absolute;
545
+ left: calc(1328 / 1920 * 100vw);
546
+ top: calc(35 / 1080 * 100vh);
547
+ width: calc(281 / 1920 * 100vw);
548
+ background: rgba(255, 255, 255, 0.3);
549
+ backdrop-filter: blur(12px);
550
+ -webkit-backdrop-filter: blur(12px);
551
+ border-radius: calc(7 / 1920 * 100vw);
552
+ box-shadow: 0 8px 32px rgba(0,0,0,0.06);
553
+ padding: calc(20 / 1920 * 100vw) calc(8 / 1920 * 100vw) calc(10 / 1920 * 100vw);
554
+ display: flex;
555
+ flex-direction: column;
556
+ gap: calc(15 / 1080 * 100vh);
557
+ }
558
+
559
+ .form-item {
560
+ position: relative;
561
+ }
562
+
563
+ .select-box,
564
+ .password-item,
565
+ .doctor-code-row {
566
+ display: flex;
567
+ align-items: center;
568
+ border-radius: calc(7 / 1920 * 100vw);
569
+ padding: 0 calc(10 / 1920 * 100vw);
570
+ }
571
+
572
+ .user-row {
573
+ height: calc(50 / 1080 * 100vh);
574
+ background: rgba(255,255,255,0.6);
575
+ cursor: pointer;
576
+ gap: calc(8 / 1920 * 100vw);
577
+ }
578
+
579
+ .select-box:not(.user-row) {
580
+ height: calc(32 / 1080 * 100vh);
581
+ background: #fff;
582
+ cursor: pointer;
583
+ gap: calc(8 / 1920 * 100vw);
584
+ }
585
+
586
+ .password-item {
587
+ height: calc(32 / 1080 * 100vh);
588
+ background: #fff;
589
+ border: 1px solid #0057FE;
590
+ }
591
+
592
+ .doctor-code-row {
593
+ height: calc(32 / 1080 * 100vh);
594
+ background: #F4F4F4;
595
+ border: 1px solid #E5E9F0;
596
+ }
597
+
598
+ .select-label {
599
+ font-size: calc(14 / 1920 * 100vw);
600
+ color: #5D5C5C;
601
+ margin-right: calc(10 / 1920 * 100vw);
602
+ white-space: nowrap;
603
+ }
604
+
605
+ .select-text {
606
+ flex: 1;
607
+ font-size: calc(14 / 1920 * 100vw);
608
+ color: #1a1a2e;
609
+ }
610
+
611
+ .user-avatar-mini {
612
+ display: flex;
613
+ align-items: center;
614
+ position: relative;
615
+ }
616
+
617
+ .avatar-circle {
618
+ width: calc(28 / 1920 * 100vw);
619
+ height: calc(28 / 1080 * 100vh);
620
+ border-radius: 50%;
621
+ overflow: hidden;
622
+ flex-shrink: 0;
623
+ }
624
+
625
+ .default-avatar {
626
+ background: #919BB2;
627
+ }
628
+
629
+ .default-avatar-small {
630
+ width: calc(24 / 1920 * 100vw);
631
+ height: calc(24 / 1080 * 100vh);
632
+ background: #919BB2;
633
+ }
634
+
635
+ .avatar-img,
636
+ .dropdown-avatar {
637
+ width: 100%;
638
+ height: 100%;
639
+ object-fit: cover;
640
+ }
641
+
642
+ .online-dot {
643
+ position: absolute;
644
+ bottom: 0;
645
+ right: 0;
646
+ width: calc(8 / 1920 * 100vw);
647
+ height: calc(8 / 1080 * 100vh);
648
+ background: #12BA76;
649
+ border-radius: 50%;
650
+ border: 2px solid #fff;
651
+ }
652
+
653
+ .password-input,
654
+ .disabled-input {
655
+ flex: 1;
656
+ border: none;
657
+ outline: none;
658
+ background: transparent;
659
+ font-size: calc(14 / 1920 * 100vw);
660
+ color: #1a1a2e;
661
+ }
662
+
663
+ .disabled-input {
664
+ cursor: not-allowed;
665
+ opacity: 0.8;
666
+ }
667
+
668
+ .password-toggle {
669
+ cursor: pointer;
670
+ padding: calc(4 / 1920 * 100vw);
671
+ }
672
+
673
+ .password-toggle svg {
674
+ width: calc(20 / 1920 * 100vw);
675
+ height: calc(20 / 1080 * 100vh);
676
+ }
677
+
678
+ .input-label {
679
+ font-size: calc(14 / 1920 * 100vw);
680
+ color: #5D5C5C;
681
+ white-space: nowrap;
682
+ margin-right: calc(10 / 1920 * 100vw);
683
+ }
684
+
685
+ /* 登录按钮 */
686
+ .login-btn-wrap {
687
+ margin-top: calc(5 / 1080 * 100vh);
688
+ }
689
+
690
+ .login-btn {
691
+ width: 100%;
692
+ height: calc(40 / 1080 * 100vh);
693
+ border-radius: calc(6 / 1920 * 100vw);
694
+ background: #0057FE;
695
+ display: flex;
696
+ align-items: center;
697
+ justify-content: center;
698
+ cursor: pointer;
699
+ box-shadow: 0 4px 14px rgba(0,87,254,0.3);
700
+ }
701
+
702
+ .login-btn:hover { background: #0046e0; }
703
+
704
+ .login-btn-text {
705
+ font-size: calc(15 / 1920 * 100vw);
706
+ font-weight: 600;
707
+ color: #fff;
708
+ }
709
+
710
+ /* 下拉菜单 */
711
+ .dropdown-menu {
712
+ position: absolute;
713
+ background: #fff;
714
+ border-radius: calc(7 / 1920 * 100vw);
715
+ box-shadow: 0 8px 28px rgba(0,0,0,0.12);
716
+ z-index: 50;
717
+ padding: calc(4 / 1920 * 100vw) 0;
718
+ max-height: calc(200 / 1080 * 100vh);
719
+ overflow-y: auto;
720
+ }
721
+
722
+ /* 系统下拉:定位在标题左下方 */
723
+ .his-dropdown-menu {
724
+ left: calc(1756 / 1920 * 100vw);
725
+ top: calc(62 / 1080 * 100vh);
726
+ min-width: calc(160 / 1920 * 100vw);
727
+ }
728
+
729
+ .dropdown-relative {
730
+ top: 100%;
731
+ left: 0;
732
+ right: 0;
733
+ min-width: 100%;
734
+ }
735
+
736
+ .dropdown-item {
737
+ padding: calc(8 / 1920 * 100vw) calc(16 / 1920 * 100vw);
738
+ font-size: calc(14 / 1920 * 100vw);
739
+ color: #3a3a4a;
740
+ cursor: pointer;
741
+ display: flex;
742
+ align-items: center;
743
+ gap: calc(10 / 1920 * 100vw);
744
+ }
745
+
746
+ .dropdown-item:hover { background: #f5f7fb; }
747
+
748
+ .dropdown-item.active { background: #eef3ff; color: #0057FE; }
749
+
750
+ /* 版权 */
751
+ .copyright {
752
+ position: absolute;
753
+ left: calc(103 / 1920 * 100vw);
754
+ top: calc(315 / 1080 * 100vh);
755
+ font-size: calc(12 / 1920 * 100vw);
756
+ color: #9a9aaa;
757
+ white-space: nowrap;
758
+ }
759
+
760
+ /* Toast */
761
+ .toast {
762
+ position: fixed;
763
+ top: 50%;
764
+ left: 50%;
765
+ transform: translate(-50%, -50%);
766
+ background: rgba(30,30,40,0.9);
767
+ color: #fff;
768
+ padding: 12px 28px;
769
+ border-radius: 8px;
770
+ font-size: 14px;
771
+ z-index: 100;
772
+ pointer-events: none;
773
+ animation: toastIn 0.35s ease forwards;
774
+ }
775
+
776
+ @keyframes toastIn {
777
+ 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.85); }
778
+ 70% { opacity: 1; transform: translate(-50%, -50%) scale(1.04); }
779
+ 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
780
+ }
781
+ </style>