@lambo-design/pro-layout 1.0.0-beta.44 → 1.0.0-beta.441

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 (40) hide show
  1. package/package.json +11 -4
  2. package/src/components/pro-layout-header/index.vue +220 -0
  3. package/src/components/pro-layout-header/pro-layout-logo/index.vue +206 -0
  4. package/src/components/pro-layout-header/pro-layout-nav/components/pro-layout-nav-slide-menu.vue +398 -0
  5. package/src/components/pro-layout-header/pro-layout-nav/index-slide.vue +226 -0
  6. package/src/components/pro-layout-header/pro-layout-nav/index.vue +564 -0
  7. package/src/components/pro-layout-header/pro-layout-slogan/index.vue +40 -0
  8. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-collect.vue +79 -0
  9. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-document.vue +82 -0
  10. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-fullscreen.vue +144 -0
  11. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-icons.vue +99 -0
  12. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-intl.vue +109 -0
  13. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-notice.vue +133 -0
  14. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-search.vue +305 -0
  15. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-quick-todo.vue +145 -0
  16. package/src/components/pro-layout-header/pro-layout-tools/components/pro-layout-tools-user.vue +64 -0
  17. package/src/components/pro-layout-header/pro-layout-tools/index.vue +38 -0
  18. package/src/components/pro-layout-header/pro-layout-trigger/index.vue +84 -0
  19. package/src/components/{pro-layout-sider-collapsed-menu.vue → pro-layout-sider/components/pro-layout-sider-collapsed-menu.vue} +30 -11
  20. package/src/components/{pro-layout-sider-icon.vue → pro-layout-sider/components/pro-layout-sider-icon.vue} +2 -2
  21. package/src/components/pro-layout-sider/components/pro-layout-sider-menu-item.vue +137 -0
  22. package/src/components/pro-layout-sider/components/pro-layout-sider-other-menu.vue +140 -0
  23. package/src/components/pro-layout-sider/components/pro-layout-sider-search.vue +345 -0
  24. package/src/components/pro-layout-sider/index.vue +477 -0
  25. package/src/components/{pro-layout-tabs.vue → pro-layout-tabs/index.vue} +115 -22
  26. package/src/index.vue +302 -38
  27. package/src/styles/color.less +267 -0
  28. package/src/styles/images/xiaoxitongzhi.png +0 -0
  29. package/src/styles/other-menu.less +63 -111
  30. package/src/utils/menuItem.js +10 -0
  31. package/src/utils/sider.js +16 -1
  32. package/src/components/pro-layout-header.vue +0 -52
  33. package/src/components/pro-layout-logo.vue +0 -79
  34. package/src/components/pro-layout-nav.vue +0 -150
  35. package/src/components/pro-layout-other-menu.vue +0 -138
  36. package/src/components/pro-layout-sider-menu-item.vue +0 -37
  37. package/src/components/pro-layout-sider.vue +0 -240
  38. package/src/components/pro-layout-tools-user.vue +0 -84
  39. package/src/components/pro-layout-tools.vue +0 -21
  40. package/src/components/pro-layout-trigger.vue +0 -48
