cloud-web-corejs 1.1.0-dev.11 → 1.1.0-dev.14

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 (48) hide show
  1. package/package.json +1 -1
  2. package/src/components/VabUpload/view.vue +25 -25
  3. package/src/components/excelExport/exportColumnMemory.js +118 -0
  4. package/src/components/excelExport/exportFieldDialog.vue +50 -38
  5. package/src/components/excelExport/index.js +30 -13
  6. package/src/components/excelExport/mixins.js +403 -65
  7. package/src/components/excelImport/mixins.js +898 -850
  8. package/src/components/mobile/wf/addTaskUserdialog.vue +100 -100
  9. package/src/components/mobile/wf/content.vue +4 -4
  10. package/src/components/mobile/wf/deleteTaskUserDialog.vue +73 -73
  11. package/src/components/mobile/wf/setCandidateDialog.vue +69 -69
  12. package/src/components/mobile/wf/urgingDialog.vue +75 -75
  13. package/src/components/table/index.js +14 -1
  14. package/src/components/table/vxeFilter/mixin.js +28 -18
  15. package/src/components/xform/docs/2026-07 table/344/270/216excelExport/344/277/256/345/244/215/345/217/212/345/257/274/345/207/272/344/274/230/345/214/226.md" +64 -57
  16. package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +528 -0
  17. package/src/components/xform/docs/2026-08 xform H5 P1 /345/256/236/347/216/260/350/247/204/346/240/274.md" +412 -0
  18. package/src/components/xform/docs/2026-08 xform H5 P2 /345/256/236/347/216/260/350/247/204/346/240/274.md" +287 -0
  19. package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +400 -0
  20. package/src/components/xform/docs/2026-09 /346/235/241/344/273/266/345/257/274/345/207/272/345/244/247/346/225/260/346/215/256/351/207/217/345/264/251/346/272/203/346/216/222/346/237/245.md" +389 -0
  21. package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +243 -243
  22. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +228 -228
  23. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +165 -165
  24. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +61 -2
  25. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +3 -0
  26. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +145 -145
  27. package/src/components/xform/form-render/container-item/data-table-item.vue +350 -347
  28. package/src/components/xform/form-render/container-item/data-table-mixin.js +251 -37
  29. package/src/components/xform/form-render/container-item/list-h5-item.vue +1 -1
  30. package/src/components/xform/utils/dynamicSchemaUtil.js +385 -361
  31. package/src/layout/components/TagsView/index.vue +325 -323
  32. package/src/store/modules/tagsView.js +241 -217
  33. package/src/utils/importLimit.js +72 -0
  34. package/src/utils/pdfUtil.js +6 -1
  35. package/src/utils/request.js +17 -0
  36. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  37. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  38. package/src/views/demo/bizTab/bill/list.vue +288 -0
  39. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  40. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  41. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  42. package/src/views/demo/bizTab/simple/list.vue +217 -0
  43. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  44. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  45. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  46. package/src/views/demo/bizTab/wf/list.vue +242 -0
  47. package/src/views/user/home/wjl/content.vue +1569 -0
  48. package/src/views/user/outLink/cc_form_view.vue +188 -0
