@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,156 @@
1
+ <script setup lang="ts">
2
+ import type { Form } from '../interface';
3
+ import { getRbacPostList } from '@/api/modules/rbac';
4
+ import { useRequest } from 'alova/client';
5
+ import { Form as AForm, Modal, theme } from 'ant-design-vue';
6
+
7
+ defineOptions({
8
+ name: 'OrgAndPosition',
9
+ });
10
+
11
+ const modelValue = defineModel<Form['userOrgList']>({ default: [] });
12
+
13
+ const { token } = theme.useToken();
14
+ const { onFieldChange } = AForm.useInjectFormItemContext();
15
+
16
+ watch(() => modelValue.value, () => {
17
+ onFieldChange();
18
+ }, { deep: true });
19
+
20
+ const { data: positionOptions } = useRequest(
21
+ params => getRbacPostList(params, {
22
+ transform(data) {
23
+ return data.data ?? [];
24
+ },
25
+ }),
26
+ { initialData: [] },
27
+ );
28
+
29
+ function uniqOrgValidator(_: unknown, value: string) {
30
+ const number = modelValue.value?.filter(item => item.orgId === value)?.length ?? 0;
31
+ if (number > 1) {
32
+ return Promise.reject(new Error('请勿重复选择组织'));
33
+ }
34
+ return Promise.resolve();
35
+ }
36
+
37
+ function onUniqCurrent(index: number) {
38
+ modelValue.value = modelValue.value?.map((e, i) => {
39
+ return {
40
+ ...e,
41
+ main: index === i,
42
+ };
43
+ });
44
+ }
45
+
46
+ function onAdd() {
47
+ modelValue.value?.push({
48
+ orgId: null,
49
+ positionList: [],
50
+ main: false,
51
+ } as any);
52
+ }
53
+
54
+ function onRemove(index: number) {
55
+ Modal.confirm({
56
+ title: '删除',
57
+ content: '确定要删除吗?',
58
+ zIndex: 4000,
59
+ onOk() {
60
+ modelValue.value?.splice(index, 1);
61
+ },
62
+ });
63
+ }
64
+ </script>
65
+
66
+ <template>
67
+ <div class="space-y-2">
68
+ <a-card
69
+ v-for="(item, index) in modelValue"
70
+ :key="index"
71
+ size="small"
72
+ :body-style="{ padding: '16px' }"
73
+ >
74
+ <template #title>
75
+ <div class="flex items-center space-x-1">
76
+ <PubinfoIcon v-if="item.main" name="org-main" class="text-2xl" />
77
+ <PubinfoIcon v-else name="org-unmain" class="text-2xl" />
78
+ <div :style="item.main ? { color: token.colorPrimary } : null" class="font-normal">
79
+ {{ `组织${index + 1}` }}
80
+ </div>
81
+ </div>
82
+ </template>
83
+ <template #extra>
84
+ <a-button
85
+ v-if="!item.main && modelValue && modelValue?.length > 1"
86
+ type="link"
87
+ danger
88
+ @click="onRemove(index)"
89
+ >
90
+ 删除
91
+ </a-button>
92
+ </template>
93
+ <a-form-item
94
+ label="所属组织"
95
+ :name="['userOrgList', index, 'orgId']"
96
+ :label-col="{ span: 6 }"
97
+ :rules="[
98
+ { required: true, message: '所属组织不能为空' },
99
+ { validator: uniqOrgValidator, trigger: 'change' },
100
+ ]"
101
+ >
102
+ <OrgSelector
103
+ :model-value="item.orgId ? [{ orgId: item.orgId, orgName: item.orgName }] : []"
104
+ @submit="(orgs) => {
105
+ const org = orgs?.[0];
106
+ item.orgId = org?.orgId;
107
+ item.orgName = org?.orgName;
108
+ }"
109
+ >
110
+ <template #trigger>
111
+ <div class="flex items-center overflow-hidden">
112
+ <a-tooltip :title="item.orgName">
113
+ <span v-if="item.orgName" class="mr-2 truncate">{{ item.orgName }}</span>
114
+ </a-tooltip>
115
+ <a-button type="primary" size="small">
116
+ 选择组织
117
+ </a-button>
118
+ </div>
119
+ </template>
120
+ </OrgSelector>
121
+ </a-form-item>
122
+
123
+ <a-form-item
124
+ label="所属岗位"
125
+ :name="['userOrgList', index, 'positionList']"
126
+ :label-col="{ span: 6 }"
127
+ >
128
+ <a-select
129
+ v-model:value="item.positionList"
130
+ label-in-value
131
+ :field-names="{ label: 'name', value: 'id' }"
132
+ :options="positionOptions"
133
+ allow-clear
134
+ mode="multiple"
135
+ placeholder="请选择所属岗位"
136
+ />
137
+ </a-form-item>
138
+
139
+ <a-form-item
140
+ label="主要组织"
141
+ :name="['userOrgList', index, 'main']"
142
+ :label-col="{ span: 6 }"
143
+ >
144
+ <a-switch
145
+ v-model:checked="item.main"
146
+ :disabled="item.main"
147
+ @change="onUniqCurrent(index)"
148
+ />
149
+ </a-form-item>
150
+ </a-card>
151
+
152
+ <a-button type="primary" @click="onAdd">
153
+ 添加组织
154
+ </a-button>
155
+ </div>
156
+ </template>
@@ -0,0 +1,260 @@
1
+ <script setup lang="ts">
2
+ import type { FormExpose } from 'ant-design-vue/es/form/Form';
3
+ import type { AuthItem } from '../interface';
4
+ import { getRbacPubDataPermissionsDataPermissionList, getRbacPubRoleGroupGetAll, postRbacPubDataPermissionsGetUserOrgDataPermissionList, postRbacUserGrantUserRoleAndDatPermission } from '@/api/modules/rbac';
5
+ import { useToggle } from '@vueuse/core';
6
+ import { message, theme } from 'ant-design-vue';
7
+ import RoleSelect from './roleSelect.vue';
8
+
9
+ defineOptions({
10
+ name: 'UserAuthorization',
11
+ });
12
+
13
+ const props = defineProps<{ userId: string }>();
14
+
15
+ const emit = defineEmits(['submit']);
16
+
17
+ interface FormData {
18
+ authList: AuthItem[]
19
+ }
20
+
21
+ const { token } = theme.useToken();
22
+ const [open, setOpen] = useToggle(false);
23
+ const [loading, setLoading] = useToggle(false);
24
+
25
+ const formRef = ref<FormExpose>();
26
+ const form = ref<FormData>({
27
+ authList: [],
28
+ });
29
+
30
+ const roleGroupOptions = ref<API.PubRole[]>([]);
31
+ const dataPermissionOptions = ref<API.shujuquanxianshituduixiang[]>([]);
32
+
33
+ function getOptionData() {
34
+ // 数据权限不分页列表
35
+ getRbacPubDataPermissionsDataPermissionList().then((res) => {
36
+ if (res.data && res.data.length) {
37
+ dataPermissionOptions.value = res.data;
38
+ }
39
+ });
40
+
41
+ // 角色组列表
42
+ getRbacPubRoleGroupGetAll({ name: '' }).then((res) => {
43
+ if (res.data && res.data.length) {
44
+ roleGroupOptions.value = res.data;
45
+ }
46
+ });
47
+ }
48
+ // 获取授权数据
49
+ function getAuthData() {
50
+ if (!props.userId) {
51
+ return;
52
+ }
53
+
54
+ // 清空之前数据
55
+ form.value.authList = [];
56
+
57
+ postRbacPubDataPermissionsGetUserOrgDataPermissionList({ userId: props.userId }).then((res) => {
58
+ if (res.data && res.data.userOrgPermissionBos && res.data.userOrgPermissionBos.length) {
59
+ form.value.authList = res.data.userOrgPermissionBos.map((item) => {
60
+ const { orgId = '', orgName = '', main = false, dataPermissionsList, roleList, orgRoleList } = item;
61
+ const o: AuthItem = {
62
+ userId: props.userId,
63
+ orgId,
64
+ orgName,
65
+ main,
66
+ roleList,
67
+ orgRoleList,
68
+ };
69
+ if (dataPermissionsList && dataPermissionsList.length) {
70
+ o.dataPermissionIds = dataPermissionsList.map((dp) => {
71
+ return {
72
+ value: dp.dataPermissionId,
73
+ label: dp.dataPermissionName,
74
+ };
75
+ });
76
+ }
77
+ return o;
78
+ });
79
+ }
80
+ });
81
+ }
82
+
83
+ async function onOpen() {
84
+ await nextTick();
85
+ setOpen(true);
86
+ getAuthData();
87
+ }
88
+
89
+ function onClose() {
90
+ setOpen(false);
91
+ }
92
+ function onSubmit() {
93
+ if (!loading) {
94
+ return;
95
+ }
96
+
97
+ setLoading(true);
98
+
99
+ formRef.value?.validate().then(() => {
100
+ const data: any[] = form.value.authList.map((item) => {
101
+ const { dataPermissionIds = [], roleList = [], orgId, userId } = item;
102
+ const rIds = (roleList || []).map((item: API.PubRole) => {
103
+ // 在下拉框中选择之后,roleIds每一项的值会变成一个对象
104
+ if (typeof item === 'object' && item.id) {
105
+ return item.id;
106
+ }
107
+ // 若未更改过,其原始值是string,直接返回
108
+ return item;
109
+ });
110
+ const dpIds = dataPermissionIds.map(item => item.value);
111
+ return {
112
+ orgId,
113
+ userId,
114
+ roleIds: rIds,
115
+ dataPermissionIds: dpIds,
116
+ };
117
+ });
118
+
119
+ postRbacUserGrantUserRoleAndDatPermission(data).then((res) => {
120
+ if (res.success) {
121
+ message.success('授权成功');
122
+ emit('submit');
123
+ onClose();
124
+ }
125
+ }).finally(() => {
126
+ setLoading(false);
127
+ });
128
+ });
129
+ }
130
+
131
+ onMounted(() => {
132
+ // 获取选项数据列表
133
+ getOptionData();
134
+ });
135
+
136
+ const roleModelRef = ref();
137
+ const selectindex = ref<number>(0);
138
+ function chooseRole(index: number) {
139
+ selectindex.value = index;
140
+ roleModelRef.value.open((form.value.authList[selectindex.value].roleList || []).map((item: API.PubRole) => item.id));
141
+ }
142
+ function onRoleSelected(data: API.PubRole[]) {
143
+ form.value.authList[selectindex.value].roleList = data;
144
+ }
145
+ defineExpose({
146
+ open: onOpen,
147
+ });
148
+ </script>
149
+
150
+ <template>
151
+ <a-drawer
152
+ v-model:open="open"
153
+ title="授权"
154
+ placement="right"
155
+ :width="520"
156
+ destroy-on-close
157
+ :footer-style="{ textAlign: 'right' }"
158
+ >
159
+ <a-form
160
+ ref="formRef"
161
+ :model="form"
162
+ :label-col="{ span: 4 }"
163
+ >
164
+ <a-card
165
+ v-for="(item, index) in form.authList"
166
+ :key="index"
167
+ size="small"
168
+ :body-style="{ padding: '16px' }"
169
+ class="auth-card"
170
+ >
171
+ <template #title>
172
+ <div class="flex items-center justify-between">
173
+ <div flex items-center>
174
+ <PubinfoIcon v-if="item.main" name="org-main" class="text-2xl" />
175
+ <PubinfoIcon v-else name="org-unmain" class="text-2xl" />
176
+ <div :style="item.main ? { color: token.colorPrimary, fontWeight: 'bold' } : {}" class="font-normal">
177
+ {{ `组织${index + 1}` }}
178
+ </div>
179
+ </div>
180
+ <div v-if="item.main" :style="{ color: token.colorPrimary, fontWeight: 'bold' }">
181
+ 主组织
182
+ </div>
183
+ </div>
184
+ </template>
185
+
186
+ <a-form-item label="组织名称" :label-col="{ span: 5 }">
187
+ <span>{{ item.orgName }}</span>
188
+ </a-form-item>
189
+ <a-form-item
190
+ label="数据权限"
191
+ :name="['authList', index, 'dataPermissionIds']"
192
+ :label-col="{ span: 5 }"
193
+ >
194
+ <a-select
195
+ v-model:value="item.dataPermissionIds"
196
+ label-in-value
197
+ :field-names="{ label: 'name', value: 'id' }"
198
+ :options="dataPermissionOptions"
199
+ allow-clear
200
+ mode="multiple"
201
+ placeholder="请选择"
202
+ />
203
+ </a-form-item>
204
+ <a-form-item label="用户自选角色" :label-col="{ span: 5 }" name="roleList">
205
+ <a-button type="primary" @click="chooseRole(index)">
206
+ 编辑角色
207
+ </a-button>
208
+ <div class="pt-10px max-h-150px overflow-auto">
209
+ <template v-for="ite in item.roleList" :key="ite.id">
210
+ <a-tooltip v-if="(ite?.name || '').length > 20" :title="ite.name">
211
+ <span class="inline-block mb-6px mr-6px bg-[#E8F3FF] rounded-2px px-8px py-3px whitespace-nowrap dark:bg-[#141414]">
212
+ {{ `${ite?.name?.slice(0, 20)}...` }}
213
+ </span>
214
+ </a-tooltip>
215
+ <span v-else class="inline-block mb-6px mr-6px bg-[#E8F3FF] rounded-2px px-8px py-3px whitespace-nowrap dark:bg-[#141414]">
216
+ {{ ite.name }}
217
+ </span>
218
+ </template>
219
+ </div>
220
+ </a-form-item>
221
+ <a-form-item label="组织基础角色" :label-col="{ span: 5 }" name="roleList">
222
+ <div class="max-h-150px overflow-auto">
223
+ <template v-for="ite in item.orgRoleList" :key="ite.id">
224
+ <a-tooltip v-if="(ite?.name || '').length > 20" :title="ite.name">
225
+ <span class="inline-block mb-6px mr-6px bg-[#E8F3FF] rounded-2px px-8px py-3px whitespace-nowrap dark:bg-[#141414]">
226
+ {{ `${ite?.name?.slice(0, 20)}...` }}
227
+ </span>
228
+ </a-tooltip>
229
+ <span v-else class="inline-block mb-6px mr-6px bg-[#E8F3FF] rounded-2px px-8px py-3px whitespace-nowrap dark:bg-[#141414]">
230
+ {{ ite.name }}
231
+ </span>
232
+ </template>
233
+ </div>
234
+ </a-form-item>
235
+ </a-card>
236
+ </a-form>
237
+
238
+ <template #footer>
239
+ <a-space>
240
+ <a-button @click="setOpen(false)">
241
+ 取消
242
+ </a-button>
243
+ <a-button type="primary" :loading="loading" @click="onSubmit()">
244
+ 提交
245
+ </a-button>
246
+ </a-space>
247
+ </template>
248
+ <RoleSelect ref="roleModelRef" @select="onRoleSelected" />
249
+ </a-drawer>
250
+ </template>
251
+
252
+ <style scoped lang="scss">
253
+ .auth-card {
254
+ margin-top: 12px;
255
+
256
+ &:first-of-type {
257
+ margin-top: 3px;
258
+ }
259
+ }
260
+ </style>
@@ -0,0 +1,267 @@
1
+ <script setup lang="ts">
2
+ import type { Rule } from 'ant-design-vue/es/form';
3
+ import type { FormExpose } from 'ant-design-vue/es/form/Form';
4
+ import type { AddForm, CurrentOrg, Data, EditForm, Form } from '../interface';
5
+ import { getRbacUserInfo, postRbacUserPubUserAdd, postRbacUserUserUpdateV2 } from '@/api/modules/rbac';
6
+ import { useToggle } from '@vueuse/core';
7
+ import { message } from 'ant-design-vue';
8
+ import { cloneDeep, isEmpty } from 'lodash-es';
9
+ import { ACTION } from '../enum';
10
+ import OrgAndPosition from './OrgAndPosition.vue';
11
+
12
+ defineOptions({
13
+ name: 'UserEdit',
14
+ });
15
+
16
+ const props = defineProps<{ currentOrg?: CurrentOrg }>();
17
+ const emit = defineEmits(['submit']);
18
+
19
+ const [open, setOpen] = useToggle(false);
20
+ const formRef = ref<FormExpose>();
21
+ const form = ref<Partial<Form>>({});
22
+ const state = reactive<{
23
+ title: string
24
+ record: Data
25
+ initData: Partial<Form>
26
+ }>({
27
+ title: '',
28
+ record: {},
29
+ initData: {
30
+ sex: '0',
31
+ enable: true,
32
+ userOrgList: [{ main: true, positionList: [] }],
33
+ },
34
+ });
35
+
36
+ function loginNameValidator(_: unknown, value: string) {
37
+ const reg = /^[A-Z!@#$%^&*0-9]+$/i;
38
+ if (!value || reg.test(value)) {
39
+ return Promise.resolve();
40
+ }
41
+ return Promise.reject(new Error('只能包含字母、数字和特殊字符!@#$%^&*'));
42
+ }
43
+
44
+ function phoneValidator(_: unknown, value: string) {
45
+ const reg = /^1(3\d|4[014-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
46
+ if (reg.test(value) || isEmpty(value)) {
47
+ return Promise.resolve();
48
+ }
49
+ return Promise.reject(new Error('请输入正确的手机号'));
50
+ }
51
+
52
+ function emailValidator(_: unknown, value: string) {
53
+ const reg = /^([a-z0-9])(\w|-)+@[a-z0-9]+\.([a-z]{2,4})$/i;
54
+ if (reg.test(value) || isEmpty(value)) {
55
+ return Promise.resolve();
56
+ }
57
+ return Promise.reject(new Error('请输入正确的邮箱地址'));
58
+ }
59
+
60
+ function idCardValidator(_: unknown, value: string) {
61
+ const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}([\dX])$)/i;
62
+ if (reg.test(value) || isEmpty(value)) {
63
+ return Promise.resolve();
64
+ }
65
+ return Promise.reject(new Error('请输入正确的身份证号码'));
66
+ }
67
+
68
+ const rules: Record<string, Rule[]> = {
69
+ loginName: [
70
+ { required: true, message: '请输入登录账号', trigger: ['blur', 'change'] },
71
+ { min: 4, max: 64, message: '登录账号需要在4位到64位之间', trigger: 'change' },
72
+ { validator: loginNameValidator, trigger: 'change' },
73
+ ],
74
+ realName: [
75
+ { required: true, message: '请输入真实姓名', trigger: 'blur' },
76
+ { min: 2, max: 128, message: '真实姓名需要在2位到128位之间', trigger: 'change' },
77
+ ],
78
+ userOrgList: [
79
+ { type: 'array', required: true, message: '请选择所属组织' },
80
+ ],
81
+ mobile: [
82
+ { validator: phoneValidator, trigger: 'change' },
83
+ ],
84
+ email: [
85
+ { validator: emailValidator, trigger: 'change' },
86
+ { max: 32, message: '邮箱不能超过32位', trigger: 'change' },
87
+ ],
88
+ idCard: [
89
+ { validator: idCardValidator, trigger: 'change' },
90
+ ],
91
+ };
92
+
93
+ async function onOpen(key: ACTION, record?: Form) {
94
+ state.title = key;
95
+ form.value = cloneDeep(state.initData);
96
+ form.value.userOrgList![0].orgId = props.currentOrg?.orgId;
97
+ form.value.userOrgList![0].orgName = props.currentOrg?.orgName;
98
+ setOpen(true);
99
+
100
+ if (key === ACTION.EDIT) {
101
+ const res = await getRbacUserInfo({ id: record?.id as string });
102
+ if (res.success) {
103
+ const { userOrgList = [], ...rest } = res?.data ?? {};
104
+ form.value = {
105
+ ...rest,
106
+ userOrgList: userOrgList?.map((item) => {
107
+ return {
108
+ ...item,
109
+ roleList: item.roles?.map(role => ({ value: role.roleId!, label: role.roleName! })) ?? [],
110
+ positionList: item.posts?.map(post => ({ value: post.postId!, label: post.postName! })) ?? [],
111
+ };
112
+ }),
113
+ };
114
+ }
115
+ }
116
+ }
117
+
118
+ const sexOptions = [
119
+ { label: '未知', value: '0' },
120
+ { label: '男', value: '1' },
121
+ { label: '女', value: '2' },
122
+ ];
123
+
124
+ const [loading, setLoading] = useToggle(false);
125
+ function onSubmit() {
126
+ formRef.value?.validate().then(() => {
127
+ const { userOrgList = [], ...rest } = form.value;
128
+ const params = {
129
+ ...rest,
130
+ orgRoles: userOrgList.map((item) => {
131
+ const { orgId, main } = item;
132
+ return {
133
+ orgId,
134
+ main,
135
+ };
136
+ }),
137
+ posts: userOrgList.map((item) => {
138
+ const { orgId, positionList = [] } = item;
139
+ return {
140
+ orgId,
141
+ postIds: positionList.map(post => post.value),
142
+ };
143
+ }),
144
+ };
145
+ const promise = state.title === ACTION.ADD
146
+ ? postRbacUserPubUserAdd(params as AddForm)
147
+ : postRbacUserUserUpdateV2(params as EditForm);
148
+ setLoading(true);
149
+ promise
150
+ .then((res) => {
151
+ if (res?.success) {
152
+ message.success(`${state.title}成功!`);
153
+ setOpen(false);
154
+ emit('submit');
155
+ }
156
+ })
157
+ .finally(() => setLoading(false));
158
+ });
159
+ }
160
+
161
+ defineExpose({
162
+ open: onOpen,
163
+ });
164
+ </script>
165
+
166
+ <template>
167
+ <a-drawer
168
+ v-model:open="open"
169
+ :title="state.title"
170
+ placement="right"
171
+ :width="520"
172
+ destroy-on-close
173
+ :footer-style="{ textAlign: 'right' }"
174
+ >
175
+ <a-form
176
+ ref="formRef"
177
+ :model="form"
178
+ :rules="rules"
179
+ :label-col="{ span: 4 }"
180
+ >
181
+ <a-form-item label="登录账号" name="loginName">
182
+ <div v-if="state.title === ACTION.EDIT">
183
+ {{ form.loginName }}
184
+ </div>
185
+ <a-input
186
+ v-else
187
+ v-model:value="form.loginName"
188
+ :maxlength="64"
189
+ placeholder="请输入登录账号"
190
+ allow-clear
191
+ />
192
+ </a-form-item>
193
+ <a-form-item label="真实姓名" name="realName">
194
+ <a-input
195
+ v-model:value="form.realName"
196
+ :maxlength="128"
197
+ placeholder="请输入真实姓名"
198
+ allow-clear
199
+ />
200
+ </a-form-item>
201
+ <a-form-item label="手机号" name="mobile">
202
+ <a-input
203
+ v-model:value="form.mobile"
204
+ :maxlength="14"
205
+ placeholder="请输入手机号"
206
+ allow-clear
207
+ />
208
+ </a-form-item>
209
+ <a-form-item label="性别" name="sex">
210
+ <a-radio-group v-model:value="form.sex" :options="sexOptions" />
211
+ </a-form-item>
212
+ <a-form-item label="邮箱" name="email">
213
+ <a-input
214
+ v-model:value="form.email"
215
+ :maxlength="32"
216
+ placeholder="请输入邮箱"
217
+ allow-clear
218
+ />
219
+ </a-form-item>
220
+ <a-form-item label="身份证" name="idCard">
221
+ <a-input
222
+ v-model:value="form.idCard"
223
+ :maxlength="18"
224
+ placeholder="请输入身份证"
225
+ allow-clear
226
+ />
227
+ </a-form-item>
228
+ <a-form-item label="是否启用" name="enable">
229
+ <a-switch v-model:checked="form.enable" />
230
+ </a-form-item>
231
+ <a-form-item label="地址" name="address">
232
+ <a-textarea
233
+ v-model:value="form.address"
234
+ :maxlength="200"
235
+ :auto-size="{ minRows: 2 }"
236
+ placeholder="请输入地址"
237
+ allow-clear
238
+ show-count
239
+ />
240
+ </a-form-item>
241
+ <a-form-item label="描述" name="description">
242
+ <a-textarea
243
+ v-model:value="form.description"
244
+ :maxlength="255"
245
+ :auto-size="{ minRows: 2 }"
246
+ placeholder="请输入描述"
247
+ allow-clear
248
+ show-count
249
+ />
250
+ </a-form-item>
251
+ <a-form-item label="所属组织" name="userOrgList">
252
+ <OrgAndPosition v-model="form.userOrgList" />
253
+ </a-form-item>
254
+ </a-form>
255
+
256
+ <template #footer>
257
+ <a-space>
258
+ <a-button @click="setOpen(false)">
259
+ 取消
260
+ </a-button>
261
+ <a-button type="primary" :loading="loading" @click="onSubmit()">
262
+ 提交
263
+ </a-button>
264
+ </a-space>
265
+ </template>
266
+ </a-drawer>
267
+ </template>