@liujitcn/kratos-admin-system 0.0.1

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 (208) hide show
  1. package/README.md +137 -0
  2. package/dist/package/declarations/index.d.ts +1 -0
  3. package/dist/package/declarations/src/ai.d.ts +10 -0
  4. package/dist/package/declarations/src/api/base/ai_message.d.ts +27 -0
  5. package/dist/package/declarations/src/api/base/ai_session.d.ts +17 -0
  6. package/dist/package/declarations/src/api/base/ai_tool.d.ts +7 -0
  7. package/dist/package/declarations/src/api/base/oauth.d.ts +13 -0
  8. package/dist/package/declarations/src/api/base/sse.d.ts +31 -0
  9. package/dist/package/declarations/src/api/system/auth.d.ts +17 -0
  10. package/dist/package/declarations/src/api/system/base_api.d.ts +22 -0
  11. package/dist/package/declarations/src/api/system/base_area.d.ts +19 -0
  12. package/dist/package/declarations/src/api/system/base_config.d.ts +20 -0
  13. package/dist/package/declarations/src/api/system/base_dept.d.ts +21 -0
  14. package/dist/package/declarations/src/api/system/base_dict.d.ts +32 -0
  15. package/dist/package/declarations/src/api/system/base_job.d.ts +28 -0
  16. package/dist/package/declarations/src/api/system/base_log.d.ts +9 -0
  17. package/dist/package/declarations/src/api/system/base_menu.d.ts +21 -0
  18. package/dist/package/declarations/src/api/system/base_migration.d.ts +10 -0
  19. package/dist/package/declarations/src/api/system/base_post.d.ts +21 -0
  20. package/dist/package/declarations/src/api/system/base_role.d.ts +23 -0
  21. package/dist/package/declarations/src/api/system/base_tenant.d.ts +21 -0
  22. package/dist/package/declarations/src/api/system/base_user.d.ts +23 -0
  23. package/dist/package/declarations/src/api/system/code_gen.d.ts +14 -0
  24. package/dist/package/declarations/src/api/system/code_gen_column.d.ts +12 -0
  25. package/dist/package/declarations/src/api/system/code_gen_proto.d.ts +10 -0
  26. package/dist/package/declarations/src/api/system/code_gen_sse.d.ts +8 -0
  27. package/dist/package/declarations/src/api/system/code_gen_table.d.ts +18 -0
  28. package/dist/package/declarations/src/api/system/project_document.d.ts +9 -0
  29. package/dist/package/declarations/src/components/Ai.vue.d.ts +3 -0
  30. package/dist/package/declarations/src/index.d.ts +3 -0
  31. package/dist/package/declarations/src/module.d.ts +2 -0
  32. package/dist/package/declarations/src/rpc/base/v1/ai_message.d.ts +82 -0
  33. package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +176 -0
  34. package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +59 -0
  35. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +167 -0
  36. package/dist/package/declarations/src/rpc/base/v1/sse.d.ts +13 -0
  37. package/dist/package/declarations/src/rpc/common/v1/common.d.ts +57 -0
  38. package/dist/package/declarations/src/rpc/common/v1/enum.d.ts +58 -0
  39. package/dist/package/declarations/src/rpc/common/v1/types.d.ts +60 -0
  40. package/dist/package/declarations/src/rpc/google/protobuf/empty.d.ts +11 -0
  41. package/dist/package/declarations/src/rpc/google/protobuf/timestamp.d.ts +107 -0
  42. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +156 -0
  43. package/dist/package/declarations/src/rpc/system/admin/v1/base_api.d.ts +193 -0
  44. package/dist/package/declarations/src/rpc/system/admin/v1/base_area.d.ts +82 -0
  45. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +112 -0
  46. package/dist/package/declarations/src/rpc/system/admin/v1/base_dept.d.ts +112 -0
  47. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +215 -0
  48. package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +177 -0
  49. package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +87 -0
  50. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +151 -0
  51. package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +64 -0
  52. package/dist/package/declarations/src/rpc/system/admin/v1/base_post.d.ts +112 -0
  53. package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +128 -0
  54. package/dist/package/declarations/src/rpc/system/admin/v1/base_tenant.d.ts +112 -0
  55. package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +161 -0
  56. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +155 -0
  57. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +143 -0
  58. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_proto.d.ts +86 -0
  59. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +149 -0
  60. package/dist/package/declarations/src/rpc/system/admin/v1/project_document.d.ts +64 -0
  61. package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +67 -0
  62. package/dist/package/declarations/src/views/ai/chat/attachment.d.ts +14 -0
  63. package/dist/package/declarations/src/views/ai/chat/components/AiMarkdown.vue.d.ts +13 -0
  64. package/dist/package/declarations/src/views/ai/chat/components/ChatPanel.vue.d.ts +45 -0
  65. package/dist/package/declarations/src/views/ai/chat/components/SessionPanel.vue.d.ts +34 -0
  66. package/dist/package/declarations/src/views/ai/chat/components/XSender.vue.d.ts +12 -0
  67. package/dist/package/declarations/src/views/ai/chat/index.vue.d.ts +4 -0
  68. package/dist/package/declarations/src/views/ai/chat/message.d.ts +59 -0
  69. package/dist/package/declarations/src/views/ai/chat/stream.d.ts +10 -0
  70. package/dist/package/declarations/src/views/ai/chat/types.d.ts +115 -0
  71. package/dist/package/declarations/src/views/base/api/index.vue.d.ts +3 -0
  72. package/dist/package/declarations/src/views/base/area/index.vue.d.ts +3 -0
  73. package/dist/package/declarations/src/views/base/config/index.vue.d.ts +3 -0
  74. package/dist/package/declarations/src/views/base/dept/index.vue.d.ts +3 -0
  75. package/dist/package/declarations/src/views/base/dict/index.vue.d.ts +3 -0
  76. package/dist/package/declarations/src/views/base/dict/item.vue.d.ts +3 -0
  77. package/dist/package/declarations/src/views/base/job/index.vue.d.ts +3 -0
  78. package/dist/package/declarations/src/views/base/job/log.vue.d.ts +3 -0
  79. package/dist/package/declarations/src/views/base/log/index.vue.d.ts +3 -0
  80. package/dist/package/declarations/src/views/base/menu/index.vue.d.ts +3 -0
  81. package/dist/package/declarations/src/views/base/migration/index.vue.d.ts +4 -0
  82. package/dist/package/declarations/src/views/base/post/index.vue.d.ts +3 -0
  83. package/dist/package/declarations/src/views/base/role/index.vue.d.ts +3 -0
  84. package/dist/package/declarations/src/views/base/tenant/index.vue.d.ts +3 -0
  85. package/dist/package/declarations/src/views/base/user/components/dept-tree.vue.d.ts +19 -0
  86. package/dist/package/declarations/src/views/base/user/index.vue.d.ts +3 -0
  87. package/dist/package/declarations/src/views/profile/components/base.vue.d.ts +13 -0
  88. package/dist/package/declarations/src/views/profile/components/password.vue.d.ts +3 -0
  89. package/dist/package/declarations/src/views/profile/components/security.vue.d.ts +15 -0
  90. package/dist/package/declarations/src/views/profile/index.vue.d.ts +3 -0
  91. package/dist/package/declarations/src/views/tool/api-doc/index.vue.d.ts +4 -0
  92. package/dist/package/declarations/src/views/tool/code-gen/code-preview/index.vue.d.ts +3 -0
  93. package/dist/package/declarations/src/views/tool/code-gen/columns/index.vue.d.ts +3 -0
  94. package/dist/package/declarations/src/views/tool/code-gen/columns/option-copy.d.ts +25 -0
  95. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenProgressDialog.vue.d.ts +16 -0
  96. package/dist/package/declarations/src/views/tool/code-gen/components/CodePreviewPane.vue.d.ts +9 -0
  97. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +32 -0
  98. package/dist/package/declarations/src/views/tool/code-gen/preview/capabilities.d.ts +20 -0
  99. package/dist/package/declarations/src/views/tool/code-gen/preview/data.d.ts +42 -0
  100. package/dist/package/declarations/src/views/tool/code-gen/preview/index.vue.d.ts +3 -0
  101. package/dist/package/declarations/src/views/tool/code-gen/proto/index.vue.d.ts +3 -0
  102. package/dist/package/declarations/src/views/tool/code-gen/table/index.vue.d.ts +3 -0
  103. package/dist/package/declarations/src/views/tool/project-doc/index.vue.d.ts +4 -0
  104. package/dist/package/src/ai.ts +16 -0
  105. package/dist/package/src/api/base/ai_message.ts +139 -0
  106. package/dist/package/src/api/base/ai_session.ts +77 -0
  107. package/dist/package/src/api/base/ai_tool.ts +22 -0
  108. package/dist/package/src/api/base/oauth.ts +47 -0
  109. package/dist/package/src/api/base/sse.ts +192 -0
  110. package/dist/package/src/api/system/auth.ts +65 -0
  111. package/dist/package/src/api/system/base_api.ts +95 -0
  112. package/dist/package/src/api/system/base_area.ts +73 -0
  113. package/dist/package/src/api/system/base_config.ts +82 -0
  114. package/dist/package/src/api/system/base_dept.ts +83 -0
  115. package/dist/package/src/api/system/base_dict.ts +144 -0
  116. package/dist/package/src/api/system/base_job.ts +125 -0
  117. package/dist/package/src/api/system/base_log.ts +32 -0
  118. package/dist/package/src/api/system/base_menu.ts +83 -0
  119. package/dist/package/src/api/system/base_migration.ts +35 -0
  120. package/dist/package/src/api/system/base_post.ts +83 -0
  121. package/dist/package/src/api/system/base_role.ts +93 -0
  122. package/dist/package/src/api/system/base_tenant.ts +83 -0
  123. package/dist/package/src/api/system/base_user.ts +93 -0
  124. package/dist/package/src/api/system/code_gen.ts +56 -0
  125. package/dist/package/src/api/system/code_gen_column.ts +43 -0
  126. package/dist/package/src/api/system/code_gen_proto.ts +32 -0
  127. package/dist/package/src/api/system/code_gen_sse.ts +33 -0
  128. package/dist/package/src/api/system/code_gen_table.ts +74 -0
  129. package/dist/package/src/api/system/project_document.ts +33 -0
  130. package/dist/package/src/components/Ai.vue +57 -0
  131. package/dist/package/src/index.ts +3 -0
  132. package/dist/package/src/module.ts +17 -0
  133. package/dist/package/src/rpc/base/v1/ai_message.ts +98 -0
  134. package/dist/package/src/rpc/base/v1/ai_session.ts +214 -0
  135. package/dist/package/src/rpc/base/v1/ai_tool.ts +74 -0
  136. package/dist/package/src/rpc/base/v1/oauth.ts +199 -0
  137. package/dist/package/src/rpc/base/v1/sse.ts +22 -0
  138. package/dist/package/src/rpc/common/v1/common.ts +71 -0
  139. package/dist/package/src/rpc/common/v1/enum.ts +71 -0
  140. package/dist/package/src/rpc/common/v1/types.ts +77 -0
  141. package/dist/package/src/rpc/google/protobuf/empty.ts +19 -0
  142. package/dist/package/src/rpc/google/protobuf/timestamp.ts +115 -0
  143. package/dist/package/src/rpc/system/admin/v1/auth.ts +208 -0
  144. package/dist/package/src/rpc/system/admin/v1/base_api.ts +241 -0
  145. package/dist/package/src/rpc/system/admin/v1/base_area.ts +105 -0
  146. package/dist/package/src/rpc/system/admin/v1/base_config.ts +140 -0
  147. package/dist/package/src/rpc/system/admin/v1/base_dept.ts +140 -0
  148. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +249 -0
  149. package/dist/package/src/rpc/system/admin/v1/base_job.ts +206 -0
  150. package/dist/package/src/rpc/system/admin/v1/base_log.ts +101 -0
  151. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +195 -0
  152. package/dist/package/src/rpc/system/admin/v1/base_migration.ts +81 -0
  153. package/dist/package/src/rpc/system/admin/v1/base_post.ts +134 -0
  154. package/dist/package/src/rpc/system/admin/v1/base_role.ts +151 -0
  155. package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +134 -0
  156. package/dist/package/src/rpc/system/admin/v1/base_user.ts +190 -0
  157. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +176 -0
  158. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +170 -0
  159. package/dist/package/src/rpc/system/admin/v1/code_gen_proto.ts +104 -0
  160. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +179 -0
  161. package/dist/package/src/rpc/system/admin/v1/project_document.ts +79 -0
  162. package/dist/package/src/rpc/system/common/v1/enum.ts +80 -0
  163. package/dist/package/src/typings/swagger-ui-dist.d.ts +28 -0
  164. package/dist/package/src/typings/x-markdown-vue.d.ts +1 -0
  165. package/dist/package/src/views/ai/chat/attachment.ts +65 -0
  166. package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +162 -0
  167. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +1861 -0
  168. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +316 -0
  169. package/dist/package/src/views/ai/chat/components/XSender.vue +554 -0
  170. package/dist/package/src/views/ai/chat/index.vue +848 -0
  171. package/dist/package/src/views/ai/chat/message.ts +416 -0
  172. package/dist/package/src/views/ai/chat/stream.ts +115 -0
  173. package/dist/package/src/views/ai/chat/types.ts +126 -0
  174. package/dist/package/src/views/base/api/index.vue +455 -0
  175. package/dist/package/src/views/base/area/index.vue +269 -0
  176. package/dist/package/src/views/base/config/index.vue +530 -0
  177. package/dist/package/src/views/base/dept/index.vue +461 -0
  178. package/dist/package/src/views/base/dict/index.vue +304 -0
  179. package/dist/package/src/views/base/dict/item.vue +373 -0
  180. package/dist/package/src/views/base/job/index.vue +535 -0
  181. package/dist/package/src/views/base/job/log.vue +202 -0
  182. package/dist/package/src/views/base/log/index.vue +317 -0
  183. package/dist/package/src/views/base/menu/index.vue +944 -0
  184. package/dist/package/src/views/base/migration/index.vue +791 -0
  185. package/dist/package/src/views/base/post/index.vue +324 -0
  186. package/dist/package/src/views/base/role/index.vue +684 -0
  187. package/dist/package/src/views/base/tenant/index.vue +328 -0
  188. package/dist/package/src/views/base/user/components/dept-tree.vue +75 -0
  189. package/dist/package/src/views/base/user/index.vue +783 -0
  190. package/dist/package/src/views/profile/components/base.vue +320 -0
  191. package/dist/package/src/views/profile/components/password.vue +269 -0
  192. package/dist/package/src/views/profile/components/security.vue +443 -0
  193. package/dist/package/src/views/profile/index.vue +199 -0
  194. package/dist/package/src/views/tool/api-doc/index.vue +275 -0
  195. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +233 -0
  196. package/dist/package/src/views/tool/code-gen/columns/index.vue +1456 -0
  197. package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +125 -0
  198. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +328 -0
  199. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +42 -0
  200. package/dist/package/src/views/tool/code-gen/config.ts +175 -0
  201. package/dist/package/src/views/tool/code-gen/preview/capabilities.ts +34 -0
  202. package/dist/package/src/views/tool/code-gen/preview/data.ts +331 -0
  203. package/dist/package/src/views/tool/code-gen/preview/index.vue +831 -0
  204. package/dist/package/src/views/tool/code-gen/proto/index.vue +703 -0
  205. package/dist/package/src/views/tool/code-gen/table/index.vue +864 -0
  206. package/dist/package/src/views/tool/project-doc/index.vue +561 -0
  207. package/package.json +60 -0
  208. package/tsconfig.json +13 -0
