@pubinfo/module-rbac 2.0.0-beta.3

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 (291) hide show
  1. package/package.json +53 -0
  2. package/src/api/modules/assist/gonggaofuwu.ts +109 -0
  3. package/src/api/modules/assist/index.ts +5 -0
  4. package/src/api/modules/assist/qunzujiekou.ts +95 -0
  5. package/src/api/modules/assist/quyujiekou.ts +97 -0
  6. package/src/api/modules/assist/typings.d.ts +364 -0
  7. package/src/api/modules/configData/heibaimingdanfuwu.ts +95 -0
  8. package/src/api/modules/configData/index.ts +5 -0
  9. package/src/api/modules/configData/typings.d.ts +347 -0
  10. package/src/api/modules/configData/xitongpeizhifuwu.ts +322 -0
  11. package/src/api/modules/configData/zidianfuwu.ts +151 -0
  12. package/src/api/modules/log/caozuorizhifuwu.ts +37 -0
  13. package/src/api/modules/log/denglurizhifuwu.ts +37 -0
  14. package/src/api/modules/log/index.ts +4 -0
  15. package/src/api/modules/log/typings.d.ts +179 -0
  16. package/src/api/modules/rbac/gangweijiekou.ts +93 -0
  17. package/src/api/modules/rbac/index.ts +13 -0
  18. package/src/api/modules/rbac/jiaosejiekou.ts +124 -0
  19. package/src/api/modules/rbac/pubJiaosezukongzhiqi.ts +113 -0
  20. package/src/api/modules/rbac/shujuquanxianzhubiaokongzhiqi.ts +186 -0
  21. package/src/api/modules/rbac/typings.d.ts +2001 -0
  22. package/src/api/modules/rbac/yonghujiekou.ts +225 -0
  23. package/src/api/modules/rbac/yonghushoucangbiaojiekou.ts +93 -0
  24. package/src/api/modules/rbac/yonghuzuijinchangyongbiaojiekou.ts +72 -0
  25. package/src/api/modules/rbac/ziyuanjiekou.ts +223 -0
  26. package/src/api/modules/rbac/zuhuguanlijiekou.ts +91 -0
  27. package/src/api/modules/rbac/zuzhijiaosebiaokongzhiqi.ts +76 -0
  28. package/src/api/modules/rbac/zuzhijiekou.ts +171 -0
  29. package/src/api/request.ts +3 -0
  30. package/src/assets/icons/403.svg +1 -0
  31. package/src/assets/icons/403_dark.svg +1 -0
  32. package/src/assets/icons/404.svg +1 -0
  33. package/src/assets/icons/404_dark.svg +1 -0
  34. package/src/assets/icons/add-child.svg +1 -0
  35. package/src/assets/icons/authority.svg +1 -0
  36. package/src/assets/icons/authorize.svg +1 -0
  37. package/src/assets/icons/blacklist-disable.svg +1 -0
  38. package/src/assets/icons/blacklist-enable.svg +1 -0
  39. package/src/assets/icons/browser-360.svg +1 -0
  40. package/src/assets/icons/browser-chrome.svg +1 -0
  41. package/src/assets/icons/browser-edge.svg +1 -0
  42. package/src/assets/icons/browser-ie.svg +1 -0
  43. package/src/assets/icons/browser-other.svg +1 -0
  44. package/src/assets/icons/browser-qq.svg +1 -0
  45. package/src/assets/icons/browser-safari.svg +1 -0
  46. package/src/assets/icons/browser-uc.svg +1 -0
  47. package/src/assets/icons/change-org.svg +1 -0
  48. package/src/assets/icons/edit.svg +1 -0
  49. package/src/assets/icons/empty-data.svg +1 -0
  50. package/src/assets/icons/favorites.svg +1 -0
  51. package/src/assets/icons/icard.svg +1 -0
  52. package/src/assets/icons/icon_animation.svg +1 -0
  53. package/src/assets/icons/icon_breadcrumb.svg +1 -0
  54. package/src/assets/icons/icon_copyright.svg +1 -0
  55. package/src/assets/icons/icon_jt.svg +1 -0
  56. package/src/assets/icons/icon_layout.svg +1 -0
  57. package/src/assets/icons/icon_mainpage.svg +1 -0
  58. package/src/assets/icons/icon_menu.svg +1 -0
  59. package/src/assets/icons/icon_page_size.svg +1 -0
  60. package/src/assets/icons/icon_position_type.svg +1 -0
  61. package/src/assets/icons/icon_safe_manage.svg +1 -0
  62. package/src/assets/icons/icon_screen_scale.svg +6 -0
  63. package/src/assets/icons/icon_system_manage.svg +1 -0
  64. package/src/assets/icons/icon_tabbar.svg +1 -0
  65. package/src/assets/icons/icon_toolbar.svg +1 -0
  66. package/src/assets/icons/icon_topbar.svg +1 -0
  67. package/src/assets/icons/icon_watermark.svg +1 -0
  68. package/src/assets/icons/image-load-fail.svg +1 -0
  69. package/src/assets/icons/log-center.svg +1 -0
  70. package/src/assets/icons/logo-sig.svg +1 -0
  71. package/src/assets/icons/logo.svg +1 -0
  72. package/src/assets/icons/mima.svg +1 -0
  73. package/src/assets/icons/not-data.svg +1 -0
  74. package/src/assets/icons/org-main.svg +1 -0
  75. package/src/assets/icons/org-unmain.svg +1 -0
  76. package/src/assets/icons/process-management.svg +1 -0
  77. package/src/assets/icons/project-management.svg +1 -0
  78. package/src/assets/icons/rbac.svg +1 -0
  79. package/src/assets/icons/remove.svg +1 -0
  80. package/src/assets/icons/resource-app.svg +1 -0
  81. package/src/assets/icons/resource-btn.svg +1 -0
  82. package/src/assets/icons/resource-index.svg +1 -0
  83. package/src/assets/icons/resource-menu.svg +1 -0
  84. package/src/assets/icons/resource-nonmenu.svg +1 -0
  85. package/src/assets/icons/setting-manage.svg +1 -0
  86. package/src/assets/icons/test.svg +1 -0
  87. package/src/assets/icons/theme-check-mark.svg +1 -0
  88. package/src/assets/icons/theme-title.svg +1 -0
  89. package/src/assets/icons/toolbar-collapse.svg +1 -0
  90. package/src/assets/icons/tree_icon.svg +1 -0
  91. package/src/assets/icons/tree_icon_checked.svg +1 -0
  92. package/src/assets/icons/view.svg +1 -0
  93. package/src/assets/icons/workbench.svg +1 -0
  94. package/src/assets/icons/zddata.svg +1 -0
  95. package/src/assets/icons/zy_checked.svg +1 -0
  96. package/src/assets/icons/zy_default.svg +1 -0
  97. package/src/assets/images/layout/item1.webp +0 -0
  98. package/src/assets/images/layout/item1_dark.webp +0 -0
  99. package/src/assets/images/layout/item2.webp +0 -0
  100. package/src/assets/images/layout/item2_dark.webp +0 -0
  101. package/src/assets/images/layout/item3.webp +0 -0
  102. package/src/assets/images/layout/item3_dark.webp +0 -0
  103. package/src/assets/images/layout/item4.webp +0 -0
  104. package/src/assets/images/layout/item4_dark.webp +0 -0
  105. package/src/assets/images/layout/item5.webp +0 -0
  106. package/src/assets/images/layout/item5_dark.webp +0 -0
  107. package/src/assets/images/page-width/anto_min_w_dark.webp +0 -0
  108. package/src/assets/images/page-width/auto.webp +0 -0
  109. package/src/assets/images/page-width/auto_dark.webp +0 -0
  110. package/src/assets/images/page-width/auto_min_w.webp +0 -0
  111. package/src/assets/images/page-width/auto_min_w_dark.webp +0 -0
  112. package/src/assets/images/page-width/icon_auto.webp +0 -0
  113. package/src/assets/images/page-width/icon_auto_dark.webp +0 -0
  114. package/src/assets/images/page-width/icon_auto_min_w.webp +0 -0
  115. package/src/assets/images/page-width/icon_auto_min_w_dark.webp +0 -0
  116. package/src/assets/images/page-width/icon_middle.webp +0 -0
  117. package/src/assets/images/page-width/icon_middle_dark.webp +0 -0
  118. package/src/assets/images/page-width/icon_middle_max_w.webp +0 -0
  119. package/src/assets/images/page-width/icon_middle_max_w_dark.webp +0 -0
  120. package/src/assets/images/page-width/middle.webp +0 -0
  121. package/src/assets/images/page-width/middle_dark.webp +0 -0
  122. package/src/assets/images/page-width/middle_max_w.webp +0 -0
  123. package/src/assets/images/page-width/middle_max_w_dark.webp +0 -0
  124. package/src/assets/lottie/breadcrumb/dark/enable.json +1 -0
  125. package/src/assets/lottie/breadcrumb/dark/enableMainMenu.json +1 -0
  126. package/src/assets/lottie/breadcrumb/dark/style.json +1 -0
  127. package/src/assets/lottie/breadcrumb/light/enable.json +1 -0
  128. package/src/assets/lottie/breadcrumb/light/enableMainMenu.json +1 -0
  129. package/src/assets/lottie/breadcrumb/light/style.json +1 -0
  130. package/src/assets/lottie/layout/data-test.json +1 -0
  131. package/src/assets/lottie/layout/data.json +1 -0
  132. package/src/assets/lottie/menu/dark/enableHotkeys.json +1 -0
  133. package/src/assets/lottie/menu/dark/enableSubMenuCollapseButton.json +1 -0
  134. package/src/assets/lottie/menu/dark/isRounded.json +1 -0
  135. package/src/assets/lottie/menu/dark/menuActiveStyle.json +1 -0
  136. package/src/assets/lottie/menu/dark/subMenuCollapse.json +1 -0
  137. package/src/assets/lottie/menu/dark/subMenuUniqueOpened.json +1 -0
  138. package/src/assets/lottie/menu/light/enableHotkeys.json +1 -0
  139. package/src/assets/lottie/menu/light/enableSubMenuCollapseButton.json +1 -0
  140. package/src/assets/lottie/menu/light/isRounded.json +1 -0
  141. package/src/assets/lottie/menu/light/menuActiveStyle.json +1 -0
  142. package/src/assets/lottie/menu/light/subMenuCollapse.json +1 -0
  143. package/src/assets/lottie/menu/light/subMenuUniqueOpened.json +1 -0
  144. package/src/assets/lottie/other/dark/enableCopyright.json +1 -0
  145. package/src/assets/lottie/other/dark/enableHotkeys.json +1 -0
  146. package/src/assets/lottie/other/dark/switchTabbarAndToolbar.json +1 -0
  147. package/src/assets/lottie/other/light/enableCopyright.json +1 -0
  148. package/src/assets/lottie/other/light/enableHotkeys.json +1 -0
  149. package/src/assets/lottie/other/light/switchTabbarAndToolbar.json +1 -0
  150. package/src/assets/lottie/page_animation/dark/fadeinout.json +1 -0
  151. package/src/assets/lottie/page_animation/dark/fadeinout_old.json +1 -0
  152. package/src/assets/lottie/page_animation/dark/tobottom.json +1 -0
  153. package/src/assets/lottie/page_animation/dark/tobottom_old.json +1 -0
  154. package/src/assets/lottie/page_animation/dark/toleft.json +1 -0
  155. package/src/assets/lottie/page_animation/dark/toleft_old.json +1 -0
  156. package/src/assets/lottie/page_animation/dark/toright.json +1 -0
  157. package/src/assets/lottie/page_animation/dark/toright_old.json +1 -0
  158. package/src/assets/lottie/page_animation/dark/totop.json +1 -0
  159. package/src/assets/lottie/page_animation/dark/totop_old.json +1 -0
  160. package/src/assets/lottie/page_animation/light/fadeinout.json +1 -0
  161. package/src/assets/lottie/page_animation/light/tobottom.json +1 -0
  162. package/src/assets/lottie/page_animation/light/toleft.json +1 -0
  163. package/src/assets/lottie/page_animation/light/toright.json +1 -0
  164. package/src/assets/lottie/page_animation/light/totop.json +1 -0
  165. package/src/assets/lottie/tabbar/dark/enable.json +1 -0
  166. package/src/assets/lottie/tabbar/dark/enableHotkeys.json +1 -0
  167. package/src/assets/lottie/tabbar/dark/enableIcon.json +1 -0
  168. package/src/assets/lottie/tabbar/dark/enableMemory.json +1 -0
  169. package/src/assets/lottie/tabbar/dark/style.json +1 -0
  170. package/src/assets/lottie/tabbar/light/enable.json +1 -0
  171. package/src/assets/lottie/tabbar/light/enableHotkeys.json +1 -0
  172. package/src/assets/lottie/tabbar/light/enableIcon.json +1 -0
  173. package/src/assets/lottie/tabbar/light/enableMemory.json +1 -0
  174. package/src/assets/lottie/tabbar/light/style.json +1 -0
  175. package/src/assets/lottie/toolbar/dark/enableColorScheme.json +1 -0
  176. package/src/assets/lottie/toolbar/dark/enableFullscreen.json +1 -0
  177. package/src/assets/lottie/toolbar/dark/enableI18n.json +1 -0
  178. package/src/assets/lottie/toolbar/dark/enableNotification.json +1 -0
  179. package/src/assets/lottie/toolbar/dark/enablePageReload.json +1 -0
  180. package/src/assets/lottie/toolbar/dark/enableUserPreferences.json +1 -0
  181. package/src/assets/lottie/toolbar/dark/navSearchEnable.json +1 -0
  182. package/src/assets/lottie/toolbar/dark/navSearchEnableHotkeys.json +1 -0
  183. package/src/assets/lottie/toolbar/light/enableColorScheme.json +1 -0
  184. package/src/assets/lottie/toolbar/light/enableFullscreen.json +1 -0
  185. package/src/assets/lottie/toolbar/light/enableI18n.json +1 -0
  186. package/src/assets/lottie/toolbar/light/enableNotification.json +1 -0
  187. package/src/assets/lottie/toolbar/light/enablePageReload.json +1 -0
  188. package/src/assets/lottie/toolbar/light/enableUserPreferences.json +1 -0
  189. package/src/assets/lottie/toolbar/light/navSearchEnable.json +1 -0
  190. package/src/assets/lottie/toolbar/light/navSearchEnableHotkeys.json +1 -0
  191. package/src/assets/lottie/watermark/dark/enableWatermark.json +1 -0
  192. package/src/assets/lottie/watermark/light/enableWatermark.json +1 -0
  193. package/src/assets/styles/vxe-table.css +13 -0
  194. package/src/components/GroupSelector/index.vue +311 -0
  195. package/src/components/OrgTree/index.vue +91 -0
  196. package/src/components/OrgUserSelector/OrgSelector.vue +135 -0
  197. package/src/components/OrgUserSelector/UserSelector.vue +164 -0
  198. package/src/components/OrgUserSelector/index.ts +47 -0
  199. package/src/components/OrgUserSelector/provider.ts +373 -0
  200. package/src/components/ResourceSelector/enum.ts +5 -0
  201. package/src/components/ResourceSelector/hooks/useAppAndResource.ts +96 -0
  202. package/src/components/ResourceSelector/index.vue +432 -0
  203. package/src/composables/useLottie.ts +65 -0
  204. package/src/index.ts +31 -0
  205. package/src/interface.ts +54 -0
  206. package/src/routes/index.ts +156 -0
  207. package/src/routes/modules/authority.manage.menu.ts +105 -0
  208. package/src/routes/modules/log.manage.menu.ts +45 -0
  209. package/src/routes/modules/safe.manage.menu.ts +71 -0
  210. package/src/routes/modules/stylesetting.manage.menu.ts +130 -0
  211. package/src/routes/modules/system.manage.menu.ts +92 -0
  212. package/src/stores/index.ts +1 -0
  213. package/src/views/blackWhiteList/components/drawerBlackWhiteList.vue +132 -0
  214. package/src/views/blackWhiteList/enum.ts +7 -0
  215. package/src/views/blackWhiteList/index.vue +309 -0
  216. package/src/views/blackWhiteList/types.ts +4 -0
  217. package/src/views/breadcrumb_setting/animationData.ts +15 -0
  218. package/src/views/breadcrumb_setting/index.vue +147 -0
  219. package/src/views/components/HCheckList.vue +47 -0
  220. package/src/views/components/animation_item.vue +37 -0
  221. package/src/views/components/setItem.vue +126 -0
  222. package/src/views/data-permission/components/createAndEditDataPermission.vue +354 -0
  223. package/src/views/data-permission/enum.ts +59 -0
  224. package/src/views/data-permission/index.vue +190 -0
  225. package/src/views/dictionary/components/drawerDictionary.vue +108 -0
  226. package/src/views/dictionary/components/drawerDictionaryItem.vue +115 -0
  227. package/src/views/dictionary/enum.ts +8 -0
  228. package/src/views/dictionary/index.vue +194 -0
  229. package/src/views/dictionary/itemlist.vue +164 -0
  230. package/src/views/group/components/drawerGroup.vue +177 -0
  231. package/src/views/group/enum.ts +25 -0
  232. package/src/views/group/index.vue +207 -0
  233. package/src/views/layout_setting/index.vue +306 -0
  234. package/src/views/log_center/components/browserType.vue +35 -0
  235. package/src/views/log_center/components/loginHistoryDetail.vue +71 -0
  236. package/src/views/log_center/components/operateHistoryDetail.vue +80 -0
  237. package/src/views/log_center/login_history.vue +239 -0
  238. package/src/views/log_center/operate_history.vue +233 -0
  239. package/src/views/menu_setting/animationData.ts +27 -0
  240. package/src/views/menu_setting/index.vue +207 -0
  241. package/src/views/organization/components/drawerOrganization.vue +161 -0
  242. package/src/views/organization/components/drawerRole.vue +159 -0
  243. package/src/views/organization/components/roleSelect.vue +258 -0
  244. package/src/views/organization/enum.ts +26 -0
  245. package/src/views/organization/index.vue +516 -0
  246. package/src/views/other_setting/animationData.ts +15 -0
  247. package/src/views/other_setting/index.vue +250 -0
  248. package/src/views/other_setting/interface.ts +26 -0
  249. package/src/views/page_animation_setting/animationData.ts +23 -0
  250. package/src/views/page_animation_setting/index.vue +200 -0
  251. package/src/views/page_w_setting/index.vue +238 -0
  252. package/src/views/position/components/drawerPosition.vue +131 -0
  253. package/src/views/position/enum.ts +8 -0
  254. package/src/views/position/index.vue +167 -0
  255. package/src/views/region/components/drawerRegion.vue +143 -0
  256. package/src/views/region/enum.ts +24 -0
  257. package/src/views/region/index.vue +246 -0
  258. package/src/views/resource/components/ResourceEdit.vue +209 -0
  259. package/src/views/resource/components/RoleRelation.vue +100 -0
  260. package/src/views/resource/enum.ts +35 -0
  261. package/src/views/resource/index.vue +237 -0
  262. package/src/views/resource/interface.ts +6 -0
  263. package/src/views/role/components/ResourceRelation.vue +113 -0
  264. package/src/views/role/components/drawerRole.vue +191 -0
  265. package/src/views/role/enum.ts +26 -0
  266. package/src/views/role/index.vue +183 -0
  267. package/src/views/role/interface.ts +6 -0
  268. package/src/views/role_group/components/ResourceRelation.vue +91 -0
  269. package/src/views/role_group/components/drawerRole.vue +153 -0
  270. package/src/views/role_group/components/roleSelect.vue +224 -0
  271. package/src/views/role_group/enum.ts +22 -0
  272. package/src/views/role_group/index.vue +170 -0
  273. package/src/views/role_group/interface.ts +6 -0
  274. package/src/views/safe_setting/index.vue +237 -0
  275. package/src/views/tabbar_setting/animationData.ts +23 -0
  276. package/src/views/tabbar_setting/index.vue +186 -0
  277. package/src/views/tenant/components/TenantEdit.vue +226 -0
  278. package/src/views/tenant/index.vue +192 -0
  279. package/src/views/tenant/interface.ts +4 -0
  280. package/src/views/theme_setting/index.vue +465 -0
  281. package/src/views/toolbar_setting/animationData.ts +42 -0
  282. package/src/views/toolbar_setting/index.vue +189 -0
  283. package/src/views/user/components/OrgAndPosition.vue +156 -0
  284. package/src/views/user/components/UserAuthorization.vue +260 -0
  285. package/src/views/user/components/UserEdit.vue +267 -0
  286. package/src/views/user/components/roleSelect.vue +258 -0
  287. package/src/views/user/enum.ts +13 -0
  288. package/src/views/user/index.vue +266 -0
  289. package/src/views/user/interface.ts +43 -0
  290. package/src/views/watermark_setting/animationData.ts +7 -0
  291. package/src/views/watermark_setting/index.vue +236 -0
