@utogether/udp-core 1.0.1-beta.9 → 1.0.2

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 (168) hide show
  1. package/build/plugins.ts +37 -39
  2. package/dist/{403-BOzKHdlm.js → 403-B1rIjAAu.js} +6 -6
  3. package/dist/{404-uwgt4Nll.js → 404-mBqc2y4t.js} +4 -4
  4. package/dist/{500-4HBf6V9m.js → 500-BoI45Zdh.js} +2 -2
  5. package/dist/{AuthorityInfo-DvbIh1vT.js → AuthorityInfo-B08NBIIn.js} +1 -1
  6. package/dist/{AuthorityInfo.vue_vue_type_style_index_0_lang-BlCPvwXU.js → AuthorityInfo.vue_vue_type_style_index_0_lang-BLP1SaiH.js} +3 -3
  7. package/dist/{Company-D7Q9BFmr.js → Company-JGGyWEWH.js} +3 -3
  8. package/dist/{CompanyPanel-C0-PJlrt.js → CompanyPanel-BQ_cCmDx.js} +7 -7
  9. package/dist/{Department-h2hlXACv.js → Department-z2iO6hwM.js} +10 -10
  10. package/dist/{DepartmentPanel-B6hDEQpG.js → DepartmentPanel-BtQe7zwU.js} +108 -78
  11. package/dist/{DesignPanel-cS58-1v9.js → DesignPanel-7mhtVWas.js} +1 -1
  12. package/dist/{DesignPanel.vue_vue_type_style_index_0_lang-LdvLC8VU.js → DesignPanel.vue_vue_type_style_index_0_lang-4EsHemj_.js} +6 -6
  13. package/dist/{DictView-T3TmpBa8.js → DictView-CjchV2Yk.js} +15 -16
  14. package/dist/InvOrganization-Pn1O_XP0.js +74 -0
  15. package/dist/{Org-CnCBDGKF.js → Org-BqytV_vi.js} +1 -1
  16. package/dist/{Preview-BaktKXB1.js → Preview-CLpUUMay.js} +2 -2
  17. package/dist/{ReportDefine-5Rb0PO9A.js → ReportDefine-Cz1KtEUF.js} +1 -1
  18. package/dist/{ReportDesign-DYdkVREA.js → ReportDesign-BaORYud4.js} +13 -13
  19. package/dist/{ReportQuery-BwhzIXMt.js → ReportQuery-CPCPXiXz.js} +1 -1
  20. package/dist/{ReportQueryFrom-PHtWwlOe.js → ReportQueryFrom-C_AcrfkJ.js} +1 -1
  21. package/dist/{ReportQueryFrom.vue_vue_type_style_index_0_lang-BE5yZNPM.js → ReportQueryFrom.vue_vue_type_style_index_0_lang-Bm67ejay.js} +1 -1
  22. package/dist/{ReportTemplate-DaadVXIi.js → ReportTemplate-CFiNMz79.js} +11 -11
  23. package/dist/{Role-Dtg3nAmG.js → Role-B-XDoJd5.js} +3 -3
  24. package/dist/{RoleAssign-DEGtLssH.js → RoleAssign-BolW8YVs.js} +8 -8
  25. package/dist/{RolePanel-DpUzfE_o.js → RolePanel-2kfs5tw9.js} +1 -1
  26. package/dist/{RolePanel-CT7BTPmy.js → RolePanel-HilSuYns.js} +1 -1
  27. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-Xyo0YEI0.js → RolePanel.vue_vue_type_script_setup_true_lang-CE4gApUY.js} +7 -7
  28. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-Dg2A6DJu.js → RolePanel.vue_vue_type_script_setup_true_lang-DPzgfAyV.js} +13 -13
  29. package/dist/{ScrollPanel.vue_vue_type_style_index_0_lang-CyutzDZS.js → ScrollPanel.vue_vue_type_style_index_0_lang-CCTH4RkH.js} +4 -4
  30. package/dist/{Staff-_NlAGkrh.js → Staff-BTk3whFC.js} +3 -3
  31. package/dist/{StaffInfo-DVgUvVgd.js → StaffInfo-d3AuSzlA.js} +1 -1
  32. package/dist/{StaffInfo.vue_vue_type_script_setup_true_lang-C8hmlFgX.js → StaffInfo.vue_vue_type_script_setup_true_lang-eOL4VlfE.js} +5 -5
  33. package/dist/{StaffPanel-DKNZE3IE.js → StaffPanel-DV-D4jjz.js} +1 -1
  34. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-4sFq3CEo.js +135 -0
  35. package/dist/{SysUser-kQUf7XKz.js → SysUser-BnjYytws.js} +2 -2
  36. package/dist/{SysUserPanel-C191uX3U.js → SysUserPanel-CBoyD-Qi.js} +1 -1
  37. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-PrTlTZR-.js +341 -0
  38. package/dist/{SystemMenu-DwuSvHnj.js → SystemMenu-kYB_ZaUt.js} +36 -36
  39. package/dist/{UserInfo-DIsInFld.js → UserInfo-4dx97VBL.js} +1 -1
  40. package/dist/{UserInfo.vue_vue_type_style_index_0_lang-CnvGdbej.js → UserInfo.vue_vue_type_style_index_0_lang-BpbC_ZDm.js} +10 -10
  41. package/dist/{childView-3Bs2UBEw.js → childView-CHPNfTEb.js} +1 -1
  42. package/dist/{childView-BawyULD7.js → childView-CKA_JgVZ.js} +1 -1
  43. package/dist/{childView.vue_vue_type_style_index_0_lang-YpWF-p2F.js → childView.vue_vue_type_style_index_0_lang-Bym2fQRd.js} +7 -7
  44. package/dist/childView.vue_vue_type_style_index_0_lang-W7bCtXeu.js +177 -0
  45. package/dist/{code-rule-DVaYcn8S.js → code-rule-CbxuZg0-.js} +40 -38
  46. package/dist/core.es.js +18 -12
  47. package/dist/{cron-task-xuzP-BpE.js → cron-task-nTOpqQYf.js} +7 -7
  48. package/dist/flow-task-B07st2aD.js +10 -0
  49. package/dist/{frameView-Cudt06qS.js → frameView-Z1tPUyCh.js} +1 -1
  50. package/dist/index-C3q8HoJM.js +4650 -0
  51. package/dist/{layoutView-BlFTV2jX.js → layoutView--MGA9zUB.js} +1766 -1760
  52. package/dist/{log-in-e7D5Ss1P.js → log-in-CSYJDA6m.js} +36 -29
  53. package/dist/log-out-DiwGCg7p.js +130 -0
  54. package/dist/login-C6Y0ajDp.js +251 -0
  55. package/dist/{login-log-kqKzKTto.js → login-log-C0V-_l3F.js} +5 -3
  56. package/dist/{lov-view-B2HaxyMs.js → lov-view-Cmv7wZZ9.js} +6 -6
  57. package/dist/{menuInfo-BxCTJ1VW.js → menuInfo-UeutJpOa.js} +1 -1
  58. package/dist/{menuInfo.vue_vue_type_style_index_0_lang-CLOPNeUW.js → menuInfo.vue_vue_type_style_index_0_lang-CWX4Mu67.js} +118 -98
  59. package/dist/{pda-app-DPsAFNiw.js → pda-app-B6w99SJo.js} +10 -10
  60. package/dist/{resource-Dibb7t8u.js → resource-BybJvUv0.js} +4 -4
  61. package/dist/{su-welcome-DejR0KkM.js → su-welcome-C1bmxHoY.js} +119 -121
  62. package/dist/sys-config-BnmIDnCj.js +370 -0
  63. package/dist/udp-core.css +1 -9
  64. package/dist/utogether-MlnyYtNS.js +4 -0
  65. package/index.ts +49 -40
  66. package/package.json +18 -18
  67. package/src/App.vue +65 -65
  68. package/src/api/http.ts +1 -4
  69. package/src/api/index.ts +4 -2
  70. package/src/api/user.ts +2 -2
  71. package/src/components/SuCharts/src/UserInfo.vue +78 -78
  72. package/src/components/SuScrollTree/ScrollPanel.vue +1 -6
  73. package/src/components/udp/content/index.vue +88 -0
  74. package/src/components/udp/{form.vue → form/form.vue} +13 -16
  75. package/src/components/udp/{grid.vue → grid/index.vue} +56 -27
  76. package/src/components/udp/index.ts +4 -9
  77. package/src/components/udp/ut-stamp-badge/index.vue +271 -0
  78. package/src/components/udp/utils.ts +66 -105
  79. package/src/layout/components/lay-navbar/index.vue +8 -6
  80. package/src/layout/components/lay-panel/index.vue +150 -150
  81. package/src/layout/components/lay-search/index.vue +25 -25
  82. package/src/layout/components/lay-select-org/index.vue +4 -9
  83. package/src/layout/components/lay-setting/index.vue +503 -510
  84. package/src/layout/components/lay-sidebar/horizontal.vue +8 -6
  85. package/src/layout/components/lay-sidebar/mixNav.vue +260 -258
  86. package/src/layout/components/lay-sidebar/sidebar-logo.vue +101 -98
  87. package/src/layout/components/lay-tag/index.vue +24 -51
  88. package/src/layout/hooks/useDataThemeChange.ts +1 -1
  89. package/src/layout/hooks/useNav.ts +176 -173
  90. package/src/layout/hooks/useTag.ts +227 -233
  91. package/src/layout/types.ts +93 -92
  92. package/src/main.ts +115 -119
  93. package/src/plugins/i18n/en.ts +302 -302
  94. package/src/plugins/i18n/module/u-workflow.ts +1 -1
  95. package/src/plugins/i18n/zh.ts +21 -6
  96. package/src/plugins/vxe-table/index.ts +116 -53
  97. package/src/plugins/vxe-table/render.tsx +945 -956
  98. package/src/router/index.ts +17 -17
  99. package/src/router/modules/flow.ts +35 -0
  100. package/src/router/modules/home.ts +32 -32
  101. package/src/router/modules/remaining.ts +58 -58
  102. package/src/router/utils.ts +420 -377
  103. package/src/store/modules/app.ts +2 -4
  104. package/src/store/modules/epTheme.ts +48 -49
  105. package/src/store/modules/multiTags.ts +15 -14
  106. package/src/store/modules/permission.ts +25 -15
  107. package/src/store/modules/system.ts +1 -3
  108. package/src/style/button.scss +85 -85
  109. package/src/style/login.css +1 -1
  110. package/src/style/vxetable.scss +61 -2
  111. package/src/utils/dataFormat/index.ts +223 -223
  112. package/src/utils/index.ts +3 -1
  113. package/src/utils/lifecycle.ts +39 -20
  114. package/src/utils/propTypes.ts +1 -6
  115. package/src/utils/storage/index.ts +2 -2
  116. package/src/utils/udp/http/index.ts +24 -11
  117. package/src/utils/udp/http/types.d.ts +3 -10
  118. package/src/views/login/login-view.vue +4 -18
  119. package/src/views/organization/company/CompanyPanel.vue +259 -259
  120. package/src/views/organization/department/Department.vue +58 -58
  121. package/src/views/organization/department/DepartmentPanel.vue +303 -283
  122. package/src/views/organization/inv-org/InvOrganization.vue +22 -7
  123. package/src/views/organization/staff/StaffInfo.vue +127 -133
  124. package/src/views/organization/staff/StaffPanel.vue +162 -145
  125. package/src/views/system/cron/cron-task.vue +2 -12
  126. package/src/views/system/menu/SystemMenu.vue +185 -183
  127. package/src/views/system/menu/menuInfo.vue +384 -363
  128. package/src/views/system/role/UserInfo.vue +195 -195
  129. package/src/views/system/role-assign/RoleAssign.vue +57 -57
  130. package/src/views/system/role-assign/RolePanel.vue +139 -139
  131. package/src/views/system/sys/sys-config.vue +69 -20
  132. package/src/views/system/sysUser/SysUserPanel.vue +97 -28
  133. package/src/views/uapp/pda/pda-app.vue +208 -208
  134. package/src/views/udev/coderule/code-rule.vue +132 -121
  135. package/src/views/udev/dict/DictView.vue +2 -2
  136. package/src/views/udev/dict/childView.vue +183 -222
  137. package/src/views/udev/lov/childView.vue +1 -7
  138. package/src/views/udev/lov/lov-view.vue +91 -91
  139. package/src/views/uhome/components/menu-favorite.vue +314 -331
  140. package/src/views/uhome/su-welcome.vue +319 -339
  141. package/src/views/ulogin/login.vue +325 -321
  142. package/src/views/upms/interface/log-in.vue +100 -106
  143. package/src/views/upms/interface/log-out.vue +104 -107
  144. package/src/views/upms/user/login-log.vue +54 -60
  145. package/src/views/urpt/design/DesignPanel.vue +507 -507
  146. package/src/views/urpt/design/Preview.vue +1 -0
  147. package/src/views/urpt/design/ReportDesign.vue +2 -4
  148. package/src/views/utask/flow-task.vue +18 -0
  149. package/types/global.d.ts +231 -236
  150. package/dist/InvOrganization-BVuOhzbt.js +0 -66
  151. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-BOOO6Cek.js +0 -111
  152. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-SwNbAEvW.js +0 -294
  153. package/dist/childView.vue_vue_type_style_index_0_lang-DWIFCX3X.js +0 -187
  154. package/dist/index-CKnq5xIa.js +0 -2623
  155. package/dist/log-out--RRncZhN.js +0 -120
  156. package/dist/login-CpKykfdf.js +0 -253
  157. package/dist/sys-config-DiySRWns.js +0 -277
  158. package/dist/utogether-Dct_14Zk.js +0 -182
  159. package/src/components/udp/count-down.vue +0 -536
  160. package/src/components/udp/flip-down/FlipCard/flip-card.vue +0 -251
  161. package/src/components/udp/flip-down/FlipCard/interfaces.ts +0 -4
  162. package/src/components/udp/flip-down/FlipClock/flip-clock.vue +0 -113
  163. package/src/components/udp/form-upload.vue +0 -482
  164. package/src/components/udp/lov.vue +0 -388
  165. package/src/components/udp/modal-form.vue +0 -189
  166. package/src/components/udp/modal-grid.vue +0 -288
  167. package/src/components/udp/upload.vue +0 -423
  168. package/src/utils/udp/useRender.ts +0 -431
