leisure-core 1.0.2 → 1.0.3

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 (94) hide show
  1. package/index.js +223 -0
  2. package/le-area/index.js +7 -0
  3. package/le-area/src/main.vue +112 -0
  4. package/le-button/index.js +7 -0
  5. package/le-button/src/main.vue +47 -0
  6. package/le-button-attach/index.js +6 -0
  7. package/le-button-attach/src/main.vue +171 -0
  8. package/le-button-msg/index.js +7 -0
  9. package/le-button-msg/src/main.vue +65 -0
  10. package/le-button-qr/index.js +7 -0
  11. package/le-button-qr/src/main.vue +96 -0
  12. package/le-date-picker/index.js +7 -0
  13. package/le-date-picker/src/main.vue +67 -0
  14. package/le-date-picker-auto/index.js +6 -0
  15. package/le-date-picker-auto/src/main.vue +131 -0
  16. package/le-dialog-container/index.js +7 -0
  17. package/le-dialog-container/src/main.vue +80 -0
  18. package/le-form/index.js +7 -0
  19. package/le-form/src/main.vue +13 -0
  20. package/le-form-item/index.js +7 -0
  21. package/le-form-item/src/main.vue +13 -0
  22. package/le-home/index.js +7 -0
  23. package/le-home/src/LeHeaderMenu.vue +60 -0
  24. package/le-home/src/main.vue +1307 -0
  25. package/le-home/src/sub.vue +82 -0
  26. package/le-image/index.js +7 -0
  27. package/le-image/src/main.vue +53 -0
  28. package/le-input/index.js +7 -0
  29. package/le-input/src/main.vue +15 -0
  30. package/le-input-advanced/index.js +7 -0
  31. package/le-input-advanced/src/main.vue +71 -0
  32. package/le-input-number/index.js +7 -0
  33. package/le-input-number/src/main.vue +15 -0
  34. package/le-input-validate/index.js +6 -0
  35. package/le-input-validate/src/main.vue +469 -0
  36. package/le-libs/js/drag.js +78 -0
  37. package/le-libs/js/event.js +3 -0
  38. package/le-libs/js/hrequest.js +76 -0
  39. package/le-libs/js/hrequestFile.js +62 -0
  40. package/le-libs/js/info.js +7 -0
  41. package/le-libs/js/tokens.js +13 -0
  42. package/le-libs/mixins/main.js +48 -0
  43. package/le-list/index.js +7 -0
  44. package/le-list/src/main.vue +645 -0
  45. package/le-list-form/index.js +7 -0
  46. package/le-list-form/src/main.vue +474 -0
  47. package/le-login/index.js +7 -0
  48. package/le-login/src/ForgotPassword.vue +613 -0
  49. package/le-login/src/main.vue +982 -0
  50. package/le-media/index.js +7 -0
  51. package/le-media/src/main.vue +298 -0
  52. package/le-media-list/index.js +7 -0
  53. package/le-media-list/src/main.vue +178 -0
  54. package/le-media-upload/index.js +7 -0
  55. package/le-media-upload/src/main.vue +329 -0
  56. package/le-menu/index.js +7 -0
  57. package/le-menu/src/main.vue +248 -0
  58. package/le-report/index.js +6 -0
  59. package/le-report/src/main.vue +1747 -0
  60. package/le-report/src/rmixins.js +30 -0
  61. package/le-role/index.js +7 -0
  62. package/le-role/src/main.vue +183 -0
  63. package/le-role/src/sub.vue +79 -0
  64. package/le-role-user/index.js +7 -0
  65. package/le-role-user/src/main.vue +160 -0
  66. package/le-role-user/src/sub.vue +90 -0
  67. package/le-select/index.js +7 -0
  68. package/le-select/src/main.vue +49 -0
  69. package/le-select-multi/index.js +6 -0
  70. package/le-select-multi/src/main.vue +816 -0
  71. package/le-select-option/index.js +7 -0
  72. package/le-select-option/src/main.vue +69 -0
  73. package/le-select-search/index.js +7 -0
  74. package/le-select-search/src/main.vue +46 -0
  75. package/le-span/index.js +7 -0
  76. package/le-span/src/main.vue +29 -0
  77. package/le-table-edit/index.js +6 -0
  78. package/le-table-edit/src/main.vue +689 -0
  79. package/le-theme/common/vars.css +131 -0
  80. package/le-theme/iconfont/iconfont.css +125 -0
  81. package/le-theme/iconfont/iconfont.ttf +0 -0
  82. package/le-theme/iconfont/iconfont.woff +0 -0
  83. package/le-theme/iconfont/iconfont.woff2 +0 -0
  84. package/le-theme/index.js +189 -0
  85. package/le-theme/pages/index.css +15 -0
  86. package/le-upload/index.js +7 -0
  87. package/le-upload/src/main.vue +134 -0
  88. package/le-upload-table/index.js +6 -0
  89. package/le-upload-table/src/main.vue +648 -0
  90. package/le-url/index.js +7 -0
  91. package/le-url/src/main.vue +27 -0
  92. package/le-video/index.js +7 -0
  93. package/le-video/src/main.vue +42 -0
  94. package/package.json +1 -6
