@epxing/business 5.3.0-beta.1 → 5.3.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 (404) hide show
  1. package/API.md +11 -6
  2. package/README.md +44 -43
  3. package/dist/src/base/AiPromptDesigner.js +1 -0
  4. package/dist/src/base/AiPromptView.js +1 -0
  5. package/dist/src/base/AiSkillEditor.js +2 -1
  6. package/dist/src/base/AiSkillEditor.vue.js +2 -0
  7. package/dist/src/base/AppConfigFormItem.js +2 -3
  8. package/dist/src/base/AppConfigFormItem.vue.js +210 -85
  9. package/dist/src/base/AppMarket.js +1 -0
  10. package/dist/src/base/AppMarketList.js +1 -0
  11. package/dist/src/base/AppMarketSystemDetail.js +1 -0
  12. package/dist/src/base/AttributeSubAdd.js +1 -0
  13. package/dist/src/base/ChooseApplication.js +1 -0
  14. package/dist/src/base/ClientAppItem.js +1 -0
  15. package/dist/src/base/ClientApplication.js +1 -0
  16. package/dist/src/base/ClientApplicationList.js +1 -0
  17. package/dist/src/base/ClientModule.js +1 -0
  18. package/dist/src/base/ClientModuleIndex.js +1 -0
  19. package/dist/src/base/ClientSystemDetail.js +1 -0
  20. package/dist/src/base/ClientSystemList.js +1 -0
  21. package/dist/src/base/CommonFieldList.js +2 -1
  22. package/dist/src/base/CommonFieldList.vue.js +2 -1
  23. package/dist/src/base/CommonSearchList.js +1 -0
  24. package/dist/src/base/CompayDetail.js +1 -0
  25. package/dist/src/base/ComponentGlobalSet.js +1 -0
  26. package/dist/src/base/ComponentParamsTree.js +1 -0
  27. package/dist/src/base/ConfigModuleIndex.js +39 -1
  28. package/dist/src/base/CurrentClientApplication.js +1 -0
  29. package/dist/src/base/CurrentVersionInfo.js +1 -0
  30. package/dist/src/base/EntityMatchCompare.js +1 -0
  31. package/dist/src/base/FieldRelationFormItem.js +1 -0
  32. package/dist/src/base/HelpDocSet.js +1 -0
  33. package/dist/src/base/IndexFormItem.js +1 -0
  34. package/dist/src/base/JobFormItem.js +1 -0
  35. package/dist/src/base/ManageAppNav.js +2 -1
  36. package/dist/src/base/ManageMenu.js +2 -1
  37. package/dist/src/base/ManageMenuItem.js +1 -0
  38. package/dist/src/base/NoInstallSystemList.js +1 -0
  39. package/dist/src/base/PageList.js +1 -0
  40. package/dist/src/base/PasswordFormItem.js +1 -0
  41. package/dist/src/base/ProcessFormItem.js +1 -0
  42. package/dist/src/base/PublishSystemApplyFormItem.js +1 -0
  43. package/dist/src/base/RequestLog.js +1 -0
  44. package/dist/src/base/RightRiskList.js +1 -0
  45. package/dist/src/base/RoleAccredit.js +1 -0
  46. package/dist/src/base/RoleBindTrace.js +253 -0
  47. package/dist/src/base/RoleGroupManage.js +1037 -0
  48. package/dist/src/base/RoleRightList.js +1 -0
  49. package/dist/src/base/RoleUserManage.js +1 -0
  50. package/dist/src/base/ServiceAccredit.js +1 -0
  51. package/dist/src/base/ServiceMenu.js +8 -6
  52. package/dist/src/base/ServiceMenuFormItem.js +1 -0
  53. package/dist/src/base/ServiceOperate.js +1 -0
  54. package/dist/src/base/SystemHelpTreeFind.js +1 -0
  55. package/dist/src/base/aiPromptMode.js +1 -0
  56. package/dist/src/base/data-check/DataChckDetail.js +1 -0
  57. package/dist/src/base/data-check/DataCheck.js +1 -0
  58. package/dist/src/base/data-check/DataCheckList.js +1 -0
  59. package/dist/src/base/data-check/DataCheckSubList.js +1 -0
  60. package/dist/src/base/entity-view/EntityViewFormItem.js +1 -0
  61. package/dist/src/base/entity-view/EntityViewSubList.js +1 -0
  62. package/dist/src/base/entity-view-config/BasicInfoDialog.js +1 -0
  63. package/dist/src/base/entity-view-config/FieldPanel.js +1 -0
  64. package/dist/src/base/entity-view-config/FieldPropForm.js +1 -0
  65. package/dist/src/base/entity-view-config/FormulaDialog.js +1 -0
  66. package/dist/src/base/entity-view-config/ObjectFieldDialog.js +1 -0
  67. package/dist/src/base/entity-view-config/RelationPanel.js +1 -0
  68. package/dist/src/base/entity-view-config/SourceManagerDialog.js +1 -0
  69. package/dist/src/base/entity-view-config/SqlPanel.js +1 -0
  70. package/dist/src/base/entity-view-config/UnionPanel.js +1 -0
  71. package/dist/src/base/entity-view-config/ViewConfig.js +1 -0
  72. package/dist/src/base/entity-view-config/constants.js +1 -0
  73. package/dist/src/base/user-type/UserTypeFormItem.js +1 -0
  74. package/dist/src/components/AddPageFormItem.js +1 -0
  75. package/dist/src/components/AddUsedInterface.js +1 -0
  76. package/dist/src/components/AiDocFormItem.js +1 -0
  77. package/dist/src/components/AiList.js +1279 -3
  78. package/dist/src/components/AiPermissionAssistant.js +1 -0
  79. package/dist/src/components/AppList.js +1 -0
  80. package/dist/src/components/Apply/AIApplyIndex.js +1 -0
  81. package/dist/src/components/Apply/ApplyIndex.js +1 -0
  82. package/dist/src/components/AttributeList.js +1 -0
  83. package/dist/src/components/Banner.js +1 -0
  84. package/dist/src/components/BatchAddFieldDialog.js +1 -0
  85. package/dist/src/components/CardO.js +1 -0
  86. package/dist/src/components/CheckForm.js +1 -0
  87. package/dist/src/components/ClientAdminFormItem.js +1 -0
  88. package/dist/src/components/ClientAdminList.js +1 -0
  89. package/dist/src/components/ClientFormItem.js +1 -0
  90. package/dist/src/components/ClientList.js +1 -0
  91. package/dist/src/components/CodeDetail.js +1 -0
  92. package/dist/src/components/CodeManage.js +1 -0
  93. package/dist/src/components/ComponentFind.js +1 -0
  94. package/dist/src/components/ComponentList.js +1 -0
  95. package/dist/src/components/ConfigParamFormItem.js +1 -0
  96. package/dist/src/components/CreatePage.js +1 -0
  97. package/dist/src/components/DashboardCreate.js +1 -0
  98. package/dist/src/components/DataLog.js +1 -0
  99. package/dist/src/components/DataLogTimeline.js +1 -0
  100. package/dist/src/components/DataSnapshot.js +1 -0
  101. package/dist/src/components/DataSnapshotList.js +1 -0
  102. package/dist/src/components/DataSyncInit.js +1 -0
  103. package/dist/src/components/DblogList.js +1 -0
  104. package/dist/src/components/DeptFind.js +1 -0
  105. package/dist/src/components/DynamicUserList.js +1 -0
  106. package/dist/src/components/EntityCheckboxFind.js +1 -0
  107. package/dist/src/components/EntityCheckboxFind.vue.js +14 -10
  108. package/dist/src/components/EntityRelationAdd.js +1 -0
  109. package/dist/src/components/EntityRelationAddFormItem.js +1 -0
  110. package/dist/src/components/EntityRightFormItem.js +2 -5
  111. package/dist/src/components/EntityRightFormItem.vue.js +3 -1
  112. package/dist/src/components/EntityRightSubList.js +1 -0
  113. package/dist/src/components/EntitySystemEr.js +492 -0
  114. package/dist/src/components/EntityTagSubList.js +1 -0
  115. package/dist/src/components/EntityTreeManage.js +1 -0
  116. package/dist/src/components/ExportSystemConfig.js +1 -0
  117. package/dist/src/components/FieldTreeFind.js +1 -0
  118. package/dist/src/components/FormulaEditor.js +1 -0
  119. package/dist/src/components/GenTestData.js +1 -0
  120. package/dist/src/components/HallNav.js +1 -0
  121. package/dist/src/components/HallNav.vue.js +7 -36
  122. package/dist/src/components/HeaderNav.js +1 -0
  123. package/dist/src/components/IconCard.js +1 -0
  124. package/dist/src/components/IconFontLibrary.js +23 -1
  125. package/dist/src/components/IconFontList.js +22 -1
  126. package/dist/src/components/IdentifyList.js +1 -0
  127. package/dist/src/components/ImportSystemConfig.js +1 -0
  128. package/dist/src/components/InterfaceSubList.js +1 -0
  129. package/dist/src/components/JsPanel.js +1 -0
  130. package/dist/src/components/LanguageImportPage.js +1 -0
  131. package/dist/src/components/LanguageSetting.js +1 -0
  132. package/dist/src/components/List/LinkItem.js +1 -0
  133. package/dist/src/components/List/List.js +1 -0
  134. package/dist/src/components/List/ListItem.js +1 -0
  135. package/dist/src/components/MenuTreeFind.js +1 -0
  136. package/dist/src/components/MessageList.js +1 -0
  137. package/dist/src/components/MessageRuleFormItem.js +1 -0
  138. package/dist/src/components/MessageRuleReceiverFormItem.js +1 -0
  139. package/dist/src/components/MessageTemplate.js +1 -0
  140. package/dist/src/components/MetaList.js +1 -0
  141. package/dist/src/components/Nav.js +1 -0
  142. package/dist/src/components/NavFormCatalogItem.js +1 -0
  143. package/dist/src/components/NumList.js +1 -0
  144. package/dist/src/components/OperateLog.js +1 -0
  145. package/dist/src/components/PageCatalog.js +1 -0
  146. package/dist/src/components/PageChart.js +1 -0
  147. package/dist/src/components/PageSwipes.js +1 -0
  148. package/dist/src/components/PersonFormItem.js +1 -0
  149. package/dist/src/components/Popup.js +1 -0
  150. package/dist/src/components/PrintFormList.js +3 -1
  151. package/dist/src/components/PrintFormList.vue.js +3 -1
  152. package/dist/src/components/PublishEntity.js +1 -0
  153. package/dist/src/components/RelyFieldTreeFind.js +1 -0
  154. package/dist/src/components/ReportFormList.js +1 -0
  155. package/dist/src/components/ReportList.js +1 -0
  156. package/dist/src/components/RightSubList.js +1 -0
  157. package/dist/src/components/RoleAddUser.js +1 -0
  158. package/dist/src/components/RoleApplicationCard.js +1 -0
  159. package/dist/src/components/RoleApplicationList.js +1 -0
  160. package/dist/src/components/RoleApplicationSet.js +1 -0
  161. package/dist/src/components/Search.js +1 -0
  162. package/dist/src/components/ServiceFormItem.js +1 -0
  163. package/dist/src/components/SnapshotDataList.js +1 -0
  164. package/dist/src/components/SystemAdminList.js +1 -0
  165. package/dist/src/components/SystemFormItem.js +1 -0
  166. package/dist/src/components/SystemNav.js +1 -0
  167. package/dist/src/components/TaskNumCard.js +1 -0
  168. package/dist/src/components/TimerRuleFormItem.js +1 -0
  169. package/dist/src/components/TodoList.js +1 -0
  170. package/dist/src/components/UpdateSystemConfig.js +1 -0
  171. package/dist/src/components/UserCard.js +1 -0
  172. package/dist/src/components/UserFind.js +1 -0
  173. package/dist/src/components/UserFormItem.js +1 -0
  174. package/dist/src/components/UserList.js +1 -0
  175. package/dist/src/components/UserManage.js +1 -0
  176. package/dist/src/components/UserRoleList.js +1 -0
  177. package/dist/src/components/ValidateRuleFormItem.js +1 -0
  178. package/dist/src/components/ViewFieldDefine.js +1 -0
  179. package/dist/src/components/WikiSpaceList.js +1 -0
  180. package/dist/src/components/WikiWorkbench.js +154 -129
  181. package/dist/src/components/authorization/AddApiPermiss.js +1 -0
  182. package/dist/src/components/authorization/AddAuthorization.js +1 -0
  183. package/dist/src/components/authorization/AddEntityFind.js +1 -0
  184. package/dist/src/components/authorization/AddNoApi.js +1 -0
  185. package/dist/src/components/authorization/AddRoleScope.js +1 -0
  186. package/dist/src/components/authorization/AiRolePlan.js +1 -0
  187. package/dist/src/components/authorization/ApiShareOtherList.js +1 -0
  188. package/dist/src/components/authorization/ApiSystemList.js +1 -0
  189. package/dist/src/components/authorization/AuthorizationInterface.js +4 -1
  190. package/dist/src/components/authorization/AuthorizationRoleSystem.js +1 -0
  191. package/dist/src/components/authorization/EntityConstraintFormItem.js +1 -0
  192. package/dist/src/components/authorization/OtherShareApiList.js +1 -0
  193. package/dist/src/components/authorization/PermissCommonRoleTabs.js +1 -0
  194. package/dist/src/components/authorization/PermissRoleAuthorization.js +1 -0
  195. package/dist/src/components/authorization/PermissRoleTabs.js +1 -0
  196. package/dist/src/components/authorization/RoleLevel.js +1 -0
  197. package/dist/src/components/authorization/RoleLevelScope.js +1 -0
  198. package/dist/src/components/authorization/SystemAddNoApi.js +1 -0
  199. package/dist/src/components/card/CardList.js +1 -0
  200. package/dist/src/components/card/CardListItem.js +1 -0
  201. package/dist/src/components/card/Title.js +1 -0
  202. package/dist/src/components/custom-bpmn/CustomContextPad.js +1 -0
  203. package/dist/src/components/custom-bpmn/CustomPalette.js +1 -0
  204. package/dist/src/components/custom-bpmn/CustomRenderer.js +1 -0
  205. package/dist/src/components/custom-bpmn/CustomRendererBpmn.js +1 -0
  206. package/dist/src/components/custom-bpmn/PropertiesView.js +1992 -1942
  207. package/dist/src/components/custom-bpmn/components/AiModel.js +1 -0
  208. package/dist/src/components/custom-bpmn/components/Api.js +1 -0
  209. package/dist/src/components/custom-bpmn/components/BatchOperation.js +1 -0
  210. package/dist/src/components/custom-bpmn/components/Copy.js +1 -0
  211. package/dist/src/components/custom-bpmn/components/DataTransform.js +1 -0
  212. package/dist/src/components/custom-bpmn/components/Demo.js +1 -0
  213. package/dist/src/components/custom-bpmn/components/EditDiv.js +1 -0
  214. package/dist/src/components/custom-bpmn/components/GenScope.js +1 -0
  215. package/dist/src/components/custom-bpmn/components/GlobalParamsTree.js +1 -0
  216. package/dist/src/components/custom-bpmn/components/Knowledges.js +1 -0
  217. package/dist/src/components/custom-bpmn/components/Login.js +1 -0
  218. package/dist/src/components/custom-bpmn/components/MessageQueue.js +1 -0
  219. package/dist/src/components/custom-bpmn/components/MetaSelect.js +1 -0
  220. package/dist/src/components/custom-bpmn/components/NumStatistic.js +1 -0
  221. package/dist/src/components/custom-bpmn/components/ObjectTransform.js +1 -0
  222. package/dist/src/components/custom-bpmn/components/OutPut.js +1 -0
  223. package/dist/src/components/custom-bpmn/components/ParamsMachining.js +1 -0
  224. package/dist/src/components/custom-bpmn/components/ParamsOutput.js +1 -0
  225. package/dist/src/components/custom-bpmn/components/ProcessAudit.js +1 -0
  226. package/dist/src/components/custom-bpmn/components/SingleMultipleFind.js +1 -0
  227. package/dist/src/components/custom-bpmn/components/TestDialog.js +1 -0
  228. package/dist/src/components/custom-bpmn/index.js +1 -0
  229. package/dist/src/components/custom-bpmn/palette.js +1 -0
  230. package/dist/src/components/custom-bpmn/util.js +1 -0
  231. package/dist/src/components/dashboard-create.js +1 -0
  232. package/dist/src/components/entity-relation-diagram/Er.js +1 -0
  233. package/dist/src/components/entity-relation-diagram/renderErNode.js +1 -0
  234. package/dist/src/components/expand/AddForm.js +1 -0
  235. package/dist/src/components/expand/AddFormItem.js +1 -0
  236. package/dist/src/components/filter/Filter.js +1 -0
  237. package/dist/src/components/filter/FilterItem.js +1 -0
  238. package/dist/src/components/hall/AppCollect.js +1 -0
  239. package/dist/src/components/hall/AppList.js +1 -0
  240. package/dist/src/components/hall/AppVisitRecord.js +1 -0
  241. package/dist/src/components/hall/Banner.js +1 -0
  242. package/dist/src/components/hall/ServiceCard.js +1 -0
  243. package/dist/src/components/hall/UserCard.js +1 -0
  244. package/dist/src/components/icon-gallery/IconGallery.js +193 -0
  245. package/dist/src/components/icon-gallery/mixin.js +150 -0
  246. package/dist/src/components/permiss/AddApi.js +1 -0
  247. package/dist/src/components/permiss/AddNoEntityApi.js +1 -0
  248. package/dist/src/components/permiss/AddSystemPermiss.js +1 -0
  249. package/dist/src/components/permiss/AllocateRole.js +1 -0
  250. package/dist/src/components/permiss/ApiSubList.js +1 -0
  251. package/dist/src/components/permiss/CommonRoleMenu.js +1 -0
  252. package/dist/src/components/permiss/FieldScope.js +1 -0
  253. package/dist/src/components/permiss/PermissManage.js +1 -0
  254. package/dist/src/components/permiss/RoleAppList.js +1 -0
  255. package/dist/src/components/permiss/RoleMenu.js +1 -0
  256. package/dist/src/components/permiss/RoleSubList.js +1 -0
  257. package/dist/src/components/permiss/jurisdiction.js +1 -0
  258. package/dist/src/components/process-healthcheck/HealthcheckChart.js +1 -0
  259. package/dist/src/components/process-healthcheck/HealthcheckRenderer.js +1 -0
  260. package/dist/src/components/process-healthcheck/index.js +1 -0
  261. package/dist/src/components/report/Config.js +1 -0
  262. package/dist/src/components/report/Design.js +1 -0
  263. package/dist/src/components/report/StatList.js +1 -0
  264. package/dist/src/components/right/EntityOtherSystemList.js +1 -0
  265. package/dist/src/components/right/SystemInterfaceList.js +1 -0
  266. package/dist/src/components/right/SystemList.js +1 -0
  267. package/dist/src/components/upLoad.js +1 -0
  268. package/dist/src/components/viewport/LookViewList.js +1 -0
  269. package/dist/src/components/viewport/ViewAddForm.js +1 -0
  270. package/dist/src/components/viewport/ViewDefineList.js +1 -0
  271. package/dist/src/components/viewport/ViewFiedList.js +1 -0
  272. package/dist/src/components/viewport/ViewScope.js +1 -0
  273. package/dist/src/components/wiki-workbench/WikiCites.js +1 -0
  274. package/dist/src/components/wiki-workbench/WikiIntake.js +87 -93
  275. package/dist/src/components/wiki-workbench/WikiIntake.vue.js +153 -73
  276. package/dist/src/components/wiki-workbench/WikiJobs.js +1 -0
  277. package/dist/src/components/wiki-workbench/WikiRevisions.js +1 -0
  278. package/dist/src/components/wiki-workbench/WikiSpaceSettings.js +1 -0
  279. package/dist/src/components/wiki-workbench/codes.js +1 -0
  280. package/dist/src/components/wiki-workbench/index.js +1 -0
  281. package/dist/src/index.js +27 -20
  282. package/dist/src/popup.js +1 -0
  283. package/dist/src/public-components.js +17 -14
  284. package/dist/src/remote.entry.js +1 -0
  285. package/dist/src/route-components.js +6 -5
  286. package/dist/src/system.component.index.js +2 -1
  287. package/dist/src/system.component.js +9 -3
  288. package/dist/src/system.component.lazy.js +2 -1
  289. package/dist/src/views/Add.js +2 -1
  290. package/dist/src/views/Add.vue.js +8 -3
  291. package/dist/src/views/AiToolManager.js +793 -317
  292. package/dist/src/views/App.js +4 -45
  293. package/dist/src/views/AppRoleSelect.js +4 -230
  294. package/dist/src/views/BatchEdit.js +1 -0
  295. package/dist/src/views/Bpmn.js +1 -0
  296. package/dist/src/views/EntityCheckPage.js +1 -0
  297. package/dist/src/views/EntityDetailPage.js +1 -0
  298. package/dist/src/views/EntityEditPage.js +1 -0
  299. package/dist/src/views/EntitySubListPage.js +1 -0
  300. package/dist/src/views/EntityTreePage.js +1 -0
  301. package/dist/src/views/Error.js +4 -207
  302. package/dist/src/views/ExcelDesign.js +327 -316
  303. package/dist/src/views/ExcelPreviewPage.js +1 -0
  304. package/dist/src/views/ExportFilePage.js +1 -0
  305. package/dist/src/views/ExportPage.js +1 -0
  306. package/dist/src/views/FormDesign.js +1 -0
  307. package/dist/src/views/I18nWorkbench.js +1 -0
  308. package/dist/src/views/ImportFilePage.js +1 -0
  309. package/dist/src/views/ImportPage.js +1 -0
  310. package/dist/src/views/JvmMemoryMonitor.js +463 -0
  311. package/dist/src/views/MEntityListPage.js +1 -0
  312. package/dist/src/views/MEntitySubListPage.js +1 -0
  313. package/dist/src/views/MinePage.js +1 -0
  314. package/dist/src/views/Module.js +4 -170
  315. package/dist/src/views/PageAttributeTreePage.js +1 -0
  316. package/dist/src/views/PageConfig.js +1 -0
  317. package/dist/src/views/Permission.js +1 -0
  318. package/dist/src/views/PersonalInfo.js +1 -0
  319. package/dist/src/views/QyWechat.js +1 -0
  320. package/dist/src/views/ReportFormListPage.js +1 -0
  321. package/dist/src/views/TaskPage.js +1 -0
  322. package/dist/src/views/WikiBinding.js +89 -25
  323. package/dist/src/views/client/AddForm.js +1 -0
  324. package/dist/src/views/client/AppMarket.js +1 -0
  325. package/dist/src/views/client/ClientIndex.js +1 -0
  326. package/dist/src/views/client/ClientModuleIndexPage.js +1 -0
  327. package/dist/src/views/client/CopySystem.js +1 -0
  328. package/dist/src/views/client/CreateAppFormItem.js +1 -0
  329. package/dist/src/views/client/CreateMethod.js +1 -0
  330. package/dist/src/views/client/InstallSystem.js +1 -0
  331. package/dist/src/views/client/ManageList.js +1 -0
  332. package/dist/src/views/client/OpenClientManage.js +1 -0
  333. package/dist/src/views/client/OpenSystemManage.js +1 -0
  334. package/dist/src/views/client/PageTabsCyclic.js +1 -0
  335. package/dist/src/views/client/SelfBuiltSystem.js +1 -0
  336. package/dist/src/views/client/StandardProduct.js +1 -0
  337. package/dist/src/views/client/SystemAppAccredit.js +1 -0
  338. package/dist/src/views/client/SystemAppManager.js +1 -0
  339. package/dist/src/views/client/SystemManager.js +1 -0
  340. package/dist/src/views/i18n/I18nAiTaskHistoryDialog.js +1 -0
  341. package/dist/src/views/i18n/I18nPublishDialog.js +1 -0
  342. package/dist/src/views/i18n/I18nTranslationList.js +1 -0
  343. package/dist/src/views/i18n/i18n-workbench-text.js +1 -0
  344. package/dist/src/views/layout/CardList.js +1 -0
  345. package/dist/src/views/layout/Grid.js +1 -0
  346. package/dist/src/views/match/AddTargetField.js +1 -0
  347. package/dist/src/views/match/MatchAddFormItem.js +1 -0
  348. package/dist/src/views/match/conversion.js +1 -0
  349. package/dist/src/views/match/customize.js +1 -0
  350. package/dist/src/views/match/fieldMatch.js +1 -0
  351. package/dist/src/views/report/AddFormItem.js +1 -0
  352. package/dist/src/views/report/DesignReport.js +1 -0
  353. package/dist/src/views/report/ReportTreeFind.js +1 -0
  354. package/dist/style.css +2867 -1487
  355. package/package.json +14 -7
  356. package/src/base/AiSkillEditor.vue +2 -0
  357. package/src/base/AppConfigFormItem.vue +211 -145
  358. package/src/base/CommonFieldList.vue +9 -6
  359. package/src/base/ConfigModuleIndex.vue +37 -1
  360. package/src/base/ManageAppNav.vue +1188 -1188
  361. package/src/base/ManageMenu.vue +933 -933
  362. package/src/base/RoleBindTrace.vue +364 -0
  363. package/src/base/RoleGroupManage.vue +1160 -0
  364. package/src/base/ServiceMenu.vue +6 -5
  365. package/src/components/AiList.vue +439 -113
  366. package/src/components/EntityCheckboxFind.vue +12 -8
  367. package/src/components/EntityRightFormItem.vue +9 -10
  368. package/src/components/EntitySystemEr.vue +517 -0
  369. package/src/components/HallNav.vue +6 -33
  370. package/src/components/IconFontLibrary.vue +27 -60
  371. package/src/components/IconFontList.vue +13 -64
  372. package/src/components/PrintFormList.vue +33 -27
  373. package/src/components/WikiWorkbench.vue +90 -60
  374. package/src/components/authorization/AuthorizationInterface.vue +2 -0
  375. package/src/components/custom-bpmn/CustomPalette.js +1 -1
  376. package/src/components/custom-bpmn/CustomRenderer.js +1 -1
  377. package/src/components/custom-bpmn/PropertiesView.vue +35 -4
  378. package/src/components/custom-bpmn/index.js +1 -1
  379. package/src/components/icon-gallery/IconGallery.vue +130 -0
  380. package/src/components/icon-gallery/mixin.jsx +109 -0
  381. package/src/components/wiki-workbench/WikiIntake.vue +178 -104
  382. package/src/index.js +24 -20
  383. package/src/public-components.js +1 -0
  384. package/src/route-components.js +4 -4
  385. package/src/system.component.index.js +1 -1
  386. package/src/views/Add.vue +8 -5
  387. package/src/views/AiToolManager.vue +326 -4
  388. package/src/views/App.vue +4 -53
  389. package/src/views/AppRoleSelect.vue +4 -334
  390. package/src/views/Error.vue +4 -63
  391. package/src/views/ExcelDesign.vue +24 -7
  392. package/src/views/JvmMemoryMonitor.vue +284 -0
  393. package/src/views/Module.vue +4 -210
  394. package/src/views/WikiBinding.vue +42 -0
  395. package/types/app.d.ts +1 -0
  396. package/types/dept-find.d.ts +1 -1
  397. package/types/index.d.ts +15 -14
  398. package/types/popup.d.ts +2 -2
  399. package/types/route-components.d.ts +1 -1
  400. package/types/user-find.d.ts +1 -1
  401. package/dist/assets/role_select-DTqRlFNz.webp +0 -0
  402. package/dist/src/components/AiList.vue.js +0 -93
  403. package/dist/src/components/IconFontLibrary.vue.js +0 -67
  404. package/dist/src/components/IconFontList.vue.js +0 -79