@@ -0,0 +1,477 @@
1
+ <template>
2
+ <div ref="listenWidth" class="pro-layout-sider-wrapper"
3
+ :class="[(collapsed || systemInfo.showSearchMenu === '0') ? 'menu-has-collapsed' : '',tabsHeight != 46 ? 'custom-tabs' : '']">
4
+ <Menu v-show="!collapsed" ref="menu"
5
+ :accordion="isAccordionMode" :active-name="activeName"
6
+ :open-names="openedNames" theme="dark"
7
+ width="auto" @on-select="handleSelect"
8
+ @on-open-change="handleOpenChange">
9
+ <template v-for="(item,index) in menuList">
10
+ <template v-if="item.children && item.children.length === 1">
11
+ <ProLayoutSiderMenuItem v-if="showChildren(item)"
12
+ :key="`menu-${item.name}`"
13
+ :parent-item="item"
14
+ :collect-map="isCollected"
15
+ :system-info="systemInfo"
16
+ :nav-list="navList">
17
+ </ProLayoutSiderMenuItem>
18
+ <MenuItem v-else :key="`menu-${item.children[0].name}`"
19
+ :name="getNameOrHref(item, true)">
20
+ <Row type="flex" justify="center" align="top">
21
+ <Col :span="getSpanNum(systemInfo,'icon')">
22
+ <ProLayoutSiderIcon v-if="systemInfo.menuLogo == '1'" :icon-type="item.type == 2 ? (isCollected.hasOwnProperty(item.name) ? 'ios-star' : 'ios-star-outline') : item.meta.icon"></ProLayoutSiderIcon>
23
+ </Col>
24
+ <Col :span="getSpanNum(systemInfo,'title')">
25
+ <div :class="['menu-title-' + item.children[0].permissionId,'draggable-text']" v-draggable="dragOptions(item.children[0])">
26
+ <Tooltip style="width: 100%" v-if="systemInfo.titleShow ==='ellipsis'" placement="right" transfer :content="showTitle(item.children[0])">
27
+ <div class="menu-title-nochildren-ellipsis">{{ showTitle(item.children[0]) }}</div>
28
+ </Tooltip>
29
+ <span v-else class="menu-title-nochildren-wrap">{{ showTitle(item.children[0]) }}</span>
30
+ </div>
31
+ </Col>
32
+ </Row>
33
+ </MenuItem>
34
+ </template>
35
+ <template v-else>
36
+ <ProLayoutSiderMenuItem v-if="showChildren(item)"
37
+ :key="`menu-${item.name}`"
38
+ :parent-item="item"
39
+ :collect-map="isCollected"
40
+ :system-info="systemInfo"
41
+ :nav-list="navList">
42
+ </ProLayoutSiderMenuItem>
43
+ <MenuItem v-else :key="`menu-${item.name}`"
44
+ :name="getNameOrHref(item)">
45
+ <Row type="flex" justify="center" align="top">
46
+ <Col :span="getSpanNum(systemInfo,'icon')">
47
+ <ProLayoutSiderIcon v-if="systemInfo.menuLogo == '1'" :icon-type="item.type == 2 ? (isCollected.hasOwnProperty(item.name) ? 'ios-star' : 'ios-star-outline') : item.meta.icon"></ProLayoutSiderIcon>
48
+ </Col>
49
+ <Col :span="getSpanNum(systemInfo,'title')">
50
+ <div :class="['menu-title-' + item.permissionId,'draggable-text']" v-draggable="dragOptions(item)">
51
+ <Tooltip style="width: 100%" v-if="systemInfo.titleShow ==='ellipsis'" placement="right" transfer :content="showTitle(item)">
52
+ <div class="menu-title-nochildren-ellipsis">{{ showTitle(item) }}</div>
53
+ </Tooltip>
54
+ <span v-else class="menu-title-nochildren-wrap">{{ showTitle(item) }}</span>
55
+ </div>
56
+ </Col>
57
+ </Row>
58
+ </MenuItem>
59
+ </template>
60
+ </template>
61
+ </Menu>
62
+
63
+ <ProLayoutSiderOtherMenu :style="systemInfo.menuScaling === '0' ? { width: otherWidth } : {}" :collapsed="collapsed" @select-menu="selectMenu"></ProLayoutSiderOtherMenu>
64
+ <ProLayoutSiderSearch
65
+ :style="systemInfo.menuScaling === '0' ? { width: otherWidth } : {}"
66
+ v-show="!collapsed && (systemInfo.showSearchMenu !== '0')"
67
+ :searchType="0"
68
+ @select-menu="selectMenu"
69
+ ></ProLayoutSiderSearch>
70
+ <div v-show="collapsed" :list="menuList" class="menu-collapsed" >
71
+ <template v-for="item in menuList">
72
+ <ProLayoutSiderCollapsedMenu v-if="item.children && item.children.length > 0" :key="`drop-menu-${item.name}`"
73
+ :parent-item="item" theme="dark" hide-title transfer
74
+ @on-click="handleSelect" :active-item="openedNames">
75
+ </ProLayoutSiderCollapsedMenu>
76
+ <Tooltip v-else :key="`drop-menu-${item.name}`" :content="showTitle(item.children && item.children[0] ? item.children[0] : item)"
77
+ placement="right" transfer>
78
+ <template v-slot:default="{ active }">
79
+ <a :style="{textAlign: 'center'}"
80
+ :class="['drop-menu-a', item.name === selectedTopParent ? 'selected-parent' : '']"
81
+ @click="handleSelect(getNameOrHref(item, true))">
82
+ <!-- <i :class="[item.meta.icon, selectedIconType === item.meta.icon ? 'selected-icon' : '']"></i>-->
83
+ <ProLayoutSiderIcon :icon-type="item.meta.icon" icon-size="26" :class="{ 'selected-icon': item.name === selectedTopParent && collapsed }"
84
+ ></ProLayoutSiderIcon>
85
+ </a>
86
+ </template>
87
+ </Tooltip>
88
+ </template>
89
+ </div>
90
+
91
+ </div>
92
+ </template>
93
+
94
+ <script>
95
+ import Bus from "@lambo-design/shared/utils/bus";
96
+ import {deepCopy} from "@lambo-design/shared/utils/assist";
97
+ import generatorMenuList from "@lambo-design/shared/utils/menu/index";
98
+ import sider from '../../utils/sider'
99
+ import ProLayoutSiderOtherMenu from "./components/pro-layout-sider-other-menu";
100
+ import ProLayoutSiderSearch from "./components/pro-layout-sider-search";
101
+ import ProLayoutSiderMenuItem from './components/pro-layout-sider-menu-item'
102
+ import ProLayoutSiderCollapsedMenu from './components/pro-layout-sider-collapsed-menu'
103
+ import {
104
+ filterMenuName, filterMenuUri, tagExists,
105
+ isOpenBlank, buildSinglePermission,arraysEqual
106
+ } from "@lambo-design/shared/utils/platform";
107
+ import config from "@lambo-design/shared/config/config";
108
+ import {getThemeVarByKey} from "@lambo-design/shared/utils/theme";
109
+
110
+ export default {
111
+ name: "pro-layout-sider",
112
+ components: {
113
+ ProLayoutSiderMenuItem,
114
+ ProLayoutSiderCollapsedMenu,
115
+ ProLayoutSiderOtherMenu,
116
+ ProLayoutSiderSearch
117
+ },
118
+ props:{
119
+ serverContext: {
120
+ type: String,
121
+ default: () => config.upmsServerContext // 设置默认值
122
+ }
123
+ },
124
+ data(){
125
+ return {
126
+ show: false,
127
+ otherWidth:'',
128
+ originalAllMenuList: [],
129
+ navList: [],
130
+ originMenuList:[],
131
+ menuList: [],
132
+ appId: '',
133
+ collapsed: false,
134
+ activeName: '',
135
+ openedNames: [],
136
+ userExpandedMenus: [], // 记录用户手动展开的菜单(非手风琴模式下使用)
137
+ activeMenu: null,
138
+ selectedMenuParent: null,
139
+ activeMenuItem: null,
140
+ openedSubMenu: null,
141
+ currentMenuItem: null,
142
+ selectedTopParent: '',
143
+ activeIcon: null,
144
+ tagValue: '',
145
+ tagList: [],
146
+ collectMenuList: [],
147
+ isCollected: {},
148
+ systemInfo:{},
149
+ tabsHeight: 46
150
+ }
151
+ },
152
+ mixins:[sider],
153
+ computed: {
154
+ isAccordionMode() {
155
+ // 当 accordionMode 为 '0' 时关闭手风琴模式,否则开启
156
+ return this.systemInfo.accordionMode !== '0';
157
+ }
158
+ },
159
+ methods: {
160
+ initListener(){
161
+ Bus.$on('origin-all-menu-list', (data)=>{
162
+ this.initAllMenu(data);
163
+ });
164
+ Bus.$on('nav-list',(data)=>{
165
+ this.initNav(data)
166
+ });
167
+ Bus.$on('menu-list',(data)=>{
168
+ this.initMenu(data)
169
+ });
170
+ Bus.$on('trigger-change',(data)=>{
171
+ this.triggerChange(data)
172
+ });
173
+ Bus.$on('change-app', ({appId,appInfo})=> {
174
+ this.changeApp(appId,appInfo)
175
+ })
176
+ Bus.$on('tag-list',(data,current)=>{
177
+ this.initTags(data,current)
178
+ });
179
+ Bus.$on('menu-click',(current)=>{
180
+ this.menuClick(current)
181
+ });
182
+ Bus.$on('select-menu',(name,item)=>{
183
+ this.selectMenu(name,item)
184
+ });
185
+ Bus.$on('collect-menu-list',(data)=>{
186
+ this.initCollectMenu(data)
187
+ });
188
+ Bus.$on('system-info',(data)=>{
189
+ this.initSystemInfo(data)
190
+ })
191
+ },
192
+ destroyListener(){
193
+ Bus.$off('origin-all-menu-list')
194
+ Bus.$off('nav-list')
195
+ Bus.$off('menu-list')
196
+ Bus.$off('trigger-change')
197
+ Bus.$off('change-app')
198
+ Bus.$off('tag-list')
199
+ Bus.$off('menu-click')
200
+ Bus.$off('select-menu')
201
+ Bus.$off('collect-menu-list')
202
+ Bus.$off('system-info')
203
+ },
204
+ initSystemInfo(data){
205
+ this.systemInfo = deepCopy(data)
206
+ },
207
+ initAllMenu(data){
208
+ this.originalAllMenuList = data;
209
+ },
210
+ initNav(data){
211
+ if (this.navList && data && arraysEqual(this.navList,data)){
212
+ return;
213
+ }
214
+ this.navList = data;
215
+ },
216
+ initMenu(data){
217
+ if (this.originMenuList && data && arraysEqual(this.originMenuList,data)){
218
+ return;
219
+ }
220
+ if (data && data.length > 0) {
221
+ let item = data[0];
222
+ if (item.appId && item.appId !== this.appId) {
223
+ return;
224
+ }
225
+ }
226
+ this.originMenuList = deepCopy(data);
227
+ this.changeMenu()
228
+ },
229
+ initCollectMenu(data){
230
+ this.collectMenuList = data;
231
+ this.isCollected = {}
232
+ this.collectMenuList.forEach(menu => {
233
+ this.isCollected[menu.name] = true
234
+ })
235
+ },
236
+ changeApp(appId,appInfo){
237
+ this.appId = appId;
238
+ this.changeMenu()
239
+ },
240
+ changeMenu(){
241
+ let treeMenuList = generatorMenuList(this.originMenuList,this.appId,'menu');
242
+ if (treeMenuList && treeMenuList.length > 0) {
243
+ this.menuList = treeMenuList;
244
+ } else {
245
+ this.menuList = [];
246
+ }
247
+ Bus.$emit('tree-menu-list',this.menuList)
248
+ this.openedNames = this.getOpenedNamesByActiveName();
249
+ },
250
+ selectMenu(name,menu) {
251
+ if (!menu) {
252
+ let res = this.originMenuList.filter(item => item.name == name)
253
+ if (res && res.length > 0) {
254
+ menu = res[0];
255
+ }
256
+ }
257
+ if (config.mainType && config.mainType == 'singleApp') {
258
+ menu = buildSinglePermission(this.originalAllMenuList, menu);
259
+ }
260
+ if (menu.appId && menu.appId != this.appId) {
261
+ let appInfo = this.navList.filter(app => app.appId === menu.appId);
262
+ Bus.$emit('change-app', {appId:menu.appId,appInfo:appInfo[0]})
263
+ }
264
+ setTimeout(()=>{
265
+ this.handleSelect(name)
266
+ },100)
267
+ },
268
+ handleSelect(name,uri,pid){
269
+ /*if (this.activeName == name) {
270
+ return;
271
+ }*/
272
+ let menu = null;
273
+ if (name.indexOf("isTurnByHref_") > -1) {
274
+ name = name.replace("isTurnByHref_","");
275
+ menu = filterMenuUri(this.menuList,name);
276
+ } else {
277
+ menu = filterMenuName(this.menuList,name);
278
+ }
279
+ let tagList = this.tagList;
280
+ if (menu && menu.name) {
281
+ if (isOpenBlank(menu)) {
282
+ Bus.$emit('menu-click', menu.name , menu)
283
+ } else {
284
+ let tag = tagList.find(item => item.name == menu.name);
285
+ if (!tag) {
286
+ tag = {}
287
+ }
288
+ if ('home' != menu.name) {
289
+ let res = tagList.filter(item => item.name !== menu.name);
290
+ menu.cts = new Date().getTime();
291
+ tag = Object.assign(tag, menu);
292
+ res.push(tag);
293
+ tagList = deepCopy(res);
294
+ }
295
+ Bus.$emit('tag-list', tagList, menu.name)
296
+ }
297
+
298
+ /*if (!tagExists(tagList,menu.name)) {
299
+ if (!isOpenBlank(menu)) {
300
+ tagList.push(menu);
301
+ } else {
302
+ Bus.$emit('menu-click', menu.name , menu)
303
+ }
304
+ } else {
305
+ let tag = tagList.find(item => item.name == menu.name);
306
+ if ('home' != menu.name) {
307
+ let res = tagList.filter(item => item.name !== menu.name);
308
+ menu.cts = new Date().getTime();
309
+ tag = Object.assign(tag, menu);
310
+ res.push(tag);
311
+ tagList = deepCopy(res);
312
+ }
313
+ }
314
+ Bus.$emit('tag-list', tagList, menu.name)*/
315
+ }
316
+ /*if (menu.meta && Array.isArray(menu.meta.crumbs)) {
317
+ let parentMenu = menu.meta.crumbs[0]
318
+ this.$set(this, 'selectedTopParent', parentMenu.name);
319
+ } else {
320
+ // 处理没有父菜单的情况
321
+ this.$set(this, 'selectedTopParent', menu.name);
322
+ }
323
+ // 如果 uri 为空,则需要根据 pid 判断是展开父菜单还是同时展开父菜单和当前菜单
324
+ if (!uri) {
325
+ let parentName;
326
+ if (pid === 0) {
327
+ // 如果 pid 为 0,表示是最外层菜单
328
+ parentName = this.getNameOrHref(menu);
329
+ } else {
330
+ // 如果 pid 不等于 0,查找并打开对应的最外层父菜单
331
+ parentName = this.getTopParent(menu);
332
+ this.openedNames = [parentName]; // 设置最外层父菜单为展开状态
333
+ this.activeName = menu.name; // 设置当前菜单为激活状态
334
+ }
335
+ }*/
336
+ },
337
+ getTopParent(menu) {
338
+ return menu.parent ? this.getTopParent(menu.parent) : menu.name;
339
+ },
340
+ triggerChange(data){
341
+ this.collapsed = data;
342
+ },
343
+ initTags(data,name){
344
+ this.tagList = data;
345
+ this.value = name;
346
+ },
347
+ menuClick(current) {
348
+ let item = this.originMenuList.filter(menu => menu.name === current && menu.type && menu.type == '2');
349
+ if (item && item.length > 0){
350
+ if (isOpenBlank(item[0])) {
351
+ //window.location.href = window.location.href;
352
+ return;
353
+ }
354
+ let type = item[0].type;
355
+ if (type == 2) {
356
+ this.activeName = current;
357
+ } else {
358
+ let pItem = this.originMenuList.filter(menu => menu.permissionId === item[0].pid);
359
+ if (pItem && pItem.length > 0){
360
+ this.activeName = pItem[0].name;
361
+ }
362
+ }
363
+ } else {
364
+ this.activeName = current;
365
+ }
366
+ },
367
+ getOpenedNamesByActiveName(){
368
+ let res = filterMenuName(this.menuList,this.activeName);
369
+ let openNames = []
370
+ if (res) {
371
+ const crumbs = res.meta.crumbs;
372
+ if (crumbs) {
373
+ crumbs.forEach(item => {
374
+ if (item.type === 1) {
375
+ openNames.push(item.name)
376
+ }
377
+ })
378
+ }
379
+ }
380
+ return openNames
381
+ },
382
+ handleOpenChange(openNames) {
383
+ // openNames 是 Menu 组件当前的所有展开项
384
+ if (this.systemInfo.accordionMode === '0') {
385
+ // 非手风琴模式:保存用户手动展开的状态
386
+ this.userExpandedMenus = [...openNames];
387
+ }
388
+ // 注意:这里不直接修改 this.openedNames,避免循环触发
389
+ },
390
+ mergeOpenedNames(newNames) {
391
+ // 如果关闭手风琴模式,保留用户手动展开的菜单
392
+ if (this.systemInfo.accordionMode === '0') {
393
+ // 合并用户展开的菜单和新的必需展开项
394
+ const merged = [...new Set([...this.userExpandedMenus, ...newNames])];
395
+ return merged;
396
+ } else {
397
+ // 手风琴模式,只保留新的 names(路径必需的展开项)
398
+ return newNames;
399
+ }
400
+ },
401
+ handleResize() {
402
+ const targetElement = this.$refs.listenWidth; // 获取 DOM 元素的引用
403
+ this.otherWidth = targetElement.clientWidth+'px'; // 获取 div 元素的宽度
404
+ },
405
+ dragOptions(item){
406
+ if (!item) {
407
+ item = {}
408
+ }
409
+ item.navList = this.navList;
410
+ return {
411
+ trigger: '.menu-title-' + item.permissionId,
412
+ body: '.menu-title-' + item.permissionId,
413
+ recover: true,
414
+ item: item
415
+ }
416
+ },
417
+ loadingCustomStyle(){
418
+ let themeKey = localStorage.getItem("theme") ? localStorage.getItem("theme") : "default"
419
+ let tabsHeight = getThemeVarByKey(themeKey,'--layout-tabs-height');
420
+ if (tabsHeight) {
421
+ this.tabsHeight = tabsHeight;
422
+ }
423
+ }
424
+ },
425
+ watch:{
426
+ activeName(){
427
+ const newOpenNames = this.getOpenedNamesByActiveName();
428
+ this.openedNames = this.mergeOpenedNames(newOpenNames);
429
+ },
430
+ openedNames() {
431
+ this.$nextTick(() => {
432
+ this.$refs.menu.updateOpened()
433
+ this.$refs.menu.updateActiveName()
434
+ })
435
+ }
436
+ },
437
+ mounted() {
438
+ window.addEventListener('resize', this.handleResize); // 监听窗口大小变化事件
439
+ this.handleResize(); // 初始化时获取一次宽度
440
+ this.loadingCustomStyle();
441
+ },
442
+ created(){
443
+ this.initListener();
444
+ },
445
+ beforeDestroy(){
446
+ this.destroyListener();
447
+ window.removeEventListener('resize', this.handleResize); // 在组件销毁前移除事件监听器,以防止内存泄漏
448
+ }
449
+
450
+ }
451
+ </script>
452
+
453
+ <style scoped lang="less">
454
+ @import "@lambo-design/core/src/styles/default";
455
+ @import '../../styles/other-menu.less';
456
+ .pro-layout-sider-wrapper{
457
+ margin-bottom: 50px;
458
+ padding-top: 47px;
459
+ .menu-collapsed {
460
+ padding-top: 10px;
461
+ /deep/a.drop-menu-a{
462
+ display: inline-block;
463
+ padding: 6px 20px;
464
+ width: 100%;
465
+ text-align: center;
466
+ font-weight: normal;
467
+ }
468
+ overflow: hidden;
469
+ }
470
+ &.menu-has-collapsed{
471
+ padding-top: 0 !important;
472
+ }
473
+ &.custom-tabs{
474
+ padding-top: 36px;
475
+ }
476
+ }
477
+ </style>
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <div class="pro-layout-tabs-wrapper">
2
+ <div class="pro-layout-tabs-wrapper" :class="tabsHeight != 46 ? 'custom-tabs' : ''">
3
3
  <div class="close-con">
