mooho-base-admin-plus 0.1.0

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 (283) hide show
  1. package/.env +5 -0
  2. package/.env.development +0 -0
  3. package/.env.production +0 -0
  4. package/.eslintignore +11 -0
  5. package/.eslintrc.js +47 -0
  6. package/.prettierrc +15 -0
  7. package/README.md +18 -0
  8. package/dist/favicon.ico +0 -0
  9. package/dist/mooho-base-admin-plus.min.esm.js +131746 -0
  10. package/dist/mooho-base-admin-plus.min.js +279 -0
  11. package/dist/setting.js +31 -0
  12. package/dist/static/images/app-barcode.png +0 -0
  13. package/dist/static/images/login/bg.png +0 -0
  14. package/dist/static/images/login/logo.png +0 -0
  15. package/dist/static/images/login/password-active.png +0 -0
  16. package/dist/static/images/login/password-default.png +0 -0
  17. package/dist/static/images/login/signIn-img.png +0 -0
  18. package/dist/static/images/login/user-active.png +0 -0
  19. package/dist/static/images/login/user-default.png +0 -0
  20. package/dist/static/images/logo-dark.png +0 -0
  21. package/dist/static/images/logo-small.png +0 -0
  22. package/dist/static/images/logo.png +0 -0
  23. package/dist/static/images/logo.svg +510 -0
  24. package/dist/static/images/no-image.png +0 -0
  25. package/dist/style.css +4 -0
  26. package/index.html +18 -0
  27. package/other/pda.vue +28 -0
  28. package/package.json +59 -0
  29. package/public/favicon.ico +0 -0
  30. package/public/setting.js +31 -0
  31. package/public/static/images/app-barcode.png +0 -0
  32. package/public/static/images/login/bg.png +0 -0
  33. package/public/static/images/login/logo.png +0 -0
  34. package/public/static/images/login/password-active.png +0 -0
  35. package/public/static/images/login/password-default.png +0 -0
  36. package/public/static/images/login/signIn-img.png +0 -0
  37. package/public/static/images/login/user-active.png +0 -0
  38. package/public/static/images/login/user-default.png +0 -0
  39. package/public/static/images/logo-dark.png +0 -0
  40. package/public/static/images/logo-small.png +0 -0
  41. package/public/static/images/logo.png +0 -0
  42. package/public/static/images/logo.svg +510 -0
  43. package/public/static/images/no-image.png +0 -0
  44. package/src/App.vue +60 -0
  45. package/src/api/application.js +35 -0
  46. package/src/api/customModel.js +187 -0
  47. package/src/api/customPage.js +15 -0
  48. package/src/api/customTable.js +24 -0
  49. package/src/api/dataSource.js +93 -0
  50. package/src/api/dataView.js +199 -0
  51. package/src/api/dictType.js +23 -0
  52. package/src/api/entityView.js +13 -0
  53. package/src/api/enum.js +15 -0
  54. package/src/api/filterColumn.js +16 -0
  55. package/src/api/model.js +244 -0
  56. package/src/api/movePlan.js +29 -0
  57. package/src/api/notification.js +28 -0
  58. package/src/api/openApiPermission.js +25 -0
  59. package/src/api/permission.js +51 -0
  60. package/src/api/planJob.js +15 -0
  61. package/src/api/process.js +23 -0
  62. package/src/api/processDef.js +36 -0
  63. package/src/api/processInst.js +16 -0
  64. package/src/api/rolePermission.js +17 -0
  65. package/src/api/roleProperty.js +36 -0
  66. package/src/api/shortcut.js +20 -0
  67. package/src/api/system.js +23 -0
  68. package/src/api/task.js +56 -0
  69. package/src/api/taskQueue.js +24 -0
  70. package/src/api/user.js +45 -0
  71. package/src/api/viewColumn.js +16 -0
  72. package/src/assets/svg/body.svg +17 -0
  73. package/src/assets/svg/header-theme-dark.svg +40 -0
  74. package/src/assets/svg/header-theme-primary.svg +40 -0
  75. package/src/assets/svg/header-top.svg +40 -0
  76. package/src/assets/svg/icon-happy.svg +1 -0
  77. package/src/assets/svg/icon-sad.svg +1 -0
  78. package/src/assets/svg/icon-social-bilibili.svg +1 -0
  79. package/src/assets/svg/icon-social-dingding.svg +1 -0
  80. package/src/assets/svg/icon-social-facebook.svg +1 -0
  81. package/src/assets/svg/icon-social-juejin.svg +1 -0
  82. package/src/assets/svg/icon-social-qq.svg +1 -0
  83. package/src/assets/svg/icon-social-twitter.svg +1 -0
  84. package/src/assets/svg/icon-social-wechat.svg +1 -0
  85. package/src/assets/svg/icon-social-weibo.svg +1 -0
  86. package/src/assets/svg/icon-social-zhihu.svg +1 -0
  87. package/src/assets/svg/nav-theme-dark.svg +40 -0
  88. package/src/assets/svg/nav-theme-light.svg +40 -0
  89. package/src/components/copyright/index.vue +28 -0
  90. package/src/components/home/notice-list.vue +62 -0
  91. package/src/components/home/shortcut.vue +125 -0
  92. package/src/components/input/dialog-select.vue +301 -0
  93. package/src/components/input/item-select.vue +195 -0
  94. package/src/components/link/index.vue +54 -0
  95. package/src/components/richEditor/index.vue +86 -0
  96. package/src/components/upload/file-upload.vue +84 -0
  97. package/src/components/upload/upload-attachment.vue +119 -0
  98. package/src/components/upload/upload-image.vue +212 -0
  99. package/src/components/view/column-check.vue +223 -0
  100. package/src/components/view/column-edit.vue +850 -0
  101. package/src/components/view/column-select.vue +206 -0
  102. package/src/components/view/condition-edit.vue +164 -0
  103. package/src/components/view/filter-edit.vue +633 -0
  104. package/src/components/view/filter-setting.vue +126 -0
  105. package/src/components/view/form-setting-layout.vue +375 -0
  106. package/src/components/view/form-setting.vue +247 -0
  107. package/src/components/view/group-column.vue +104 -0
  108. package/src/components/view/group-method.vue +104 -0
  109. package/src/components/view/mixin.js +72 -0
  110. package/src/components/view/modal-form-filter.vue +319 -0
  111. package/src/components/view/modal-form-sort.vue +248 -0
  112. package/src/components/view/modal-form.vue +453 -0
  113. package/src/components/view/modal-table.vue +471 -0
  114. package/src/components/view/table-filter.vue +702 -0
  115. package/src/components/view/table-setting.vue +533 -0
  116. package/src/components/view/view-chart.vue +423 -0
  117. package/src/components/view/view-form-draggable.vue +837 -0
  118. package/src/components/view/view-form.vue +1444 -0
  119. package/src/components/view/view-table.vue +2261 -0
  120. package/src/components/workflow/flow-chart.vue +846 -0
  121. package/src/directive/focus.js +10 -0
  122. package/src/directive/tabHide.js +9 -0
  123. package/src/i18n/index.js +15 -0
  124. package/src/i18n/locale/en-US.js +1 -0
  125. package/src/i18n/locale/lang.js +1 -0
  126. package/src/i18n/locale/zh-CN.js +1 -0
  127. package/src/i18n/locale.js +102 -0
  128. package/src/index.js +222 -0
  129. package/src/layouts/basic-layout/header-breadcrumb/index.vue +122 -0
  130. package/src/layouts/basic-layout/header-collapse/index.vue +44 -0
  131. package/src/layouts/basic-layout/header-fullscreen/index.vue +19 -0
  132. package/src/layouts/basic-layout/header-i18n/index.vue +45 -0
  133. package/src/layouts/basic-layout/header-log/index.vue +41 -0
  134. package/src/layouts/basic-layout/header-logo/index.vue +23 -0
  135. package/src/layouts/basic-layout/header-notice/index.vue +218 -0
  136. package/src/layouts/basic-layout/header-reload/index.vue +21 -0
  137. package/src/layouts/basic-layout/header-search/index.vue +37 -0
  138. package/src/layouts/basic-layout/header-setting/index.vue +219 -0
  139. package/src/layouts/basic-layout/header-user/index.vue +175 -0
  140. package/src/layouts/basic-layout/i18n.js +50 -0
  141. package/src/layouts/basic-layout/index.vue +280 -0
  142. package/src/layouts/basic-layout/menu-head/index.vue +120 -0
  143. package/src/layouts/basic-layout/menu-head/title.vue +48 -0
  144. package/src/layouts/basic-layout/menu-side/index.vue +113 -0
  145. package/src/layouts/basic-layout/menu-side/menu-collapse.vue +76 -0
  146. package/src/layouts/basic-layout/menu-side/menu-item.vue +31 -0
  147. package/src/layouts/basic-layout/menu-side/menu-title.vue +56 -0
  148. package/src/layouts/basic-layout/menu-side/submenu.vue +31 -0
  149. package/src/layouts/basic-layout/mixins/click-item.js +21 -0
  150. package/src/layouts/basic-layout/mixins/sider-menu-badge.js +13 -0
  151. package/src/layouts/basic-layout/mixins/translate-title.js +11 -0
  152. package/src/layouts/basic-layout/tabs/index.vue +192 -0
  153. package/src/layouts/basic-layout/water-mark/index.vue +29 -0
  154. package/src/libs/lodop/index.js +145 -0
  155. package/src/libs/random_str.js +10 -0
  156. package/src/libs/request/index.js +158 -0
  157. package/src/libs/system/index.js +234 -0
  158. package/src/libs/util.cookies.js +44 -0
  159. package/src/libs/util.db.js +13 -0
  160. package/src/libs/util.js +55 -0
  161. package/src/libs/util.log.js +88 -0
  162. package/src/libs/water-mark.js +44 -0
  163. package/src/menu/header.js +20 -0
  164. package/src/menu/modules/dashboard.js +23 -0
  165. package/src/menu/sider.js +12 -0
  166. package/src/mixins/app.js +9 -0
  167. package/src/mixins/page.js +643 -0
  168. package/src/pages/account/login.vue +101 -0
  169. package/src/pages/common/home.vue +169 -0
  170. package/src/pages/common/task-form.vue +350 -0
  171. package/src/pages/common/todo.vue +31 -0
  172. package/src/pages/system/apiLog.vue +79 -0
  173. package/src/pages/system/applicationType.vue +182 -0
  174. package/src/pages/system/customPage.vue +62 -0
  175. package/src/pages/system/customTable.vue +98 -0
  176. package/src/pages/system/dict.vue +36 -0
  177. package/src/pages/system/dictType.vue +58 -0
  178. package/src/pages/system/entityView.vue +38 -0
  179. package/src/pages/system/error/404.vue +6 -0
  180. package/src/pages/system/extendColumn.vue +99 -0
  181. package/src/pages/system/formView.vue +136 -0
  182. package/src/pages/system/log.vue +55 -0
  183. package/src/pages/system/notice.vue +26 -0
  184. package/src/pages/system/openApi.vue +26 -0
  185. package/src/pages/system/openUser.vue +66 -0
  186. package/src/pages/system/organization.vue +98 -0
  187. package/src/pages/system/organizationType.vue +26 -0
  188. package/src/pages/system/permission.vue +175 -0
  189. package/src/pages/system/planJob.vue +40 -0
  190. package/src/pages/system/printTemplate.vue +48 -0
  191. package/src/pages/system/process.vue +79 -0
  192. package/src/pages/system/processType.vue +26 -0
  193. package/src/pages/system/role.vue +395 -0
  194. package/src/pages/system/rolePropertyEdit.vue +480 -0
  195. package/src/pages/system/sequenceSetting.vue +26 -0
  196. package/src/pages/system/systemData.vue +52 -0
  197. package/src/pages/system/tableView.vue +386 -0
  198. package/src/pages/system/taskQueue.vue +48 -0
  199. package/src/pages/system/user.vue +250 -0
  200. package/src/pages/template/processPage.vue +243 -0
  201. package/src/pages/template/reportPage.vue +66 -0
  202. package/src/pages/template/viewPage.vue +139 -0
  203. package/src/plugins/auth/index.js +21 -0
  204. package/src/plugins/error/index.js +31 -0
  205. package/src/plugins/index.js +24 -0
  206. package/src/plugins/sweetalert2/index.js +20 -0
  207. package/src/router/dynamic.js +183 -0
  208. package/src/router/index.js +84 -0
  209. package/src/setting.js +202 -0
  210. package/src/store/index.js +9 -0
  211. package/src/store/modules/admin/index.js +16 -0
  212. package/src/store/modules/admin/modules/account.js +103 -0
  213. package/src/store/modules/admin/modules/cache.js +119 -0
  214. package/src/store/modules/admin/modules/dataView.js +112 -0
  215. package/src/store/modules/admin/modules/db.js +231 -0
  216. package/src/store/modules/admin/modules/i18n.js +87 -0
  217. package/src/store/modules/admin/modules/layout.js +115 -0
  218. package/src/store/modules/admin/modules/loader.js +44 -0
  219. package/src/store/modules/admin/modules/log.js +77 -0
  220. package/src/store/modules/admin/modules/menu.js +338 -0
  221. package/src/store/modules/admin/modules/page.js +466 -0
  222. package/src/store/modules/admin/modules/user.js +96 -0
  223. package/src/store/modules/admin/modules/viewPage.js +34 -0
  224. package/src/styles/common.less +47 -0
  225. package/src/styles/css/default.css +510 -0
  226. package/src/styles/css/login.css +1217 -0
  227. package/src/styles/default/index.less +6 -0
  228. package/src/styles/font/demo.css +539 -0
  229. package/src/styles/font/demo_index.html +372 -0
  230. package/src/styles/font/icon-demo/demo.css +539 -0
  231. package/src/styles/font/icon-demo/demo_index.html +423 -0
  232. package/src/styles/font/icon-demo/iconfont.css +61 -0
  233. package/src/styles/font/icon-demo/iconfont.eot +0 -0
  234. package/src/styles/font/icon-demo/iconfont.js +1 -0
  235. package/src/styles/font/icon-demo/iconfont.svg +59 -0
  236. package/src/styles/font/icon-demo/iconfont.ttf +0 -0
  237. package/src/styles/font/icon-demo/iconfont.woff +0 -0
  238. package/src/styles/font/icon-demo/iconfont.woff2 +0 -0
  239. package/src/styles/font/iconfont.css +47 -0
  240. package/src/styles/font/iconfont.js +1 -0
  241. package/src/styles/font/iconfont.json +65 -0
  242. package/src/styles/font/iconfont.ttf +0 -0
  243. package/src/styles/font/iconfont.woff +0 -0
  244. package/src/styles/font/iconfont.woff2 +0 -0
  245. package/src/styles/font/ionicons.svg +870 -0
  246. package/src/styles/font/ionicons.ttf +0 -0
  247. package/src/styles/font/ionicons.woff +0 -0
  248. package/src/styles/font/ionicons.woff2 +0 -0
  249. package/src/styles/index.less +7 -0
  250. package/src/styles/layout/basic-layout/layout.less +527 -0
  251. package/src/styles/layout/basic-layout/menu.less +274 -0
  252. package/src/styles/layout/index.less +2 -0
  253. package/src/styles/setting.less +6 -0
  254. package/styleguide.config.js +22 -0
  255. package/test/api/barcode.js +50 -0
  256. package/test/api/inbound.js +47 -0
  257. package/test/api/interfaceLog.js +15 -0
  258. package/test/api/interfaceQueue.js +15 -0
  259. package/test/api/interfaceServer.js +29 -0
  260. package/test/api/movePlan.js +50 -0
  261. package/test/api/movePlanItem.js +13 -0
  262. package/test/api/moveType.js +22 -0
  263. package/test/api/openApiPermission.js +25 -0
  264. package/test/api/outbound.js +40 -0
  265. package/test/api/permission.js +34 -0
  266. package/test/api/rolePermission.js +17 -0
  267. package/test/api/user.js +40 -0
  268. package/test/api/viewColumn.js +16 -0
  269. package/test/api/warehouse.js +13 -0
  270. package/test/api/warehouseMoveType.js +18 -0
  271. package/test/main.js +55 -0
  272. package/test/package.js +33 -0
  273. package/test/pages/home/index.vue +22 -0
  274. package/test/pages/task/test.vue +28 -0
  275. package/test/pages/test/dataViewTest.vue +28 -0
  276. package/test/pages/test/logReport.vue +25 -0
  277. package/test/pages/test/testPage.vue +38 -0
  278. package/test/router/routes.js +88 -0
  279. package/test/setting.env.js +22 -0
  280. package/test/styles/css/custom.css +0 -0
  281. package/test/styles/css/login.css +1217 -0
  282. package/vite.config.js +72 -0
  283. package/vue.config.js +20 -0