@@ -1,331 +1,314 @@
1
- <template>
2
- <vxe-modal
3
- v-model="showModal"
4
- :loading="loading"
5
- width="75%"
6
- height="80%"
7
- title="常用菜单设置(拖动可改变菜单顺序)"
8
- class-name="u-favorite-modal"
9
- show-footer
10
- @close="onClose"
11
- >
12
- <template #default>
13
- <div class="">
14
- <el-scrollbar heigth="100" class="w-full border-b border-slate-300">
15
- <template #default>
16
- <div class="w-full h-24">
17
- <el-empty v-if="!favoriteMenus.length" :image-size="50" description="" class="p-0" />
18
- <draggable
19
- :list="favoriteMenus"
20
- handle=".drag-item"
21
- animation="300"
22
- item-key="id"
23
- class="flex"
24
- @end="onMoveEnd"
25
- >
26
- <template #item="{ element, index }">
27
- <div class="">
28
- <div
29
- class="h-24 w-24 flex justify-center items-center flex-col relative drag-item ut-menu-top-item"
30
- >
31
- <div
32
- class="rounded-full w-10 h-10 flex items-center justify-center"
33
- :style="{ backgroundColor: getColor(index) }"
34
- >
35
- <iconify-icon-offline
36
- :icon="element.icon || `ri:${icons[index]}-line`"
37
- class="text-2xl text-white"
38
- />
39
- </div>
40
- <span
41
- class="w-[90%] text-xs mt-2 text-ellipsis overflow-hidden whitespace-nowrap text-center"
42
- >
43
- {{ element.menuName }}
44
- </span>
45
- <i
46
- class="ri-indeterminate-circle-line right-3 top-2 text-base hidden ut-menu-del"
47
- @click="onRemoveFavorite(element, index)"
48
- />
49
- </div>
50
- </div>
51
- </template>
52
- </draggable>
53
- </div>
54
- </template>
55
- </el-scrollbar>
56
- <el-scrollbar class="u-favorite-menu--contain">
57
- <template #default>
58
- <div class="p-3">
59
- <div v-for="menu in menuList" :key="menu.id" class="grandparent-node">
60
- <div class="flex items-center">
61
- <div class="w-2 h-4 bg-green-400" />
62
- <div class="ml-1 font-bold text-base">{{ menu.menuName }}</div>
63
- </div>
64
- <div class="pl-3 py-2">
65
- <vxe-checkbox-group v-model="checkboxModel[menu.id]" @change="onChange(menu, $event)">
66
- <vxe-checkbox
67
- v-for="item in handleMenuCategoryGroup(menu).menus"
68
- :key="item.id"
69
- :label="item.id"
70
- :content="item.menuName"
71
- />
72
- </vxe-checkbox-group>
73
- </div>
74
- <div
75
- v-for="item in handleMenuCategoryGroup(menu).folder"
76
- :key="item.id"
77
- class="parent-node pl-3"
78
- >
79
- <div class="flex items-center">
80
- <div class="w-2 h-4 bg-blue-400" />
81
- <div class="ml-1 font-bold text-sm">{{ item.menuName }}</div>
82
- </div>
83
-
84
- <div class="pl-3 py-2">
85
- <vxe-checkbox-group
86
- v-model="checkboxModel[item.id]"
87
- @change="onChange(item, $event)"
88
- >
89
- <vxe-checkbox
90
- v-for="child in handleMenuCategoryGroup(item).menus"
91
- :key="child.id"
92
- :label="child.id"
93
- :content="child.menuName"
94
- />
95
- </vxe-checkbox-group>
96
- </div>
97
- <div
98
- v-for="child in handleMenuCategoryGroup(item).folder"
99
- :key="child.id"
100
- class="child-node pl-3"
101
- >
102
- <div class="flex items-center">
103
- <div class="w-2 h-4 bg-red-400" />
104
- <div class="ml-1 font-bold text-sm">{{ child.menuName }}</div>
105
- </div>
106
-
107
- <div class="py-2">
108
- <vxe-checkbox-group
109
- v-model="checkboxModel[child.id]"
110
- @change="onChange(item, $event)"
111
- >
112
- <vxe-checkbox
113
- v-for="subChild in handleMenuCategoryGroup(child).menus"
114
- :key="subChild.id"
115
- :label="subChild.id"
116
- :content="subChild.menuName"
117
- />
118
- </vxe-checkbox-group>
119
- </div>
120
- </div>
121
- </div>
122
- </div>
123
- </div>
124
- </template>
125
- </el-scrollbar>
126
- </div>
127
- </template>
128
- <template #footer>
129
- <div class="flex justify-end">
130
- <ut-button content="cancel" status="warning" @tap="onClose" />
131
- <ut-button content="confirm" @tap="onConfirm" />
132
- </div>
133
- </template>
134
- </vxe-modal>
135
- </template>
136
- <script setup lang="ts">
137
- import { ref, onMounted, nextTick } from 'vue';
138
- import { clone, max } from 'xe-utils';
139
- import { dbstorage, delay, warnMessage, successMessage } from '@utogether/utils';
140
- import Draggable from 'vuedraggable';
141
- import { getServiceApi } from '../../../api';
142
-
143
- interface IProps {
144
- dataSource: IRecord[];
145
- icons: Array<String>;
146
- userName: string;
147
- }
148
-
149
- const props = withDefaults(defineProps<IProps>(), {
150
- dataSource: () => [],
151
- icons: () => [],
152
- userName: ''
153
- });
154
-
155
- // 用户菜单
156
- const favoriteMenus = ref([]);
157
- const menuList = ref([]);
158
- const showModal = ref(false);
159
- const loading = ref(false);
160
- const checkboxModel = ref<IRecord>({});
161
- // const cacheCheckModel = {}; // 缓存最初选中的数据
162
-
163
- const url = '/upfm/v1/menuFavority';
164
-
165
- const getCacheMenuList = async () => {
166
- menuList.value = await dbstorage.getItem(`U-${props.userName}-ROUTES`);
167
- menuList.value = menuList.value.filter(f => f.menuCode !== 'SysHome');
168
- await delay(64);
169
- setCheckboxedMenu();
170
- };
171
-
172
- /** 上部删除 */
173
- const onRemoveFavorite = (item, idx) => {
174
- favoriteMenus.value.splice(idx, 1);
175
- const index = checkboxModel.value[item.parentId]?.findIndex(f => f === item.menuId);
176
- checkboxModel.value[item.parentId].splice(index, 1);
177
- // index = cacheCheckModel[item.parentId]?.findIndex(f => f.id === item.id);
178
- // cacheCheckModel[item.parentId].splice(index, 1);
179
- };
180
-
181
- /** 菜单分组 */
182
- const handleMenuCategoryGroup = data => {
183
- const folder = [];
184
- const menus = [];
185
- data.children.forEach(e => {
186
- if (['5', '100'].includes(e.menuCategory)) {
187
- folder.push(e);
188
- } else {
189
- menus.push(e);
190
- }
191
- });
192
- return { folder, menus };
193
- };
194
-
195
- /** 设置默认选中 */
196
- const setCheckboxedMenu = () => {
197
- props.dataSource.forEach(data => {
198
- if (checkboxModel.value[data.parentId]) {
199
- checkboxModel.value[data.parentId].push(data.menuId);
200
- // cacheCheckModel[data.parentId].push(data);
201
- } else {
202
- checkboxModel.value[data.parentId] = [data.menuId];
203
- // cacheCheckModel[data.parentId] = [data];
204
- }
205
- });
206
- };
207
- /** checkbox change */
208
- const onChange = (menu, event) => {
209
- debugger;
210
- if (event.checked) {
211
- // 新增
212
- if (favoriteMenus.value.length === 16) {
213
- nextTick(() => {
214
- checkboxModel.value[menu.id].splice(checkboxModel.value[menu.id].length - 1, 1);
215
- });
216
- return warnMessage('最多只能选择16个常用功能');
217
- }
218
- // const max = getMax();
219
- // if (cacheCheckModel[menu.id]) {
220
- // cacheCheckModel[menu.id].push({ id: event.label, seqNo: max + 10 });
221
- // } else {
222
- // cacheCheckModel[menu.id] = [{ id: event.label, seqNo: max + 10 }];
223
- // }
224
-
225
- const menuItem = menu.children.find(f => f.id === event.label);
226
- if (menuItem) {
227
- menuItem.seqNo = getMax() + 10;
228
- menuItem.menuId = menuItem.id;
229
- favoriteMenus.value.push(menuItem);
230
- }
231
- } else {
232
- // 顶部删除
233
- let idx = favoriteMenus.value.findIndex(f => f.menuId === event.label);
234
- idx !== -1 && favoriteMenus.value.splice(idx, 1);
235
- // checkbox删除
236
- idx = checkboxModel.value[menu.id].findIndex(f => f === event.label);
237
- idx !== -1 && checkboxModel.value[menu.id].splice(idx, 1);
238
- // 缓存删除
239
- // idx = cacheCheckModel[menu.id].findIndex(f => f.id === event.label);
240
- // idx !== -1 && cacheCheckModel[menu.id].splice(idx, 1);
241
- }
242
- };
243
- const onMoveEnd = () => {
244
- favoriteMenus.value.forEach((item, idx) => {
245
- item.seqNo = (idx + 1) * 10;
246
- });
247
- };
248
- /** 获取排序最大值 */
249
- const getMax = () => {
250
- return max(favoriteMenus.value, item => item.seqNo)?.seqNo || 0;
251
- };
252
- const onConfirm = () => {
253
- console.log(favoriteMenus);
254
- const body = favoriteMenus.value.map(m => {
255
- return {
256
- userName: props.userName,
257
- menuId: m.menuId,
258
- seqNo: m.seqNo
259
- };
260
- });
261
- console.log(body);
262
- loading.value = true;
263
- getServiceApi()
264
- .post(url, body)
265
- .then(() => {
266
- successMessage();
267
- onClose();
268
- emit('success');
269
- })
270
- .finally(() => {
271
- loading.value = false;
272
- });
273
- };
274
-
275
- const onClose = () => {
276
- showModal.value = false;
277
- emit('close');
278
- };
279
-
280
- const getColor = idx => {
281
- const colorSet = ['#409eff', '#67c23a', '#13c2c2', '#e85f33', 'orange'];
282
- return colorSet[idx % 5];
283
- };
284
-
285
- const emit = defineEmits<{ (e: 'close'): void; (e: 'success'): void }>();
286
-
287
- onMounted(() => {
288
- favoriteMenus.value = clone(props.dataSource, true);
289
- showModal.value = true;
290
- getCacheMenuList();
291
- });
292
- </script>
293
- <style lang="scss">
294
- .u-favorite-modal {
295
- .vxe-modal--body .vxe-modal--content {
296
- padding: 0;
297
- overflow: hidden !important;
298
- }
299
-
300
- .el-empty {
301
- &__description {
302
- margin-top: 10px;
303
- }
304
- }
305
-
306
- .ut-menu-top-item:hover {
307
- .ut-menu-del {
308
- position: absolute;
309
- display: inline-block;
310
- color: rgb(240 94 94);
311
- cursor: pointer;
312
- }
313
- }
314
-
315
- .u-favorite-menu--contain {
316
- height: calc(100vh - 320px);
317
- }
318
-
319
- .vxe-checkbox,
320
- .vxe-checkbox + .vxe-checkbox {
321
- width: 120px;
322
- padding: 4px 0;
323
- margin-right: 10px;
324
- margin-left: 0;
325
- }
326
-
327
- .vxe-modal--footer {
328
- border-top: 1px solid #e8e8e8;
329
- }
330
- }
331
- </style>
1
+ <template>
2
+ <vxe-modal
3
+ v-model="showModal"
4
+ :loading="loading"
5
+ width="75%"
6
+ height="80%"
7
+ title="常用菜单设置(拖动可改变菜单顺序)"
8
+ class-name="u-favorite-modal"
9
+ show-footer
10
+ @close="onClose"
11
+ >
12
+ <template #default>
13
+ <div class="">
14
+ <el-scrollbar heigth="100" class="w-full border-b border-slate-300">
15
+ <template #default>
16
+ <div class="w-full h-24">
17
+ <el-empty v-if="!favoriteMenus.length" :image-size="50" description="" class="p-0" />
18
+ <draggable
19
+ :list="favoriteMenus"
20
+ handle=".drag-item"
21
+ animation="300"
22
+ item-key="id"
23
+ class="flex"
24
+ @end="onMoveEnd"
25
+ >
26
+ <template #item="{ element, index }">
27
+ <div class="">
28
+ <div
29
+ class="h-24 w-24 flex justify-center items-center flex-col relative drag-item ut-menu-top-item"
30
+ >
31
+ <div
32
+ class="rounded-full w-10 h-10 flex items-center justify-center"
33
+ :style="{ backgroundColor: getColor(index) }"
34
+ >
35
+ <iconify-icon-offline
36
+ :icon="element.icon || `ri:${icons[index]}-line`"
37
+ class="text-2xl text-white"
38
+ />
39
+ </div>
40
+ <span class="w-[90%] text-xs mt-2 text-ellipsis overflow-hidden whitespace-nowrap text-center">
41
+ {{ element.menuName }}
42
+ </span>
43
+ <i
44
+ class="ri-indeterminate-circle-line right-3 top-2 text-base hidden ut-menu-del"
45
+ @click="onRemoveFavorite(element, index)"
46
+ />
47
+ </div>
48
+ </div>
49
+ </template>
50
+ </draggable>
51
+ </div>
52
+ </template>
53
+ </el-scrollbar>
54
+ <el-scrollbar class="u-favorite-menu--contain">
55
+ <template #default>
56
+ <div class="p-3 pb-14" style="padding-bottom: 54px">
57
+ <div v-for="menu in menuList" :key="menu.id" class="grandparent-node">
58
+ <div class="flex items-center">
59
+ <div class="w-2 h-4 bg-green-400" />
60
+ <div class="ml-1 font-bold text-base">{{ menu.menuName }}</div>
61
+ </div>
62
+ <div class="pl-3 py-2">
63
+ <vxe-checkbox-group v-model="checkboxModel[menu.id]" @change="onChange(menu, $event)">
64
+ <vxe-checkbox
65
+ v-for="item in handleMenuCategoryGroup(menu).menus"
66
+ :key="item.id"
67
+ :label="item.id"
68
+ :content="item.menuName"
69
+ />
70
+ </vxe-checkbox-group>
71
+ </div>
72
+ <div v-for="item in handleMenuCategoryGroup(menu).folder" :key="item.id" class="parent-node pl-3">
73
+ <div class="flex items-center">
74
+ <div class="w-2 h-4 bg-blue-400" />
75
+ <div class="ml-1 font-bold text-sm">{{ item.menuName }}</div>
76
+ </div>
77
+
78
+ <div class="pl-3 py-2">
79
+ <vxe-checkbox-group v-model="checkboxModel[item.id]" @change="onChange(item, $event)">
80
+ <vxe-checkbox
81
+ v-for="child in handleMenuCategoryGroup(item).menus"
82
+ :key="child.id"
83
+ :label="child.id"
84
+ :content="child.menuName"
85
+ />
86
+ </vxe-checkbox-group>
87
+ </div>
88
+ <div v-for="child in handleMenuCategoryGroup(item).folder" :key="child.id" class="child-node pl-3">
89
+ <div class="flex items-center">
90
+ <div class="w-2 h-4 bg-red-400" />
91
+ <div class="ml-1 font-bold text-sm">{{ child.menuName }}</div>
92
+ </div>
93
+
94
+ <div class="py-2">
95
+ <vxe-checkbox-group v-model="checkboxModel[child.id]" @change="onChange(item, $event)">
96
+ <vxe-checkbox
97
+ v-for="subChild in handleMenuCategoryGroup(child).menus"
98
+ :key="subChild.id"
99
+ :label="subChild.id"
100
+ :content="subChild.menuName"
101
+ />
102
+ </vxe-checkbox-group>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ </template>
109
+ </el-scrollbar>
110
+ </div>
111
+ </template>
112
+ <template #footer>
113
+ <div class="flex justify-end">
114
+ <ut-button content="cancel" status="warning" @tap="onClose" />
115
+ <ut-button content="confirm" @tap="onConfirm" />
116
+ </div>
117
+ </template>
118
+ </vxe-modal>
119
+ </template>
120
+ <script setup lang="ts">
121
+ import { ref, onMounted, nextTick } from 'vue';
122
+ import { clone, max } from 'xe-utils';
123
+ import { dbstorage, delay, warnMessage, successMessage } from '@utogether/utils';
124
+ import Draggable from 'vuedraggable';
125
+ import { getServiceApi } from '../../../api';
126
+
127
+ interface IProps {
128
+ dataSource: IRecord[];
129
+ icons: Array<String>;
130
+ userName: string;
131
+ }
132
+
133
+ const props = withDefaults(defineProps<IProps>(), {
134
+ dataSource: () => [],
135
+ icons: () => [],
136
+ userName: ''
137
+ });
138
+
139
+ // 用户菜单
140
+ const favoriteMenus = ref([]);
141
+ const menuList = ref([]);
142
+ const showModal = ref(false);
143
+ const loading = ref(false);
144
+ const checkboxModel = ref<IRecord>({});
145
+ // const cacheCheckModel = {}; // 缓存最初选中的数据
146
+
147
+ const url = '/upfm/v1/menuFavority';
148
+
149
+ const getCacheMenuList = async () => {
150
+ menuList.value = await dbstorage.getItem(`U-${props.userName}-ROUTES`);
151
+ menuList.value = menuList.value.filter(f => f.menuCode !== 'SysHome');
152
+ await delay(64);
153
+ setCheckboxedMenu();
154
+ };
155
+
156
+ /** 上部删除 */
157
+ const onRemoveFavorite = (item, idx) => {
158
+ favoriteMenus.value.splice(idx, 1);
159
+ const index = checkboxModel.value[item.parentId]?.findIndex(f => f === item.menuId);
160
+ checkboxModel.value[item.parentId].splice(index, 1);
161
+ // index = cacheCheckModel[item.parentId]?.findIndex(f => f.id === item.id);
162
+ // cacheCheckModel[item.parentId].splice(index, 1);
163
+ };
164
+
165
+ /** 菜单分组 */
166
+ const handleMenuCategoryGroup = data => {
167
+ const folder = [];
168
+ const menus = [];
169
+ data.children.forEach(e => {
170
+ if (['5', '100'].includes(e.menuCategory)) {
171
+ folder.push(e);
172
+ } else {
173
+ menus.push(e);
174
+ }
175
+ });
176
+ return { folder, menus };
177
+ };
178
+
179
+ /** 设置默认选中 */
180
+ const setCheckboxedMenu = () => {
181
+ props.dataSource.forEach(data => {
182
+ if (checkboxModel.value[data.parentId]) {
183
+ checkboxModel.value[data.parentId].push(data.menuId);
184
+ // cacheCheckModel[data.parentId].push(data);
185
+ } else {
186
+ checkboxModel.value[data.parentId] = [data.menuId];
187
+ // cacheCheckModel[data.parentId] = [data];
188
+ }
189
+ });
190
+ };
191
+ /** checkbox change */
192
+ const onChange = (menu, event) => {
193
+ if (event.checked) {
194
+ // 新增
195
+ if (favoriteMenus.value.length === 16) {
196
+ nextTick(() => {
197
+ checkboxModel.value[menu.id].splice(checkboxModel.value[menu.id].length - 1, 1);
198
+ });
199
+ return warnMessage('最多只能选择16个常用功能');
200
+ }
201
+ // const max = getMax();
202
+ // if (cacheCheckModel[menu.id]) {
203
+ // cacheCheckModel[menu.id].push({ id: event.label, seqNo: max + 10 });
204
+ // } else {
205
+ // cacheCheckModel[menu.id] = [{ id: event.label, seqNo: max + 10 }];
206
+ // }
207
+
208
+ const menuItem = menu.children.find(f => f.id === event.label);
209
+ if (menuItem) {
210
+ menuItem.seqNo = getMax() + 10;
211
+ menuItem.menuId = menuItem.id;
212
+ favoriteMenus.value.push(menuItem);
213
+ }
214
+ } else {
215
+ // 顶部删除
216
+ let idx = favoriteMenus.value.findIndex(f => f.menuId === event.label);
217
+ idx !== -1 && favoriteMenus.value.splice(idx, 1);
218
+ // checkbox删除
219
+ idx = checkboxModel.value[menu.id].findIndex(f => f === event.label);
220
+ idx !== -1 && checkboxModel.value[menu.id].splice(idx, 1);
221
+ // 缓存删除
222
+ // idx = cacheCheckModel[menu.id].findIndex(f => f.id === event.label);
223
+ // idx !== -1 && cacheCheckModel[menu.id].splice(idx, 1);
224
+ }
225
+ };
226
+ const onMoveEnd = () => {
227
+ favoriteMenus.value.forEach((item, idx) => {
228
+ item.seqNo = (idx + 1) * 10;
229
+ });
230
+ };
231
+ /** 获取排序最大值 */
232
+ const getMax = () => {
233
+ return max(favoriteMenus.value, item => item.seqNo)?.seqNo || 0;
234
+ };
235
+ const onConfirm = () => {
236
+ console.log(favoriteMenus);
237
+ const body = favoriteMenus.value.map(m => {
238
+ return {
239
+ userName: props.userName,
240
+ menuId: m.menuId,
241
+ seqNo: m.seqNo
242
+ };
243
+ });
244
+ console.log(body);
245
+ loading.value = true;
246
+ getServiceApi()
247
+ .post(url, body)
248
+ .then(() => {
249
+ successMessage();
250
+ onClose();
251
+ emit('success');
252
+ })
253
+ .finally(() => {
254
+ loading.value = false;
255
+ });
256
+ };
257
+
258
+ const onClose = () => {
259
+ showModal.value = false;
260
+ emit('close');
261
+ };
262
+
263
+ const getColor = idx => {
264
+ const colorSet = ['#409eff', '#67c23a', '#13c2c2', '#e85f33', 'orange'];
265
+ return colorSet[idx % 5];
266
+ };
267
+
268
+ const emit = defineEmits<{ (e: 'close'): void; (e: 'success'): void }>();
269
+
270
+ onMounted(() => {
271
+ favoriteMenus.value = clone(props.dataSource, true);
272
+ showModal.value = true;
273
+ getCacheMenuList();
274
+ });
275
+ </script>
276
+ <style lang="scss">
277
+ .u-favorite-modal {
278
+ .vxe-modal--body .vxe-modal--content {
279
+ padding: 0;
280
+ overflow: hidden !important;
281
+ }
282
+
283
+ .el-empty {
284
+ &__description {
285
+ margin-top: 10px;
286
+ }
287
+ }
288
+
289
+ .ut-menu-top-item:hover {
290
+ .ut-menu-del {
291
+ position: absolute;
292
+ display: inline-block;
293
+ color: rgb(240 94 94);
294
+ cursor: pointer;
295
+ }
296
+ }
297
+
298
+ .u-favorite-menu--contain {
299
+ height: calc(100vh - 320px);
300
+ }
301
+
302
+ .vxe-checkbox,
303
+ .vxe-checkbox + .vxe-checkbox {
304
+ width: 120px;
305
+ padding: 4px 0;
306
+ margin-right: 10px;
307
+ margin-left: 0;
308
+ }
309
+
310
+ .vxe-modal--footer {
311
+ border-top: 1px solid #e8e8e8;
312
+ }
313
+ }
314
+ </style>