4
4
  <Dropdown transfer @on-click="handleTagsOption">
5
5
  <Icon :size="24" type="ios-close-circle-outline" class="btn-close"/>
6
6
  <DropdownMenu slot="list">
7
- <DropdownItem name="close-all">关闭所有</DropdownItem>
8
- <DropdownItem name="close-others">关闭其他</DropdownItem>
7
+ <DropdownItem name="close-all">{{ t('pro-layout.tabs.close-all') }}</DropdownItem>
8
+ <DropdownItem name="close-others">{{ t('pro-layout.tabs.close-others') }}</DropdownItem>
9
9
  </DropdownMenu>
10
10
  </Dropdown>
11
11
  </div>
@@ -46,15 +46,18 @@ import {
46
46
  getPreviousTagIndex,
47
47
  getDelTagIndex,
48
48
  setTagNavListInLocalstorage,
49
- showTitle
49
+ showTitle, getRootPermission
50
50
  } from '@lambo-design/shared/utils/platform'
51
51
  import beforeClose from '@lambo-design/shared/utils/menu/before-close'
52
52
  import Bus from "@lambo-design/shared/utils/bus";
53
53
  import config from "@lambo-design/shared/config/config";
54
54
  import {deepCopy} from "@lambo-design/shared/utils/assist";