@@ -0,0 +1,432 @@
1
+ <script setup lang="ts">
2
+ import type { EventDataNode, TreeProps } from 'ant-design-vue/es/tree';
3
+ import type { Key } from 'ant-design-vue/es/vc-tree/interface.d';
4
+ import type { CheckInfo } from 'ant-design-vue/es/vc-tree/props';
5
+ import type { ResourceMode } from './enum';
6
+ import { useToggle } from '@vueuse/core';
7
+ import { Form } from 'ant-design-vue';
8
+ import { RESOURCE_MODE } from './enum';
9
+
10
+ defineOptions({
11
+ name: 'ResourceSelector',
12
+ });
13
+
14
+ const props = withDefaults(defineProps<{
15
+ title?: string
16
+ mode?: ResourceMode
17
+ }>(), {
18
+ title: '资源选择',
19
+ mode: RESOURCE_MODE.ROLE,
20
+ });
21
+
22
+ const emit = defineEmits(['select']);
23
+
24
+ const isDataPermissionMode = computed(() => props.mode === RESOURCE_MODE.DATA_PERMISSION);
25
+
26
+ interface StringMap<T> { [key: string]: T };
27
+
28
+ type TreeNode = API.PubResource & {
29
+ children?: TreeNode[]
30
+ };
31
+ interface ReInfo {
32
+ id: string
33
+ name: string
34
+ }
35
+ interface CheckedKeys {
36
+ checked: Key[]
37
+ halfChecked: Key[]
38
+ }
39
+ const checkedKeys: Ref<CheckedKeys> = ref({ checked: [], halfChecked: [] });
40
+ const expandedKeys = ref<string[]>([]);
41
+ const rightItems: Ref<ReInfo[]> = ref([]);
42
+ const resourceMap: Ref<StringMap<string>> = ref({});
43
+ const resourceCount: Ref<number> = ref(0);
44
+ const treeData = ref<TreeProps['treeData'] & TreeNode[]>([]);
45
+
46
+ const open = defineModel<boolean>('open');
47
+
48
+ const setOpen = useToggle(open);
49
+
50
+ watch(() => checkedKeys.value.checked, (val) => {
51
+ rightItems.value = val.reduce((acc: ReInfo[], item) => {
52
+ const temp = {
53
+ id: item as string,
54
+ name: resourceMap.value[item],
55
+ };
56
+ acc.push(temp);
57
+ return acc;
58
+ }, []);
59
+ }, { deep: true });
60
+
61
+ function onOpen(ids: Key[], tree: any[], resMap: StringMap<string>) {
62
+ checkedKeys.value.checked = [...ids];
63
+ treeData.value = tree;
64
+ resourceMap.value = resMap;
65
+ resourceCount.value = Object.keys(resourceMap.value).length;
66
+
67
+ // 默认展开第一级
68
+ if (tree[0]?.id) {
69
+ expandedKeys.value = [tree[0]?.id];
70
+ }
71
+ setOpen(true);
72
+ }
73
+
74
+ function onCheck(node: Key[] | CheckedKeys, e: CheckInfo) {
75
+ // 数据权限模式时, 采用check-strictly=true时的默认值,即:只勾选/反选被点击的节点
76
+ if (isDataPermissionMode.value) {
77
+ return;
78
+ }
79
+
80
+ /*
81
+ 角色模式时:
82
+ 1.勾选:勾选节点时,同时勾选其所有祖先节点;
83
+ 2.反选:反选节点时,同时反选其所有子节点,不动祖先节点。
84
+ */
85
+ if (e.checked) {
86
+ function getParents(obj: any) {
87
+ if (obj.parent) {
88
+ checkedKeys.value.checked.push(obj.key);
89
+ getParents(obj.parent);
90
+ }
91
+ else {
92
+ checkedKeys.value.checked.push(obj.key);
93
+ }
94
+ }
95
+ getParents(e.node);
96
+ }
97
+ else {
98
+ const childKeys = getAllDescendantIds([e.node], e.node.id);
99
+ childKeys.forEach((delkey) => {
100
+ const index = checkedKeys.value.checked.findIndex(item => item === delkey);
101
+ if (index >= 0) {
102
+ checkedKeys.value.checked.splice(index, 1);
103
+ }
104
+ });
105
+ }
106
+ checkedKeys.value.checked = Array.from(new Set(checkedKeys.value.checked));
107
+ }
108
+
109
+ function clearAllChecked() {
110
+ checkedKeys.value.checked = [];
111
+ }
112
+
113
+ function handleCloseTag(removedTagId: string) {
114
+ const allDeleteIds = getAllDescendantIds(treeData.value, removedTagId);
115
+ allDeleteIds.forEach((delkey) => {
116
+ const index = checkedKeys.value.checked.findIndex(item => item === delkey);
117
+ if (index >= 0) {
118
+ checkedKeys.value.checked.splice(index, 1);
119
+ }
120
+ });
121
+ }
122
+
123
+ /** 获取该节点信息 */
124
+ function getNodeById(nodes: any, id: string): TreeNode | undefined {
125
+ for (const node of nodes) {
126
+ if (node.id === id) {
127
+ return node;
128
+ }
129
+ if (node.children) {
130
+ const foundNode = getNodeById(node.children, id);
131
+ if (foundNode) {
132
+ return foundNode;
133
+ }
134
+ }
135
+ }
136
+ return undefined;
137
+ }
138
+
139
+ /** 获取该节点下所有子节点的ID(包括该节点) */
140
+ function getAllDescendantIds(nodes: any, targetNodeId: string): string[] {
141
+ const result: string[] = [];
142
+ const targetNode = getNodeById(nodes, targetNodeId);
143
+ if (targetNode) {
144
+ function dfs(node: TreeNode): void {
145
+ result.push(node.id as string);
146
+ if (node.children) {
147
+ for (const child of node.children) {
148
+ dfs(child);
149
+ }
150
+ }
151
+ }
152
+
153
+ dfs(targetNode);
154
+ }
155
+
156
+ return result;
157
+ }
158
+
159
+ function checkAllChildren(record: EventDataNode) {
160
+ const data: string[] = getAllChildren(record.id);
161
+ // 如果有子节点需要选中,那么当前节点一定选中
162
+ if (data.length > 0) {
163
+ data.push(record.id);
164
+ data.forEach((item) => {
165
+ const itemIndex = checkedKeys.value.checked.findIndex(ckey => ckey === item);
166
+ if (itemIndex < 0) {
167
+ checkedKeys.value.checked.push(item);
168
+ }
169
+ });
170
+ }
171
+ }
172
+
173
+ function clearAllChildren(record: EventDataNode) {
174
+ const data: string[] = getAllChildren(record.id);
175
+ data.forEach((item) => {
176
+ const itemIndex = checkedKeys.value.checked.findIndex(ckey => ckey === item);
177
+ if (itemIndex >= 0) {
178
+ checkedKeys.value.checked.splice(itemIndex, 1);
179
+ }
180
+ });
181
+ }
182
+
183
+ function checkNextChildren(record: EventDataNode) {
184
+ const data: string[] = getNextChildren(record.id);
185
+ // 如果有子节点需要选中,那么当前节点一定选中
186
+ if (data.length > 0) {
187
+ data.push(record.id);
188
+ data.forEach((item) => {
189
+ const itemIndex = checkedKeys.value.checked.findIndex(ckey => ckey === item);
190
+ if (itemIndex < 0) {
191
+ checkedKeys.value.checked.push(item);
192
+ }
193
+ });
194
+ }
195
+ }
196
+
197
+ function clearNextChildren(record: EventDataNode) {
198
+ const data: string[] = getNextChildren(record.id);
199
+ data.forEach((item) => {
200
+ const itemIndex = checkedKeys.value.checked.findIndex(ckey => ckey === item);
201
+ if (itemIndex >= 0) {
202
+ checkedKeys.value.checked.splice(itemIndex, 1);
203
+ }
204
+ });
205
+ }
206
+
207
+ function getNextChildren(id: string) {
208
+ const targetNode = getNodeById(treeData.value, id);
209
+ if (targetNode && targetNode.children && targetNode.children.length > 0) {
210
+ return targetNode.children.reduce((acc: string[], item) => {
211
+ // 不勾选禁用的节点
212
+ if (isDataPermissionMode.value && (item as any)?.disabled) {
213
+ return acc;
214
+ }
215
+
216
+ acc.push(item.id!);
217
+ return acc;
218
+ }, []);
219
+ }
220
+ else {
221
+ return [];
222
+ }
223
+ }
224
+
225
+ function getAllChildren(id: string) {
226
+ const data: string[] = getAllDescendantIds(treeData.value, id);
227
+ const index = data.indexOf(id);
228
+ data.splice(index, 1);
229
+
230
+ // 不勾选禁用的节点
231
+ return data
232
+ ?.map(id => getNodeById(treeData.value, id))
233
+ ?.filter(item => isDataPermissionMode.value ? !(item as any).disabled : true)
234
+ ?.map(item => item!.id as string);
235
+ }
236
+
237
+ const { onFieldChange } = Form.useInjectFormItemContext();
238
+ function notifySelect() {
239
+ emit('select', rightItems.value);
240
+ onFieldChange();
241
+ setOpen(false);
242
+ }
243
+
244
+ defineExpose({
245
+ open: onOpen,
246
+ });
247
+ </script>
248
+
249
+ <template>
250
+ <a-modal
251
+ v-model:open="open"
252
+ class="custom_modal"
253
+ :title="title"
254
+ :mask-closable="false"
255
+ :width="750"
256
+ >
257
+ <div class="h-340px border-1px border-solid flex flex-row border_color">
258
+ <div class="w-360px flex flex-col">
259
+ <div class="w-full h-34px bg-[#F2F3F5] flex px-15px items-center justify-between text-[#1D2129] dark:bg-[#1D2129] dark:text-[#F2F3F5]">
260
+ <div class="">
261
+ 全部资源
262
+ </div>
263
+ <div>{{ checkedKeys.checked.length }}/{{ resourceCount }}</div>
264
+ </div>
265
+ <div class="flex-1 overflow-auto py-10px pr-10px">
266
+ <a-tree
267
+ v-model:checked-keys="checkedKeys"
268
+ v-model:expanded-keys="expandedKeys"
269
+ class="h-full custom_tree"
270
+ block-node
271
+ checkable
272
+ check-strictly
273
+ :field-names="{ children: 'children', title: 'name', key: 'id' }"
274
+ :tree-data="treeData"
275
+ @check="onCheck"
276
+ >
277
+ <template #title="record">
278
+ <div class="flex items-center">
279
+ <PubinfoIcon v-if="record.checked" name="zy_checked" size="24px" />
280
+ <PubinfoIcon v-else name="zy_default" size="24px" />
281
+ <span class="mx-4px">
282
+ {{ record.name }}
283
+ </span>
284
+ <!-- "操作"功能显示逻辑:角色模式下非叶子节点时显示; 数据权限模式下非叶子节点 且 数据disabled字段不为true时显示 -->
285
+ <a-dropdown v-if="!record.leaf && (!isDataPermissionMode || !record.disabled)" class="bg-[#e8f3ff] dark:bg-[#141414]" :trigger="['click']">
286
+ <a class="ant-dropdown-link whitespace-nowrap" style="padding: 2px 4px;" @click.prevent>
287
+ <span class="text-base">操作</span>
288
+ <DownOutlined :style="{ fontSize: '10px' }" />
289
+ </a>
290
+ <template #overlay>
291
+ <a-menu>
292
+ <a-menu-item key="0">
293
+ <a @click="checkAllChildren(record)">选中所有下级</a>
294
+ </a-menu-item>
295
+ <a-menu-item key="1">
296
+ <a @click="clearAllChildren(record)">取消所有下级</a>
297
+ </a-menu-item>
298
+ <a-menu-item key="3">
299
+ <a @click="checkNextChildren(record)">选中下一级</a>
300
+ </a-menu-item>
301
+ <a-menu-item key="4">
302
+ <a @click="clearNextChildren(record)">取消下一级</a>
303
+ </a-menu-item>
304
+ </a-menu>
305
+ </template>
306
+ </a-dropdown>
307
+ </div>
308
+ </template>
309
+ </a-tree>
310
+ </div>
311
+ </div>
312
+
313
+ <div class="flex-1 flex flex-col border-solid border-0px border-l-1px border_color">
314
+ <div class="w-full h-34px bg-[#F2F3F5] flex px-15px items-center justify-between text-[#1D2129] dark:bg-[#1D2129] dark:text-[#F2F3F5]">
315
+ <div class="">
316
+ 已选资源
317
+ </div>
318
+ <div class="cursor-pointer text-[#165DFF]" @click="clearAllChecked">
319
+ 清空
320
+ </div>
321
+ </div>
322
+ <div class="flex-1 p-10px overflow-auto">
323
+ <div v-for="item in rightItems" :key="item.id" class="inline-block mb-6px max-w-300px">
324
+ <a-tooltip v-if="item.name?.length > 20" :title="item.name">
325
+ <a-tag class="custom_tag bg-[#e8f3ff] dark:bg-[#141414]" closable @close="handleCloseTag(item.id)">
326
+ {{ `${item.name?.slice(0, 20)}...` }}
327
+ </a-tag>
328
+ </a-tooltip>
329
+ <a-tag
330
+ v-else
331
+ class="custom_tag bg-[#e8f3ff] dark:bg-[#141414]"
332
+ closable
333
+ @close="handleCloseTag(item.id)"
334
+ >
335
+ {{ item.name }}
336
+ </a-tag>
337
+ </div>
338
+ </div>
339
+ </div>
340
+ </div>
341
+
342
+ <template #footer>
343
+ <a-button @click="setOpen(false)">
344
+ 取消
345
+ </a-button>
346
+ <a-button type="primary" @click="notifySelect">
347
+ 确定
348
+ </a-button>
349
+ </template>
350
+ </a-modal>
351
+ </template>
352
+
353
+ <style lang="scss" scoped>
354
+ .border_color {
355
+ border-color: #e5e6eb;
356
+ }
357
+
358
+ [data-theme="dark"] {
359
+ .border_color {
360
+ border-color: rgb(253 253 253 / 12%);
361
+ }
362
+ }
363
+
364
+ .border_c {
365
+ border: 1px dashed #ccc;
366
+ border-radius: 10px;
367
+ }
368
+
369
+ :deep(.ant-dropdown-link) {
370
+ padding: 4px 6px;
371
+ font-size: 12px;
372
+ border-radius: 2px;
373
+ transform: scale(0.7);
374
+ }
375
+ </style>
376
+
377
+ <style lang='scss' scoped>
378
+ .custom_modal {
379
+ :deep(.ant-modal-content) {
380
+ padding: 0;
381
+ border-radius: 0;
382
+ }
383
+
384
+ :deep(.ant-modal-header) {
385
+ padding: 12px 16px;
386
+ margin-bottom: 0;
387
+ border-bottom: 1px solid #e5e6eb;
388
+ }
389
+
390
+ :deep(.ant-modal-title) {
391
+ font-size: 16px;
392
+ font-weight: 500;
393
+ color: #1d2129;
394
+ }
395
+
396
+ :deep(.ant-modal-body) {
397
+ padding: 16px;
398
+ }
399
+
400
+ :deep(.ant-modal-footer) {
401
+ padding: 16px;
402
+ border-top: 1px solid #e5e6eb;
403
+
404
+ .ant-btn {
405
+ border-radius: 2px;
406
+ }
407
+ }
408
+ }
409
+
410
+ :deep(.ant-tree-checkbox) {
411
+ margin-block-start: 0;
412
+ margin-inline-end: 2px;
413
+ }
414
+
415
+ :deep(.ant-tree-checkbox + span .ant-tree-iconEle) {
416
+ margin-right: 4px;
417
+ }
418
+
419
+ .custom_tag {
420
+ padding: 3px 8px;
421
+ border-width: 0;
422
+ border-radius: 2px;
423
+
424
+ :deep(.ant-tag-close-icon) {
425
+ color: rgb(22 93 255 / 60%);
426
+
427
+ &:hover {
428
+ color: #165dff;
429
+ }
430
+ }
431
+ }
432
+ </style>
@@ -0,0 +1,65 @@
1
+ import type { AnimationItem } from 'lottie-web';
2
+ import type { MaybeRef } from 'vue';
3
+ import { tryOnMounted } from '@vueuse/core';
4
+ import lottie from 'lottie-web/build/player/lottie_light';
5
+ import { useTheme } from 'pubinfo';
6
+ import { onMounted, onUnmounted } from 'vue';
7
+
8
+ interface Path {
9
+ lightAnimationData: any
10
+ darkAnimationData: any
11
+ }
12
+
13
+ export function useLottie(DomRef: MaybeRef<Element | null>, themePath: Path) {
14
+ let anim: AnimationItem | null;
15
+
16
+ function create() {
17
+ const { isDark } = useTheme();
18
+ const animationPath = computed(() => {
19
+ return isDark.value ? themePath.darkAnimationData : themePath.lightAnimationData;
20
+ });
21
+ onMounted(() => {
22
+ createLottie(animationPath.value);
23
+ watch(isDark, () => {
24
+ destroy();
25
+ createLottie(animationPath.value);
26
+ });
27
+ });
28
+ onUnmounted(destroy);
29
+ }
30
+
31
+ function createLottie(animationPath: string) {
32
+ const container = unref(DomRef)!;
33
+ anim = lottie.loadAnimation({
34
+ path: animationPath,
35
+ container,
36
+ renderer: 'svg',
37
+ loop: true,
38
+ autoplay: false,
39
+ // animationData,
40
+ });
41
+ }
42
+
43
+ function play() {
44
+ tryOnMounted(() => {
45
+ anim?.play();
46
+ });
47
+ }
48
+
49
+ function stop() {
50
+ tryOnMounted(() => {
51
+ anim?.stop();
52
+ });
53
+ }
54
+
55
+ function destroy() {
56
+ if (anim) {
57
+ anim.destroy();
58
+ anim = null;
59
+ }
60
+ }
61
+
62
+ create();
63
+
64
+ return { play, stop, destroy };
65
+ }
package/src/index.ts ADDED
@@ -0,0 +1,31 @@
1
+ import type { ModuleOptions } from 'pubinfo';
2
+ import type { RbacOptions } from './interface';
3
+ import { defineAsyncRoutes, pubinfoInjectionKey } from 'pubinfo';
4
+ import { filterPages } from './routes';
5
+
6
+ import './assets/styles/vxe-table.css';
7
+ import 'uno.css';
8
+
9
+ export function rbac(options: RbacOptions = {}): ModuleOptions {
10
+ const { pages } = options;
11
+
12
+ // TODO 考虑路由注册顺序
13
+ const asyncRoutes = filterPages({ pages });
14
+ defineAsyncRoutes(asyncRoutes);
15
+
16
+ return {
17
+ name: 'rbac',
18
+ async setup({ app }) {
19
+ app.provide(pubinfoInjectionKey, {
20
+ loadIcon(name: string) {
21
+ const modules = (import.meta as any).glob('./assets/icons/*', { eager: true });
22
+ const path = `./assets/icons/${name}.svg`;
23
+ return modules[path]?.default;
24
+ },
25
+ });
26
+ },
27
+ };
28
+ }
29
+
30
+ export * from './interface';
31
+ export default rbac;
@@ -0,0 +1,54 @@
1
+ import type { RouteRecordRaw } from 'vue-router';
2
+
3
+ export interface RbacOptions {
4
+ /** 替换或隐藏页面,为空时默认展示所有页面 */
5
+ pages?: RbacPages
6
+ }
7
+
8
+ export interface RbacPages {
9
+ AuthorityManage?: {
10
+ Resource?: PageOptions
11
+ Role?: PageOptions
12
+ RoleGroup?: PageOptions
13
+ DataPermission?: PageOptions
14
+ Organization?: PageOptions
15
+ User?: PageOptions
16
+ Tenant?: PageOptions
17
+ } | boolean
18
+
19
+ SystemManage?: {
20
+ DictionaryPage: {
21
+ Dictionary?: PageOptions
22
+ DictionaryItem?: PageOptions
23
+ }
24
+ Position?: PageOptions
25
+ Region?: PageOptions
26
+ Group?: PageOptions
27
+ } | boolean
28
+
29
+ SettingManage?: {
30
+ ThemeSetting?: PageOptions
31
+ LayoutSetting?: PageOptions
32
+ PageAnimationSetting?: PageOptions
33
+ PageSizeSetting?: PageOptions
34
+ MenuSetting?: PageOptions
35
+ TabbarSetting?: PageOptions
36
+ ToolbarSetting?: PageOptions
37
+ BreadcrumbSetting?: PageOptions
38
+ OtherSetting?: PageOptions
39
+ } | boolean
40
+
41
+ SafeManage?: {
42
+ Blacklist?: PageOptions
43
+ Whitelist?: PageOptions
44
+ SafeSetting?: PageOptions
45
+ WatermarkSetting?: PageOptions
46
+ } | boolean
47
+
48
+ LogManage?: {
49
+ LoginHistory?: PageOptions
50
+ OperateHistory?: PageOptions
51
+ } | boolean
52
+ }
53
+
54
+ export type PageOptions = RouteRecordRaw | boolean;