@@ -0,0 +1,1307 @@
1
+ <template>
2
+ <el-container class="le-home-cp-container">
3
+ <el-header class="header">
4
+ <el-row type="flex" align="middle" class="header-row">
5
+ <el-col :span="effectiveHeaderMenu.length ? 4 : 8" class="leftsection">
6
+ <div class="grid-content bg-purple">
7
+ <span class="userinfo-inner" @click="clickLeftTop">{{
8
+ companyInfo.name
9
+ }}</span>
10
+ </div>
11
+ </el-col>
12
+ <el-col
13
+ v-if="effectiveHeaderMenu.length"
14
+ :span="12"
15
+ class="middlesection"
16
+ >
17
+ <el-menu
18
+ mode="horizontal"
19
+ class="header-menu"
20
+ :background-color="headerMenuBgColor"
21
+ :text-color="headerMenuTextColor"
22
+ :active-text-color="headerMenuActiveTextColor"
23
+ :unique-opened="true"
24
+ popper-class="le-header-menu-popper"
25
+ >
26
+ <le-header-menu
27
+ v-for="item in effectiveHeaderMenu"
28
+ :key="item.id || item.name"
29
+ :item="item"
30
+ :level="0"
31
+ :on-select="handleHeaderMenuSelect"
32
+ ></le-header-menu>
33
+ </el-menu>
34
+ </el-col>
35
+ <el-col
36
+ :span="effectiveHeaderMenu.length ? 8 : 16"
37
+ class="rightsection"
38
+ >
39
+ <div class="grid-content bg-purple-light">
40
+ <slot name="rightComment"> </slot>
41
+ <el-dropdown size="medium" trigger="click" @command="handleCommand">
42
+ <span class="el-dropdown-link userinfo-inner-t">
43
+ <!-- <img src="@/assets/tx.png" class="img" /> -->
44
+ {{ username }}
45
+ <i class="el-icon-arrow-down el-icon--right"></i>
46
+ </span>
47
+ <el-dropdown-menu slot="dropdown">
48
+ <el-dropdown-item
49
+ v-for="item in extraDropdownItems"
50
+ :key="item.command"
51
+ :command="item.command"
52
+ :divided="item.divided"
53
+ >
54
+ {{ item.label }}
55
+ </el-dropdown-item>
56
+ <el-dropdown-item command="openSysSettings"
57
+ >系统设置</el-dropdown-item
58
+ >
59
+ <el-dropdown-item command="2" divided
60
+ >退出系统</el-dropdown-item
61
+ >
62
+ </el-dropdown-menu>
63
+ </el-dropdown>
64
+ </div>
65
+ </el-col>
66
+ </el-row>
67
+ </el-header>
68
+ <el-container>
69
+ <el-aside
70
+ class="aside"
71
+ :class="{ aside_hide: isHideMenu }"
72
+ :style="asideStyle"
73
+ ref="asideRef"
74
+ >
75
+ <el-menu
76
+ ref="sideMenu"
77
+ :unique-opened="true"
78
+ class="menu"
79
+ :background-color="menuBackgroundColor"
80
+ :text-color="menuTextColor"
81
+ :active-text-color="menuActiveTextColor"
82
+ >
83
+ <el-submenu
84
+ :index="item1.name"
85
+ v-for="item1 in menuData"
86
+ :key="item1.id"
87
+ >
88
+ <template slot="title">
89
+ <div @click="clickTitle">
90
+ <i :class="item1.icon"></i>&nbsp;
91
+ <span>{{ item1.title }}</span>
92
+ </div>
93
+ </template>
94
+ <el-menu-item
95
+ class="menuItem"
96
+ v-for="item2 in item1.children"
97
+ :key="item2.id"
98
+ :index="item2.name"
99
+ @click="clickMenuItem(item2)"
100
+ :title="shouldShowTooltip(item2.title) ? item2.title : ''"
101
+ >
102
+ &nbsp;&nbsp;
103
+ <span class="menu-item-text">{{ item2.title }}</span>
104
+ </el-menu-item>
105
+ </el-submenu>
106
+ </el-menu>
107
+ <!-- 只在展开时显示拖动条 -->
108
+ <div
109
+ v-if="!isHideMenu"
110
+ class="drag-handle"
111
+ @mousedown.prevent="startDrag"
112
+ ></div>
113
+ </el-aside>
114
+ <el-main class="main" style="padding: 10px 20px">
115
+ <div class="aside_open_close" @click="asidechange">
116
+ <i class="el-icon-arrow-left" v-if="aside_open_close"></i>
117
+ <i class="el-icon-arrow-right" v-else></i>
118
+ </div>
119
+ <div>
120
+ <el-tabs
121
+ class="el-tabs_"
122
+ v-model="tabNameCurrent"
123
+ closable
124
+ @tab-click="handleTabClick"
125
+ @tab-remove="removeTab"
126
+ >
127
+ <el-tab-pane
128
+ v-for="item in tabsAll"
129
+ :key="item.name"
130
+ :label="item.title"
131
+ :name="item.name"
132
+ >
133
+ </el-tab-pane>
134
+ </el-tabs>
135
+ <router-view
136
+ :key="refreshKey.toString() + $route.fullPath"
137
+ ></router-view>
138
+ </div>
139
+ </el-main>
140
+ </el-container>
141
+ <!-- 系统设置对话框 -->
142
+ <el-dialog
143
+ :visible.sync="sysSettingsVisible"
144
+ title="系统设置"
145
+ width="560px"
146
+ :close-on-click-modal="false"
147
+ custom-class="rounded-dialog"
148
+ append-to-body
149
+ >
150
+ <el-tabs v-model="sysSettingsTab" type="border-card">
151
+ <!-- 修改密码 -->
152
+ <el-tab-pane label="修改密码" name="pwd">
153
+ <el-form
154
+ ref="sysPwdForm"
155
+ :model="sysPwdForm"
156
+ :rules="sysPwdRules"
157
+ label-width="100px"
158
+ style="padding: 20px 0"
159
+ >
160
+ <el-form-item label="新密码" prop="newPwd">
161
+ <el-input
162
+ v-model="sysPwdForm.newPwd"
163
+ type="password"
164
+ placeholder="请输入新密码"
165
+ show-password
166
+ ></el-input>
167
+ </el-form-item>
168
+ <el-form-item label="确认密码" prop="confirmPwd">
169
+ <el-input
170
+ v-model="sysPwdForm.confirmPwd"
171
+ type="password"
172
+ placeholder="请再次输入新密码"
173
+ show-password
174
+ ></el-input>
175
+ </el-form-item>
176
+ </el-form>
177
+ </el-tab-pane>
178
+
179
+ <!-- 修改个人信息 -->
180
+ <el-tab-pane label="修改个人信息" name="person">
181
+ <el-form
182
+ ref="sysPerForm"
183
+ :model="sysPerForm"
184
+ :rules="sysPerRules"
185
+ label-width="100px"
186
+ style="padding: 20px 0"
187
+ >
188
+ <el-form-item label="昵称" prop="nick">
189
+ <el-input
190
+ v-model="sysPerForm.nick"
191
+ placeholder="请输入昵称"
192
+ ></el-input>
193
+ </el-form-item>
194
+ <el-form-item label="手机号" prop="phone">
195
+ <el-input
196
+ v-model="sysPerForm.phone"
197
+ placeholder="请输入手机号"
198
+ maxlength="11"
199
+ ></el-input>
200
+ </el-form-item>
201
+ </el-form>
202
+ </el-tab-pane>
203
+
204
+ <!-- 设置皮肤 -->
205
+ <el-tab-pane label="设置皮肤" name="skin">
206
+ <div class="skin-picker">
207
+ <div
208
+ v-for="skin in availableSkins"
209
+ :key="skin.name"
210
+ :class="['skin-item', { active: currentSkin === skin.name }]"
211
+ @click="selectSkin(skin.name)"
212
+ >
213
+ <div class="skin-color" :style="{ background: skin.color }"></div>
214
+ <div class="skin-info">
215
+ <div class="skin-name">{{ skin.label }}</div>
216
+ <div class="skin-desc" v-if="skin.name === currentSkin">
217
+ 当前使用
218
+ </div>
219
+ </div>
220
+ <i
221
+ v-if="currentSkin === skin.name"
222
+ class="el-icon-check skin-check"
223
+ ></i>
224
+ </div>
225
+ </div>
226
+ </el-tab-pane>
227
+ </el-tabs>
228
+ <!-- 对话框底部按钮:根据当前 tab 显示不同按钮 -->
229
+ <div slot="footer">
230
+ <template v-if="sysSettingsTab === 'pwd'">
231
+ <el-button @click="sysSettingsVisible = false">取消</el-button>
232
+ <el-button type="primary" @click="submitSysPwd">确定</el-button>
233
+ </template>
234
+ <template v-else-if="sysSettingsTab === 'person'">
235
+ <el-button @click="sysSettingsVisible = false">取消</el-button>
236
+ <el-button type="primary" @click="submitSysPer">确定</el-button>
237
+ </template>
238
+ <template v-else-if="sysSettingsTab === 'skin'">
239
+ <el-button @click="sysSettingsVisible = false">关闭</el-button>
240
+ </template>
241
+ </div>
242
+ </el-dialog>
243
+ <div v-show="contextMenuVisible">
244
+ <ul
245
+ :style="{ left: menuLeft + 'px', top: menuTop + 'px' }"
246
+ class="contextmenu"
247
+ >
248
+ <li>
249
+ <el-button
250
+ type="text"
251
+ size="mini"
252
+ icon="el-icon-refresh"
253
+ @click="closeOtherTab"
254
+ >关闭其它</el-button
255
+ >
256
+ </li>
257
+ <li>
258
+ <el-button
259
+ type="text"
260
+ size="mini"
261
+ icon="el-icon-error"
262
+ @click="closeAllTabs"
263
+ >关闭所有</el-button
264
+ >
265
+ </li>
266
+ </ul>
267
+ </div>
268
+ <slot name="otherContainer"></slot>
269
+ </el-container>
270
+ </template>
271
+ <script>
272
+ import { cloneDeep } from "lodash";
273
+ import { throttle } from "lodash"; // 可选,用于性能优化
274
+ import LeHeaderMenu from "./LeHeaderMenu.vue";
275
+ export default {
276
+ name: "le-home",
277
+ components: { LeHeaderMenu },
278
+ props: {
279
+ extraDropdownItems: {
280
+ type: Array,
281
+ default: () => [],
282
+ },
283
+ companyInfo: {
284
+ type: Object,
285
+ default: () => ({}),
286
+ },
287
+ showClose: {
288
+ type: Boolean,
289
+ default: true,
290
+ },
291
+ // 顶部横向菜单数据,支持多级嵌套
292
+ // 数据结构: [{ id, name, title, icon, children: [...] }]
293
+ headerMenu: {
294
+ type: Array,
295
+ default: () => [],
296
+ },
297
+ // 是否显示顶部横向菜单
298
+ // true: 只要 headerMenu 有数据就显示
299
+ // false: 即使 headerMenu 有数据也不显示
300
+ showHeaderMenu: {
301
+ type: Boolean,
302
+ default: false,
303
+ },
304
+ },
305
+
306
+ data() {
307
+ // var validatePass = (rule, value, callback) => {
308
+ // if (value === "") {
309
+ // callback(new Error("请输入密码"));
310
+ // } else {
311
+ // if (value.length < 8) {
312
+ // callback(new Error("密码至少8位"));
313
+ // } else {
314
+ // if (this.ruleForm.confirmPwd !== "") {
315
+ // this.$refs.ruleForm.validateField("confirmPwd ");
316
+ // }
317
+ // callback();
318
+ // }
319
+ // }
320
+ // };
321
+ // var validatePass2 = (rule, value, callback) => {
322
+ // if (value === "") {
323
+ // callback(new Error("请再次输入密码"));
324
+ // } else if (value !== this.ruleForm.pwd) {
325
+ // callback(new Error("两次输入密码不一致!"));
326
+ // } else {
327
+ // callback();
328
+ // }
329
+ // };
330
+ return {
331
+ style: {
332
+ display: "block",
333
+ },
334
+
335
+ isHideMenu: false,
336
+ aside_open_close: true,
337
+ menuData: [],
338
+ title: "",
339
+ // cacheView: [],
340
+ // showChangePwd: false,
341
+ // showPerInfo: false,
342
+ username: "",
343
+ // changeUid: "",
344
+ tabNameCurrent: "",
345
+ tabsAll: [],
346
+ //右键菜单
347
+ contextMenuVisible: false,
348
+ menuLeft: 0,
349
+ menuTop: 0,
350
+ pwdinfo: "",
351
+ refreshKey: 0,
352
+ // 仅添加以下3个变量
353
+ isDragging: false,
354
+ asideWidth: 200, // 默认宽度,与原宽度一致
355
+ dragStartInfo: null, // {startX, startWidth}
356
+ // 系统设置对话框
357
+ sysSettingsVisible: false,
358
+ sysSettingsTab: "pwd",
359
+ sysPwdForm: {
360
+ oldPwd: "",
361
+ newPwd: "",
362
+ confirmPwd: "",
363
+ },
364
+ sysPwdRules: {
365
+ // oldPwd: [{ required: true, message: "请输入原密码", trigger: "blur" }],//
366
+ newPwd: [
367
+ { required: true, message: "请输入新密码", trigger: "blur" },
368
+ { min: 8, message: "密码至少8位", trigger: "blur" },
369
+ ],
370
+ confirmPwd: [
371
+ { required: true, message: "请再次输入新密码", trigger: "blur" },
372
+ {
373
+ validator: (rule, value, callback) => {
374
+ if (value !== this.sysPwdForm.newPwd) {
375
+ callback(new Error("两次输入密码不一致"));
376
+ } else {
377
+ callback();
378
+ }
379
+ },
380
+ trigger: "blur",
381
+ },
382
+ ],
383
+ },
384
+ sysPerForm: {
385
+ nick: "",
386
+ phone: "",
387
+ },
388
+ sysPerRules: {
389
+ nick: [{ required: true, message: "请输入昵称", trigger: "blur" }],
390
+ phone: [
391
+ { required: true, message: "请输入手机号", trigger: "blur" },
392
+ {
393
+ pattern: /^1[3-9]\d{9}$/,
394
+ message: "请输入正确的手机号",
395
+ trigger: "blur",
396
+ },
397
+ ],
398
+ },
399
+ // 当前皮肤名(响应式,供皮肤选择器和 UI 刷新使用)
400
+ currentSkin: "default",
401
+ };
402
+ },
403
+ computed: {
404
+ asideStyle() {
405
+ // 依赖 currentSkin 让 Vue 知道需要重算(getCssVar 读取 DOM 不是响应式的)
406
+ if (this.currentSkin) {
407
+ // 触发访问,建立依赖关系
408
+ }
409
+ if (this.isHideMenu) {
410
+ return {
411
+ width: "0px",
412
+ minWidth: "0px",
413
+ maxWidth: "0px",
414
+ flex: "0 0 0px",
415
+ backgroundColor: this.getCssVar("--le-color-aside-bg", "#3A3A3A"),
416
+ };
417
+ }
418
+ return {
419
+ width: `${this.asideWidth}px`,
420
+ minWidth: `${this.asideWidth}px`,
421
+ maxWidth: `${this.asideWidth}px`,
422
+ flex: `0 0 ${this.asideWidth}px`,
423
+ transition: this.isDragging ? "none" : "width 0.3s",
424
+ backgroundColor: this.getCssVar("--le-color-aside-bg", "#3A3A3A"),
425
+ };
426
+ },
427
+ // el-menu 的三个颜色 prop,绑定到 CSS 变量,实现主题切换
428
+ menuBackgroundColor() {
429
+ return this.currentSkin, this.getCssVar("--le-color-menu-bg", "#3A3A3A");
430
+ },
431
+ menuTextColor() {
432
+ return this.currentSkin, this.getCssVar("--le-color-aside-text", "#fff");
433
+ },
434
+ menuActiveTextColor() {
435
+ return (
436
+ this.currentSkin, this.getCssVar("--le-color-aside-active", "#ffd04b")
437
+ );
438
+ },
439
+ // header 横向菜单:综合判断 showHeaderMenu + headerMenu 数据 + 过滤隐藏项
440
+ effectiveHeaderMenu() {
441
+ if (!this.showHeaderMenu) return [];
442
+ if (!this.headerMenu || !this.headerMenu.length) return [];
443
+ return this._filterHiddenMenus(this.headerMenu);
444
+ },
445
+ // header 横向菜单颜色(跟随主题)
446
+ headerMenuBgColor() {
447
+ return (
448
+ this.currentSkin, this.getCssVar("--le-color-header-bg", "#212121")
449
+ );
450
+ },
451
+ headerMenuTextColor() {
452
+ return this.currentSkin, this.getCssVar("--le-color-aside-text", "#fff");
453
+ },
454
+ headerMenuActiveTextColor() {
455
+ return (
456
+ this.currentSkin, this.getCssVar("--le-color-aside-active", "#ffd04b")
457
+ );
458
+ },
459
+ // 皮肤列表(供下拉子菜单渲染)
460
+ availableSkins() {
461
+ return [
462
+ { name: "default", label: "默认蓝", color: "#409eff" },
463
+ { name: "dark", label: "深色", color: "#0f172a" },
464
+ { name: "green", label: "翠绿", color: "#00b96b" },
465
+ ];
466
+ },
467
+ },
468
+ mounted() {
469
+ this.username =
470
+ this.$store.getters.userinfo.nick || this.$store.getters.userinfo.account;
471
+ let tab_top_dom = document.getElementsByClassName("el-tabs_");
472
+ tab_top_dom[0].oncontextmenu = this.openContextMenu;
473
+ if (
474
+ this.companyInfo &&
475
+ this.companyInfo.name &&
476
+ this.companyInfo.name.length > 0
477
+ ) {
478
+ this.$store.commit("setCname", this.companyInfo.name);
479
+ }
480
+
481
+ // let dict = [
482
+ // {
483
+ // title: "是",
484
+ // value: 1,
485
+ // },
486
+ // {
487
+ // title: "否",
488
+ // value: 0,
489
+ // },
490
+ // ];
491
+
492
+ // this.$store.commit("setDict", dict);
493
+
494
+ const menus = cloneDeep(this.$store.getters.menu);
495
+ this.menuData = menus.filter(function (item) {
496
+ if (item.children) {
497
+ item.children = item.children.filter((child) => child.ishide === 0);
498
+ }
499
+ return item;
500
+ });
501
+ this.$emit("homeInit");
502
+ document.addEventListener("keydown", this.handleKeyDown);
503
+
504
+ // 监听全局鼠标事件
505
+ document.addEventListener("mousemove", this.handleDrag);
506
+ document.addEventListener("mouseup", this.stopDrag);
507
+
508
+ // 2026-08-26:监听主题切换事件,更新响应式皮肤名触发 computed 重算
509
+ this._themeChangeHandler = (e) => {
510
+ const skinName =
511
+ (e && e.detail) ||
512
+ (this.$leTheme && this.$leTheme.current) ||
513
+ "default";
514
+ // 更新 currentSkin 后,所有依赖 currentSkin 的 computed 会自动重算
515
+ // 包括 asideStyle, menuBackgroundColor, menuTextColor, headerMenuBgColor 等
516
+ this.currentSkin = skinName;
517
+ };
518
+ // 初始化当前皮肤名
519
+ if (this.$leTheme) {
520
+ this.currentSkin = this.$leTheme.current;
521
+ }
522
+ if (typeof window !== "undefined") {
523
+ window.addEventListener("le-theme-change", this._themeChangeHandler);
524
+ }
525
+ },
526
+
527
+ watch: {
528
+ contextMenuVisible() {
529
+ if (this.contextMenuVisible) {
530
+ document.body.addEventListener("click", this.closeMenu);
531
+ } else {
532
+ document.body.removeEventListener("click", this.closeMenu);
533
+ }
534
+ },
535
+ },
536
+ beforeDestroy() {
537
+ document.removeEventListener("keydown", this.handleKeyDown);
538
+ document.removeEventListener("mousemove", this.handleDrag);
539
+ document.removeEventListener("mouseup", this.stopDrag);
540
+ if (typeof window !== "undefined" && this._themeChangeHandler) {
541
+ window.removeEventListener("le-theme-change", this._themeChangeHandler);
542
+ }
543
+ this.stopDrag();
544
+ },
545
+ methods: {
546
+ // 递归过滤隐藏菜单项(ishide === 1 的项被过滤,其子项也一并丢弃)
547
+ _filterHiddenMenus(list) {
548
+ if (!Array.isArray(list)) return [];
549
+ return list
550
+ .filter((item) => item.ishide !== 1)
551
+ .map((item) => {
552
+ if (item.children && item.children.length) {
553
+ return {
554
+ ...item,
555
+ children: this._filterHiddenMenus(item.children),
556
+ };
557
+ }
558
+ return item;
559
+ });
560
+ },
561
+ // 2026-08-26:读取 CSS 变量的 helper,返回指定变量值(回退到 fallback)
562
+ getCssVar(name, fallback) {
563
+ try {
564
+ const v = getComputedStyle(document.documentElement)
565
+ .getPropertyValue(name)
566
+ .trim();
567
+ return v || fallback;
568
+ } catch (e) {
569
+ return fallback;
570
+ }
571
+ },
572
+ // header 横向菜单项点击处理(复用 clickMenuItem 的导航逻辑)
573
+ handleHeaderMenuSelect(item) {
574
+ this.clickMenuItem(item);
575
+ },
576
+ handleKeyDown(e) {
577
+ // F5 键的 keyCode 是 116
578
+ if (e.keyCode === 116) {
579
+ e.preventDefault(); // 阻止默认刷新行为
580
+ this.refreshView();
581
+ }
582
+ },
583
+ refreshView() {
584
+ this.refreshKey++;
585
+ // 可以添加一些视觉反馈
586
+ this.$message.success("数据已刷新");
587
+ },
588
+ openContextMenu(e) {
589
+ e.preventDefault(); //防止默认菜单弹出
590
+ this.contextMenuVisible = true;
591
+
592
+ this.menuLeft = e.clientX;
593
+ this.menuTop = e.clientY + 20;
594
+ },
595
+ closeMenu() {
596
+ this.contextMenuVisible = false;
597
+ },
598
+ closeOtherTab() {
599
+ this.tabsAll = this.tabsAll.filter(
600
+ (item) => item.name == this.tabNameCurrent,
601
+ );
602
+ },
603
+ closeAllTabs() {
604
+ this.contextMenuVisible = false;
605
+ this.tabNameCurrent = "";
606
+ this.tabsAll = [];
607
+ this.$router.push({ path: "/home" });
608
+ },
609
+ //解决空白标签页右键
610
+ openContextMenu1(e) {
611
+ if (e.srcElement.id != "") {
612
+ this.contextMenuVisible = true;
613
+ //这个参数是获取右键标签页的id属性,应该和你的key有关,你要截取-后面部分的
614
+ this.closeindex = e.srcElement.id.split("-")[1]; //
615
+ } else {
616
+ this.contextMenuVisible = false;
617
+ }
618
+ },
619
+ handleCommand(command) {
620
+ if (command === "openSysSettings") {
621
+ this.sysSettingsTab = "pwd";
622
+ this.sysPwdForm = { oldPwd: "", newPwd: "", confirmPwd: "" };
623
+ this.sysPerForm = {
624
+ nick: this.$store.getters.userinfo.nick || "",
625
+ phone: this.$store.getters.userinfo.phone || "",
626
+ };
627
+ this.sysSettingsVisible = true;
628
+ } else if (command === "2") {
629
+ this.signout();
630
+ } else {
631
+ this.$emit("command", command); // 抛出外部命令
632
+ }
633
+ },
634
+ changPwd() {},
635
+ // 系统设置 - 提交修改密码
636
+ submitSysPwd() {
637
+ this.$refs.sysPwdForm.validate((valid) => {
638
+ if (valid) {
639
+ const payload = {
640
+ uid: this.$store.getters.userinfo.id,
641
+ pwd: this.sysPwdForm.newPwd,
642
+ confirmPwd: this.sysPwdForm.confirmPwd,
643
+ };
644
+ // 方案一:emit 给宿主,由宿主决定如何调用接口
645
+ this.$emit("userChangePwd", payload, this.changePwdAfter);
646
+ }
647
+ });
648
+ },
649
+ // 系统设置 - 提交修改个人信息
650
+ submitSysPer() {
651
+ this.$refs.sysPerForm.validate((valid) => {
652
+ if (valid) {
653
+ const payload = {
654
+ uid: this.$store.getters.userinfo.id,
655
+ nick: this.sysPerForm.nick,
656
+ phone: this.sysPerForm.phone,
657
+ };
658
+ this.$emit("savePerInfo", payload, () => {
659
+ this.sysSettingsVisible = false;
660
+ try {
661
+ let userinfo = this.$store.getters.userinfo;
662
+ if (userinfo) {
663
+ userinfo.nick = payload.nick;
664
+ userinfo.phone = payload.phone;
665
+ this.$store.commit("setUserInfo", userinfo);
666
+ }
667
+ } catch (e) {}
668
+ });
669
+ }
670
+ });
671
+ },
672
+ // 系统设置 - 选择皮肤
673
+ selectSkin(skinName) {
674
+ this.$leTheme.set(skinName);
675
+ this.$message.success("皮肤切换成功");
676
+ },
677
+ validatePhone(phone) {
678
+ const phoneRegex = /^1[3-9]\d{9}$/;
679
+ return phoneRegex.test(phone);
680
+ },
681
+
682
+ changePwdAfter(res) {
683
+ if (res && res.data && res.data.code == "10000") {
684
+ this.$message.success("更新成功");
685
+ this.sysSettingsVisible = false;
686
+ localStorage.clear();
687
+ this.$store.commit("setUserInfo", null);
688
+ this.$router.replace({ path: "/" });
689
+ } else {
690
+ this.pwdinfo = res;
691
+ }
692
+ },
693
+ signout() {
694
+ this.$confirm("退出登录, 是否继续?", "提示", {
695
+ confirmButtonText: "确定",
696
+ cancelButtonText: "取消",
697
+ type: "warning",
698
+ }).then(() => {
699
+ this.$router.push({ path: "/" });
700
+ localStorage.clear();
701
+ });
702
+ },
703
+ clickMenuItem(item) {
704
+ this.style.display = "none";
705
+
706
+ if (item.name === this.tabNameCurrent) {
707
+ this.$message.info("当前页面已经打开");
708
+ return;
709
+ }
710
+
711
+ // 查找是否已经存在相同name的标签页
712
+ const existingTabIndex = this.tabsAll.findIndex(
713
+ (tab) => tab.name === item.name,
714
+ );
715
+
716
+ if (existingTabIndex > -1) {
717
+ // 已存在,用新的替换
718
+ const newTab = this._createTabItem(item);
719
+ this.tabsAll[existingTabIndex] = newTab;
720
+
721
+ // 如果替换的是当前激活的标签页,需要跳转
722
+ if (this.tabNameCurrent === item.name) {
723
+ this.$router.push(newTab);
724
+ } else {
725
+ // 如果替换的不是当前激活的标签页,设置当前激活并跳转
726
+ this.tabNameCurrent = newTab.name;
727
+ this.$router.push(newTab);
728
+ }
729
+ } else {
730
+ this._navi2Page(item);
731
+ }
732
+ },
733
+ _createTabItem(item) {
734
+ let value;
735
+ if (item.param) {
736
+ value = {
737
+ name: item.name,
738
+ title: item.title,
739
+ params: {
740
+ status: item.param,
741
+ btns: item.btns,
742
+ },
743
+ };
744
+ } else {
745
+ if (item.component && item.component != "") {
746
+ value = {
747
+ name: item.name,
748
+ title: item.title,
749
+ params: {
750
+ btns: item.btns,
751
+ },
752
+ };
753
+ }
754
+ }
755
+ return value;
756
+ },
757
+ _navi2Page(item) {
758
+ const value = this._createTabItem(item);
759
+ if (!value) return; // 防止空值
760
+
761
+ this.tabNameCurrent = value.name;
762
+ if (this.tabsAll && this.tabsAll.length >= 8) {
763
+ let elen = this.tabsAll.length;
764
+ this.tabsAll[elen - 1] = value;
765
+ } else {
766
+ this.tabsAll.push(value);
767
+ }
768
+ this.$router.push(value);
769
+ },
770
+ handleTabClick(clickTab, event) {
771
+ // if (clickTab.name == this.tabNameCurrent) return;
772
+ let tabs = this.tabsAll;
773
+ let currentTab;
774
+ tabs.forEach((tab, index) => {
775
+ if (tab.name === clickTab.name) {
776
+ currentTab = tab;
777
+ }
778
+ });
779
+ this.$router.push(currentTab);
780
+ },
781
+ removeTab(targetName) {
782
+ let tabs = this.tabsAll;
783
+ let nextTab;
784
+ tabs.forEach((tab, index) => {
785
+ if (tab.name == targetName) {
786
+ nextTab = tabs[index + 1] || tabs[index - 1];
787
+ if (nextTab) {
788
+ this.tabNameCurrent = nextTab.name;
789
+ }
790
+ }
791
+ });
792
+ this.tabsAll = tabs.filter((tab) => tab.name !== targetName);
793
+ if (nextTab) {
794
+ this.$router.push(nextTab);
795
+ } else {
796
+ this.tabNameCurrent = "";
797
+ this.$router.push("/Home");
798
+ }
799
+ },
800
+ clickTitle() {
801
+ this.style.display = "block";
802
+ },
803
+ asidechange() {
804
+ this.isHideMenu = !this.isHideMenu;
805
+ if (this.isHideMenu) {
806
+ this.aside_open_close = false;
807
+ } else {
808
+ this.aside_open_close = true;
809
+ // 确保展开时使用当前保存的宽度
810
+ const savedWidth = localStorage.getItem("le-aside-width");
811
+ if (savedWidth) {
812
+ this.asideWidth = parseInt(savedWidth, 10);
813
+ }
814
+ }
815
+ },
816
+ shouldShowTooltip(text) {
817
+ return text && text.length > 8;
818
+ },
819
+ clickLeftTop() {
820
+ this.$emit("clickLeftTop");
821
+ },
822
+ startDrag(e) {
823
+ e.preventDefault();
824
+ e.stopPropagation();
825
+
826
+ this.isDragging = true;
827
+ this.dragStartInfo = {
828
+ startX: e.clientX,
829
+ startWidth: this.asideWidth,
830
+ };
831
+
832
+ document.body.style.cursor = "col-resize";
833
+ document.body.style.userSelect = "none";
834
+
835
+ // 临时添加事件监听(更可靠)
836
+ window.addEventListener("mousemove", this.handleDrag);
837
+ window.addEventListener("mouseup", this.stopDrag);
838
+ },
839
+
840
+ handleDrag(e) {
841
+ if (!this.isDragging || !this.dragStartInfo) return;
842
+
843
+ e.preventDefault();
844
+ e.stopPropagation();
845
+
846
+ const diff = e.clientX - this.dragStartInfo.startX;
847
+ let newWidth = this.dragStartInfo.startWidth + diff;
848
+
849
+ // 限制宽度范围(150-500px)
850
+ newWidth = Math.max(150, Math.min(500, newWidth));
851
+
852
+ // 更新数据
853
+ this.asideWidth = newWidth;
854
+
855
+ // 直接操作 DOM 确保生效
856
+ const asideEl = this.$refs.asideRef?.$el;
857
+ if (asideEl) {
858
+ asideEl.style.width = `${newWidth}px`;
859
+ asideEl.style.minWidth = `${newWidth}px`;
860
+ asideEl.style.maxWidth = `${newWidth}px`;
861
+ asideEl.style.flex = `0 0 ${newWidth}px`;
862
+ }
863
+ },
864
+
865
+ stopDrag() {
866
+ if (this.isDragging) {
867
+ this.isDragging = false;
868
+ this.dragStartInfo = null;
869
+
870
+ // 移除临时事件监听
871
+ window.removeEventListener("mousemove", this.handleDrag);
872
+ window.removeEventListener("mouseup", this.stopDrag);
873
+
874
+ // 保存到 localStorage
875
+ localStorage.setItem("le-aside-width", this.asideWidth.toString());
876
+
877
+ // 恢复样式
878
+ document.body.style.cursor = "";
879
+ document.body.style.userSelect = "";
880
+ }
881
+ },
882
+ },
883
+ };
884
+ </script>
885
+ <style lang="scss" scoped>
886
+ .le-home-cp-container {
887
+ height: 100vh;
888
+ font-size: 15px;
889
+
890
+ .header {
891
+ background-color: var(--le-color-header-bg) !important;
892
+ color: #fff;
893
+ height: 60px;
894
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
895
+
896
+ /* 清除 Element UI el-row / el-col 默认背景 */
897
+ .el-row,
898
+ .el-col {
899
+ background-color: transparent !important;
900
+ }
901
+
902
+ /* 清除 grid-content / bg-purple 等示例类的默认背景 */
903
+ .grid-content,
904
+ .bg-purple,
905
+ .bg-purple-light {
906
+ background-color: transparent !important;
907
+ }
908
+
909
+ .header-row {
910
+ height: 60px;
911
+ }
912
+
913
+ .leftsection,
914
+ .middlesection,
915
+ .rightsection {
916
+ height: 60px;
917
+ line-height: 60px;
918
+ display: flex;
919
+ align-items: center;
920
+ }
921
+
922
+ .leftsection {
923
+ .userinfo-inner {
924
+ font-size: 18px;
925
+ font-weight: bold;
926
+ cursor: pointer;
927
+ }
928
+ }
929
+
930
+ .middlesection {
931
+ flex: 1;
932
+ display: flex;
933
+ align-items: center;
934
+ padding: 0 16px;
935
+
936
+ .header-menu {
937
+ border-bottom: none;
938
+ height: 60px;
939
+ line-height: 60px;
940
+ width: 100%;
941
+
942
+ /* 菜单项悬停/激活色 */
943
+ .el-menu-item,
944
+ .el-submenu__title {
945
+ height: 60px;
946
+ line-height: 60px;
947
+ border-bottom: none;
948
+ font-size: 15px;
949
+ min-width: 100px;
950
+ text-align: center;
951
+
952
+ &:hover {
953
+ background-color: rgba(255, 255, 255, 0.1) !important;
954
+ }
955
+ }
956
+
957
+ .el-submenu__icon-arrow {
958
+ font-size: 12px;
959
+ margin-left: 4px;
960
+ }
961
+
962
+ .el-menu-item.is-active {
963
+ border-bottom: 2px solid var(--le-color-aside-active);
964
+ }
965
+ }
966
+ }
967
+
968
+ .rightsection {
969
+ justify-content: flex-end;
970
+
971
+ .el-dropdown-link {
972
+ cursor: pointer;
973
+ color: #fff;
974
+ }
975
+ }
976
+ }
977
+
978
+ /* 修改 .aside 样式 - 移除固定宽度 !important */
979
+ .aside {
980
+ background: var(--le-color-aside-bg);
981
+ color: var(--le-color-aside-text);
982
+ /* 移除 width: 200px !important */
983
+ transform: width 0.5s;
984
+ position: relative;
985
+ /* 添加弹性布局相关属性 */
986
+ flex-shrink: 0 !important;
987
+ overflow: visible !important;
988
+ height: calc(100vh - 60px);
989
+ display: flex;
990
+ flex-direction: column;
991
+
992
+ /* 拖动条样式 */
993
+ .drag-handle {
994
+ position: absolute;
995
+ right: 0;
996
+ top: 0;
997
+ bottom: 0;
998
+ width: 1px; /* 从6px改为4px */
999
+ cursor: col-resize;
1000
+ z-index: 1000;
1001
+ background-color: transparent;
1002
+
1003
+ &:hover {
1004
+ background-color: var(--le-color-aside-handle-hover);
1005
+ width: 4px; /* 确保hover时也是4px */
1006
+ }
1007
+
1008
+ &:active {
1009
+ background-color: var(--le-color-aside-handle-active);
1010
+ }
1011
+ }
1012
+
1013
+ &.aside_hide {
1014
+ width: 0px !important;
1015
+ min-width: 0 !important;
1016
+ max-width: 0 !important;
1017
+ flex: 0 0 0 !important;
1018
+ overflow: hidden !important;
1019
+
1020
+ .drag-handle {
1021
+ display: none !important;
1022
+ }
1023
+ }
1024
+ }
1025
+
1026
+ .el-aside {
1027
+ height: calc(100vh - 60px);
1028
+ }
1029
+
1030
+ .el-main {
1031
+ height: calc(100vh - 60px);
1032
+ // overflow: hidden !important;
1033
+ flex: 1;
1034
+
1035
+ display: flex;
1036
+ flex-direction: column;
1037
+ overflow-y: auto;
1038
+ padding: 10px 20px;
1039
+ }
1040
+
1041
+ .el-main > div:last-child {
1042
+ flex: 1;
1043
+ min-height: 0;
1044
+ display: flex;
1045
+ flex-direction: column;
1046
+ }
1047
+
1048
+ .el-main > div:last-child > *:last-child {
1049
+ flex: 1;
1050
+ min-height: 0;
1051
+ }
1052
+
1053
+ .menu {
1054
+ background: none;
1055
+ color: var(--le-color-aside-text);
1056
+ flex: 1;
1057
+ overflow-y: auto;
1058
+ }
1059
+
1060
+ .main {
1061
+ position: relative;
1062
+ color: var(--le-color-header-bg);
1063
+ }
1064
+
1065
+ .headerlogo {
1066
+ line-height: 60px;
1067
+ margin-top: 10px;
1068
+ }
1069
+
1070
+ .rightsection {
1071
+ line-height: 60px;
1072
+ text-align: right;
1073
+ }
1074
+
1075
+ .leftsection {
1076
+ line-height: 60px;
1077
+ text-align: start;
1078
+ font-size: 22px;
1079
+ }
1080
+
1081
+ .userinfo-inner {
1082
+ margin-left: 20px;
1083
+ cursor: pointer;
1084
+ }
1085
+
1086
+ .userinfo-inner-t {
1087
+ color: #fff !important;
1088
+ font-size: 18px;
1089
+ cursor: pointer;
1090
+ }
1091
+
1092
+ .el-icon-arrow-down {
1093
+ font-size: 16px;
1094
+ }
1095
+
1096
+ .el-dropdown-menu__item {
1097
+ font-size: 15px !important;
1098
+ }
1099
+
1100
+ .logofont {
1101
+ font-size: 25px;
1102
+ padding-bottom: 10px;
1103
+ line-height: 60px;
1104
+ }
1105
+
1106
+ .cursor {
1107
+ cursor: pointer;
1108
+ }
1109
+
1110
+ .aside_open_close {
1111
+ position: absolute;
1112
+ left: 0;
1113
+ top: 25%;
1114
+ width: 16px;
1115
+ height: 60px;
1116
+ line-height: 60px;
1117
+ color: #fff;
1118
+ background-color: var(--le-color-aside-toggle-bg);
1119
+ border-radius: 0 6px 6px 0;
1120
+ font-size: 20px;
1121
+ z-index: 1000;
1122
+ cursor: pointer;
1123
+ }
1124
+
1125
+ .aside_open_close:hover {
1126
+ background-color: var(--le-color-aside-toggle-hover);
1127
+ color: #fff;
1128
+ }
1129
+
1130
+ .grid-content {
1131
+ }
1132
+
1133
+ .bg-purple-light {
1134
+ display: flex;
1135
+ display: -webkit-flex;
1136
+ justify-content: flex-end;
1137
+ align-content: center;
1138
+ align-items: center;
1139
+ column-gap: 6px;
1140
+ }
1141
+
1142
+ .contextmenu {
1143
+ width: 100px;
1144
+ margin: 0;
1145
+ border: 1px solid var(--le-color-contextmenu-border);
1146
+ background: var(--le-color-contextmenu-bg);
1147
+ z-index: 3000;
1148
+ position: absolute;
1149
+ list-style-type: none;
1150
+ padding: 5px 0;
1151
+ border-radius: 4px;
1152
+ font-size: 14px;
1153
+ color: var(--le-color-contextmenu-text);
1154
+ box-shadow: 2px 2px 3px 0 var(--le-color-contextmenu-shadow);
1155
+
1156
+ .li {
1157
+ margin: 0;
1158
+ padding: 0px 2px;
1159
+
1160
+ :hover {
1161
+ background: var(--le-color-contextmenu-hover);
1162
+ cursor: pointer;
1163
+ }
1164
+
1165
+ .button {
1166
+ color: var(--le-color-contextmenu-text);
1167
+ }
1168
+ }
1169
+ }
1170
+ }
1171
+
1172
+ .img {
1173
+ width: 20px;
1174
+ height: 20px;
1175
+ }
1176
+
1177
+ ::-webkit-scrollbar {
1178
+ width: 0;
1179
+ height: 0;
1180
+ background-color: transparent;
1181
+ }
1182
+
1183
+ .menuItem {
1184
+ .menu-item-text {
1185
+ display: inline-block;
1186
+ max-width: calc(100% + 25px);
1187
+ overflow: hidden;
1188
+ text-overflow: ellipsis;
1189
+ white-space: nowrap;
1190
+ }
1191
+ }
1192
+
1193
+ .rounded-dialog {
1194
+ border-radius: 12px !important;
1195
+ overflow: hidden;
1196
+ }
1197
+
1198
+ /* 皮肤选择器样式 */
1199
+ .skin-picker {
1200
+ display: flex;
1201
+ flex-direction: column;
1202
+ gap: 12px;
1203
+ padding: 16px 0;
1204
+ }
1205
+
1206
+ .skin-item {
1207
+ display: flex;
1208
+ align-items: center;
1209
+ padding: 12px 16px;
1210
+ border: 2px solid var(--le-color-border);
1211
+ border-radius: 8px;
1212
+ cursor: pointer;
1213
+ transition: all 0.2s ease;
1214
+
1215
+ &:hover {
1216
+ border-color: var(--le-color-primary);
1217
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
1218
+ }
1219
+
1220
+ &.active {
1221
+ border-color: var(--le-color-primary);
1222
+ background-color: var(--le-color-primary-light-9);
1223
+ }
1224
+ }
1225
+
1226
+ .skin-color {
1227
+ width: 32px;
1228
+ height: 32px;
1229
+ border-radius: 50%;
1230
+ margin-right: 16px;
1231
+ flex-shrink: 0;
1232
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
1233
+ }
1234
+
1235
+ .skin-info {
1236
+ flex: 1;
1237
+ }
1238
+
1239
+ .skin-name {
1240
+ font-size: 15px;
1241
+ font-weight: 600;
1242
+ color: var(--le-color-text-strong);
1243
+ }
1244
+
1245
+ .skin-desc {
1246
+ font-size: 12px;
1247
+ color: var(--le-color-primary);
1248
+ margin-top: 2px;
1249
+ }
1250
+
1251
+ .skin-check {
1252
+ font-size: 20px;
1253
+ color: var(--le-color-primary);
1254
+ }
1255
+ </style>
1256
+ <style lang="scss">
1257
+ /* header 菜单弹出层样式(挂在 body 上,需全局样式)
1258
+ 弹出层不受 el-menu prop 控制,需手动设置背景色与 header 一致 */
1259
+ .le-header-menu-popper {
1260
+ background-color: var(--le-color-header-bg) !important;
1261
+
1262
+ .el-menu {
1263
+ border-right: none;
1264
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
1265
+ min-width: 160px;
1266
+ background-color: var(--le-color-header-bg) !important;
1267
+ }
1268
+
1269
+ .el-menu-item,
1270
+ .el-submenu__title {
1271
+ height: 40px;
1272
+ line-height: 40px;
1273
+ border-bottom: none;
1274
+ padding: 0 20px;
1275
+ min-width: 160px;
1276
+ font-size: 14px;
1277
+ background-color: var(--le-color-header-bg) !important;
1278
+ color: var(--le-color-aside-text) !important;
1279
+
1280
+ &:hover {
1281
+ background-color: rgba(255, 255, 255, 0.1) !important;
1282
+ }
1283
+ }
1284
+
1285
+ .el-menu-item.is-active {
1286
+ color: var(--le-color-aside-active) !important;
1287
+ background-color: rgba(255, 255, 255, 0.1) !important;
1288
+ }
1289
+
1290
+ .el-submenu__icon-arrow {
1291
+ float: right;
1292
+ margin-right: 0;
1293
+ color: var(--le-color-aside-text) !important;
1294
+ }
1295
+ }
1296
+
1297
+ /* 用户下拉菜单(系统设置/皮肤选择)全局样式 */
1298
+ .el-dropdown-menu {
1299
+ .el-dropdown-menu__item {
1300
+ position: relative;
1301
+
1302
+ &.skin-active {
1303
+ color: var(--le-color-aside-active);
1304
+ }
1305
+ }
1306
+ }
1307
+ </style>