55
+ import {getThemeVarByKey} from "@lambo-design/shared/utils/theme";
56
+ import Locale from "@lambo-design/core/src/mixins/locale";
55
57
 
56
58
  export default {
57
59
  name: 'pro-layout-tabs',
60
+ mixins: [Locale],
58
61
  data() {
59
62
  return {
60
63
  systemInfo: {},
@@ -72,9 +75,16 @@ export default {
72
75
  contextMenuTop: 0,
73
76
  visible: false,
74
77
  menuList: {
75
- others: '关闭其他',
76
- all: '关闭所有'
77
- }
78
+ others: this.t('pro-layout.tabs.close-others'),
79
+ all: this.t('pro-layout.tabs.close-all')
80
+ },
81
+ tabsHeight: 46
82
+ }
83
+ },
84
+ props: {
85
+ notSingleApp: {
86
+ type: Boolean,
87
+ default: true
78
88
  }
79
89
  },
80
90
  methods: {
@@ -138,8 +148,31 @@ export default {
138
148
  }, 200)
139
149
  },
140
150
  changeApp(appId,appInfo){
151
+ let oldAppId = this.appId
152
+ let oldAppInfo = this.appInfo
141
153
  this.appId = appId;
142
154
  this.appInfo = appInfo;
155
+ if(oldAppId !== appId && oldAppInfo && this.appInfo){
156
+ let oldAppConfig = {}
157
+ if(oldAppInfo.extendProps){
158
+ oldAppConfig = oldAppInfo.extendProps
159
+ }
160
+ if(oldAppInfo.setting){
161
+ oldAppConfig = JSON.parse(oldAppInfo.setting)
162
+ }
163
+ let newAppConfig = {}
164
+ if(this.appInfo.extendProps){
165
+ newAppConfig = this.appInfo.extendProps
166
+ }
167
+ if(this.appInfo.setting){
168
+ newAppConfig = JSON.parse(this.appInfo.setting)
169
+ }
170
+ if(oldAppConfig && oldAppConfig.hasOwnProperty('is_hide_left_menu')
171
+ && oldAppConfig.is_hide_left_menu === '1' && oldAppConfig.homePagePath){
172
+ let removeTag = this.tagList.filter(item => item.meta.appId === oldAppInfo.appId)
173
+ this.handleClose(removeTag[0],true)
174
+ }
175
+ }
143
176
  },