@@ -0,0 +1,466 @@
1
+ /**
2
+ * 多标签页
3
+ * */
4
+ import { get, cloneDeep } from 'lodash';
5
+ import router from '../../../../router';
6
+ import Setting from '../../../../setting';
7
+ import menuSider from '../../../../menu/sider';
8
+ import { getAllSiderMenu, includeArray } from '../../../../libs/system';
9
+
10
+ // 判定是否需要缓存
11
+ const isKeepAlive = data => get(data, 'meta.cache', false);
12
+
13
+ export default {
14
+ namespaced: true,
15
+ state: {
16
+ // 可以在多页 tab 模式下显示的页面
17
+ pool: [],
18
+ // 当前显示的多页面列表
19
+ opened: Setting.page.opened,
20
+ // 当前页面
21
+ current: '',
22
+ // 需要缓存的页面 name
23
+ keepAlive: []
24
+ },
25
+ actions: {
26
+ /**
27
+ * @description 从持久化数据载入分页列表
28
+ */
29
+ openedLoad({ state, commit, dispatch, rootState }, { loadOpenedTabs = true }) {
30
+ return new Promise(async resolve => {
31
+ // store 赋值
32
+ let value = await dispatch(
33
+ 'admin/db/get',
34
+ {
35
+ dbName: 'sys',
36
+ path: 'page.opened',
37
+ defaultValue: Setting.page.opened,
38
+ user: true
39
+ },
40
+ { root: true }
41
+ );
42
+ if (!loadOpenedTabs) value = [];
43
+ // 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签
44
+ // 以 fullPath 字段为准
45
+ // 如果页面过多的话可能需要优化算法
46
+ // valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效
47
+ const valid = [];
48
+ // 处理数据
49
+ state.opened = value
50
+ .map(opened => {
51
+ // 忽略首页
52
+ if (opened.fullPath === '/index') {
53
+ valid.push(1);
54
+ return opened;
55
+ }
56
+ // 尝试在所有的支持多标签页的页面里找到 name 匹配的页面
57
+ const find = state.pool.find(item => item.name === opened.name);
58
+ // 如果 value 项有 keepMeta 字段,则保留 meta
59
+ if (opened.keepMeta) {
60
+ find.meta = Object.assign({}, opened.meta);
61
+ }
62
+ // 记录有效或无效信息
63
+ valid.push(find ? 1 : 0);
64
+ // 返回合并后的数据 新的覆盖旧的
65
+ // 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存
66
+ return Object.assign({}, opened, find);
67
+ })
68
+ .filter((opened, index) => valid[index] === 1)
69
+ // 对 menu 鉴权过滤
70
+ .filter(opened => {
71
+ const allSiderMenu = getAllSiderMenu(menuSider);
72
+ const find = allSiderMenu.find(item => item.path === opened.fullPath);
73
+
74
+ let state = true;
75
+ if (find && find.auth) {
76
+ const userInfo = rootState.admin.user.info;
77
+ // @权限
78
+ const access = cloneDeep(userInfo.access);
79
+ // 给 access 强制加一个 hidden 的权限,否则菜单隐藏后,Tabs 页签会不显示该页签
80
+ access.push('hidden');
81
+ // 如果用户当前的权限,不是该 menu 对应的 权限,则过滤这个 Tab
82
+ if (access && !includeArray(find.auth, access)) state = false;
83
+ }
84
+ return state;
85
+ });
86
+ // 根据 opened 数据生成缓存设置
87
+ commit('keepAliveRefresh');
88
+ // end
89
+ resolve();
90
+ });
91
+ },
92
+ /**
93
+ * 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened
94
+ */
95
+ opened2db({ state, dispatch }) {
96
+ return new Promise(async resolve => {
97
+ // 设置数据
98
+ dispatch(
99
+ 'admin/db/set',
100
+ {
101
+ dbName: 'sys',
102
+ path: 'page.opened',
103
+ value: state.opened,
104
+ user: true
105
+ },
106
+ { root: true }
107
+ );
108
+ // end
109
+ resolve();
110
+ });
111
+ },
112
+ /**
113
+ * @description 更新页面列表上的某一项
114
+ * @param {Object} param { index, params, query, fullPath } 路由信息
115
+ */
116
+ openedUpdate({ state, dispatch }, { index, params, query, fullPath, meta, keepMeta = false }) {
117
+ return new Promise(async resolve => {
118
+ // 更新页面列表某一项
119
+ let page = state.opened[index];
120
+ page.params = params || page.params;
121
+ page.query = query || page.query;
122
+ page.fullPath = fullPath || page.fullPath;
123
+ page.meta = meta || page.meta;
124
+ page.keepMeta = keepMeta;
125
+ state.opened.splice(index, 1, page);
126
+ // 持久化
127
+ await dispatch('opened2db');
128
+ // end
129
+ resolve();
130
+ });
131
+ },
132
+ /**
133
+ * @description 更新页面当前项
134
+ * @param {Object} param { params, query, fullPath } 路由信息
135
+ */
136
+ currentUpdate({ state, dispatch }, { params, query, fullPath, meta, keepMeta = false }) {
137
+ return new Promise(async resolve => {
138
+ setTimeout(async () => {
139
+ // 更新当前项
140
+ const index = state.opened.findIndex(item => item.fullPath === state.current);
141
+ let page = state.opened[index];
142
+ page.params = params || page.params;
143
+ page.query = query || page.query;
144
+ page.fullPath = fullPath || page.fullPath;
145
+ page.meta = meta || page.meta;
146
+ page.keepMeta = keepMeta;
147
+ state.opened.splice(index, 1, page);
148
+ // 持久化
149
+ await dispatch('opened2db');
150
+ // end
151
+ resolve();
152
+ }, 0);
153
+ });
154
+ },
155
+ /**
156
+ * @description 新增一个 tag (打开一个页面)
157
+ * @param {Object} param new tag info
158
+ */
159
+ add({ state, commit, dispatch }, { tag, params, query, fullPath }) {
160
+ return new Promise(async resolve => {
161
+ // 设置新的 tag 在新打开一个以前没打开过的页面时使用
162
+ let newTag = tag;
163
+ newTag.params = params || newTag.params;
164
+ newTag.query = query || newTag.query;
165
+ newTag.fullPath = fullPath || newTag.fullPath;
166
+ // 添加进当前显示的页面数组
167
+ state.opened.push(newTag);
168
+ // 如果这个页面需要缓存 将其添加到缓存设置
169
+ if (isKeepAlive(newTag)) {
170
+ commit('keepAlivePush', tag.name);
171
+ }
172
+ // 持久化
173
+ await dispatch('opened2db');
174
+ // end
175
+ resolve();
176
+ });
177
+ },
178
+ /**
179
+ * @description 打开一个新的页面
180
+ * @param {Object} param 从路由钩子的 to 对象上获取 { name, params, query, fullPath } 路由信息
181
+ */
182
+ open({ state, commit, dispatch }, { name, params, query, fullPath }) {
183
+ return new Promise(async resolve => {
184
+ // 已经打开的页面
185
+ let opened = state.opened;
186
+ // 判断此页面是否已经打开 并且记录位置
187
+ let pageOpenedIndex = 0;
188
+ const pageOpened = opened.find((page, index) => {
189
+ const same = page.fullPath === fullPath;
190
+ pageOpenedIndex = same ? index : pageOpenedIndex;
191
+ return same;
192
+ });
193
+ if (pageOpened) {
194
+ // 页面以前打开过
195
+ await dispatch('openedUpdate', {
196
+ index: pageOpenedIndex,
197
+ params,
198
+ query,
199
+ fullPath
200
+ });
201
+ } else {
202
+ // 页面以前没有打开过
203
+ let page = state.pool.find(t => t.name === name);
204
+ // 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示
205
+ if (page) {
206
+ await dispatch('add', {
207
+ tag: Object.assign({}, page),
208
+ params,
209
+ query,
210
+ fullPath
211
+ });
212
+ }
213
+ }
214
+ commit('currentSet', fullPath);
215
+ // end
216
+ resolve();
217
+ });
218
+ },
219
+ /**
220
+ * @description 关闭一个 tag (关闭一个页面)
221
+ * @param {Object} param { tagName: 要关闭的标签名字 }
222
+ */
223
+ close({ state, commit, dispatch }, { tagName }) {
224
+ return new Promise(async resolve => {
225
+ // 下个新的页面
226
+ let newPage = state.opened[0];
227
+ const isCurrent = state.current === tagName;
228
+ // 如果关闭的页面就是当前显示的页面
229
+ if (isCurrent) {
230
+ // 去找一个新的页面
231
+ let len = state.opened.length;
232
+ for (let i = 0; i < len; i++) {
233
+ if (state.opened[i].fullPath === tagName) {
234
+ // 是否只剩最后一个,是则跳首页
235
+ if (len > 1) {
236
+ // 如果是最后一个,则向前一个跳,否则向下一个跳
237
+ if (i === len - 1) {
238
+ newPage = state.opened[i - 1];
239
+ } else {
240
+ newPage = state.opened[i + 1];
241
+ }
242
+ } else {
243
+ newPage = {};
244
+ }
245
+ break;
246
+ }
247
+ }
248
+ }
249
+ // 找到这个页面在已经打开的数据里是第几个
250
+ const index = state.opened.findIndex(page => page.fullPath === tagName);
251
+ if (index >= 0) {
252
+ // 如果这个页面是缓存的页面 将其在缓存设置中删除
253
+ commit('keepAliveRemove', state.opened[index].name);
254
+ // 更新数据 删除关闭的页面
255
+ state.opened.splice(index, 1);
256
+ }
257
+ // 持久化
258
+ await dispatch('opened2db');
259
+ // 最后需要判断是否需要跳到首页
260
+ if (isCurrent) {
261
+ const { name = 'index', params = {}, query = {} } = newPage;
262
+ let routerObj = {
263
+ name,
264
+ params,
265
+ query
266
+ };
267
+ router.push(routerObj, () => {});
268
+ }
269
+ // end
270
+ resolve();
271
+ });
272
+ },
273
+ /**
274
+ * @description 关闭当前标签左边的标签
275
+ * @param {Object} param { pageSelect: 当前选中的tagName }
276
+ */
277
+ closeLeft({ state, commit, dispatch }, { pageSelect } = {}) {
278
+ return new Promise(async resolve => {
279
+ const pageAim = pageSelect || state.current;
280
+ let currentIndex = 0;
281
+ state.opened.forEach((page, index) => {
282
+ if (page.fullPath === pageAim) {
283
+ currentIndex = index;
284
+ }
285
+ });
286
+ if (currentIndex > 0) {
287
+ // 删除打开的页面 并在缓存设置中删除
288
+ state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name));
289
+ }
290
+ state.current = pageAim;
291
+ if (router.currentRoute.value.fullPath !== pageAim) {
292
+ router.push(pageAim);
293
+ }
294
+ // 持久化
295
+ await dispatch('opened2db');
296
+ // end
297
+ resolve();
298
+ });
299
+ },
300
+ /**
301
+ * @description 关闭当前标签右边的标签
302
+ * @param {Object} param { pageSelect: 当前选中的tagName }
303
+ */
304
+ closeRight({ state, commit, dispatch }, { pageSelect } = {}) {
305
+ return new Promise(async resolve => {
306
+ const pageAim = pageSelect || state.current;
307
+ let currentIndex = 0;
308
+ state.opened.forEach((page, index) => {
309
+ if (page.fullPath === pageAim) {
310
+ currentIndex = index;
311
+ }
312
+ });
313
+ // 删除打开的页面 并在缓存设置中删除
314
+ state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name));
315
+ // 设置当前的页面
316
+ state.current = pageAim;
317
+ if (router.currentRoute.value.fullPath !== pageAim) {
318
+ router.push(pageAim);
319
+ }
320
+ // 持久化
321
+ await dispatch('opened2db');
322
+ // end
323
+ resolve();
324
+ });
325
+ },
326
+ /**
327
+ * @description 关闭当前激活之外的 tag
328
+ * @param {Object} param { pageSelect: 当前选中的tagName }
329
+ */
330
+ closeOther({ state, commit, dispatch }, { pageSelect } = {}) {
331
+ return new Promise(async resolve => {
332
+ const pageAim = pageSelect || state.current;
333
+ let currentIndex = 0;
334
+ state.opened.forEach((page, index) => {
335
+ if (page.fullPath === pageAim) {
336
+ currentIndex = index;
337
+ }
338
+ });
339
+ // 删除打开的页面数据 并更新缓存设置
340
+ if (currentIndex === 0) {
341
+ state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name));
342
+ } else {
343
+ state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name));
344
+ state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name));
345
+ }
346
+ // 设置新的页面
347
+ state.current = pageAim;
348
+ if (router.currentRoute.value.fullPath !== pageAim) {
349
+ router.push(pageAim);
350
+ }
351
+ // 持久化
352
+ await dispatch('opened2db');
353
+ // end
354
+ resolve();
355
+ });
356
+ },
357
+ /**
358
+ * @description 关闭所有 tag
359
+ * @param {Object} state vuex state
360
+ */
361
+ closeAll({ state, commit, dispatch }) {
362
+ return new Promise(async resolve => {
363
+ // 删除打开的页面 并在缓存设置中删除
364
+ state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name));
365
+ // 持久化
366
+ await dispatch('opened2db');
367
+ // 关闭所有的标签页后需要判断一次现在是不是在首页
368
+ if (router.currentRoute.value.name !== 'index') {
369
+ router.push(
370
+ {
371
+ name: 'index'
372
+ },
373
+ () => {}
374
+ );
375
+ }
376
+ // end
377
+ resolve();
378
+ });
379
+ },
380
+ /**
381
+ * @description 直接更新 opened,用于拖拽调整页签顺序
382
+ * */
383
+ updateOpened({ state, dispatch }, { opened }) {
384
+ return new Promise(async resolve => {
385
+ state.opened = opened;
386
+ // 持久化
387
+ await dispatch('opened2db');
388
+ // end
389
+ resolve();
390
+ });
391
+ }
392
+ },
393
+ mutations: {
394
+ /**
395
+ * @class keepAlive
396
+ * @description 从已经打开的页面记录中更新需要缓存的页面记录
397
+ * @param {Object} state vuex state
398
+ */
399
+ keepAliveRefresh(state) {
400
+ state.keepAlive = state.opened.filter(item => isKeepAlive(item)).map(e => e.name);
401
+ },
402
+ /**
403
+ * @description 删除一个页面的缓存设置
404
+ * @param {Object} state vuex state
405
+ * @param {String} name name
406
+ */
407
+ keepAliveRemove(state, name) {
408
+ const list = [...state.keepAlive];
409
+ const index = list.findIndex(item => item === name);
410
+
411
+ if (index !== -1) {
412
+ list.splice(index, 1);
413
+ state.keepAlive = list;
414
+ }
415
+ },
416
+ /**
417
+ * @description 增加一个页面的缓存设置
418
+ * @param {Object} state vuex state
419
+ * @param {String} name name
420
+ */
421
+ keepAlivePush(state, name) {
422
+ const keep = [...state.keepAlive];
423
+ keep.push(name);
424
+ state.keepAlive = keep;
425
+ },
426
+ /**
427
+ * @description 清空页面缓存设置
428
+ * @param {Object} state vuex state
429
+ */
430
+ keepAliveClean(state) {
431
+ state.keepAlive = [];
432
+ },
433
+ /**
434
+ * @class current
435
+ * @description 设置当前激活的页面 fullPath
436
+ * @param {Object} state vuex state
437
+ * @param {String} fullPath new fullPath
438
+ */
439
+ currentSet(state, fullPath) {
440
+ state.current = fullPath;
441
+ },
442
+ /**
443
+ * @class pool
444
+ * @description 保存 pool (候选池)
445
+ * @param {Object} state vuex state
446
+ * @param {Array} routes routes
447
+ */
448
+ init(state, routes) {
449
+ const pool = [];
450
+ const push = function (routes) {
451
+ routes.forEach(route => {
452
+ if (route.children) {
453
+ push(route.children);
454
+ } else {
455
+ if (!route.hidden) {
456
+ const { meta, name, path } = route;
457
+ pool.push({ meta, name, path });
458
+ }
459
+ }
460
+ });
461
+ };
462
+ push(routes);
463
+ state.pool = pool;
464
+ }
465
+ }
466
+ };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * 用户信息
3
+ * */
4
+ export default {
5
+ namespaced: true,
6
+ state: {
7
+ // 用户信息
8
+ info: {},
9
+ // 附加数据
10
+ data: {}
11
+ },
12
+ actions: {
13
+ /**
14
+ * @description 设置用户数据
15
+ * @param {Object} state vuex state
16
+ * @param {Object} dispatch vuex dispatch
17
+ * @param {*} info info
18
+ */
19
+ set({ state, dispatch }, info) {
20
+ return new Promise(async resolve => {
21
+ // store 赋值
22
+ state.info = info;
23
+ // 持久化
24
+ await dispatch(
25
+ 'admin/db/set',
26
+ {
27
+ dbName: 'sys',
28
+ path: 'user.info',
29
+ value: info,
30
+ user: true
31
+ },
32
+ { root: true }
33
+ );
34
+ // end
35
+ resolve();
36
+ });
37
+ },
38
+ /**
39
+ * @description 设置用户附加数据
40
+ * @param {Object} state vuex state
41
+ * @param {Object} dispatch vuex dispatch
42
+ * @param {*} data data
43
+ */
44
+ setData({ state, dispatch }, data) {
45
+ return new Promise(async resolve => {
46
+ // store 赋值
47
+ state.data = data;
48
+ // 持久化
49
+ await dispatch(
50
+ 'admin/db/set',
51
+ {
52
+ dbName: 'sys',
53
+ path: 'user.data',
54
+ value: data,
55
+ user: true
56
+ },
57
+ { root: true }
58
+ );
59
+ // end
60
+ resolve();
61
+ });
62
+ },
63
+ /**
64
+ * @description 从数据库取用户数据
65
+ * @param {Object} state vuex state
66
+ * @param {Object} dispatch vuex dispatch
67
+ */
68
+ load({ state, dispatch }) {
69
+ return new Promise(async resolve => {
70
+ // store 赋值
71
+ state.info = await dispatch(
72
+ 'admin/db/get',
73
+ {
74
+ dbName: 'sys',
75
+ path: 'user.info',
76
+ defaultValue: {},
77
+ user: true
78
+ },
79
+ { root: true }
80
+ );
81
+ state.data = await dispatch(
82
+ 'admin/db/get',
83
+ {
84
+ dbName: 'sys',
85
+ path: 'user.data',
86
+ defaultValue: {},
87
+ user: true
88
+ },
89
+ { root: true }
90
+ );
91
+ // end
92
+ resolve();
93
+ });
94
+ }
95
+ }
96
+ };
@@ -0,0 +1,34 @@
1
+ import customPageApi from '../../../../api/customPage';
2
+
3
+ /**
4
+ * 缓存信息
5
+ * */
6
+ export default {
7
+ namespaced: true,
8
+ state: {
9
+ // 自定义页面
10
+ pages: {}
11
+ },
12
+ getters: {
13
+ get: state => id => {
14
+ return state.pages[id];
15
+ }
16
+ },
17
+ actions: {
18
+ /**
19
+ * @description 加载数据视图
20
+ * @param {Object} state vuex state
21
+ * @param {*} id 代码
22
+ */
23
+ async load({ state }, id) {
24
+ if (!(id in state.pages)) {
25
+ let res = await customPageApi.get(id);
26
+ state.pages[id] = res;
27
+
28
+ return res;
29
+ } else {
30
+ return state.pages[id];
31
+ }
32
+ }
33
+ }
34
+ };
@@ -0,0 +1,47 @@
1
+ #app, body, html{
2
+ height: 100%;
3
+ }
4
+ body{
5
+ background-color: @background-color-base;
6
+ font-size: 14px;
7
+ }
8
+
9
+ // 隐藏滚动条样式
10
+ .i-scrollbar-hide{
11
+ &::-webkit-scrollbar{
12
+ width: 0;
13
+ }
14
+ &::-webkit-scrollbar-track{
15
+ background-color: transparent;
16
+ }
17
+ &::-webkit-scrollbar-thumb{
18
+ background: #e8eaec;
19
+ }
20
+ }
21
+
22
+ // 极简滚动条样式
23
+ .i-scrollbar{
24
+ &::-webkit-scrollbar{
25
+ width: 6px;
26
+ }
27
+ &::-webkit-scrollbar-track{
28
+ background-color: transparent;
29
+ }
30
+ &::-webkit-scrollbar-thumb{
31
+ background: #808695;
32
+ border-radius: 4px;
33
+ }
34
+ }
35
+
36
+ // 去除 Table 的左右边框,更精简
37
+ .i-table-no-border{
38
+ .ivu-table th{
39
+ background-color: #fff;
40
+ }
41
+ .ivu-table-wrapper, .ivu-table tr:last-child td{
42
+ border: none;
43
+ }
44
+ .ivu-table:before, .ivu-table:after{
45
+ display: none;
46
+ }
47
+ }