vue2-client 1.22.31 → 1.22.32

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.22.31",
3
+ "version": "1.22.32",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -59,7 +59,6 @@ routerResource.example = {
59
59
  // component: () => import('@vue2-client/pages/LayoutTest/index.vue')
60
60
  // component: () => import('@vue2-client/base-client/components/common/XDescriptions/demo.vue')
61
61
  // component: () => import('@vue2-client/base-client/components/his/HChart/demo.vue'),
62
- component: () => import('@vue2-client/base-client/components/his/Login/index.vue'),
63
62
  // component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
64
63
  // component: () => import('@vue2-client/base-client/components/common/XFormTable/demo.vue')
65
64
  // component: () => import('@vue2-client/base-client/components/common/AfMap/demo.vue')
@@ -94,7 +93,7 @@ routerResource.example = {
94
93
  // component: () => import('@vue2-client/components/FilePreview/FilePreviewDemo.vue'),
95
94
  // component: () => import('@vue2-client/pages/ReportGrid/index.vue'),
96
95
  // component: () => import('@vue2-client/base-client/components/common/HIS/demo.vue'),
97
- // component: () => import('@vue2-client/components/MarkdownEditor/demo.vue'),
96
+ component: () => import('@vue2-client/components/MarkdownEditor/demo.vue'),
98
97
  }
99
98
  // routerResource.example = () =>
100
99
  // import('@vue2-client/pages/Example')
@@ -1,781 +0,0 @@
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>