144
177
  emitTags(data,current){
145
178
  Bus.$emit('tag-list',data,current);
@@ -183,20 +216,22 @@ export default {
183
216
  }, 100)
184
217
  }
185
218
  },
186
- handleClose(current) {
219
+ handleClose(current,isHomePage) {
187
220
  if (current.meta && current.meta.beforeCloseName && current.meta.beforeCloseName in beforeClose) {
188
221
  new Promise(beforeClose[current.meta.beforeCloseName]).then(close => {
189
222
  if (close) {
190
- this.close(current)
223
+ this.close(current,isHomePage)
191
224
  }
192
225
  })
193
226
  } else {
194
- this.close(current)
227
+ this.close(current,isHomePage)
195
228
  }
196
229
  },
197
- close(route) {
230
+ close(route,isHomePage) {
198
231
  let value = this.value;
199
- if (route.name == this.value) {
232
+ if (isHomePage) {
233
+ value = config.homeRouter.name;
234
+ } else if (route.name == this.value) {
200
235
  let preTagIndex = getPreviousTagIndex(this.tagList, this.value)
201
236
  value = this.tagList[preTagIndex].name;
202
237
  }
@@ -204,18 +239,33 @@ export default {
204
239
  this.emitTags(res, value);
205
240
  },
206
241
  handleClick(item) {
207
- this.value = item.name
208
- Bus.$emit('menu-click', item.name , item)
209
- if (item.meta && item.meta.appId
210
- && item.meta.appId != this.appId
211
- && item.meta.appId != config.homeRouter.meta.appId) {
212
- let appInfo = this.navList.filter(app => app.appId === item.meta.appId);
213
- if (appInfo && appInfo.length > 0) {
214
- Bus.$emit('change-app', {appId:appInfo[0].appId,appInfo:appInfo[0]})
215
- } else {
216
- Bus.$emit('change-app', {appId:item.meta.appId,appInfo:null})
242
+ if (item.meta && item.meta.appId && item.meta.appId != config.homeRouter.meta.appId) {
243
+ let appIdInner = item.meta.appId;
244
+ if (!this.notSingleApp) {
245
+ // 如果是单应用模式,根据permissionId找到最上层目录(即导航栏中的应用)的permissionId
246
+ const permissionList = this.$store.getters.getOriginalPermissionList;
247
+ if (permissionList && permissionList.length > 0) {
248
+ const permission = {
249
+ pid: item.pid,
250
+ appId: item.meta ? item.meta.appId : item.appId
251
+ }
252
+ const rootPermission = getRootPermission(permissionList, permission);
253
+ if (rootPermission && rootPermission.permissionId) {
254
+ appIdInner = rootPermission.permissionId
255
+ }
256
+ }
257
+ }
258
+ if (appIdInner != this.appId) {
259
+ let appInfo = this.navList.filter(app => app.appId === appIdInner);
260
+ if (appInfo && appInfo.length > 0) {
261
+ Bus.$emit('change-app', {appId: appInfo[0].appId, appInfo: appInfo[0]})
262
+ } else {
263
+ Bus.$emit('change-app', {appId: appIdInner, appInfo: null})
264
+ }
217
265
  }
218
266
  }
267
+ this.value = item.name
268
+ Bus.$emit('menu-click', item.name , item);
219
269
  },
220
270
  showTitleInside(item) {
221
271
  return showTitle(item, this)
@@ -261,6 +311,13 @@ export default {
261
311
  },
262
312
  closeMenu() {
263
313
  this.visible = false
314
+ },
315
+ loadingCustomStyle(){
316
+ let themeKey = localStorage.getItem("theme") ? localStorage.getItem("theme") : "default"
317
+ let tabsHeight = getThemeVarByKey(themeKey,'--layout-tabs-height');
318
+ if (tabsHeight) {
319
+ this.tabsHeight = tabsHeight;
320
+ }
264
321
  }
265
322
  },
266
323
  watch: {
@@ -276,6 +333,7 @@ export default {
276
333
  setTimeout(() => {
277
334
  this.getTagElementByRoute(this.value)
278
335
  }, 200)
336
+ this.loadingCustomStyle();
279
337
  },
280
338
  created(){
281
339
  this.initListener();
@@ -400,5 +458,40 @@ export default {
400
458
  background-color: var(--primary-color,@_primary-color)
401
459
  }
402
460
  }
461
+ &.custom-tabs{
462
+ height: 36px;
463
+ line-height: 30px;
464
+ .close-con{
465
+ .btn-close{
466
+ margin-top: 5px;
467
+ }
468
+ }
469
+ .btn-con{
470
+ padding: 5px 0px;
471
+ }
472
+ .scroll-outer{
473
+ left: 8px;
474
+ right: 51px;
475
+ .scroll-body{
476
+ /deep/.ivu-tag-dot{
477
+ height: 28px;
478
+ line-height: 28px;
479
+ padding: 0 8px;
480
+ .ivu-tag-dot-inner{
481
+ width: 10px;
482
+ height: 10px;
483
+ margin-right: 2px;
484
+ top: 1px;
485
+ }
486
+ }
487
+ /deep/.ivu-tag{
488
+ .ivu-icon-ios-close{
489
+ margin-left: 0px !important;
490
+ top: 0px;
491
+ }
492
+ }
493
+ }
494
+ }
495
+ }
403
496
  }
404
497
  </style>