vue2-client 1.8.310 → 1.8.312

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 (222) hide show
  1. package/.env +19 -19
  2. package/.eslintrc.js +90 -90
  3. package/CHANGELOG.md +824 -824
  4. package/Components.md +60 -60
  5. package/babel.config.js +21 -21
  6. package/docs/LowCode/lowcode.md +155 -155
  7. package/docs/LowCode/lowcodeForDeveloper.md +230 -230
  8. package/docs/index.md +30 -30
  9. package/index.js +31 -31
  10. package/jest-transform-stub.js +8 -8
  11. package/jest.config.js +21 -21
  12. package/jest.setup.js +7 -7
  13. package/package.json +97 -97
  14. package/public/index.html +27 -27
  15. package/src/App.vue +188 -188
  16. package/src/ReportView.js +19 -19
  17. package/src/assets/img/querySlotDemo.svg +15 -15
  18. package/src/assets/svg/badtwo.svg +1 -1
  19. package/src/assets/svg/goodtwo.svg +1 -1
  20. package/src/base-client/components/common/AMisRender/index.js +3 -3
  21. package/src/base-client/components/common/AMisRender/index.vue +263 -263
  22. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +438 -416
  23. package/src/base-client/components/common/AddressSearchCombobox/demo.vue +36 -36
  24. package/src/base-client/components/common/AddressSearchCombobox/ic_map.svg +6 -6
  25. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  26. package/src/base-client/components/common/CitySelect/CitySelect.vue +342 -342
  27. package/src/base-client/components/common/CitySelect/index.js +3 -3
  28. package/src/base-client/components/common/CitySelect/index.md +109 -109
  29. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +669 -669
  30. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +1014 -1014
  31. package/src/base-client/components/common/CreateQuery/index.js +3 -3
  32. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  33. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +452 -452
  34. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +511 -511
  35. package/src/base-client/components/common/CreateSimpleFormQuery/index.js +3 -3
  36. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  37. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +149 -149
  38. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  39. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  40. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +166 -166
  41. package/src/base-client/components/common/FormGroupQuery/index.js +3 -3
  42. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  43. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  44. package/src/base-client/components/common/LowCodeComponent/LowCodeEditorPanel.vue +413 -350
  45. package/src/base-client/components/common/LowCodeComponent/LowCodePageOrganization.vue +502 -502
  46. package/src/base-client/components/common/LowCodeComponent/LowCodeRender.vue +728 -699
  47. package/src/base-client/components/common/LowCodeComponent/LowCodeRenderEnter.vue +29 -29
  48. package/src/base-client/components/common/LowCodeComponent/LowCodeUIStore.vue +219 -162
  49. package/src/base-client/components/common/PersonSetting/PersonSetting.vue +208 -208
  50. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  51. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  52. package/src/base-client/components/common/Tree/index.js +2 -2
  53. package/src/base-client/components/common/Upload/Upload.vue +239 -239
  54. package/src/base-client/components/common/Upload/index.js +3 -3
  55. package/src/base-client/components/common/XAddForm/XAddForm.vue +105 -105
  56. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +807 -807
  57. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  58. package/src/base-client/components/common/XAddNativeForm/lowcodeEditorRegister.js +16 -16
  59. package/src/base-client/components/common/XAddNativeFormOA/XAddNativeFormOA.vue +303 -303
  60. package/src/base-client/components/common/XAddNativeFormOA/index.js +3 -3
  61. package/src/base-client/components/common/XAddNativeFormOA/index.md +146 -146
  62. package/src/base-client/components/common/XBadge/XBadge.vue +78 -78
  63. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  64. package/src/base-client/components/common/XDataCard/XDataCard.vue +355 -0
  65. package/src/base-client/components/common/XDataCard/index.js +3 -0
  66. package/src/base-client/components/common/XDataCard/index.md +1 -0
  67. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  68. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  69. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  70. package/src/base-client/components/common/XDescriptions/XDescriptions.vue +188 -187
  71. package/src/base-client/components/common/XDescriptions/XDescriptionsGroup.vue +306 -306
  72. package/src/base-client/components/common/XDescriptions/demo.vue +50 -50
  73. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  74. package/src/base-client/components/common/XDescriptions/index.md +83 -83
  75. package/src/base-client/components/common/XDetailsView/XDetailsView.vue +214 -214
  76. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  77. package/src/base-client/components/common/XForm/XForm.vue +294 -294
  78. package/src/base-client/components/common/XForm/XFormItem.vue +911 -911
  79. package/src/base-client/components/common/XForm/XTreeSelect.vue +207 -207
  80. package/src/base-client/components/common/XForm/index.md +178 -178
  81. package/src/base-client/components/common/XFormCol/XFormCol.vue +36 -36
  82. package/src/base-client/components/common/XFormGroup/XFormGroup.vue +241 -241
  83. package/src/base-client/components/common/XFormGroup/demo.vue +40 -40
  84. package/src/base-client/components/common/XFormGroup/index.js +3 -3
  85. package/src/base-client/components/common/XFormGroup/index.md +38 -38
  86. package/src/base-client/components/common/XFormGroupDetails/XFormGroupDetails.vue +72 -72
  87. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  88. package/src/base-client/components/common/XFormTable/XFormTable.vue +545 -539
  89. package/src/base-client/components/common/XFormTable/demo.vue +72 -72
  90. package/src/base-client/components/common/XFormTable/index.md +98 -98
  91. package/src/base-client/components/common/XFormTable/lowcodeEditorRegister.js +30 -30
  92. package/src/base-client/components/common/XImportExcel/XImportExcel.vue +147 -147
  93. package/src/base-client/components/common/XReport/XReport.vue +858 -858
  94. package/src/base-client/components/common/XReport/XReportDemo.vue +266 -266
  95. package/src/base-client/components/common/XReport/XReportDesign.vue +509 -509
  96. package/src/base-client/components/common/XReport/XReportJsonRender.vue +295 -295
  97. package/src/base-client/components/common/XReport/XReportTrGroup.vue +801 -801
  98. package/src/base-client/components/common/XReport/index.js +3 -3
  99. package/src/base-client/components/common/XReport/index.md +44 -44
  100. package/src/base-client/components/common/XReportSlot/XReportSlot.vue +110 -110
  101. package/src/base-client/components/common/XReportSlot/index.js +3 -3
  102. package/src/base-client/components/common/XSimpleDescriptions/XSimpleDescriptions.vue +137 -0
  103. package/src/base-client/components/common/XSimpleDescriptions/index.js +3 -0
  104. package/src/base-client/components/common/XSimpleDescriptions/index.md +7 -0
  105. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  106. package/src/base-client/components/common/XStepView/index.js +3 -3
  107. package/src/base-client/components/common/XStepView/index.md +31 -31
  108. package/src/base-client/components/common/XTable/XTable.vue +715 -676
  109. package/src/base-client/components/common/XTable/index.md +255 -255
  110. package/src/base-client/components/common/XTree/XTree.vue +423 -423
  111. package/src/base-client/components/common/XTree/index.js +3 -3
  112. package/src/base-client/components/common/XTree/index.md +36 -36
  113. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +114 -114
  114. package/src/base-client/components/common/XTreeOne/lowcodeEditorRegister.js +11 -11
  115. package/src/base-client/components/index.js +51 -51
  116. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  117. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  118. package/src/base-client/plugins/AppData.js +121 -121
  119. package/src/base-client/plugins/Config.js +19 -19
  120. package/src/base-client/plugins/GetLoginInfoService.js +183 -183
  121. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  122. package/src/bootstrap.js +39 -39
  123. package/src/components/CodeMirror/inedx.vue +118 -118
  124. package/src/components/CodeMirror/setting.js +40 -40
  125. package/src/components/FilePreview/FilePreview.vue +166 -166
  126. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  127. package/src/components/STable/index.js +361 -361
  128. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  129. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  130. package/src/components/menu/SideMenu.vue +75 -75
  131. package/src/components/menu/menu.js +273 -273
  132. package/src/components/tool/AStepItem.vue +60 -60
  133. package/src/config/CreateQueryConfig.js +322 -322
  134. package/src/config/default/antd.config.js +89 -89
  135. package/src/config/default/setting.config.js +55 -55
  136. package/src/font-style/font.css +4 -4
  137. package/src/layouts/CommonLayout.vue +56 -56
  138. package/src/layouts/PageLayout.vue +151 -151
  139. package/src/layouts/SinglePageView.vue +138 -138
  140. package/src/layouts/header/AdminHeader.vue +132 -132
  141. package/src/layouts/header/HeaderNotice.vue +177 -177
  142. package/src/layouts/tabs/TabsHead.vue +189 -189
  143. package/src/layouts/tabs/TabsView.vue +387 -387
  144. package/src/lib.js +1 -1
  145. package/src/main.js +26 -26
  146. package/src/mock/extend/index.js +84 -84
  147. package/src/mock/goods/index.js +108 -108
  148. package/src/pages/AMisDemo/AMisDemo.vue +325 -325
  149. package/src/pages/AMisDemo/AMisDemo2.vue +74 -74
  150. package/src/pages/DynamicStatistics/ChartSelector.vue +331 -331
  151. package/src/pages/DynamicStatistics/DataTabs.vue +83 -83
  152. package/src/pages/DynamicStatistics/DynamicTable.vue +128 -128
  153. package/src/pages/DynamicStatistics/EvaluationArea.vue +69 -69
  154. package/src/pages/DynamicStatistics/FavoriteList.vue +51 -51
  155. package/src/pages/DynamicStatistics/QuestionHistoryAndFavorites.vue +591 -591
  156. package/src/pages/DynamicStatistics/SearchBar.vue +192 -192
  157. package/src/pages/DynamicStatistics/index.vue +282 -282
  158. package/src/pages/Example/index.vue +193 -33
  159. package/src/pages/NewDynamicStatistics/ChartSelector.vue +331 -331
  160. package/src/pages/NewDynamicStatistics/DataTabs.vue +122 -122
  161. package/src/pages/NewDynamicStatistics/DynamicTable.vue +128 -128
  162. package/src/pages/NewDynamicStatistics/EvaluationArea.vue +69 -69
  163. package/src/pages/NewDynamicStatistics/FavoriteList.vue +51 -51
  164. package/src/pages/NewDynamicStatistics/QuestionHistoryAndFavorites.vue +289 -289
  165. package/src/pages/NewDynamicStatistics/SearchBar.vue +193 -193
  166. package/src/pages/NewDynamicStatistics/index.vue +258 -258
  167. package/src/pages/ServiceReview/index.vue +284 -284
  168. package/src/pages/XReportView/index.vue +62 -62
  169. package/src/pages/login/Login.vue +378 -378
  170. package/src/pages/login/LoginV3.vue +389 -389
  171. package/src/pages/lowCode/lowCodeEditor.vue +1219 -1030
  172. package/src/pages/lowCode/lowCodeRenderPage.vue +43 -43
  173. package/src/pages/resourceManage/orgListManage.vue +98 -98
  174. package/src/pages/system/dictionary/index.vue +44 -44
  175. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  176. package/src/pages/system/monitor/operLog/index.vue +37 -37
  177. package/src/pages/system/settings/modifyPassword.vue +117 -117
  178. package/src/pages/system/ticket/index.vue +480 -480
  179. package/src/pages/system/ticket/submitTicketSuccess.vue +484 -484
  180. package/src/router/async/config.async.js +34 -34
  181. package/src/router/async/router.map.js +104 -104
  182. package/src/router/guards.js +223 -223
  183. package/src/router/index.js +27 -27
  184. package/src/router.js +19 -19
  185. package/src/services/api/TicketDetailsViewApi.js +46 -46
  186. package/src/services/api/cas.js +79 -79
  187. package/src/services/api/common.js +307 -307
  188. package/src/services/api/entity.js +18 -18
  189. package/src/services/api/index.js +17 -17
  190. package/src/services/api/restTools.js +46 -46
  191. package/src/services/apiService.js +14 -14
  192. package/src/services/user.js +71 -71
  193. package/src/services/v3Api.js +81 -81
  194. package/src/store/modules/index.js +5 -5
  195. package/src/store/modules/lowCode.js +33 -33
  196. package/src/store/modules/setting.js +119 -119
  197. package/src/theme/default/style.less +58 -58
  198. package/src/theme/global.less +139 -139
  199. package/src/utils/authority-utils.js +85 -85
  200. package/src/utils/errorCode.js +6 -6
  201. package/src/utils/formatter.js +80 -80
  202. package/src/utils/htmlToPDF.js +108 -108
  203. package/src/utils/htmlToPDFApi.js +5 -5
  204. package/src/utils/indexedDB.js +258 -258
  205. package/src/utils/login.js +188 -188
  206. package/src/utils/lowcode/lowcodeComponentMixin.js +120 -120
  207. package/src/utils/lowcode/lowcodeLog.js +29 -29
  208. package/src/utils/lowcode/lowcodeUtils.js +373 -373
  209. package/src/utils/lowcode/registerComponentForEditor.js +11 -11
  210. package/src/utils/lowcode/registerComponentForRender.js +11 -11
  211. package/src/utils/map-utils.js +47 -47
  212. package/src/utils/reg.js +95 -95
  213. package/src/utils/request.js +347 -347
  214. package/src/utils/routerUtil.js +435 -435
  215. package/src/utils/runEvalFunction.js +6 -6
  216. package/src/utils/util.js +241 -241
  217. package/src/utils/waterMark.js +31 -31
  218. package/test/Amis.spec.js +163 -163
  219. package/test/Tree.spec.js +167 -167
  220. package/test/myDialog.spec.js +46 -46
  221. package/vue.config.js +181 -181
  222. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,387 +1,387 @@