@@ -0,0 +1,304 @@
1
+ <!-- 字典 -->
2
+ <template>
3
+ <div class="table-box">
4
+ <ProTable
5
+ ref="proTable"
6
+ row-key="id"
7
+ :columns="columns"
8
+ :header-actions="headerActions"
9
+ :request-api="requestBaseDictTable"
10
+ />
11
+
12
+ <FormDialog
13
+ v-model="dialog.visible"
14
+ ref="formDialogRef"
15
+ :title="dialog.title"
16
+ width="500px"
17
+ :model="formData"
18
+ :fields="formFields"
19
+ :rules="rules"
20
+ label-width="100px"
21
+ @confirm="handleSubmit"
22
+ @close="handleCloseDialog"
23
+ />
24
+ </div>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { computed, reactive, ref } from "vue";
29
+ import { ElMessage, ElMessageBox } from "element-plus";
30
+ import { CirclePlus, Delete, EditPen, List } from "@element-plus/icons-vue";
31
+ import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
32
+ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
33
+ import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
34
+ import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
35
+ import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
36
+ import { defBaseDictService } from "@liujitcn/kratos-admin-system/api/system/base_dict";
37
+ import type { BaseDict, BaseDictForm, PageBaseDictRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
38
+ import router, { navigateTo } from "@liujitcn/kratos-admin-core/navigation";
39
+ import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
40
+ import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
41
+
42
+ defineOptions({
43
+ name: "BaseDict",
44
+ inheritAttrs: false
45
+ });
46
+
47
+ const { BUTTONS } = useAuthButtons();
48
+ const proTable = ref<ProTableInstance>();
49
+ const formDialogRef = ref<InstanceType<typeof FormDialog>>();
50
+
51
+ const dialog = reactive({
52
+ title: "",
53
+ visible: false
54
+ });
55
+
56
+ const formData = reactive<BaseDictForm>({
57
+ /** 字典ID */
58
+ id: 0,
59
+ /** 字典编号 */
60
+ code: "",
61
+ /** 字典名称 */
62
+ name: "",
63
+ /** 状态 */
64
+ status: Status.ENABLE
65
+ });
66
+
67
+ const rules = computed(() => ({
68
+ name: [
69
+ { required: true, message: "请输入字典名称", trigger: "blur" },
70
+ { max: 50, message: "字典名称不能超过 50 个字符", trigger: "blur" }
71
+ ],
72
+ code: [
73
+ { required: true, message: "请输入字典编码", trigger: "blur" },
74
+ { max: 50, message: "字典编号不能超过 50 个字符", trigger: "blur" }
75
+ ],
76
+ status: [{ required: true, message: "状态不能为空", trigger: "change" }]
77
+ }));
78
+
79
+ const statusOptions: ProFormOption[] = [
80
+ { label: "启用", value: Status.ENABLE },
81
+ { label: "禁用", value: Status.DISABLE }
82
+ ];
83
+
84
+ /** 字典表单字段配置。 */
85
+ const formFields: ProFormField[] = [
86
+ { prop: "name", label: "字典名称", component: "input", props: { placeholder: "请输入字典名称" } },
87
+ { prop: "code", label: "字典编码", component: "input", props: { placeholder: "请输入字典编码" } },
88
+ { prop: "status", label: "状态", component: "radio-group", options: statusOptions }
89
+ ];
90
+
91
+ /** 字典表格列配置。 */
92
+ const columns: ColumnProps[] = [
93
+ { type: "selection", width: 55 },
94
+ { prop: "name", label: "字典名称", minWidth: 140, search: { el: "input" } },
95
+ { prop: "code", label: "字典编码", minWidth: 160, search: { el: "input" } },
96
+ {
97
+ prop: "status",
98
+ label: "状态",
99
+ minWidth: 100,
100
+ search: { el: "select" },
101
+ cellType: "status",
102
+ statusProps: {
103
+ activeValue: Status.ENABLE,
104
+ inactiveValue: Status.DISABLE,
105
+ activeText: "启用",
106
+ inactiveText: "禁用",
107
+ disabled: () => !BUTTONS.value["base:dict:status"],
108
+ beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDict)
109
+ }
110
+ },
111
+ { prop: "created_at", label: "创建时间", minWidth: 180 },
112
+ { prop: "updated_at", label: "更新时间", minWidth: 180 },
113
+ {
114
+ prop: "operation",
115
+ label: "操作",
116
+ width: 240,
117
+ fixed: "right",
118
+ cellType: "actions",
119
+ actions: [
120
+ {
121
+ label: "字典数据",
122
+ type: "primary",
123
+ link: true,
124
+ icon: List,
125
+ hidden: () => !BUTTONS.value["base:dict:items"],
126
+ onClick: scope => handleOpenBaseDictItem(scope.row as BaseDict)
127
+ },
128
+ {
129
+ label: "编辑",
130
+ type: "primary",
131
+ link: true,
132
+ icon: EditPen,
133
+ hidden: () => !BUTTONS.value["base:dict:update"],
134
+ params: scope => ({ dictId: scope.row.id }),
135
+ onClick: (scope, params) => handleOpenDialog((params?.dictId as number | undefined) ?? (scope.row as BaseDict).id)
136
+ },
137
+ {
138
+ label: "删除",
139
+ type: "danger",
140
+ link: true,
141
+ icon: Delete,
142
+ hidden: () => !BUTTONS.value["base:dict:delete"],
143
+ onClick: scope => handleDelete(scope.row as BaseDict)
144
+ }
145
+ ]
146
+ }
147
+ ];
148
+
149
+ /** 字典顶部按钮配置。 */
150
+ const headerActions: HeaderActionProps[] = [
151
+ {
152
+ label: "新增",
153
+ type: "success",
154
+ icon: CirclePlus,
155
+ hidden: () => !BUTTONS.value["base:dict:create"],
156
+ onClick: () => handleOpenDialog()
157
+ },
158
+ {
159
+ label: "删除",
160
+ type: "danger",
161
+ icon: Delete,
162
+ hidden: () => !BUTTONS.value["base:dict:delete"],
163
+ disabled: scope => !scope.selectedList.length,
164
+ onClick: scope => handleDelete(scope.selectedList as BaseDict[])
165
+ }
166
+ ];
167
+
168
+ /**
169
+ * 请求字典列表,并由 ProTable 统一管理分页搜索。
170
+ */
171
+ async function requestBaseDictTable(params: PageBaseDictRequest) {
172
+ const data = await defBaseDictService.PageBaseDict(buildPageRequest(params));
173
+ return { data: { list: data.base_dicts ?? [], total: data.total } };
174
+ }
175
+
176
+ /**
177
+ * 刷新字典表格数据。
178
+ */
179
+ function refreshTable() {
180
+ proTable.value?.getTableList();
181
+ }
182
+
183
+ /**
184
+ * 打开字典编辑弹窗。
185
+ */
186
+ function handleOpenDialog(dictId?: number) {
187
+ resetForm();
188
+ dialog.title = dictId ? "修改字典" : "新增字典";
189
+ dialog.visible = true;
190
+ if (!dictId) return;
191
+
192
+ defBaseDictService.GetBaseDict({ id: dictId }).then(data => {
193
+ Object.assign(formData, data);
194
+ });
195
+ }
196
+
197
+ /**
198
+ * 关闭字典弹窗并恢复表单初始值。
199
+ */
200
+ function handleCloseDialog() {
201
+ dialog.visible = false;
202
+ resetForm();
203
+ }
204
+
205
+ /**
206
+ * 重置字典表单,避免新增时带入上次编辑结果。
207
+ */
208
+ function resetForm() {
209
+ formDialogRef.value?.resetFields();
210
+ formDialogRef.value?.clearValidate();
211
+ formData.id = 0;
212
+ formData.code = "";
213
+ formData.name = "";
214
+ formData.status = Status.ENABLE;
215
+ }
216
+
217
+ /**
218
+ * 提交字典表单。
219
+ */
220
+ function handleSubmit() {
221
+ formDialogRef.value?.validate()?.then(isValid => {
222
+ if (!isValid) return;
223
+
224
+ const submitData = JSON.parse(JSON.stringify(formData)) as BaseDictForm;
225
+ const request = submitData.id
226
+ ? defBaseDictService.UpdateBaseDict({ base_dict: submitData })
227
+ : defBaseDictService.CreateBaseDict({ base_dict: submitData });
228
+ request.then(() => {
229
+ ElMessage.success(submitData.id ? "修改字典成功" : "新增字典成功");
230
+ handleCloseDialog();
231
+ refreshTable();
232
+ });
233
+ });
234
+ }
235
+
236
+ /**
237
+ * 在字典状态切换前先完成确认与接口调用,避免首屏渲染触发误操作。
238
+ */
239
+ async function handleBeforeSetStatus(row: BaseDict) {
240
+ const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
241
+ const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
242
+ const dictName = row.name || row.code || String(row.id);
243
+ try {
244
+ await ElMessageBox.confirm(`是否确定${text}字典?\n字典名称:${dictName}`, "提示", {
245
+ confirmButtonText: "确认",
246
+ cancelButtonText: "取消",
247
+ type: "warning"
248
+ });
249
+ await defBaseDictService.SetBaseDictStatus({ id: row.id, status: nextStatus });
250
+ ElMessage.success(`${text}成功`);
251
+ refreshTable();
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * 删除字典,兼容单项删除与批量删除。
260
+ */
261
+ function handleDelete(selected?: number | string | Array<number | string> | BaseDict | BaseDict[]) {
262
+ const dictList = Array.isArray(selected)
263
+ ? (selected.filter(item => typeof item === "object") as BaseDict[])
264
+ : selected && typeof selected === "object"
265
+ ? [selected as BaseDict]
266
+ : [];
267
+ const dictIds = (
268
+ dictList.length ? dictList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
269
+ ).join(",");
270
+ if (!dictIds) {
271
+ ElMessage.warning("请勾选删除项");
272
+ return;
273
+ }
274
+
275
+ const confirmMessage = dictList.length
276
+ ? dictList.length === 1
277
+ ? `是否确定删除字典?\n字典名称:${dictList[0].name || dictList[0].code || `ID:${dictList[0].id}`}`
278
+ : `确认删除已选中的 ${dictList.length} 个字典吗?`
279
+ : "确认删除已选中的字典吗?";
280
+
281
+ ElMessageBox.confirm(confirmMessage, "警告", {
282
+ confirmButtonText: "确定",
283
+ cancelButtonText: "取消",
284
+ type: "warning"
285
+ }).then(
286
+ () => {
287
+ defBaseDictService.DeleteBaseDict({ id: dictIds }).then(() => {
288
+ ElMessage.success("删除字典成功");
289
+ refreshTable();
290
+ });
291
+ },
292
+ () => {
293
+ ElMessage.info("已取消删除字典");
294
+ }
295
+ );
296
+ }
297
+
298
+ /**
299
+ * 打开字典数据页面。
300
+ */
301
+ function handleOpenBaseDictItem(row: BaseDict) {
302
+ navigateTo(router, "/base/dict/item", { dictId: row.id, title: `【${row.name}】字典数据` });
303
+ }
304
+ </script>
@@ -0,0 +1,373 @@
1
+ <!-- 字典数据 -->
2
+ <template>
3
+ <div class="table-box">
4
+ <ProTable
5
+ ref="proTable"
6
+ row-key="id"
7
+ :columns="columns"
8
+ :header-actions="headerActions"
9
+ :request-api="requestBaseDictItemTable"
10
+ />
11
+
12
+ <FormDialog
13
+ v-model="dialog.visible"
14
+ ref="formDialogRef"
15
+ :title="dialog.title"
16
+ width="820px"
17
+ :model="formData"
18
+ :fields="formFields"
19
+ :rules="rules"
20
+ label-width="100px"
21
+ @confirm="handleSubmit"
22
+ @close="handleCloseDialog"
23
+ >
24
+ <template #tagTypeField>
25
+ <div class="dict-item-tag-type">
26
+ <el-tag v-if="formData.tag_type" :type="formatTagType(formData.tag_type)" class="mr-2">
27
+ {{ formData.label || "标签预览" }}
28
+ </el-tag>
29
+ <el-radio-group v-model="formData.tag_type">
30
+ <el-radio value="success" border size="small">success</el-radio>
31
+ <el-radio value="warning" border size="small">warning</el-radio>
32
+ <el-radio value="info" border size="small">info</el-radio>
33
+ <el-radio value="primary" border size="small">primary</el-radio>
34
+ <el-radio value="danger" border size="small">danger</el-radio>
35
+ <el-radio value="" border size="small">清空</el-radio>
36
+ </el-radio-group>
37
+ </div>
38
+ </template>
39
+ </FormDialog>
40
+ </div>
41
+ </template>
42
+
43
+ <script setup lang="ts">
44
+ import { computed, h, reactive, ref, watch } from "vue";
45
+ import { useRoute } from "vue-router";
46
+ import { ElMessage, ElMessageBox, ElTag } from "element-plus";
47
+ import { CirclePlus, Delete, EditPen } from "@element-plus/icons-vue";
48
+ import type { ColumnProps, HeaderActionProps, ProTableInstance, RenderScope } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
49
+ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
50
+ import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
51
+ import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
52
+ import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
53
+ import { defBaseDictService } from "@liujitcn/kratos-admin-system/api/system/base_dict";
54
+ import type { BaseDictItem, BaseDictItemForm, PageBaseDictItemRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
55
+ import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
56
+ import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
57
+
58
+ defineOptions({
59
+ name: "BaseDictItem",
60
+ inheritAttrs: false
61
+ });
62
+
63
+ const route = useRoute();
64
+ const { BUTTONS } = useAuthButtons();
65
+ const proTable = ref<ProTableInstance>();
66
+ const formDialogRef = ref<InstanceType<typeof FormDialog>>();
67
+
68
+ const dictId = ref(Number(route.query.dictId ?? 0));
69
+
70
+ const dialog = reactive({
71
+ title: "",
72
+ visible: false
73
+ });
74
+
75
+ const formData = reactive<BaseDictItemForm>({
76
+ /** 字典项ID */
77
+ id: 0,
78
+ /** 字典ID */
79
+ dict_id: dictId.value,
80
+ /** 字典值 */
81
+ value: "",
82
+ /** 字典项标签 */
83
+ label: "",
84
+ /** 标签类型 */
85
+ tag_type: "",
86
+ /** 排序 */
87
+ sort: 1,
88
+ /** 状态 */
89
+ status: Status.ENABLE
90
+ });
91
+
92
+ const rules = computed(() => ({
93
+ value: [{ required: true, max: 50, message: "请输入字典值(不超过50个字符)", trigger: "blur" }],
94
+ label: [{ required: true, max: 100, message: "请输入字典标签(不超过100个字符)", trigger: "blur" }],
95
+ tag_type: [{ max: 50, message: "标签类型不能超过 50 个字符", trigger: "blur" }],
96
+ sort: [{ required: true, message: "请输入排序", trigger: "blur" }],
97
+ status: [{ required: true, message: "状态不能为空", trigger: "change" }]
98
+ }));
99
+
100
+ const statusOptions: ProFormOption[] = [
101
+ { label: "启用", value: Status.ENABLE },
102
+ { label: "禁用", value: Status.DISABLE }
103
+ ];
104
+
105
+ /** 字典项表单字段配置。 */
106
+ const formFields: ProFormField[] = [
107
+ { prop: "label", label: "字典标签", component: "input", props: { placeholder: "请输入字典标签" } },
108
+ { prop: "value", label: "字典值", component: "input", props: { placeholder: "请输入字典值" } },
109
+ {
110
+ prop: "sort",
111
+ label: "排序",
112
+ component: "input-number",
113
+ props: { min: 1, precision: 0, step: 1, controlsPosition: "right", style: { width: "100%" } }
114
+ },
115
+ { prop: "status", label: "状态", component: "radio-group", options: statusOptions },
116
+ { prop: "tag_type", label: "标签类型", component: "slot", slotName: "tagTypeField", colSpan: 24 }
117
+ ];
118
+
119
+ /**
120
+ * 规范化标签类型,兼容 Element Plus Tag 的可选值。
121
+ */
122
+ function formatTagType(tag_type: string) {
123
+ if (["success", "info", "warning", "primary", "danger"].includes(tag_type)) {
124
+ return tag_type as "success" | "info" | "warning" | "primary" | "danger";
125
+ }
126
+ return undefined;
127
+ }
128
+
129
+ /**
130
+ * 渲染标签类型列,统一复用字典项标签的展示方式。
131
+ */
132
+ function renderTagTypeCell(scope: RenderScope<BaseDictItem>) {
133
+ if (!scope.row.tag_type) return "无";
134
+ return h(
135
+ ElTag,
136
+ {
137
+ type: formatTagType(scope.row.tag_type),
138
+ effect: "plain"
139
+ },
140
+ () => scope.row.label
141
+ );
142
+ }
143
+
144
+ /** 字典项表格列配置。 */
145
+ const columns: ColumnProps[] = [
146
+ { type: "selection", width: 55 },
147
+ { prop: "label", label: "字典标签", minWidth: 140, search: { el: "input" } },
148
+ { prop: "value", label: "字典值", minWidth: 140 },
149
+ { prop: "sort", label: "排序", minWidth: 90, align: "right" },
150
+ {
151
+ prop: "tag_type",
152
+ label: "标签类型",
153
+ minWidth: 120,
154
+ render: scope => renderTagTypeCell(scope as unknown as RenderScope<BaseDictItem>)
155
+ },
156
+ {
157
+ prop: "status",
158
+ label: "状态",
159
+ minWidth: 100,
160
+ search: { el: "select" },
161
+ cellType: "status",
162
+ statusProps: {
163
+ activeValue: Status.ENABLE,
164
+ inactiveValue: Status.DISABLE,
165
+ activeText: "启用",
166
+ inactiveText: "禁用",
167
+ disabled: () => !BUTTONS.value["base:dict-item:status"],
168
+ beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDictItem)
169
+ }
170
+ },
171
+ { prop: "created_at", label: "创建时间", minWidth: 180 },
172
+ { prop: "updated_at", label: "更新时间", minWidth: 180 },
173
+ {
174
+ prop: "operation",
175
+ label: "操作",
176
+ width: 180,
177
+ fixed: "right",
178
+ cellType: "actions",
179
+ actions: [
180
+ {
181
+ label: "编辑",
182
+ type: "primary",
183
+ link: true,
184
+ icon: EditPen,
185
+ hidden: () => !BUTTONS.value["base:dict-item:update"],
186
+ params: scope => ({ dictItemId: scope.row.id }),
187
+ onClick: (scope, params) => handleOpenDialog((params?.dictItemId as number | undefined) ?? (scope.row as BaseDictItem).id)
188
+ },
189
+ {
190
+ label: "删除",
191
+ type: "danger",
192
+ link: true,
193
+ icon: Delete,
194
+ hidden: () => !BUTTONS.value["base:dict-item:delete"],
195
+ onClick: scope => handleDelete(scope.row as BaseDictItem)
196
+ }
197
+ ]
198
+ }
199
+ ];
200
+
201
+ /** 字典项顶部按钮配置。 */
202
+ const headerActions: HeaderActionProps[] = [
203
+ {
204
+ label: "新增",
205
+ type: "success",
206
+ icon: CirclePlus,
207
+ hidden: () => !BUTTONS.value["base:dict-item:create"],
208
+ onClick: () => handleOpenDialog()
209
+ },
210
+ {
211
+ label: "删除",
212
+ type: "danger",
213
+ icon: Delete,
214
+ hidden: () => !BUTTONS.value["base:dict-item:delete"],
215
+ disabled: scope => !scope.selectedList.length,
216
+ onClick: scope => handleDelete(scope.selectedList as BaseDictItem[])
217
+ }
218
+ ];
219
+
220
+ watch(
221
+ () => route.query.dictId,
222
+ value => {
223
+ dictId.value = Number(value ?? 0);
224
+ formData.dict_id = dictId.value;
225
+ proTable.value?.search();
226
+ }
227
+ );
228
+
229
+ /**
230
+ * 请求字典项分页列表,并补充当前路由上的字典 ID。
231
+ */
232
+ async function requestBaseDictItemTable(params: PageBaseDictItemRequest) {
233
+ const data = await defBaseDictService.PageBaseDictItem({ ...buildPageRequest(params), dict_id: dictId.value });
234
+ return { data: { list: data.base_dict_items ?? [], total: data.total } };
235
+ }
236
+
237
+ /**
238
+ * 刷新字典项表格。
239
+ */
240
+ function refreshTable() {
241
+ proTable.value?.getTableList();
242
+ }
243
+
244
+ /**
245
+ * 打开字典项编辑弹窗。
246
+ */
247
+ function handleOpenDialog(dictItemId?: number) {
248
+ resetForm();
249
+ dialog.title = dictItemId ? "修改字典数据" : "新增字典数据";
250
+ dialog.visible = true;
251
+ if (!dictItemId) return;
252
+
253
+ defBaseDictService.GetBaseDictItem({ id: dictItemId }).then(data => {
254
+ Object.assign(formData, data);
255
+ });
256
+ }
257
+
258
+ /**
259
+ * 关闭字典项弹窗并恢复默认值。
260
+ */
261
+ function handleCloseDialog() {
262
+ dialog.visible = false;
263
+ resetForm();
264
+ }
265
+
266
+ /**
267
+ * 重置字典项表单,避免弹窗之间相互污染。
268
+ */
269
+ function resetForm() {
270
+ formDialogRef.value?.resetFields();
271
+ formDialogRef.value?.clearValidate();
272
+ formData.id = 0;
273
+ formData.dict_id = dictId.value;
274
+ formData.value = "";
275
+ formData.label = "";
276
+ formData.tag_type = "";
277
+ formData.sort = 1;
278
+ formData.status = Status.ENABLE;
279
+ }
280
+
281
+ /**
282
+ * 提交字典项表单。
283
+ */
284
+ function handleSubmit() {
285
+ formDialogRef.value?.validate()?.then(isValid => {
286
+ if (!isValid) return;
287
+
288
+ formData.dict_id = dictId.value;
289
+ const submitData = JSON.parse(JSON.stringify(formData)) as BaseDictItemForm;
290
+ const request = submitData.id
291
+ ? defBaseDictService.UpdateBaseDictItem({ base_dict_item: submitData })
292
+ : defBaseDictService.CreateBaseDictItem({ base_dict_item: submitData });
293
+ request.then(() => {
294
+ ElMessage.success(submitData.id ? "修改字典数据成功" : "新增字典数据成功");
295
+ handleCloseDialog();
296
+ refreshTable();
297
+ });
298
+ });
299
+ }
300
+
301
+ /**
302
+ * 在字典项状态切换前先完成确认与接口调用,避免首屏渲染触发误操作。
303
+ */
304
+ async function handleBeforeSetStatus(row: BaseDictItem) {
305
+ const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
306
+ const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
307
+ const itemName = row.label || row.value || `ID:${row.id}`;
308
+ try {
309
+ await ElMessageBox.confirm(`是否确定${text}字典数据?\n字典标签:${itemName}`, "提示", {
310
+ confirmButtonText: "确认",
311
+ cancelButtonText: "取消",
312
+ type: "warning"
313
+ });
314
+ await defBaseDictService.SetBaseDictItemStatus({ id: row.id, status: nextStatus });
315
+ ElMessage.success(`${text}成功`);
316
+ refreshTable();
317
+ return true;
318
+ } catch {
319
+ return false;
320
+ }
321
+ }
322
+
323
+ /**
324
+ * 删除字典项,兼容单项删除与批量删除。
325
+ */
326
+ function handleDelete(selected?: number | string | Array<number | string> | BaseDictItem | BaseDictItem[]) {
327
+ const dictItemList = Array.isArray(selected)
328
+ ? (selected.filter(item => typeof item === "object") as BaseDictItem[])
329
+ : selected && typeof selected === "object"
330
+ ? [selected as BaseDictItem]
331
+ : [];
332
+ const dictItemIds = (
333
+ dictItemList.length
334
+ ? dictItemList.map(item => item.id)
335
+ : normalizeSelectedIds(selected as number | string | Array<number | string>)
336
+ ).join(",");
337
+ if (!dictItemIds) {
338
+ ElMessage.warning("请勾选删除项");
339
+ return;
340
+ }
341
+
342
+ const singleItemName = dictItemList[0]?.label || dictItemList[0]?.value || `ID:${dictItemList[0]?.id ?? ""}`;
343
+ const confirmMessage = dictItemList.length
344
+ ? dictItemList.length === 1
345
+ ? `是否确定删除字典数据?\n字典标签:${singleItemName}`
346
+ : `确认删除已选中的 ${dictItemList.length} 项字典数据吗?`
347
+ : "确认删除已选中的字典数据吗?";
348
+
349
+ ElMessageBox.confirm(confirmMessage, "警告", {
350
+ confirmButtonText: "确定",
351
+ cancelButtonText: "取消",
352
+ type: "warning"
353
+ }).then(
354
+ () => {
355
+ defBaseDictService.DeleteBaseDictItem({ id: dictItemIds }).then(() => {
356
+ ElMessage.success("删除字典数据成功");
357
+ refreshTable();
358
+ });
359
+ },
360
+ () => {
361
+ ElMessage.info("已取消删除字典数据");
362
+ }
363
+ );
364
+ }
365
+ </script>
366
+
367
+ <style scoped>
368
+ .dict-item-tag-type {
369
+ display: flex;
370
+ flex-wrap: wrap;
371
+ gap: 12px;
372
+ }
373
+ </style>