@@ -1,323 +1,325 @@
1
- <template>
2
- <div id="tags-view-container" class="navbar-tag">
3
- <div @click="$baseEventBus.$emit('triggerMenu')" class="telescopMenuIcon"><i class="iconfont" :class="isMenu?'icon-shouqi':'icon-shouqi-copy'"></i></div>
4
- <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
5
- <router-link
6
- v-for="tag in visitedViews"
7
- ref="tag"
8
- :key="viewKey(tag)"
9
- :class="isActive(tag)?'active':''"
10
- :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
11
- tag="span"
12
- class="tags-view-item"
13
- @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
14
- @contextmenu.prevent.native="openMenu(tag,$event)"
15
- >
16
- <i class="el-icon-s-home" v-if="tag.name =='home'"></i>
17
- {{ getMenuName(tag) }}
18
-
19
- <span v-if="!!tag.meta.user_affix" class="el-icon-close is-disabled"/>
20
- <span v-else-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
21
- </router-link>
22
- </scroll-pane>
23
- <div class="tags-operBox">
24
- <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('左移')" placement="bottom">
25
- <i class="el-icon-arrow-left" layadmin-event="leftPage"
26
- one-link-mark="yes" @click="$refs.scrollPane.handleScrollLeft()"/>
27
- </el-tooltip>
28
- <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('右移')" placement="bottom" l>
29
- <i class="el-icon-arrow-right" ayadmin-event="rightPage"
30
- one-link-mark="yes" @click="$refs.scrollPane.handleScrollRight()"/>
31
- </el-tooltip>
32
- <el-dropdown >
33
- <span class="el-dropdown-link" style="padding-right:10px;padding-left:4px;">
34
- <i class="el-icon-more el-icon--right"></i>
35
- </span>
36
- <el-dropdown-menu slot="dropdown">
37
- <el-dropdown-item @click.native="refreshSelectedTag($route)" :disabled="getIsLock()">
38
- <i class="el-icon-refresh"/><span>{{ $t1('刷新') }}</span>
39
- </el-dropdown-item>
40
- <el-dropdown-item @click.native="closeAllTags($route)">
41
- <i class="el-icon-close"/><span>{{ $t1('全部关闭') }}</span>
42
- </el-dropdown-item>
43
- </el-dropdown-menu>
44
- </el-dropdown>
45
- <!-- <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('刷新')" placement="bottom">
46
- <i class="el-icon-refresh" @click="refreshSelectedTag($route)"/>
47
- </el-tooltip>
48
- <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('全部关闭')" placement="bottom">
49
- <i class="el-icon-close" @click="closeAllTags(selectedTag)"/>
50
- </el-tooltip> -->
51
- </div>
52
- <!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
53
- <li @click="refreshSelectedTag(selectedTag)">Refresh</li>
54
- <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li>
55
- <li @click="closeOthersTags">Close Others</li>
56
- <li @click="closeAllTags(selectedTag)">Close All</li>
57
- </ul> -->
58
- </div>
59
- </template>
60
-
61
- <script>
62
- import ScrollPane from './ScrollPane'
63
- import path from 'path'
64
- import { viewKey, isRepeatable } from '@base/utils/repeatOpen'
65
-
66
- export default {
67
- components: {ScrollPane},
68
- props: {
69
- isMenu: {
70
- type: Boolean
71
- }
72
- },
73
- data() {
74
- return {
75
- visible: false,
76
- top: 0,
77
- left: 0,
78
- selectedTag: {},
79
- affixTags: []
80
- }
81
- },
82
- computed: {
83
- visitedViews() {
84
- return this.$store.state.tagsView.visitedViews
85
- },
86
- routes() {
87
- return this.$store.state.permission.routes
88
- }
89
- },
90
- watch: {
91
- $route() {
92
- this.addTags()
93
- this.moveToCurrentTag()
94
- },
95
- visible(value) {
96
- if (value) {
97
- document.body.addEventListener('click', this.closeMenu)
98
- } else {
99
- document.body.removeEventListener('click', this.closeMenu)
100
- }
101
- }
102
- },
103
- mounted() {
104
- this.initTags()
105
- this.addTags()
106
- },
107
- methods: {
108
- getMenuName(item) {
109
- let locale = this.$i18n?.locale;
110
- let zhTitle = item.meta?.title || "";
111
- let enTitle = item.meta?.enTitle || '';
112
- let title;
113
- if (locale == "en") {
114
- title = enTitle || zhTitle;
115
- } else {
116
- title = zhTitle
117
- }
118
- if (!enTitle || locale !== "en") {
119
- title = zhTitle
120
- }
121
- if (this.$t1) {
122
- title = this.$t1(title)
123
- }
124
- if (item.repeatIndex > 1) {
125
- title = `${title} (${item.repeatIndex})`
126
- }
127
- return title;
128
- },
129
- viewKey(view) {
130
- return viewKey(view)
131
- },
132
- isActive(route) {
133
- return viewKey(route) === viewKey(this.$route)
134
- },
135
- isAffix(tag) {
136
- return tag.meta && tag.meta.affix
137
- },
138
- filterAffixTags(routes, basePath = '/') {
139
- let tags = []
140
- routes.forEach(route => {
141
- if (route.meta && route.meta.affix) {
142
- const tagPath = path.resolve(basePath, route.path)
143
- tags.push({
144
- fullPath: tagPath,
145
- path: tagPath,
146
- name: route.name,
147
- meta: {...route.meta}
148
- })
149
- }
150
- if (route.children) {
151
- const tempTags = this.filterAffixTags(route.children, route.path)
152
- if (tempTags.length >= 1) {
153
- tags = [...tags, ...tempTags]
154
- }
155
- }
156
- })
157
- return tags
158
- },
159
- initTags() {
160
- const affixTags = this.affixTags = this.filterAffixTags(this.routes)
161
- for (const tag of affixTags) {
162
- // Must have tag name
163
- if (tag.name) {
164
- this.$store.dispatch('tagsView/addVisitedView', tag)
165
- }
166
- }
167
- },
168
- addTags() {
169
- const {name} = this.$route
170
- if (name) {
171
- this.$store.dispatch('tagsView/addView', this.$route)
172
- }
173
- return false
174
- },
175
- moveToCurrentTag() {
176
- const tags = this.$refs.tag
177
- this.$nextTick(() => {
178
- const routeIsRepeat = isRepeatable(this.$route)
179
- for (const tag of tags) {
180
- const matched = routeIsRepeat
181
- ? tag.to.fullPath === this.$route.fullPath
182
- : tag.to.path === this.$route.path
183
- if (matched) {
184
- this.$refs.scrollPane.moveToTarget(tag)
185
- // when query is different then update
186
- if (tag.to.fullPath !== this.$route.fullPath) {
187
- this.$store.dispatch('tagsView/updateVisitedView', this.$route)
188
- }
189
- break
190
- }
191
- }
192
- })
193
- },
194
- refreshSelectedTag(view) {
195
- this.$baseEventBus.$emit("reflushRouteView", view);
196
- /* if(this.$route.name=="outLink"){
197
- let a = this.$baseEventBus.$emit("getAppMain");
198
- let t = this.$parent.$refs["appMain"].$refs["ref_"+this.$route.path][0];
199
- t.$baseReload();
200
- }else{
201
- this.$store.dispatch('tagsView/delCachedView', view).then(() => {
202
- const { fullPath } = view
203
- this.$nextTick(() => {
204
- this.$router.replace({
205
- path: '/redirect' + fullPath
206
- })
207
- })
208
- })
209
- } */
210
- },
211
- closeSelectedTag(view) {
212
- if(view.meta.user_affix)return
213
- this.$store.dispatch('tagsView/delView', view).then(({visitedViews}) => {
214
- if (this.isActive(view)) {
215
- this.toLastView(visitedViews, view)
216
- }
217
- })
218
- },
219
- closeOthersTags() {
220
- this.$router.push(this.selectedTag)
221
- this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
222
- this.moveToCurrentTag()
223
- })
224
- },
225
- closeAllTags(view) {
226
- this.$baseConfirm(this.$t1('您确定要全部关闭吗?')).then(() => {
227
- this.$store.dispatch('tagsView/delAllViews').then(({visitedViews}) => {
228
- if (this.affixTags.some(tag => tag.path === view.path)) {
229
- return
230
- }
231
- this.toLastView(visitedViews, view)
232
- })
233
- })
234
- },
235
- toLastView(visitedViews, view) {
236
- const latestView = visitedViews.slice(-1)[0]
237
- if (latestView) {
238
- this.$router.push(latestView.fullPath)
239
- } else {
240
- // now the default is to redirect to the home page if there is no tags-view,
241
- // you can adjust it according to your needs.
242
- if (view.name === 'Dashboard') {
243
- // to reload home page
244
- this.$router.replace({path: '/redirect' + view.fullPath})
245
- } else {
246
- this.$router.push('/')
247
- }
248
- }
249
- },
250
- openMenu(tag, e) {
251
- const menuMinWidth = 105
252
- const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
253
- const offsetWidth = this.$el.offsetWidth // container width
254
- const maxLeft = offsetWidth - menuMinWidth // left boundary
255
- const left = e.clientX - offsetLeft + 15 // 15: margin right
256
-
257
- if (left > maxLeft) {
258
- this.left = maxLeft
259
- } else {
260
- this.left = left
261
- }
262
-
263
- this.top = e.clientY
264
- this.visible = true
265
- this.selectedTag = tag
266
- },
267
- closeMenu() {
268
- this.visible = false
269
- },
270
- handleScroll() {
271
- this.closeMenu()
272
- },
273
- getIsLock() {
274
- let path = this.$route.path;
275
- let visitedViews = this.$store.state.tagsView.visitedViews
276
- let currentItem = visitedViews.find(item => item.path == path)
277
- return !!currentItem?.meta?.user_affix;
278
- },
279
- }
280
- }
281
- </script>
282
-
283
- <style scoped lang="scss">
284
- @import '~@/styles/variables.scss';
285
-
286
- .navbar-tag .tags-view-item.active {
287
- background: $baseColor !important;
288
- }
289
- </style>
290
- <style lang="scss">
291
- //reset element css of el-icon-close
292
- span.el-icon-close.is-disabled{
293
- cursor: not-allowed;
294
- }
295
- .tags-view-wrapper {
296
- .tags-view-item {
297
- .el-icon-close {
298
- width: 14px;
299
- height: 14px;
300
- vertical-align: text-bottom;
301
- line-height: 12px;
302
- border-radius: 50%;
303
- text-align: center;
304
- transition: all .3s cubic-bezier(.645, .045, .355, 1);
305
- transform-origin: 100% 50%;
306
- display: none;
307
- position: absolute;
308
- right: 12px;
309
- top: 8px;
310
-
311
- &:before {
312
- transform: scale(.84);
313
- display: inline-block;
314
- vertical-align: -1.8px;
315
- }
316
- }
317
-
318
- &:hover .el-icon-close {
319
- display: block;
320
- }
321
- }
322
- }
323
- </style>
1
+ <template>
2
+ <div id="tags-view-container" class="navbar-tag">
3
+ <div @click="$baseEventBus.$emit('triggerMenu')" class="telescopMenuIcon"><i class="iconfont" :class="isMenu?'icon-shouqi':'icon-shouqi-copy'"></i></div>
4
+ <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
5
+ <router-link
6
+ v-for="tag in visitedViews"
7
+ ref="tag"
8
+ :key="viewKey(tag)"
9
+ :class="isActive(tag)?'active':''"
10
+ :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
11
+ tag="span"
12
+ class="tags-view-item"
13
+ @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
14
+ @contextmenu.prevent.native="openMenu(tag,$event)"
15
+ >
16
+ <i class="el-icon-s-home" v-if="tag.name =='home'"></i>
17
+ {{ getMenuName(tag) }}
18
+
19
+ <span v-if="!!tag.meta.user_affix" class="el-icon-close is-disabled"/>
20
+ <span v-else-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
21
+ </router-link>
22
+ </scroll-pane>
23
+ <div class="tags-operBox">
24
+ <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('左移')" placement="bottom">
25
+ <i class="el-icon-arrow-left" layadmin-event="leftPage"
26
+ one-link-mark="yes" @click="$refs.scrollPane.handleScrollLeft()"/>
27
+ </el-tooltip>
28
+ <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('右移')" placement="bottom" l>
29
+ <i class="el-icon-arrow-right" ayadmin-event="rightPage"
30
+ one-link-mark="yes" @click="$refs.scrollPane.handleScrollRight()"/>
31
+ </el-tooltip>
32
+ <el-dropdown >
33
+ <span class="el-dropdown-link" style="padding-right:10px;padding-left:4px;">
34
+ <i class="el-icon-more el-icon--right"></i>
35
+ </span>
36
+ <el-dropdown-menu slot="dropdown">
37
+ <el-dropdown-item @click.native="refreshSelectedTag($route)" :disabled="getIsLock()">
38
+ <i class="el-icon-refresh"/><span>{{ $t1('刷新') }}</span>
39
+ </el-dropdown-item>
40
+ <el-dropdown-item @click.native="closeAllTags($route)">
41
+ <i class="el-icon-close"/><span>{{ $t1('全部关闭') }}</span>
42
+ </el-dropdown-item>
43
+ </el-dropdown-menu>
44
+ </el-dropdown>
45
+ <!-- <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('刷新')" placement="bottom">
46
+ <i class="el-icon-refresh" @click="refreshSelectedTag($route)"/>
47
+ </el-tooltip>
48
+ <el-tooltip :enterable="false" class="item" effect="dark" :content="$t1('全部关闭')" placement="bottom">
49
+ <i class="el-icon-close" @click="closeAllTags(selectedTag)"/>
50
+ </el-tooltip> -->
51
+ </div>
52
+ <!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
53
+ <li @click="refreshSelectedTag(selectedTag)">Refresh</li>
54
+ <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">Close</li>
55
+ <li @click="closeOthersTags">Close Others</li>
56
+ <li @click="closeAllTags(selectedTag)">Close All</li>
57
+ </ul> -->
58
+ </div>
59
+ </template>
60
+
61
+ <script>
62
+ import ScrollPane from './ScrollPane'
63
+ import path from 'path'
64
+ import { viewKey, isRepeatable } from '@base/utils/repeatOpen'
65
+
66
+ export default {
67
+ components: {ScrollPane},
68
+ props: {
69
+ isMenu: {
70
+ type: Boolean
71
+ }
72
+ },
73
+ data() {
74
+ return {
75
+ visible: false,
76
+ top: 0,
77
+ left: 0,
78
+ selectedTag: {},
79
+ affixTags: []
80
+ }
81
+ },
82
+ computed: {
83
+ visitedViews() {
84
+ return this.$store.state.tagsView.visitedViews
85
+ },
86
+ routes() {
87
+ return this.$store.state.permission.routes
88
+ }
89
+ },
90
+ watch: {
91
+ $route() {
92
+ this.addTags()
93
+ this.moveToCurrentTag()
94
+ },
95
+ visible(value) {
96
+ if (value) {
97
+ document.body.addEventListener('click', this.closeMenu)
98
+ } else {
99
+ document.body.removeEventListener('click', this.closeMenu)
100
+ }
101
+ }
102
+ },
103
+ mounted() {
104
+ this.initTags()
105
+ this.addTags()
106
+ },
107
+ methods: {
108
+ getMenuName(item) {
109
+ let locale = this.$i18n?.locale;
110
+ let zhTitle = item.meta?.title || "";
111
+ let enTitle = item.meta?.enTitle || '';
112
+ let title;
113
+ if (locale == "en") {
114
+ title = enTitle || zhTitle;
115
+ } else {
116
+ title = zhTitle
117
+ }
118
+ if (!enTitle || locale !== "en") {
119
+ title = zhTitle
120
+ }
121
+ if (this.$t1) {
122
+ title = this.$t1(title)
123
+ }
124
+ if (item.repeatIndex > 1) {
125
+ title = `${title} (${item.repeatIndex})`
126
+ }
127
+ return title;
128
+ },
129
+ viewKey(view) {
130
+ return viewKey(view)
131
+ },
132
+ isActive(route) {
133
+ return viewKey(route) === viewKey(this.$route)
134
+ },
135
+ isAffix(tag) {
136
+ return tag.meta && tag.meta.affix
137
+ },
138
+ filterAffixTags(routes, basePath = '/') {
139
+ let tags = []
140
+ routes.forEach(route => {
141
+ if (route.meta && route.meta.affix) {
142
+ const tagPath = path.resolve(basePath, route.path)
143
+ tags.push({
144
+ fullPath: tagPath,
145
+ path: tagPath,
146
+ name: route.name,
147
+ meta: {...route.meta}
148
+ })
149
+ }
150
+ if (route.children) {
151
+ const tempTags = this.filterAffixTags(route.children, route.path)
152
+ if (tempTags.length >= 1) {
153
+ tags = [...tags, ...tempTags]
154
+ }
155
+ }
156
+ })
157
+ return tags
158
+ },
159
+ initTags() {
160
+ const affixTags = this.affixTags = this.filterAffixTags(this.routes)
161
+ for (const tag of affixTags) {
162
+ // Must have tag name
163
+ if (tag.name) {
164
+ this.$store.dispatch('tagsView/addVisitedView', tag)
165
+ }
166
+ }
167
+ },
168
+ addTags() {
169
+ const {name} = this.$route
170
+ if (name) {
171
+ this.$store.dispatch('tagsView/addView', this.$route)
172
+ }
173
+ return false
174
+ },
175
+ moveToCurrentTag() {
176
+ const tags = this.$refs.tag
177
+ this.$nextTick(() => {
178
+ const routeIsRepeat = isRepeatable(this.$route)
179
+ for (const tag of tags) {
180
+ const matched = routeIsRepeat
181
+ ? tag.to.fullPath === this.$route.fullPath
182
+ : tag.to.path === this.$route.path
183
+ if (matched) {
184
+ this.$refs.scrollPane.moveToTarget(tag)
185
+ // when query is different then update
186
+ if (tag.to.fullPath !== this.$route.fullPath) {
187
+ this.$store.dispatch('tagsView/updateVisitedView', this.$route)
188
+ }
189
+ break
190
+ }
191
+ }
192
+ })
193
+ },
194
+ refreshSelectedTag(view) {
195
+ this.$baseEventBus.$emit("reflushRouteView", view);
196
+ /* if(this.$route.name=="outLink"){
197
+ let a = this.$baseEventBus.$emit("getAppMain");
198
+ let t = this.$parent.$refs["appMain"].$refs["ref_"+this.$route.path][0];
199
+ t.$baseReload();
200
+ }else{
201
+ this.$store.dispatch('tagsView/delCachedView', view).then(() => {
202
+ const { fullPath } = view
203
+ this.$nextTick(() => {
204
+ this.$router.replace({
205
+ path: '/redirect' + fullPath
206
+ })
207
+ })
208
+ })
209
+ } */
210
+ },
211
+ closeSelectedTag(view) {
212
+ if(view.meta.user_affix)return
213
+ this.$store.dispatch('tagsView/delView', view).then(({visitedViews}) => {
214
+ if (this.isActive(view)) {
215
+ this.toLastView(visitedViews, view)
216
+ }
217
+ })
218
+ },
219
+ closeOthersTags() {
220
+ this.$router.push(this.selectedTag)
221
+ this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
222
+ this.moveToCurrentTag()
223
+ })
224
+ },
225
+ closeAllTags(view) {
226
+ this.$baseConfirm(this.$t1('您确定要全部关闭吗?')).then(() => {
227
+ this.$store.dispatch('tagsView/delAllViews').then(({visitedViews}) => {
228
+ if (this.affixTags.some(tag => tag.path === view.path)) {
229
+ return
230
+ }
231
+ this.toLastView(visitedViews, view)
232
+ })
233
+ })
234
+ },
235
+ toLastView(visitedViews, view) {
236
+ const latestView = visitedViews.slice(-1)[0]
237
+ if (latestView) {
238
+ this.$router.push(latestView.fullPath)
239
+ } else {
240
+ // now the default is to redirect to the home page if there is no tags-view,
241
+ // you can adjust it according to your needs.
242
+ if (view.name === 'Dashboard') {
243
+ // to reload home page
244
+ this.$router.replace({path: '/redirect' + view.fullPath})
245
+ } else {
246
+ this.$router.push('/')
247
+ }
248
+ }
249
+ },
250
+ openMenu(tag, e) {
251
+ const menuMinWidth = 105
252
+ const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
253
+ const offsetWidth = this.$el.offsetWidth // container width
254
+ const maxLeft = offsetWidth - menuMinWidth // left boundary
255
+ const left = e.clientX - offsetLeft + 15 // 15: margin right
256
+
257
+ if (left > maxLeft) {
258
+ this.left = maxLeft
259
+ } else {
260
+ this.left = left
261
+ }
262
+
263
+ this.top = e.clientY
264
+ this.visible = true
265
+ this.selectedTag = tag
266
+ },
267
+ closeMenu() {
268
+ this.visible = false
269
+ },
270
+ handleScroll() {
271
+ this.closeMenu()
272
+ },
273
+ getIsLock() {
274
+ // 按 viewKey 而不是 path 定位:可重复打开时同一 path 有多个页签,
275
+ // path 找到的可能是另一个实例(锁的是 A,却把 B 的刷新按钮禁掉)
276
+ let key = viewKey(this.$route)
277
+ let visitedViews = this.$store.state.tagsView.visitedViews
278
+ let currentItem = visitedViews.find(item => viewKey(item) === key)
279
+ return !!currentItem?.meta?.user_affix;
280
+ },
281
+ }
282
+ }
283
+ </script>
284
+
285
+ <style scoped lang="scss">
286
+ @import '~@/styles/variables.scss';
287
+
288
+ .navbar-tag .tags-view-item.active {
289
+ background: $baseColor !important;
290
+ }
291
+ </style>
292
+ <style lang="scss">
293
+ //reset element css of el-icon-close
294
+ span.el-icon-close.is-disabled{
295
+ cursor: not-allowed;
296
+ }
297
+ .tags-view-wrapper {
298
+ .tags-view-item {
299
+ .el-icon-close {
300
+ width: 14px;
301
+ height: 14px;
302
+ vertical-align: text-bottom;
303
+ line-height: 12px;
304
+ border-radius: 50%;
305
+ text-align: center;
306
+ transition: all .3s cubic-bezier(.645, .045, .355, 1);
307
+ transform-origin: 100% 50%;
308
+ display: none;
309
+ position: absolute;
310
+ right: 12px;
311
+ top: 8px;
312
+
313
+ &:before {
314
+ transform: scale(.84);
315
+ display: inline-block;
316
+ vertical-align: -1.8px;
317
+ }
318
+ }
319
+
320
+ &:hover .el-icon-close {
321
+ display: block;
322
+ }
323
+ }
324
+ }
325
+ </style>