1
- <template>
2
- <div id="TabsView">
3
- <admin-layout>
4
- <contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect" />
5
- <tabs-head
6
- v-if="multiPage"
7
- :active="activePage"
8
- :page-list="pageList"
9
- @change="changePage"
10
- @close="remove"
11
- @refresh="refresh"
12
- @contextmenu="onContextmenu"
13
- />
14
- <div :class="['tabs-view-content', layout, pageWidth]" :style="`margin-top: ${multiPage ? -24 : 0}px`">
15
- <page-toggle-transition v-show="!$route.meta.singlePage" :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
16
- <a-keep-alive :exclude-keys="excludeKeys" v-if="multiPage && cachePage" v-model="clearCaches">
17
- <router-view v-if="!refreshing" ref="tabContent" :key="$route.fullPath" />
18
- </a-keep-alive>
19
- <router-view ref="tabContent" v-else-if="!refreshing" />
20
- </page-toggle-transition>
21
- <template v-for="page in single">
22
- <single-page-view
23
- v-show="page.meta.singlePage === $route.meta.singlePage"
24
- :single-page-url="page.meta.singlePage"
25
- :full-path="page.fullPath"
26
- :key="page.meta.singlePage"
27
- @load="onSinglePageLoad" />
28
- </template>
29
- </div>
30
- </admin-layout>
31
- </div>
32
- </template>
33
-
34
- <script>
35
- import AdminLayout from '@vue2-client/layouts/AdminLayout'
36
- import Contextmenu from '@vue2-client/components/menu/Contextmenu'
37
- import PageToggleTransition from '@vue2-client/components/transition/PageToggleTransition'
38
- import { mapState, mapMutations } from 'vuex'
39
- import { getI18nKey } from '@vue2-client/utils/routerUtil'
40
- import AKeepAlive from '@vue2-client/components/cache/AKeepAlive'
41
- import TabsHead from '@vue2-client/layouts/tabs/TabsHead'
42
- import SinglePageView from '../SinglePageView'
43
-
44
- export default {
45
- name: 'TabsView',
46
- i18n: require('./i18n'),
47
- components: { SinglePageView, TabsHead, PageToggleTransition, Contextmenu, AdminLayout, AKeepAlive },
48
- data () {
49
- return {
50
- clearCaches: [],
51
- pageList: [],
52
- activePage: '',
53
- menuVisible: false,
54
- refreshing: false,
55
- allSinglePages: [],
56
- excludeKeys: []
57
- }
58
- },
59
- computed: {
60
- ...mapState('setting', ['multiPage', 'cachePage', 'animate', 'layout', 'pageWidth']),
61
- ...mapState('account', ['single']),
62
- menuItemList () {
63
- return [
64
- { key: '1', icon: 'vertical-right', text: this.$t('closeLeft') },
65
- { key: '2', icon: 'vertical-left', text: this.$t('closeRight') },
66
- { key: '3', icon: 'close', text: this.$t('closeOthers') },
67
- { key: '4', icon: 'sync', text: this.$t('refresh') }
68
- ]
69
- },
70
- tabsOffset () {
71
- return this.multiPage ? 24 : 0
72
- }
73
- },
74
- created () {
75
- this.loadCacheConfig(this.$router?.options?.routes)
76
- this.loadCachedTabs()
77
- // 解决单页面为首页时首次登录不加载问题
78
- if (this.$route.meta.singlePage && this.single.length === 0) {
79
- this.allSinglePages.forEach(item => {
80
- if (this.$route.fullPath.includes(item.fullPath)) {
81
- this.setSingle(item)
82
- }
83
- })
84
- }
85
- const route = this.$route
86
- if (this.pageList.findIndex(item => item.path === route.fullPath) === -1) {
87
- this.pageList.push(this.createPage(route))
88
- }
89
- this.activePage = route.fullPath
90
- if (this.multiPage) {
91
- this.$nextTick(() => {
92
- this.setCachedKey(route)
93
- })
94
- this.addListener()
95
- }
96
- },
97
- mounted () {
98
- this.correctPageMinHeight(-this.tabsOffset)
99
- },
100
- beforeDestroy () {
101
- this.removeListener()
102
- this.correctPageMinHeight(this.tabsOffset)
103
- },
104
- watch: {
105
- '$router.options.routes': function (val) {
106
- this.excludeKeys = []
107
- this.loadCacheConfig(val)
108
- },
109
- $route: function (newRoute) {
110
- this.activePage = newRoute.fullPath
111
- const page = this.pageList.find(item => item.path === newRoute.fullPath)
112
- if (!this.multiPage) {
113
- this.pageList = [this.createPage(newRoute)]
114
- } else if (page) {
115
- page.fullPath = newRoute.fullPath
116
- } else if (!page) {
117
- this.pageList.push(this.createPage(newRoute))
118
- }
119
- if (this.multiPage) {
120
- this.$nextTick(() => {
121
- this.setCachedKey(newRoute)
122
- })
123
- }
124
- },
125
- multiPage: function (newVal) {
126
- if (!newVal) {
127
- this.pageList = [this.createPage(this.$route)]
128
- this.removeListener()
129
- } else {
130
- this.addListener()
131
- }
132
- },
133
- tabsOffset (newVal, oldVal) {
134
- this.correctPageMinHeight(oldVal - newVal)
135
- }
136
- },
137
- methods: {
138
- changePage (key) {
139
- this.activePage = key
140
- const page = this.pageList.find(item => item.path === key)
141
- this.$router.push(page.fullPath)
142
- },
143
- remove (key, next) {
144
- if (this.pageList.length === 1) {
145
- return this.$message.warning(this.$t('warn'))
146
- }
147
- this.setSingle({ path: key, delete: true })
148
- // 清除缓存
149
- let index = this.pageList.findIndex(item => item.path === key)
150
- this.clearCaches = this.pageList.splice(index, 1).map(page => page.cachedKey)
151
- if (next) {
152
- this.$router.push(next)
153
- } else if (key === this.activePage) {
154
- index = index >= this.pageList.length ? this.pageList.length - 1 : index
155
- this.activePage = this.pageList[index].path
156
- this.$router.push(this.activePage)
157
- }
158
- },
159
- refresh (key, page) {
160
- page = page || this.pageList.find(item => item.path === key)
161
- page.loading = true
162
- // 单页面刷新
163
- const singlePage = this.allSinglePages.find(item => item.fullPath === key)
164
- if (singlePage) {
165
- window.frames[singlePage.fullPath].location.reload()
166
- return
167
- }
168
- this.clearCache(page)
169
- if (key === this.activePage) {
170
- // eslint-disable-next-line no-return-assign
171
- this.reloadContent(() => page.loading = false)
172
- } else {
173
- // 其实刷新很快,加这个延迟纯粹为了 loading 状态多展示一会儿,让用户感知刷新这一过程
174
- // eslint-disable-next-line no-return-assign
175
- setTimeout(() => page.loading = false, 500)
176
- }
177
- },
178
- onSinglePageLoad (fullPath) {
179
- const page = this.pageList.find(item => item.fullPath === fullPath)
180
- page.loading = false
181
- },
182
- onContextmenu (pageKey, e) {
183
- if (pageKey) {
184
- e.preventDefault()
185
- e.meta = pageKey
186
- this.menuVisible = true
187
- }
188
- },
189
- onMenuSelect (key, target, pageKey) {
190
- switch (key) {
191
- case '1': this.closeLeft(pageKey); break
192
- case '2': this.closeRight(pageKey); break
193
- case '3': this.closeOthers(pageKey); break
194
- case '4': this.refresh(pageKey); break
195
- default: break
196
- }
197
- },
198
- closeOthers (pageKey) {
199
- // 清除缓存
200
- const clearPages = this.pageList.filter(item => item.path !== pageKey && !item.unclose)
201
- this.clearCaches = clearPages.map(item => item.cachedKey)
202
- this.pageList = this.pageList.filter(item => !clearPages.includes(item))
203
- // 判断跳转
204
- if (this.activePage !== pageKey) {
205
- this.activePage = pageKey
206
- this.$router.push(this.activePage)
207
- }
208
- },
209
- closeLeft (pageKey) {
210
- const index = this.pageList.findIndex(item => item.path === pageKey)
211
- // 清除缓存
212
- const clearPages = this.pageList.filter((item, i) => i < index && !item.unclose)
213
- this.clearCaches = clearPages.map(item => item.cachedKey)
214
- this.pageList = this.pageList.filter(item => !clearPages.includes(item))
215
- // 判断跳转
216
- if (!this.pageList.find(item => item.path === this.activePage)) {
217
- this.activePage = pageKey
218
- this.$router.push(this.activePage)
219
- }
220
- },
221
- closeRight (pageKey) {
222
- // 清除缓存
223
- const index = this.pageList.findIndex(item => item.path === pageKey)
224
- const clearPages = this.pageList.filter((item, i) => i > index && !item.unclose)
225
- this.clearCaches = clearPages.map(item => item.cachedKey)
226
- this.pageList = this.pageList.filter(item => !clearPages.includes(item))
227
- // 判断跳转
228
- if (!this.pageList.find(item => item.path === this.activePage)) {
229
- this.activePage = pageKey
230
- this.$router.push(this.activePage)
231
- }
232
- },
233
- clearCache (page) {
234
- page._init_ = false
235
- this.clearCaches = [page.cachedKey]
236
- },
237
- reloadContent (onLoaded) {
238
- this.refreshing = true
239
- setTimeout(() => {
240
- this.refreshing = false
241
- this.$nextTick(() => {
242
- this.setCachedKey(this.$route)
243
- if (typeof onLoaded === 'function') {
244
- onLoaded.apply(this, [])
245
- }
246
- })
247
- }, 200)
248
- },
249
- pageName (page) {
250
- return this.$t(getI18nKey(page.keyPath))
251
- },
252
- /**
253
- * 添加监听器
254
- */
255
- addListener () {
256
- window.addEventListener('page:close', this.closePageListener)
257
- window.addEventListener('page:refresh', this.refreshPageListener)
258
- window.addEventListener('unload', this.unloadListener)
259
- },
260
- /**
261
- * 移出监听器
262
- */
263
- removeListener () {
264
- window.removeEventListener('page:close', this.closePageListener)
265
- window.removeEventListener('page:refresh', this.refreshPageListener)
266
- window.removeEventListener('unload', this.unloadListener)
267
- },
268
- /**
269
- * 页签关闭事件监听
270
- * @param event 页签关闭事件
271
- */
272
- closePageListener (event) {
273
- const { closeRoute, nextRoute } = event.detail
274
- const closePath = typeof closeRoute === 'string' ? closeRoute : closeRoute.path
275
- const path = closePath && closePath.split('?')[0]
276
- this.remove(path, nextRoute)
277
- },
278
- /**
279
- * 页面刷新事件监听
280
- * @param event 页签关闭事件
281
- */
282
- refreshPageListener (event) {
283
- const { pageKey } = event.detail
284
- const path = pageKey && pageKey.split('?')[0]
285
- this.refresh(path)
286
- },
287
- /**
288
- * 页面 unload 事件监听器,添加页签到 session 缓存,用于刷新时保留页签
289
- */
290
- unloadListener () {
291
- const tabs = this.pageList.map(item => ({ ...item, _init_: false }))
292
- sessionStorage.setItem(process.env.VUE_APP_TBAS_KEY, JSON.stringify(tabs))
293
- },
294
- createPage (route) {
295
- return {
296
- keyPath: route.matched[route.matched.length - 1].path,
297
- fullPath: route.fullPath,
298
- loading: false,
299
- path: route.fullPath,
300
- title: route.meta && route.meta.page && route.meta.page.title,
301
- unclose: route.meta && route.meta.page && (route.meta.page.closable === false)
302
- }
303
- },
304
- /**
305
- * 设置页面缓存的key
306
- * @param route 页面对应的路由
307
- */
308
- setCachedKey (route) {
309
- const page = this.pageList.find(item => item.path === route.path)
310
- page.unclose = route.meta && route.meta.page && (route.meta.page.closable === false)
311
- if (!page._init_) {
312
- const vnode = this.$refs.tabContent.$vnode
313
- page.cachedKey = vnode.key + vnode.componentOptions.Ctor.cid
314
- page._init_ = true
315
- }
316
- },
317
- /**
318
- * 加载缓存的 tabs
319
- */
320
- loadCachedTabs () {
321
- const cachedTabsStr = sessionStorage.getItem(process.env.VUE_APP_TBAS_KEY)
322
- if (cachedTabsStr) {
323
- try {
324
- // 加载缓存的单页面
325
- const allCachedPath = JSON.parse(cachedTabsStr).map(str => { return str.fullPath })
326
- this.allSinglePages.forEach(item => {
327
- if (allCachedPath.includes(item.fullPath)) {
328
- // 如果缓存中有单页面 加载到 state.single
329
- this.setSingle(item)
330
- }
331
- })
332
- const cachedTabs = JSON.parse(cachedTabsStr)
333
- if (cachedTabs.length > 0) {
334
- this.pageList = cachedTabs
335
- }
336
- } catch (e) {
337
- console.warn('failed to load cached tabs, got exception:', e)
338
- } finally {
339
- sessionStorage.removeItem(process.env.VUE_APP_TBAS_KEY)
340
- }
341
- }
342
- },
343
- loadCacheConfig (routes, pCache = true) {
344
- routes.forEach(item => {
345
- const cacheAble = item.meta?.page?.cacheAble ?? pCache ?? true
346
- if (item.meta && item.meta.singlePage) {
347
- // 找到所有单页面添加到 allSinglePages 中
348
- this.allSinglePages.push(item)
349
- }
350
- if (!cacheAble) {
351
- this.excludeKeys.push(new RegExp(`${item.path.replace(/:[^/]*/g, '[^/]*')}(\\?.*)?\\d*$`))
352
- }
353
- if (item.children) {
354
- this.loadCacheConfig(item.children, cacheAble)
355
- }
356
- })
357
- },
358
- ...mapMutations('setting', ['correctPageMinHeight']),
359
- ...mapMutations('account', ['setSingle'])
360
- }
361
- }
362
- </script>
363
-
364
- <style lang="less">
365
- #TabsView {
366
- .tabs-view {
367
- margin: -16px auto 8px;
368
- &.head.fixed {
369
- max-width: 100%;
370
- }
371
- }
372
- .tabs-view-content {
373
- position: relative;
374
- &.head.fixed {
375
- width: 100%;
376
- margin: 0 auto;
377
- }
378
- > div > div > .ant-card:first-of-type > .ant-card-body {
379
- max-height: calc(100vh - 64px - 48px - 24px);
380
- overflow-y: auto;
381
- &::-webkit-scrollbar {
382
- display: none;
383
- }
384
- }
385
- }
386
- }
387
- </style>
1
+ <template>
2
+ <div id="TabsView">
3
+ <admin-layout>
4
+ <contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect" />
5
+ <tabs-head
6
+ v-if="multiPage"
7
+ :active="activePage"
8
+ :page-list="pageList"
9
+ @change="changePage"
10
+ @close="remove"
11
+ @refresh="refresh"
12
+ @contextmenu="onContextmenu"
13
+ />
14
+ <div :class="['tabs-view-content', layout, pageWidth]" :style="`margin-top: ${multiPage ? -24 : 0}px`">
15
+ <page-toggle-transition v-show="!$route.meta.singlePage" :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
16
+ <a-keep-alive :exclude-keys="excludeKeys" v-if="multiPage && cachePage" v-model="clearCaches">
17
+ <router-view v-if="!refreshing" ref="tabContent" :key="$route.fullPath" />
18
+ </a-keep-alive>
19
+ <router-view ref="tabContent" v-else-if="!refreshing" />
20
+ </page-toggle-transition>
21
+ <template v-for="page in single">
22
+ <single-page-view
23
+ v-show="page.meta.singlePage === $route.meta.singlePage"
24
+ :single-page-url="page.meta.singlePage"
25
+ :full-path="page.fullPath"
26
+ :key="page.meta.singlePage"
27
+ @load="onSinglePageLoad" />
28
+ </template>
29
+ </div>
30
+ </admin-layout>
31
+ </div>
32
+ </template>
33
+
34
+ <script>
35
+ import AdminLayout from '@vue2-client/layouts/AdminLayout'
36
+ import Contextmenu from '@vue2-client/components/menu/Contextmenu'
37
+ import PageToggleTransition from '@vue2-client/components/transition/PageToggleTransition'
38
+ import { mapState, mapMutations } from 'vuex'
39
+ import { getI18nKey } from '@vue2-client/utils/routerUtil'
40
+ import AKeepAlive from '@vue2-client/components/cache/AKeepAlive'
41
+ import TabsHead from '@vue2-client/layouts/tabs/TabsHead'
42
+ import SinglePageView from '../SinglePageView'
43
+
44
+ export default {
45
+ name: 'TabsView',
46
+ i18n: require('./i18n'),
47
+ components: { SinglePageView, TabsHead, PageToggleTransition, Contextmenu, AdminLayout, AKeepAlive },
48
+ data () {
49
+ return {
50
+ clearCaches: [],
51
+ pageList: [],
52
+ activePage: '',
53
+ menuVisible: false,
54
+ refreshing: false,
55
+ allSinglePages: [],
56
+ excludeKeys: []
57
+ }
58
+ },
59
+ computed: {
60
+ ...mapState('setting', ['multiPage', 'cachePage', 'animate', 'layout', 'pageWidth']),
61
+ ...mapState('account', ['single']),
62
+ menuItemList () {
63
+ return [
64
+ { key: '1', icon: 'vertical-right', text: this.$t('closeLeft') },
65
+ { key: '2', icon: 'vertical-left', text: this.$t('closeRight') },
66
+ { key: '3', icon: 'close', text: this.$t('closeOthers') },
67
+ { key: '4', icon: 'sync', text: this.$t('refresh') }
68
+ ]
69
+ },
70
+ tabsOffset () {
71
+ return this.multiPage ? 24 : 0
72
+ }
73
+ },
74
+ created () {
75
+ this.loadCacheConfig(this.$router?.options?.routes)
76
+ this.loadCachedTabs()
77
+ // 解决单页面为首页时首次登录不加载问题
78
+ if (this.$route.meta.singlePage && this.single.length === 0) {
79
+ this.allSinglePages.forEach(item => {
80
+ if (this.$route.fullPath.includes(item.fullPath)) {
81
+ this.setSingle(item)
82
+ }
83
+ })
84
+ }
85
+ const route = this.$route
86
+ if (this.pageList.findIndex(item => item.path === route.fullPath) === -1) {
87
+ this.pageList.push(this.createPage(route))
88
+ }
89
+ this.activePage = route.fullPath
90
+ if (this.multiPage) {
91
+ this.$nextTick(() => {
92
+ this.setCachedKey(route)
93
+ })
94
+ this.addListener()
95
+ }
96
+ },
97
+ mounted () {
98
+ this.correctPageMinHeight(-this.tabsOffset)
99
+ },
100
+ beforeDestroy () {
101
+ this.removeListener()
102
+ this.correctPageMinHeight(this.tabsOffset)
103
+ },
104
+ watch: {
105
+ '$router.options.routes': function (val) {
106
+ this.excludeKeys = []
107
+ this.loadCacheConfig(val)
108
+ },
109
+ $route: function (newRoute) {
110
+ this.activePage = newRoute.fullPath
111
+ const page = this.pageList.find(item => item.path === newRoute.fullPath)
112
+ if (!this.multiPage) {
113
+ this.pageList = [this.createPage(newRoute)]
114
+ } else if (page) {
115
+ page.fullPath = newRoute.fullPath
116
+ } else if (!page) {
117
+ this.pageList.push(this.createPage(newRoute))
118
+ }
119
+ if (this.multiPage) {
120
+ this.$nextTick(() => {
121
+ this.setCachedKey(newRoute)
122
+ })
123
+ }
124
+ },
125
+ multiPage: function (newVal) {
126
+ if (!newVal) {
127
+ this.pageList = [this.createPage(this.$route)]
128
+ this.removeListener()
129
+ } else {
130
+ this.addListener()
131
+ }
132
+ },
133
+ tabsOffset (newVal, oldVal) {
134
+ this.correctPageMinHeight(oldVal - newVal)
135
+ }
136
+ },
137
+ methods: {
138
+ changePage (key) {
139
+ this.activePage = key
140
+ const page = this.pageList.find(item => item.path === key)
141
+ this.$router.push(page.fullPath)
142
+ },
143
+ remove (key, next) {
144
+ if (this.pageList.length === 1) {
145
+ return this.$message.warning(this.$t('warn'))
146
+ }
147
+ this.setSingle({ path: key, delete: true })
148
+ // 清除缓存
149
+ let index = this.pageList.findIndex(item => item.path === key)
150
+ this.clearCaches = this.pageList.splice(index, 1).map(page => page.cachedKey)
151
+ if (next) {
152
+ this.$router.push(next)
153
+ } else if (key === this.activePage) {
154
+ index = index >= this.pageList.length ? this.pageList.length - 1 : index
155
+ this.activePage = this.pageList[index].path
156
+ this.$router.push(this.activePage)
157
+ }
158
+ },
159
+ refresh (key, page) {
160
+ page = page || this.pageList.find(item => item.path === key)
161
+ page.loading = true
162
+ // 单页面刷新
163
+ const singlePage = this.allSinglePages.find(item => item.fullPath === key)
164
+ if (singlePage) {
165
+ window.frames[singlePage.fullPath].location.reload()
166
+ return
167
+ }
168
+ this.clearCache(page)
169
+ if (key === this.activePage) {
170
+ // eslint-disable-next-line no-return-assign
171
+ this.reloadContent(() => page.loading = false)
172
+ } else {
173
+ // 其实刷新很快,加这个延迟纯粹为了 loading 状态多展示一会儿,让用户感知刷新这一过程
174
+ // eslint-disable-next-line no-return-assign
175
+ setTimeout(() => page.loading = false, 500)
176
+ }
177
+ },
178
+ onSinglePageLoad (fullPath) {
179
+ const page = this.pageList.find(item => item.fullPath === fullPath)
180
+ page.loading = false
181
+ },
182
+ onContextmenu (pageKey, e) {
183
+ if (pageKey) {
184
+ e.preventDefault()
185
+ e.meta = pageKey
186
+ this.menuVisible = true
187
+ }
188
+ },
189
+ onMenuSelect (key, target, pageKey) {
190
+ switch (key) {
191
+ case '1': this.closeLeft(pageKey); break
192
+ case '2': this.closeRight(pageKey); break
193
+ case '3': this.closeOthers(pageKey); break
194
+ case '4': this.refresh(pageKey); break
195
+ default: break
196
+ }
197
+ },
198
+ closeOthers (pageKey) {
199
+ // 清除缓存
200
+ const clearPages = this.pageList.filter(item => item.path !== pageKey && !item.unclose)
201
+ this.clearCaches = clearPages.map(item => item.cachedKey)
202
+ this.pageList = this.pageList.filter(item => !clearPages.includes(item))
203
+ // 判断跳转
204
+ if (this.activePage !== pageKey) {
205
+ this.activePage = pageKey
206
+ this.$router.push(this.activePage)
207
+ }
208
+ },
209
+ closeLeft (pageKey) {
210
+ const index = this.pageList.findIndex(item => item.path === pageKey)
211
+ // 清除缓存
212
+ const clearPages = this.pageList.filter((item, i) => i < index && !item.unclose)
213
+ this.clearCaches = clearPages.map(item => item.cachedKey)
214
+ this.pageList = this.pageList.filter(item => !clearPages.includes(item))
215
+ // 判断跳转
216
+ if (!this.pageList.find(item => item.path === this.activePage)) {
217
+ this.activePage = pageKey
218
+ this.$router.push(this.activePage)
219
+ }
220
+ },
221
+ closeRight (pageKey) {
222
+ // 清除缓存
223
+ const index = this.pageList.findIndex(item => item.path === pageKey)
224
+ const clearPages = this.pageList.filter((item, i) => i > index && !item.unclose)
225
+ this.clearCaches = clearPages.map(item => item.cachedKey)
226
+ this.pageList = this.pageList.filter(item => !clearPages.includes(item))
227
+ // 判断跳转
228
+ if (!this.pageList.find(item => item.path === this.activePage)) {
229
+ this.activePage = pageKey
230
+ this.$router.push(this.activePage)
231
+ }
232
+ },
233
+ clearCache (page) {
234
+ page._init_ = false
235
+ this.clearCaches = [page.cachedKey]
236
+ },
237
+ reloadContent (onLoaded) {
238
+ this.refreshing = true
239
+ setTimeout(() => {
240
+ this.refreshing = false
241
+ this.$nextTick(() => {
242
+ this.setCachedKey(this.$route)
243
+ if (typeof onLoaded === 'function') {
244
+ onLoaded.apply(this, [])
245
+ }
246
+ })
247
+ }, 200)
248
+ },
249
+ pageName (page) {
250
+ return this.$t(getI18nKey(page.keyPath))
251
+ },
252
+ /**
253
+ * 添加监听器
254
+ */
255
+ addListener () {
256
+ window.addEventListener('page:close', this.closePageListener)
257
+ window.addEventListener('page:refresh', this.refreshPageListener)
258
+ window.addEventListener('unload', this.unloadListener)
259
+ },
260
+ /**
261
+ * 移出监听器
262
+ */
263
+ removeListener () {
264
+ window.removeEventListener('page:close', this.closePageListener)
265
+ window.removeEventListener('page:refresh', this.refreshPageListener)
266
+ window.removeEventListener('unload', this.unloadListener)
267
+ },
268
+ /**
269
+ * 页签关闭事件监听
270
+ * @param event 页签关闭事件
271
+ */
272
+ closePageListener (event) {
273
+ const { closeRoute, nextRoute } = event.detail
274
+ const closePath = typeof closeRoute === 'string' ? closeRoute : closeRoute.path
275
+ const path = closePath && closePath.split('?')[0]
276
+ this.remove(path, nextRoute)
277
+ },
278
+ /**
279
+ * 页面刷新事件监听
280
+ * @param event 页签关闭事件
281
+ */
282
+ refreshPageListener (event) {
283
+ const { pageKey } = event.detail
284
+ const path = pageKey && pageKey.split('?')[0]
285
+ this.refresh(path)
286
+ },
287
+ /**
288
+ * 页面 unload 事件监听器,添加页签到 session 缓存,用于刷新时保留页签
289
+ */
290
+ unloadListener () {
291
+ const tabs = this.pageList.map(item => ({ ...item, _init_: false }))
292
+ sessionStorage.setItem(process.env.VUE_APP_TBAS_KEY, JSON.stringify(tabs))
293
+ },
294
+ createPage (route) {
295
+ return {
296
+ keyPath: route.matched[route.matched.length - 1].path,
297
+ fullPath: route.fullPath,
298
+ loading: false,
299
+ path: route.fullPath,
300
+ title: route.meta && route.meta.page && route.meta.page.title,
301
+ unclose: route.meta && route.meta.page && (route.meta.page.closable === false)
302
+ }
303
+ },
304
+ /**
305
+ * 设置页面缓存的key
306
+ * @param route 页面对应的路由
307
+ */
308
+ setCachedKey (route) {
309
+ const page = this.pageList.find(item => item.path === route.path)
310
+ page.unclose = route.meta && route.meta.page && (route.meta.page.closable === false)
311
+ if (!page._init_) {
312
+ const vnode = this.$refs.tabContent.$vnode
313
+ page.cachedKey = vnode.key + vnode.componentOptions.Ctor.cid
314
+ page._init_ = true
315
+ }
316
+ },
317
+ /**
318
+ * 加载缓存的 tabs
319
+ */
320
+ loadCachedTabs () {
321
+ const cachedTabsStr = sessionStorage.getItem(process.env.VUE_APP_TBAS_KEY)
322
+ if (cachedTabsStr) {
323
+ try {
324
+ // 加载缓存的单页面
325
+ const allCachedPath = JSON.parse(cachedTabsStr).map(str => { return str.fullPath })
326
+ this.allSinglePages.forEach(item => {
327
+ if (allCachedPath.includes(item.fullPath)) {
328
+ // 如果缓存中有单页面 加载到 state.single
329
+ this.setSingle(item)
330
+ }
331
+ })
332
+ const cachedTabs = JSON.parse(cachedTabsStr)
333
+ if (cachedTabs.length > 0) {
334
+ this.pageList = cachedTabs
335
+ }
336
+ } catch (e) {
337
+ console.warn('failed to load cached tabs, got exception:', e)
338
+ } finally {
339
+ sessionStorage.removeItem(process.env.VUE_APP_TBAS_KEY)
340
+ }
341
+ }
342
+ },
343
+ loadCacheConfig (routes, pCache = true) {
344
+ routes.forEach(item => {
345
+ const cacheAble = item.meta?.page?.cacheAble ?? pCache ?? true
346
+ if (item.meta && item.meta.singlePage) {
347
+ // 找到所有单页面添加到 allSinglePages 中
348
+ this.allSinglePages.push(item)
349
+ }
350
+ if (!cacheAble) {
351
+ this.excludeKeys.push(new RegExp(`${item.path.replace(/:[^/]*/g, '[^/]*')}(\\?.*)?\\d*$`))
352
+ }
353
+ if (item.children) {
354
+ this.loadCacheConfig(item.children, cacheAble)
355
+ }
356
+ })
357
+ },
358
+ ...mapMutations('setting', ['correctPageMinHeight']),
359
+ ...mapMutations('account', ['setSingle'])
360
+ }
361
+ }
362
+ </script>
363
+
364
+ <style lang="less">
365
+ #TabsView {
366
+ .tabs-view {
367
+ margin: -16px auto 8px;
368
+ &.head.fixed {
369
+ max-width: 100%;
370
+ }
371
+ }
372
+ .tabs-view-content {
373
+ position: relative;
374
+ &.head.fixed {
375
+ width: 100%;
376
+ margin: 0 auto;
377
+ }
378
+ > div > div > .ant-card:first-of-type > .ant-card-body {
379
+ max-height: calc(100vh - 64px - 48px - 24px);
380
+ overflow-y: auto;
381
+ &::-webkit-scrollbar {
382
+ display: none;
383
+ }
384
+ }
385
+ }
386
+ }
387
+ </style>