@@ -0,0 +1,1160 @@
1
+ <template>
2
+ <div class="rgm-page">
3
+ <div class="split">
4
+ <!-- 左:角色组列表 -->
5
+ <div class="split__left">
6
+ <div class="v9-card">
7
+ <div class="v9-block-title">角色组</div>
8
+ <div class="group-list">
9
+ <div
10
+ v-for="g in groupList"
11
+ :key="g.ID"
12
+ :class="['grp-item', { 'is-active': g.ID === curGroupId }]"
13
+ @click="selectGroup(g.ID)"
14
+ >
15
+ <div class="grp-item__body">
16
+ <div class="grp-item__name">{{ g.NAME }}</div>
17
+ <div class="grp-item__meta">{{ g.CODE }} · {{ g.roleCount }} 个角色 · 已授 {{ g.userCount }} 人</div>
18
+ </div>
19
+ <div class="grp-item__ops">
20
+ <button class="v9-btn v9-btn--text" @click.stop="openGroupForm(g)">编辑</button>
21
+ <button class="v9-btn v9-btn--text is-danger" @click.stop="openDelGroup(g)">删除</button>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <button class="v9-btn v9-btn--default grp-add-btn" @click="openGroupForm(null)">
26
+ <i class="el-icon-plus"></i> 新建角色组
27
+ </button>
28
+ </div>
29
+ <div class="v9-form-item__tip grp-left-tip">角色组为租户级定义,不属于任何业务系统;一个角色同一时间只能属于一个角色组。</div>
30
+ </div>
31
+
32
+ <!-- 右:组详情 -->
33
+ <div class="split__right">
34
+ <!-- 未选组 -->
35
+ <div v-if="!curGroup" class="v9-card">
36
+ <div class="v9-empty">
37
+ <i class="el-icon-box v9-empty__icon"></i>
38
+ <div>请先新建角色组</div>
39
+ </div>
40
+ </div>
41
+
42
+ <template v-else>
43
+ <!-- 重新应用提示条(G-04,历史差量兜底:正常流程加角色已自动补授) -->
44
+ <div v-if="pendingApply && pendingApply.length && curGroup.userCount > 0" class="tipbar tipbar--info">
45
+ <i class="el-icon-info"></i>
46
+ <div class="tipbar__main">检测到 {{ pendingApply.length }} 个角色的历史差量:已通过本组授权的 {{ curGroup.userCount }} 个用户尚未获得这些角色,可手动补授。</div>
47
+ <button class="v9-btn v9-btn--primary" @click="applyGroup">应用到 {{ curGroup.userCount }} 个用户</button>
48
+ </div>
49
+
50
+ <!-- 组信息 -->
51
+ <div class="v9-card">
52
+ <div class="v9-block-title">组信息</div>
53
+ <table class="v9-desc-table">
54
+ <tbody>
55
+ <tr>
56
+ <th>组名称</th><td>{{ curGroup.NAME }}</td>
57
+ <th>组编码</th><td>{{ curGroup.CODE }}</td>
58
+ <th>排序号</th><td>{{ curGroup.ORDER_NUM }}</td>
59
+ </tr>
60
+ <tr>
61
+ <th>描述</th><td colspan="5">{{ curGroup.DESC || '—' }}</td>
62
+ </tr>
63
+ </tbody>
64
+ </table>
65
+ <div class="grp-edit-row">
66
+ <button class="v9-btn v9-btn--default" @click="openGroupForm(curGroup)"><i class="el-icon-edit"></i> 编辑</button>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- 组概况统计 -->
71
+ <div class="v9-figure-grid v9-figure-grid--3">
72
+ <div class="v9-figure">
73
+ <div class="v9-figure__label">组内角色</div>
74
+ <div class="v9-figure__value">{{ curGroup.roleCount }}</div>
75
+ </div>
76
+ <div class="v9-figure">
77
+ <div class="v9-figure__label">已授权用户</div>
78
+ <div class="v9-figure__value">{{ curGroup.userCount }}</div>
79
+ </div>
80
+ <div class="v9-figure">
81
+ <div class="v9-figure__label">覆盖系统</div>
82
+ <div class="v9-figure__value">{{ detail.sysCount }}</div>
83
+ </div>
84
+ </div>
85
+
86
+ <!-- 组内角色 / 已授权用户页签 -->
87
+ <div class="v9-card">
88
+ <div class="v9-tabs">
89
+ <div :class="['v9-tabs__item', { 'is-active': activeTab === 'roles' }]" @click="switchGroupTab('roles')">组内角色({{ curGroup.roleCount }})</div>
90
+ <div :class="['v9-tabs__item', { 'is-active': activeTab === 'users' }]" @click="switchGroupTab('users')">已授权用户({{ curGroup.userCount }})</div>
91
+ </div>
92
+
93
+ <!-- 页签一:组内角色 -->
94
+ <div v-show="activeTab === 'roles'" class="grp-tab-body">
95
+ <div class="grp-tab-toolbar">
96
+ <button class="v9-btn v9-btn--primary" @click="openPickRole"><i class="el-icon-plus"></i> 添加角色</button>
97
+ <span class="v9-form-item__tip grp-inline-tip">组不需要覆盖全部系统,内容按需;组内新增角色自动补授已授权用户,移除角色自动按位收回</span>
98
+ </div>
99
+ <div v-if="!groupRoles.length" class="v9-empty">
100
+ <i class="el-icon-box v9-empty__icon"></i>
101
+ <div>组内暂无角色,点击「添加角色」开始</div>
102
+ </div>
103
+ <table v-else class="v9-table">
104
+ <thead>
105
+ <tr>
106
+ <th style="width:60px">序号</th>
107
+ <th>角色名称</th>
108
+ <th>所属系统</th>
109
+ <th>角色编码</th>
110
+ <th style="width:100px">操作</th>
111
+ </tr>
112
+ </thead>
113
+ <tbody>
114
+ <tr v-for="(r, i) in groupRoles" :key="r.ID">
115
+ <td>{{ i + 1 }}</td>
116
+ <td>{{ r.NAME }}</td>
117
+ <td><i :class="r.systemIcon" class="grp-sys-icon"></i>{{ r.SYSTEM_NAME }}</td>
118
+ <td><span class="v9-tag v9-tag--info">{{ r.CODE }}</span></td>
119
+ <td><button class="v9-btn v9-btn--text is-danger" @click="openRemoveRole(r)">移除</button></td>
120
+ </tr>
121
+ </tbody>
122
+ </table>
123
+ </div>
124
+
125
+ <!-- 页签二:已授权用户 -->
126
+ <div v-show="activeTab === 'users'" class="grp-tab-body">
127
+ <div class="grp-tab-toolbar">
128
+ <button class="v9-btn v9-btn--primary" @click="openAddUser"><i class="el-icon-plus"></i> 添加用户</button>
129
+ <span class="v9-form-item__tip grp-inline-tip">添加后用户立即获得组内全部角色;后续组内新增角色也会自动补授这些用户</span>
130
+ </div>
131
+ <div v-if="!groupUsers.length" class="v9-empty">
132
+ <i class="el-icon-box v9-empty__icon"></i>
133
+ <div>暂无通过本组授权的用户,点击「添加用户」开始</div>
134
+ </div>
135
+ <template v-else>
136
+ <table class="v9-table">
137
+ <thead>
138
+ <tr>
139
+ <th style="width:60px">序号</th>
140
+ <th>姓名</th>
141
+ <th>工作证号</th>
142
+ <th>部门</th>
143
+ <th>持有本组角色数</th>
144
+ <th style="width:160px">操作</th>
145
+ </tr>
146
+ </thead>
147
+ <tbody>
148
+ <tr v-for="(u, i) in groupUsers" :key="u.ID">
149
+ <td>{{ i + 1 }}</td>
150
+ <td>{{ u.NAME }}</td>
151
+ <td>{{ u.USER_NO }}</td>
152
+ <td>{{ u.DEPT_NAME }}</td>
153
+ <td>{{ u.roleCount }}</td>
154
+ <td><button class="v9-btn v9-btn--text is-danger" @click="openRemoveUser(u)">移除</button></td>
155
+ </tr>
156
+ </tbody>
157
+ </table>
158
+ <div class="v9-form-item__tip grp-table-foot-tip">按组来源(SOURCE_GROUP)反查,用于影响面评估与审计。</div>
159
+ </template>
160
+ </div>
161
+ </div>
162
+ </template>
163
+ </div>
164
+ </div>
165
+
166
+ <!-- ================= 弹窗:新建 / 编辑角色组 ================= -->
167
+ <div v-if="dlg.groupForm" class="v9-overlay" @click.self="dlg.groupForm = false">
168
+ <div class="v9-dialog">
169
+ <div class="v9-dialog__header">
170
+ <span>{{ formGroup.ID ? '编辑角色组' : '新建角色组' }}</span>
171
+ <span class="v9-dialog__close" @click="dlg.groupForm = false"><i class="el-icon-close"></i></span>
172
+ </div>
173
+ <div class="v9-dialog__body">
174
+ <div class="v9-form-item">
175
+ <label class="v9-form-item__label is-required">组名称</label>
176
+ <input v-model="formGroup.NAME" :class="['v9-input', { 'is-error': formErr.name }]" placeholder="租户内唯一,如:教师">
177
+ <div v-if="formErr.name" class="v9-form-item__error">组名称必填且不能与现有组重复</div>
178
+ </div>
179
+ <div class="v9-form-item">
180
+ <label class="v9-form-item__label is-required">组编码</label>
181
+ <input v-model="formGroup.CODE" :class="['v9-input', { 'is-error': formErr.code }]" placeholder="大小写字母 / 下划线,如:TEACHER">
182
+ <div v-if="formErr.code" class="v9-form-item__error">编码必填,仅限大小写字母、数字与下划线,且不能重复</div>
183
+ </div>
184
+ <div class="v9-form-item">
185
+ <label class="v9-form-item__label">描述</label>
186
+ <input v-model="formGroup.DESC" class="v9-input" placeholder="组的业务含义,授权人可见">
187
+ </div>
188
+ <div class="v9-form-item">
189
+ <label class="v9-form-item__label">排序号</label>
190
+ <input v-model="formGroup.ORDER_NUM" class="v9-input">
191
+ </div>
192
+ </div>
193
+ <div class="v9-dialog__footer">
194
+ <button class="v9-btn v9-btn--default" @click="dlg.groupForm = false">取消</button>
195
+ <button class="v9-btn v9-btn--primary" @click="saveGroupForm">保存</button>
196
+ </div>
197
+ </div>
198
+ </div>
199
+
200
+ <!-- ================= 弹窗:添加角色(按系统分组 + 单组归属置灰) ================= -->
201
+ <div v-if="dlg.pickRole" class="v9-overlay" @click.self="dlg.pickRole = false">
202
+ <div class="v9-dialog v9-dialog--lg">
203
+ <div class="v9-dialog__header">
204
+ <span>向「{{ curGroup && curGroup.NAME }}」添加角色</span>
205
+ <span class="v9-dialog__close" @click="dlg.pickRole = false"><i class="el-icon-close"></i></span>
206
+ </div>
207
+ <div class="v9-dialog__body">
208
+ <div class="v9-form-item__tip pick-tip">按系统分组展示本租户全部可选角色(含租户公共角色),可跨系统勾选;已属于其他组的角色置灰,保存时后端同样会校验拦截(角色单组归属)。</div>
209
+ <div class="pick-scroll">
210
+ <div v-for="sys in selectableRoles" :key="sys.SYSTEM" class="pick-group">
211
+ <div class="pick-group__title"><i :class="sys.icon"></i>{{ sys.SYSTEM_NAME }}</div>
212
+ <label
213
+ v-for="r in sys.roles"
214
+ :key="r.ID"
215
+ :class="['pick-item', { 'is-disabled': r.disabled }]"
216
+ >
217
+ <input
218
+ v-model="selRoleIds"
219
+ type="checkbox"
220
+ :value="r.ID"
221
+ :disabled="r.disabled"
222
+ >
223
+ <span class="pick-item__name">{{ r.NAME }}</span>
224
+ <span class="v9-tag v9-tag--info">{{ r.CODE }}</span>
225
+ <span v-if="r.inGroup" class="v9-tag v9-tag--success">已在组内</span>
226
+ <span v-else-if="r.ownerGroupName" class="v9-tag v9-tag--warning">已属组 {{ r.ownerGroupName }}</span>
227
+ </label>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ <div class="v9-dialog__footer">
232
+ <span class="v9-form-item__tip pick-count">{{ pickCountText }}</span>
233
+ <button class="v9-btn v9-btn--default" @click="dlg.pickRole = false">取消</button>
234
+ <button class="v9-btn v9-btn--primary" @click="savePickRole">加入组内</button>
235
+ </div>
236
+ </div>
237
+ </div>
238
+
239
+ <!-- ================= 弹窗:移除角色(移出并收回,按位) ================= -->
240
+ <div v-if="dlg.removeRole" class="v9-overlay" @click.self="dlg.removeRole = false">
241
+ <div class="v9-dialog">
242
+ <div class="v9-dialog__header">
243
+ <span>移出并收回:「{{ rmRole.label }}」</span>
244
+ <span class="v9-dialog__close" @click="dlg.removeRole = false"><i class="el-icon-close"></i></span>
245
+ </div>
246
+ <div class="v9-dialog__body">
247
+ <div class="tipbar tipbar--warn">
248
+ <i class="el-icon-warning-outline"></i>
249
+ <div class="tipbar__main">该角色已通过本组授予 <b>{{ rmRole.total }}</b> 个用户({{ rmRole.total - rmRole.withManual }} 条仅组来源、{{ rmRole.withManual }} 条另有手工授予)</div>
250
+ </div>
251
+ <div class="v9-form-item__tip">移出后按位收回该角色的组来源:同时有手工授予的绑定仅清除组来源、记录保留;仅组来源的绑定整条删除、权限收回。</div>
252
+ </div>
253
+ <div class="v9-dialog__footer">
254
+ <button class="v9-btn v9-btn--default" @click="dlg.removeRole = false">取消</button>
255
+ <button class="v9-btn v9-btn--primary" @click="doRemoveRole">移出并收回</button>
256
+ </div>
257
+ </div>
258
+ </div>
259
+
260
+ <!-- ================= 弹窗:删除角色组 ================= -->
261
+ <div v-if="dlg.delGroup" class="v9-overlay" @click.self="dlg.delGroup = false">
262
+ <div class="v9-dialog">
263
+ <div class="v9-dialog__header">
264
+ <span>删除角色组「{{ delGroupData.NAME }}」</span>
265
+ <span class="v9-dialog__close" @click="dlg.delGroup = false"><i class="el-icon-close"></i></span>
266
+ </div>
267
+ <div class="v9-dialog__body">
268
+ <div class="tipbar tipbar--danger del-tipbar">
269
+ <i class="el-icon-warning-outline"></i>
270
+ <div class="tipbar__main">删除组不可恢复。已通过本组授予的授权将按位收回:</div>
271
+ </div>
272
+ <table class="v9-desc-table del-impact">
273
+ <tbody>
274
+ <tr><th>仅组来源绑定</th><td>{{ delGroupData.onlyGroup }} 条 → 整条删除(权限收回)</td></tr>
275
+ <tr><th>组 + 手工并存绑定</th><td>{{ delGroupData.both }} 条 → 仅清除组来源,手工授权保留</td></tr>
276
+ <tr><th>涉及用户</th><td>{{ delGroupData.userCount }} 人</td></tr>
277
+ </tbody>
278
+ </table>
279
+ <div class="v9-form-item__tip">同时持有手工授予的绑定仅清除组来源、记录保留,手工授权不受影响;仅组来源的绑定整条删除。</div>
280
+ </div>
281
+ <div class="v9-dialog__footer">
282
+ <button class="v9-btn v9-btn--default" @click="dlg.delGroup = false">取消</button>
283
+ <button class="v9-btn v9-btn--danger" @click="doDelGroup"><i class="el-icon-delete"></i> 删除并收回授权</button>
284
+ </div>
285
+ </div>
286
+ </div>
287
+
288
+ <!-- ================= 弹窗:向组添加用户 ================= -->
289
+ <div v-if="dlg.addUser" class="v9-overlay" @click.self="dlg.addUser = false">
290
+ <div class="v9-dialog v9-dialog--md">
291
+ <div class="v9-dialog__header">
292
+ <span>向「{{ curGroup && curGroup.NAME }}」添加用户</span>
293
+ <span class="v9-dialog__close" @click="dlg.addUser = false"><i class="el-icon-close"></i></span>
294
+ </div>
295
+ <div class="v9-dialog__body">
296
+ <div class="v9-form-item__tip pick-tip">选中用户将立即获得组内全部角色(物化展开写入用户角色绑定,权限即时生效);已手工授予的角色会并列保留手工来源,不跳过、不覆盖。</div>
297
+ <div class="v9-input-wrap au-search">
298
+ <span class="v9-input-prefix"><i class="el-icon-search"></i></span>
299
+ <input v-model="addUserKeyword" class="v9-input" placeholder="输入姓名、工号过滤" @input="filterAddUser">
300
+ </div>
301
+ <div class="pick-scroll au-scroll" v-loading="addUserLoading">
302
+ <template v-if="selectableUsers.length">
303
+ <label
304
+ v-for="u in selectableUsers"
305
+ :key="u.ID"
306
+ :class="['pick-item', { 'is-disabled': u.inGroup }]"
307
+ >
308
+ <input
309
+ v-model="selUserIds"
310
+ type="checkbox"
311
+ :value="u.ID"
312
+ :disabled="u.inGroup"
313
+ >
314
+ <span class="pick-item__name">{{ u.NAME }}</span>
315
+ <span class="v9-tag v9-tag--info">{{ u.USER_NO }}</span>
316
+ <span class="v9-form-item__tip grp-inline-tip">{{ u.DEPT_NAME }}</span>
317
+ <span v-if="u.inGroup" class="v9-tag v9-tag--success">已在本组</span>
318
+ </label>
319
+ </template>
320
+ <div v-else class="v9-empty">
321
+ <i class="el-icon-search v9-empty__icon"></i>
322
+ <div>没有匹配的用户</div>
323
+ </div>
324
+ </div>
325
+ <el-pagination
326
+ v-if="addUserTotal > addUserLimit"
327
+ small
328
+ layout="prev, pager, next"
329
+ v-model:current-page="addUserPage"
330
+ :page-size="addUserLimit"
331
+ :total="addUserTotal"
332
+ @current-change="handleAddUserPage"
333
+ />
334
+ </div>
335
+ <div class="v9-dialog__footer">
336
+ <span class="v9-form-item__tip pick-count">{{ userCountText }}</span>
337
+ <button class="v9-btn v9-btn--default" @click="dlg.addUser = false">取消</button>
338
+ <button class="v9-btn v9-btn--primary" @click="doAddUsers"><i class="el-icon-circle-plus"></i> 授予组内全部角色</button>
339
+ </div>
340
+ </div>
341
+ </div>
342
+
343
+ <!-- ================= 弹窗:从组移除用户 ================= -->
344
+ <div v-if="dlg.removeUser" class="v9-overlay" @click.self="dlg.removeUser = false">
345
+ <div class="v9-dialog">
346
+ <div class="v9-dialog__header">
347
+ <span>从「{{ curGroup && curGroup.NAME }}」移除「{{ rmUser.label }}」</span>
348
+ <span class="v9-dialog__close" @click="dlg.removeUser = false"><i class="el-icon-close"></i></span>
349
+ </div>
350
+ <div class="v9-dialog__body">
351
+ <table class="v9-desc-table ru-impact">
352
+ <tbody>
353
+ <tr><th>通过本组持有的角色</th><td>{{ rmUser.total }} 个</td></tr>
354
+ <tr><th>仅组来源</th><td>{{ rmUser.total - rmUser.withManual }} 个 → 整条删除(权限收回)</td></tr>
355
+ <tr><th>另有手工授予</th><td>{{ rmUser.withManual }} 个 → 仅清除组来源,手工权限保留</td></tr>
356
+ </tbody>
357
+ </table>
358
+ <div class="v9-form-item__tip">按位收回:另有手工授予的角色仅清除组来源、手工权限保留;仅组来源的角色整条删除、权限收回。</div>
359
+ </div>
360
+ <div class="v9-dialog__footer">
361
+ <button class="v9-btn v9-btn--default" @click="dlg.removeUser = false">取消</button>
362
+ <button class="v9-btn v9-btn--danger" @click="doRemoveUser"><i class="el-icon-delete"></i> 移除并收回</button>
363
+ </div>
364
+ </div>
365
+ </div>
366
+
367
+ <!-- 轻提示 -->
368
+ <div class="toast-box">
369
+ <div v-if="toast.show" :class="['v9-message', toastClass]">
370
+ <i :class="toastIcon" class="v9-message__icon"></i>
371
+ <span>{{ toast.text }}</span>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ </template>
376
+
377
+ <script>
378
+ import component from '@epxing/core/src/mixins/component.js'
379
+
380
+ export default {
381
+ name: 'epx-role-group-manage',
382
+ mixins: [component],
383
+ data () {
384
+ return {
385
+ curGroupId: '', // 当前查看的组
386
+ groupList: [], // 组列表(含 roleCount / userCount 聚合)
387
+ curGroup: null, // 当前组基本信息
388
+ detail: { sysCount: 0 }, // 组详情附加统计
389
+ groupRoles: [], // 组内角色
390
+ groupUsers: [], // 已授权用户
391
+ activeTab: 'roles', // 当前页签
392
+ pendingApply: [], // 本次新增待重新应用的角色
393
+ // 弹窗开关
394
+ dlg: {
395
+ groupForm: false,
396
+ pickRole: false,
397
+ removeRole: false,
398
+ delGroup: false,
399
+ addUser: false,
400
+ removeUser: false
401
+ },
402
+ // 新建/编辑表单
403
+ formGroup: { ID: '', NAME: '', CODE: '', DESC: '', ORDER_NUM: 100 },
404
+ formErr: { name: false, code: false },
405
+ // 添加角色
406
+ selectableRoles: [], // 按系统分组
407
+ selRoleIds: [],
408
+ // 移除角色
409
+ rmRole: { id: '', label: '', total: 0, withManual: 0 },
410
+ // 删除组
411
+ delGroupData: { ID: '', NAME: '', onlyGroup: 0, both: 0, userCount: 0 },
412
+ // 添加用户(后端分页,避免租户用户量大时全量渲染拖垮页面)
413
+ selectableUsers: [],
414
+ selUserIds: [],
415
+ addUserKeyword: '',
416
+ addUserTotal: 0,
417
+ addUserPage: 1,
418
+ addUserLimit: 50,
419
+ addUserLoading: false,
420
+ addUserTimer: null,
421
+ // 移除用户
422
+ rmUser: { id: '', label: '', total: 0, withManual: 0 },
423
+ // 轻提示
424
+ toast: { show: false, type: 'success', text: '' },
425
+ toastTimer: null
426
+ }
427
+ },
428
+ computed: {
429
+ pickCountText () {
430
+ return this.selRoleIds.length ? '已选 ' + this.selRoleIds.length + ' 个角色' : '尚未选择角色'
431
+ },
432
+ userCountText () {
433
+ return this.selUserIds.length ? '已选 ' + this.selUserIds.length + ' 个用户' : '尚未选择用户'
434
+ },
435
+ toastClass () {
436
+ return { success: 'v9-message--success', error: 'v9-message--error', warn: 'v9-message--warning', info: 'v9-message--info' }[this.toast.type] || 'v9-message--info'
437
+ },
438
+ toastIcon () {
439
+ return { success: 'el-icon-success', error: 'el-icon-error', warn: 'el-icon-warning-outline', info: 'el-icon-info' }[this.toast.type] || 'el-icon-info'
440
+ }
441
+ },
442
+ created () {
443
+ this.getGroupList(() => {
444
+ // 支持从绑定追溯页带组 ID 进入
445
+ const qid = this.$query && this.$query.groupId
446
+ if (qid && this.groupList.some(g => g.ID === qid)) {
447
+ this.selectGroup(qid)
448
+ } else if (this.groupList.length) {
449
+ this.selectGroup(this.groupList[0].ID)
450
+ }
451
+ })
452
+ },
453
+ methods: {
454
+ msg (type, text) {
455
+ this.toast = { show: true, type, text }
456
+ clearTimeout(this.toastTimer)
457
+ this.toastTimer = setTimeout(() => { this.toast.show = false }, type === 'error' ? 6000 : 3600)
458
+ },
459
+ // ---------- 数据加载 ----------
460
+ getGroupList (cb) {
461
+ this.$http.$request({ action: 'getGroupList', entityId: 'FM_ROLE_GROUP' })
462
+ .then(data => {
463
+ this.groupList = data.groups || []
464
+ cb && cb()
465
+ })
466
+ .catch(err => this.msg('error', err.message || '获取角色组列表失败'))
467
+ },
468
+ getGroupDetail () {
469
+ if (!this.curGroupId) return
470
+ this.$http.$request({ action: 'getGroupDetail', entityId: 'FM_ROLE_GROUP', groupId: this.curGroupId })
471
+ .then(data => {
472
+ this.curGroup = data.group || null
473
+ this.groupRoles = data.roles || []
474
+ this.groupUsers = data.users || []
475
+ this.detail.sysCount = (data.stats && data.stats.sysCount) || 0
476
+ this.pendingApply = data.pendingApply || []
477
+ })
478
+ .catch(err => this.msg('error', err.message || '获取组详情失败'))
479
+ },
480
+ selectGroup (gid) {
481
+ this.curGroupId = gid
482
+ this.activeTab = 'roles'
483
+ this.getGroupList()
484
+ this.getGroupDetail()
485
+ },
486
+ switchGroupTab (tab) {
487
+ this.activeTab = tab
488
+ },
489
+ // ---------- 新建 / 编辑组 ----------
490
+ openGroupForm (g) {
491
+ this.formGroup = g
492
+ ? { ID: g.ID, NAME: g.NAME, CODE: g.CODE, DESC: g.DESC || '', ORDER_NUM: g.ORDER_NUM }
493
+ : { ID: '', NAME: '', CODE: '', DESC: '', ORDER_NUM: 100 }
494
+ this.formErr = { name: false, code: false }
495
+ this.dlg.groupForm = true
496
+ },
497
+ saveGroupForm () {
498
+ const name = (this.formGroup.NAME || '').trim()
499
+ const code = (this.formGroup.CODE || '').trim()
500
+ this.formErr.name = !name
501
+ this.formErr.code = !/^[A-Za-z][A-Za-z0-9_]*$/.test(code)
502
+ if (this.formErr.name || this.formErr.code) return
503
+ this.$http.$request({
504
+ action: 'saveGroup',
505
+ entityId: 'FM_ROLE_GROUP',
506
+ 'bean.ID': this.formGroup.ID || '',
507
+ 'bean.NAME': name,
508
+ 'bean.CODE': code,
509
+ 'bean.DESC': (this.formGroup.DESC || '').trim(),
510
+ 'bean.ORDER_NUM': parseInt(this.formGroup.ORDER_NUM, 10) || 0
511
+ })
512
+ .then(() => {
513
+ const isNew = !this.formGroup.ID
514
+ this.dlg.groupForm = false
515
+ this.getGroupList(() => {
516
+ if (isNew) {
517
+ // 新建后定位到新组,引导添加角色
518
+ const created = this.groupList[this.groupList.length - 1]
519
+ if (created) this.selectGroup(created.ID)
520
+ } else {
521
+ this.getGroupDetail()
522
+ }
523
+ })
524
+ this.msg('success', '角色组「' + name + '」' + (isNew ? '已创建,接下来向组内添加角色' : '已保存'))
525
+ })
526
+ .catch(err => {
527
+ // 后端唯一性校验拦截
528
+ const msgText = err.message || ''
529
+ if (msgText.indexOf('名称') >= 0) this.formErr.name = true
530
+ if (msgText.indexOf('编码') >= 0) this.formErr.code = true
531
+ this.msg('error', msgText || '保存失败')
532
+ })
533
+ },
534
+ // ---------- 添加角色 ----------
535
+ openPickRole () {
536
+ this.selRoleIds = []
537
+ this.$http.$request({ action: 'getSelectableRoles', entityId: 'FM_ROLE_GROUP', groupId: this.curGroupId })
538
+ .then(data => {
539
+ this.selectableRoles = data.systems || []
540
+ this.dlg.pickRole = true
541
+ })
542
+ .catch(err => this.msg('error', err.message || '获取可选角色失败'))
543
+ },
544
+ savePickRole () {
545
+ if (!this.selRoleIds.length) { this.msg('warn', '请先勾选要加入的角色'); return }
546
+ this.$http.$request({
547
+ action: 'addRolesToGroup',
548
+ entityId: 'FM_ROLE_GROUP',
549
+ groupId: this.curGroupId,
550
+ roleIds: this.selRoleIds.join(',')
551
+ })
552
+ .then(data => {
553
+ this.dlg.pickRole = false
554
+ this.getGroupList()
555
+ this.getGroupDetail()
556
+ this.msg('success', '已加入 ' + this.selRoleIds.length + ' 个角色' + (data.appliedCreated ? ',已自动补授给本组已授权用户(新建绑定 ' + data.appliedCreated + ' 条)' : ''))
557
+ })
558
+ .catch(err => this.msg('error', err.message || '保存被拦截(角色单组归属校验)'))
559
+ },
560
+ // ---------- 移除角色(按位收回) ----------
561
+ openRemoveRole (r) {
562
+ this.$http.$request({
563
+ action: 'getRemoveRoleImpact',
564
+ entityId: 'FM_ROLE_GROUP',
565
+ groupId: this.curGroupId,
566
+ roleId: r.ID
567
+ })
568
+ .then(data => {
569
+ this.rmRole = { id: r.ID, label: r.NAME + '(' + r.SYSTEM_NAME + ')', total: data.total || 0, withManual: data.withManual || 0 }
570
+ this.dlg.removeRole = true
571
+ })
572
+ .catch(err => this.msg('error', err.message || '获取影响统计失败'))
573
+ },
574
+ doRemoveRole () {
575
+ this.$http.$request({
576
+ action: 'removeRoleFromGroup',
577
+ entityId: 'FM_ROLE_GROUP',
578
+ groupId: this.curGroupId,
579
+ roleId: this.rmRole.id
580
+ })
581
+ .then(data => {
582
+ this.dlg.removeRole = false
583
+ this.getGroupList()
584
+ this.getGroupDetail()
585
+ this.msg('success', '「' + this.rmRole.label + '」已移出并收回组来源:整条删除 ' + (data.removed || 0) + ' 条;另有手工授予的 ' + (data.kept || 0) + ' 条仅清组位、绑定保留', 6000)
586
+ })
587
+ .catch(err => this.msg('error', err.message || '移除失败'))
588
+ },
589
+ // ---------- 重新应用(差量补绑) ----------
590
+ applyGroup () {
591
+ this.$http.$request({ action: 'applyGroup', entityId: 'FM_ROLE_GROUP', groupId: this.curGroupId })
592
+ .then(data => {
593
+ this.getGroupDetail()
594
+ this.msg('success', '已按发起时刻的组内角色与用户快照补绑:新建 ' + (data.created || 0) + ' 条,判重跳过 ' + (data.skipped || 0) + ' 条')
595
+ })
596
+ .catch(err => this.msg('error', err.message || '重新应用失败'))
597
+ },
598
+ // ---------- 删除组(按位收回) ----------
599
+ openDelGroup (g) {
600
+ this.$http.$request({ action: 'getDeleteGroupImpact', entityId: 'FM_ROLE_GROUP', groupId: g.ID })
601
+ .then(data => {
602
+ this.delGroupData = {
603
+ ID: g.ID,
604
+ NAME: g.NAME,
605
+ onlyGroup: data.onlyGroup || 0,
606
+ both: data.both || 0,
607
+ userCount: data.userCount || 0
608
+ }
609
+ this.dlg.delGroup = true
610
+ })
611
+ .catch(err => this.msg('error', err.message || '获取影响统计失败'))
612
+ },
613
+ doDelGroup () {
614
+ this.$http.$request({ action: 'deleteGroup', entityId: 'FM_ROLE_GROUP', groupId: this.delGroupData.ID })
615
+ .then(data => {
616
+ this.dlg.delGroup = false
617
+ this.msg('success', '角色组「' + this.delGroupData.NAME + '」已删除:收回绑定 ' + (data.removed || 0) + ' 条,另有手工授予的 ' + (data.kept || 0) + ' 条仅清组位、记录保留', 6000)
618
+ this.curGroupId = ''
619
+ this.curGroup = null
620
+ this.getGroupList(() => {
621
+ if (this.groupList.length) this.selectGroup(this.groupList[0].ID)
622
+ })
623
+ })
624
+ .catch(err => this.msg('error', err.message || '删除失败'))
625
+ },
626
+ // ---------- 添加用户(物化展开) ----------
627
+ openAddUser () {
628
+ this.selUserIds = []
629
+ this.addUserKeyword = ''
630
+ this.addUserPage = 1
631
+ this.getSelectableUsers()
632
+ this.dlg.addUser = true
633
+ },
634
+ getSelectableUsers () {
635
+ this.addUserLoading = true
636
+ this.$http.$request({
637
+ action: 'getSelectableUsers',
638
+ entityId: 'FM_ROLE_GROUP',
639
+ groupId: this.curGroupId,
640
+ keyword: this.addUserKeyword,
641
+ page: this.addUserPage,
642
+ limit: this.addUserLimit
643
+ })
644
+ .then(data => {
645
+ this.selectableUsers = data.users || []
646
+ this.addUserTotal = data.total || 0
647
+ })
648
+ .catch(err => this.msg('error', err.message || '获取用户失败'))
649
+ .finally(() => { this.addUserLoading = false })
650
+ },
651
+ filterAddUser () {
652
+ // 输入防抖:每敲一键都全量检索会打爆后端
653
+ clearTimeout(this.addUserTimer)
654
+ this.addUserTimer = setTimeout(() => {
655
+ this.addUserPage = 1
656
+ this.getSelectableUsers()
657
+ }, 300)
658
+ },
659
+ handleAddUserPage (page) {
660
+ this.addUserPage = page
661
+ this.getSelectableUsers()
662
+ },
663
+ doAddUsers () {
664
+ if (!this.selUserIds.length) { this.msg('warn', '请先勾选要添加的用户'); return }
665
+ this.$http.$request({
666
+ action: 'addUsersToGroup',
667
+ entityId: 'FM_ROLE_GROUP',
668
+ groupId: this.curGroupId,
669
+ userIds: this.selUserIds.join(',')
670
+ })
671
+ .then(data => {
672
+ this.dlg.addUser = false
673
+ this.getGroupList()
674
+ this.getGroupDetail()
675
+ const both = data.both ? '其中 ' + data.both + ' 个角色另有手工授予,已并列保留(两来源并存)' : ''
676
+ this.msg('success', '已添加 ' + this.selUserIds.length + ' 个用户并展开组内角色:新建 ' + (data.created || 0) + ' 条,组位置为本组 ' + (data.moved || 0) + ' 条,判重跳过 ' + (data.skipped || 0) + ' 条。' + both, 6000)
677
+ })
678
+ .catch(err => this.msg('error', err.message || '添加失败'))
679
+ },
680
+ // ---------- 移除用户(按位收回) ----------
681
+ openRemoveUser (u) {
682
+ this.$http.$request({
683
+ action: 'getRemoveUserImpact',
684
+ entityId: 'FM_ROLE_GROUP',
685
+ groupId: this.curGroupId,
686
+ userId: u.ID
687
+ })
688
+ .then(data => {
689
+ this.rmUser = { id: u.ID, label: u.NAME + '(' + u.USER_NO + ')', total: data.total || 0, withManual: data.withManual || 0 }
690
+ this.dlg.removeUser = true
691
+ })
692
+ .catch(err => this.msg('error', err.message || '获取影响统计失败'))
693
+ },
694
+ doRemoveUser () {
695
+ this.$http.$request({
696
+ action: 'removeUserFromGroup',
697
+ entityId: 'FM_ROLE_GROUP',
698
+ groupId: this.curGroupId,
699
+ userId: this.rmUser.id
700
+ })
701
+ .then(data => {
702
+ this.dlg.removeUser = false
703
+ this.getGroupList()
704
+ this.getGroupDetail()
705
+ this.msg('success', '已移除该用户:整条删除 ' + (data.removed || 0) + ' 条;另有手工授予的 ' + (data.kept || 0) + ' 条仅清组位、绑定保留', 6000)
706
+ })
707
+ .catch(err => this.msg('error', err.message || '移除失败'))
708
+ }
709
+ }
710
+ }
711
+ </script>
712
+
713
+ <style lang="scss" scoped>
714
+ /* ===== 以下样式值均取自原型 V9 设计系统,保持逐项一致 ===== */
715
+ .rgm-page {
716
+ min-height: 100%;
717
+ padding: 24px;
718
+ background: var(--epx-bg-card, #f2f3f7);
719
+ font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
720
+ font-size: 14px;
721
+ line-height: 22px;
722
+ color: var(--epx-text, #444);
723
+ }
724
+
725
+ /* 左右布局 */
726
+ .split {
727
+ display: flex;
728
+ gap: 16px;
729
+ align-items: flex-start;
730
+ }
731
+ .split__left { flex: 0 0 280px; }
732
+ .split__right { flex: 1 1 auto; min-width: 0; }
733
+ @media (max-width: 992px) {
734
+ .split { flex-direction: column; }
735
+ .split__left { flex: none; width: 100%; }
736
+ }
737
+
738
+ /* 卡片 */
739
+ .v9-card {
740
+ background: var(--epx-bg-card, #fff);
741
+ border-radius: 4px;
742
+ padding: 24px;
743
+ }
744
+ /* 区块标题(主题色竖条) */
745
+ .v9-block-title {
746
+ display: flex;
747
+ align-items: center;
748
+ gap: 8px;
749
+ font-size: 16px;
750
+ font-weight: 600;
751
+ color: var(--epx-text, #222);
752
+ margin-bottom: 16px;
753
+ &::before {
754
+ content: '';
755
+ width: 4px;
756
+ height: 16px;
757
+ border-radius: 2px;
758
+ background: #0874e7;
759
+ }
760
+ }
761
+
762
+ /* 组列表项 */
763
+ .group-list { display: flex; flex-direction: column; gap: 2px; }
764
+ .grp-item {
765
+ display: flex;
766
+ align-items: center;
767
+ gap: 8px;
768
+ padding: 12px 16px;
769
+ border-radius: 4px;
770
+ cursor: pointer;
771
+ border: 1px solid transparent;
772
+ border-left: 3px solid transparent;
773
+ &:hover {
774
+ background: var(--epx-bg-card, #f5f7fa);
775
+ .grp-item__ops { visibility: visible; }
776
+ }
777
+ &.is-active {
778
+ background: var(--epx-bg, #e6f6ff);
779
+ border-left-color: var(--el-color-primary, #0874e7);
780
+ }
781
+ }
782
+ .grp-item__name { font-weight: 500; color: var(--epx-text, #222); }
783
+ .grp-item__meta { font-size: 12px; color: var(--epx-text-secondary, #888); margin-top: 2px; }
784
+ .grp-item__ops { margin-left: auto; visibility: hidden; white-space: nowrap; }
785
+ .grp-add-btn { width: 100%; margin-top: 12px; }
786
+ .grp-left-tip { margin-top: 8px; }
787
+
788
+ /* 按钮 */
789
+ .v9-btn {
790
+ display: inline-flex;
791
+ align-items: center;
792
+ justify-content: center;
793
+ gap: 6px;
794
+ height: 32px;
795
+ padding: 0 16px;
796
+ font-size: 14px;
797
+ line-height: 1;
798
+ border: 1px solid transparent;
799
+ border-radius: 4px;
800
+ cursor: pointer;
801
+ user-select: none;
802
+ white-space: nowrap;
803
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
804
+ background: var(--epx-bg-card, #fff);
805
+ color: var(--epx-text, #444);
806
+ outline: none;
807
+ font-family: inherit;
808
+ &--default {
809
+ background: var(--epx-bg-card, #fff);
810
+ border-color: var(--epx-border, #dcdfe6);
811
+ color: var(--epx-text, #444);
812
+ &:hover { color: var(--el-color-primary, #0874e7); border-color: var(--epx-border, #82cbff); background: var(--epx-bg, #e6f6ff); }
813
+ }
814
+ &--primary {
815
+ background: #0874e7;
816
+ color: #fff;
817
+ &:hover { background: var(--epx-bg, #2f95f5); }
818
+ &:active { background: #0057c2; }
819
+ }
820
+ &--danger {
821
+ background: var(--epx-bg, #f56c6c);
822
+ color: #fff;
823
+ &:hover { background: var(--epx-bg, #f78989); }
824
+ &:active { background: var(--epx-bg, #dd6161); }
825
+ }
826
+ &--text {
827
+ background: transparent;
828
+ border-color: transparent;
829
+ color: var(--el-color-primary, #0874e7);
830
+ padding: 0 4px;
831
+ height: auto;
832
+ &:hover { color: var(--epx-text-secondary, #2f95f5); background: transparent; }
833
+ &.is-danger { color: var(--el-color-danger, #f56c6c); }
834
+ }
835
+ }
836
+
837
+ /* 提示条 */
838
+ .tipbar {
839
+ display: flex;
840
+ align-items: center;
841
+ gap: 8px;
842
+ padding: 12px 16px;
843
+ border-radius: 4px;
844
+ font-size: 14px;
845
+ margin-bottom: 16px;
846
+ &--info { background: var(--epx-bg, #e6f6ff); color: var(--el-color-primary, #0874e7); }
847
+ &--warn { background: var(--epx-bg-card, #fdf6ec); color: var(--epx-text-secondary, #e6a23a); }
848
+ &--danger { background: var(--epx-bg-card, #fef0f0); color: var(--el-color-danger, #f56c6c); }
849
+ .tipbar__main { flex: 1; }
850
+ b { font-weight: 600; }
851
+ }
852
+
853
+ /* 数字统计卡 */
854
+ .v9-figure-grid {
855
+ display: grid;
856
+ grid-template-columns: repeat(3, minmax(0, 1fr));
857
+ gap: 12px;
858
+ }
859
+ .v9-figure {
860
+ background: var(--epx-bg-card, #f5f7fa);
861
+ border-radius: 4px;
862
+ padding: 16px;
863
+ min-width: 0;
864
+ transition: box-shadow 0.15s, background 0.15s;
865
+ &:hover { box-shadow: 0 4px 12px rgba(17, 24, 39, 0.08), 0 2px 6px -2px rgba(17, 24, 39, 0.05); }
866
+ }
867
+ .v9-figure__label {
868
+ font-size: 12px;
869
+ color: var(--epx-text-secondary, #888);
870
+ margin-bottom: 4px;
871
+ white-space: nowrap;
872
+ overflow: hidden;
873
+ text-overflow: ellipsis;
874
+ }
875
+ .v9-figure__value {
876
+ font-size: 20px;
877
+ font-weight: 600;
878
+ color: var(--epx-text, #222);
879
+ line-height: 28px;
880
+ }
881
+ @media (max-width: 1100px) {
882
+ .v9-figure-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
883
+ }
884
+
885
+ /* 下划线页签 */
886
+ .v9-tabs {
887
+ display: flex;
888
+ gap: 24px;
889
+ border-bottom: 1px solid var(--epx-border, #e4e7ed);
890
+ }
891
+ .v9-tabs__item {
892
+ position: relative;
893
+ padding: 12px 0;
894
+ cursor: pointer;
895
+ color: var(--epx-text, #444);
896
+ &.is-active {
897
+ color: var(--el-color-primary, #0874e7);
898
+ &::after {
899
+ content: '';
900
+ position: absolute;
901
+ left: 0;
902
+ right: 0;
903
+ bottom: -1px;
904
+ height: 2px;
905
+ background: #0874e7;
906
+ }
907
+ }
908
+ }
909
+ .grp-tab-body { margin-top: 16px; }
910
+ .grp-tab-toolbar { margin-bottom: 12px; display: flex; align-items: center; }
911
+ .grp-inline-tip { display: inline; margin-left: 12px; margin-top: 0; }
912
+ .grp-sys-icon { margin-right: 4px; }
913
+ .grp-table-foot-tip { margin-top: 8px; }
914
+ .grp-edit-row { margin-top: 12px; }
915
+
916
+ /* 表格 */
917
+ .v9-table {
918
+ width: 100%;
919
+ border-collapse: collapse;
920
+ background: var(--epx-bg-card, #fff);
921
+ font-size: 14px;
922
+ th, td {
923
+ padding: 0 16px;
924
+ height: 48px;
925
+ text-align: left;
926
+ border-bottom: 1px solid var(--epx-border, #e4e7ed);
927
+ }
928
+ thead th {
929
+ background: var(--epx-bg-card, #f2f3f7);
930
+ color: var(--epx-text, #444);
931
+ font-weight: 500;
932
+ white-space: nowrap;
933
+ }
934
+ tbody td { color: var(--epx-text, #444); }
935
+ tbody tr:hover > td { background: var(--epx-bg, #e6f6ff); }
936
+ }
937
+
938
+ /* 描述型表格 */
939
+ .v9-desc-table {
940
+ width: 100%;
941
+ border-collapse: collapse;
942
+ border: 1px solid var(--epx-border, #e4e7ed);
943
+ th {
944
+ width: 120px;
945
+ text-align: right;
946
+ padding: 12px 16px;
947
+ background: var(--epx-bg-card, #f5f7fa);
948
+ color: var(--epx-text, #444);
949
+ font-weight: 400;
950
+ border: 1px solid var(--epx-border, #e4e7ed);
951
+ vertical-align: middle;
952
+ }
953
+ td {
954
+ padding: 12px 16px;
955
+ color: var(--epx-text, #222);
956
+ border: 1px solid var(--epx-border, #e4e7ed);
957
+ vertical-align: middle;
958
+ }
959
+ }
960
+
961
+ /* 标签 */
962
+ .v9-tag {
963
+ display: inline-flex;
964
+ align-items: center;
965
+ height: 22px;
966
+ padding: 0 8px;
967
+ font-size: 12px;
968
+ border-radius: 4px;
969
+ border: 1px solid transparent;
970
+ line-height: 1;
971
+ &--primary { background: var(--epx-bg, #e6f6ff); color: var(--el-color-primary, #0874e7); border-color: var(--epx-border, #82cbff); }
972
+ &--success { background: var(--epx-bg-card, #f0f9eb); color: var(--epx-text-secondary, #67c23a); border-color: var(--epx-border, #c2e7b0); }
973
+ &--warning { background: var(--epx-bg-card, #fdf6ec); color: var(--epx-text-secondary, #e6a23a); border-color: var(--epx-border, #f5dab1); }
974
+ &--danger { background: var(--epx-bg-card, #fef0f0); color: var(--el-color-danger, #f56c6c); border-color: var(--epx-border, #fab6b6); }
975
+ &--info { background: var(--epx-bg-card, #f4f4f5); color: var(--epx-text-secondary, #888); border-color: var(--epx-border, #e9e9eb); }
976
+ }
977
+
978
+ /* 空状态 */
979
+ .v9-empty {
980
+ display: flex;
981
+ flex-direction: column;
982
+ align-items: center;
983
+ justify-content: center;
984
+ padding: 40px 0;
985
+ color: var(--epx-text-secondary, #888);
986
+ gap: 12px;
987
+ }
988
+ .v9-empty__icon { font-size: 64px; color: var(--epx-text-secondary, #c0c4cc); }
989
+
990
+ /* 表单 */
991
+ .v9-form-item { margin-bottom: 16px; }
992
+ .v9-form-item__label {
993
+ display: block;
994
+ margin-bottom: 8px;
995
+ font-size: 14px;
996
+ color: var(--epx-text, #444);
997
+ &.is-required::before {
998
+ content: '*';
999
+ color: var(--el-color-danger, #f56c6c);
1000
+ margin-right: 4px;
1001
+ }
1002
+ }
1003
+ .v9-form-item__error { margin-top: 4px; font-size: 12px; color: var(--el-color-danger, #f56c6c); }
1004
+ .v9-form-item__tip { margin-top: 4px; font-size: 12px; color: var(--epx-text-secondary, #888); }
1005
+
1006
+ /* 输入框 */
1007
+ .v9-input {
1008
+ width: 100%;
1009
+ height: 32px;
1010
+ padding: 0 12px;
1011
+ font-size: 14px;
1012
+ color: var(--epx-text, #444);
1013
+ background: var(--epx-bg-card, #fff);
1014
+ border: 1px solid var(--epx-border, #dcdfe6);
1015
+ border-radius: 4px;
1016
+ outline: none;
1017
+ font-family: inherit;
1018
+ transition: border-color 0.15s, box-shadow 0.15s;
1019
+ &::placeholder { color: var(--epx-text-secondary, #aaa); }
1020
+ &:hover { border-color: var(--epx-border, #c0c4cc); }
1021
+ &:focus { border-color: var(--epx-border, #0874e7); box-shadow: 0 0 0 3px rgba(8, 116, 231, 0.15); }
1022
+ &.is-error { border-color: var(--epx-border, #f56c6c); }
1023
+ }
1024
+ .v9-input-wrap {
1025
+ position: relative;
1026
+ display: inline-flex;
1027
+ align-items: center;
1028
+ width: 100%;
1029
+ .v9-input { padding-left: 32px; }
1030
+ .v9-input-prefix {
1031
+ position: absolute;
1032
+ top: 50%;
1033
+ transform: translateY(-50%);
1034
+ left: 12px;
1035
+ display: inline-flex;
1036
+ align-items: center;
1037
+ height: 16px;
1038
+ font-size: 16px;
1039
+ line-height: 1;
1040
+ color: var(--epx-text-secondary, #888);
1041
+ pointer-events: none;
1042
+ }
1043
+ }
1044
+
1045
+ /* 弹窗 */
1046
+ .v9-overlay {
1047
+ position: fixed;
1048
+ top: 0;
1049
+ right: 0;
1050
+ bottom: 0;
1051
+ left: 0;
1052
+ z-index: 2000;
1053
+ background: rgba(0, 0, 0, 0.5);
1054
+ display: flex;
1055
+ align-items: flex-start;
1056
+ justify-content: center;
1057
+ padding-top: 15vh;
1058
+ }
1059
+ .v9-dialog {
1060
+ background: var(--epx-bg-card, #fff);
1061
+ width: 520px;
1062
+ max-width: 90vw;
1063
+ border-radius: 8px;
1064
+ box-shadow: 0 12px 32px rgba(17, 24, 39, 0.10), 0 6px 12px -4px rgba(17, 24, 39, 0.06);
1065
+ overflow: hidden;
1066
+ &--md { width: 680px; }
1067
+ &--lg { width: 900px; }
1068
+ }
1069
+ .v9-dialog__header {
1070
+ height: 56px;
1071
+ display: flex;
1072
+ align-items: center;
1073
+ padding: 0 24px;
1074
+ font-size: 16px;
1075
+ font-weight: 600;
1076
+ color: var(--epx-text, #222);
1077
+ }
1078
+ .v9-dialog__close {
1079
+ margin-left: auto;
1080
+ cursor: pointer;
1081
+ color: var(--epx-text-secondary, #888);
1082
+ font-size: 18px;
1083
+ }
1084
+ .v9-dialog__body {
1085
+ padding: 20px 24px;
1086
+ color: var(--epx-text, #444);
1087
+ }
1088
+ .v9-dialog__footer {
1089
+ height: 56px;
1090
+ display: flex;
1091
+ align-items: center;
1092
+ justify-content: flex-end;
1093
+ gap: 12px;
1094
+ padding: 0 24px;
1095
+ }
1096
+
1097
+ /* 角色选择器(按系统分组) */
1098
+ .pick-tip { margin-bottom: 12px; margin-top: 0; }
1099
+ .pick-scroll { max-height: 380px; overflow: auto; }
1100
+ .pick-group { margin-bottom: 16px; }
1101
+ .pick-group__title {
1102
+ display: flex;
1103
+ align-items: center;
1104
+ gap: 8px;
1105
+ font-weight: 500;
1106
+ color: var(--epx-text, #222);
1107
+ padding: 8px 0;
1108
+ border-bottom: 1px solid var(--epx-border, #e4e7ed);
1109
+ margin-bottom: 8px;
1110
+ i { color: var(--epx-text, #5c6066); }
1111
+ }
1112
+ .pick-item {
1113
+ display: flex;
1114
+ align-items: center;
1115
+ gap: 8px;
1116
+ padding: 8px 8px 8px 16px;
1117
+ border-radius: 4px;
1118
+ cursor: pointer;
1119
+ &:hover { background: var(--epx-bg-card, #f5f7fa); }
1120
+ &.is-disabled {
1121
+ color: var(--epx-text-secondary, #aaa);
1122
+ cursor: not-allowed;
1123
+ background: transparent;
1124
+ &:hover { background: transparent; }
1125
+ }
1126
+ }
1127
+ .pick-item__name { min-width: 120px; }
1128
+ .pick-count { flex: 1; margin-top: 0; }
1129
+
1130
+ /* 添加用户 */
1131
+ .au-search { margin-bottom: 12px; }
1132
+ .au-scroll { max-height: 320px; }
1133
+ .ru-impact { margin-bottom: 16px; }
1134
+ .del-tipbar { margin-bottom: 12px; }
1135
+ .del-impact { margin-bottom: 12px; }
1136
+
1137
+ /* 轻提示 */
1138
+ .toast-box {
1139
+ position: fixed;
1140
+ top: 76px;
1141
+ left: 50%;
1142
+ transform: translateX(-50%);
1143
+ z-index: 3000;
1144
+ max-width: 640px;
1145
+ }
1146
+ .v9-message {
1147
+ display: inline-flex;
1148
+ align-items: center;
1149
+ gap: 8px;
1150
+ max-width: 640px;
1151
+ padding: 10px 16px;
1152
+ border-radius: 4px;
1153
+ font-size: 14px;
1154
+ box-shadow: 0 4px 12px rgba(17, 24, 39, 0.08), 0 2px 6px -2px rgba(17, 24, 39, 0.05);
1155
+ &--success { background: var(--epx-bg-card, #f0f9eb); color: var(--epx-text, #444); .v9-message__icon { color: var(--epx-text-secondary, #67c23a); } }
1156
+ &--warning { background: var(--epx-bg-card, #fdf6ec); color: var(--epx-text, #444); .v9-message__icon { color: var(--epx-text-secondary, #e6a23a); } }
1157
+ &--error { background: var(--epx-bg-card, #fef0f0); color: var(--epx-text, #444); .v9-message__icon { color: var(--el-color-danger, #f56c6c); } }
1158
+ &--info { background: var(--epx-bg, #edf2fc); color: var(--epx-text, #444); .v9-message__icon { color: var(--el-color-primary, #0874e7); } }
1159
+ }
1160
+ </style>