@liujitcn/kratos-admin-system 0.0.51 → 0.0.53

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 (60) hide show
  1. package/README.md +1 -1
  2. package/dist/package/declarations/src/api/base/v1/sse.d.ts +1 -1
  3. package/dist/package/declarations/src/components/tenant-project/TenantProjectManager.vue.d.ts +1 -2
  4. package/dist/package/declarations/src/components/tenant-project/tenant-project-manager-data.d.ts +10 -0
  5. package/dist/package/declarations/src/components/tenant-project/tenant-project-manager.d.ts +8 -3
  6. package/dist/package/declarations/src/index.d.ts +1 -1
  7. package/dist/package/declarations/src/locales/generated.d.ts +32 -0
  8. package/dist/package/declarations/src/rpc/base/v1/ai_search.d.ts +26 -0
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +0 -1
  10. package/dist/package/declarations/src/views/ai/chat/components/speech-recognition.d.ts +6 -2
  11. package/dist/package/src/api/base/v1/sse.ts +19 -12
  12. package/dist/package/src/components/log/LogTable.vue +25 -18
  13. package/dist/package/src/components/notification/Notification.vue +14 -7
  14. package/dist/package/src/components/tenant-project/TenantProjectManager.vue +106 -62
  15. package/dist/package/src/components/tenant-project/tenant-project-manager-data.ts +39 -1
  16. package/dist/package/src/components/tenant-project/tenant-project-manager.ts +19 -4
  17. package/dist/package/src/components/tenant-project-grant/ProjectGrantDialog.vue +22 -7
  18. package/dist/package/src/index.ts +2 -0
  19. package/dist/package/src/locales/en-US.json +8 -0
  20. package/dist/package/src/locales/ja-JP.json +8 -0
  21. package/dist/package/src/locales/zh-CN.json +8 -0
  22. package/dist/package/src/locales/zh-TW.json +8 -0
  23. package/dist/package/src/rpc/base/v1/ai_search.ts +37 -0
  24. package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +0 -1
  25. package/dist/package/src/views/ai/chat/components/XSender.vue +1 -36
  26. package/dist/package/src/views/ai/chat/components/speech-recognition.ts +28 -7
  27. package/dist/package/src/views/ai/chat/index.vue +16 -7
  28. package/dist/package/src/views/base/api-log/index.vue +1 -1
  29. package/dist/package/src/views/base/area/index.vue +15 -9
  30. package/dist/package/src/views/base/backup-management/archive-config/index.vue +22 -10
  31. package/dist/package/src/views/base/backup-management/backup-config/index.vue +13 -6
  32. package/dist/package/src/views/base/config/index.vue +38 -14
  33. package/dist/package/src/views/base/dept/index.vue +31 -25
  34. package/dist/package/src/views/base/dict/index.vue +12 -8
  35. package/dist/package/src/views/base/dict/item.vue +12 -8
  36. package/dist/package/src/views/base/i18n-custom/index.vue +13 -7
  37. package/dist/package/src/views/base/job/index.vue +12 -8
  38. package/dist/package/src/views/base/job/log.vue +14 -9
  39. package/dist/package/src/views/base/language/index.vue +7 -4
  40. package/dist/package/src/views/base/login-policy/index.vue +22 -11
  41. package/dist/package/src/views/base/menu/index.vue +23 -16
  42. package/dist/package/src/views/base/message/index.vue +65 -21
  43. package/dist/package/src/views/base/message-category/index.vue +10 -4
  44. package/dist/package/src/views/base/oauth-client/index.vue +15 -5
  45. package/dist/package/src/views/base/post/index.vue +10 -4
  46. package/dist/package/src/views/base/redact-output-policy/index.vue +12 -5
  47. package/dist/package/src/views/base/redact-rule/index.vue +8 -7
  48. package/dist/package/src/views/base/redact-storage-policy/index.vue +32 -8
  49. package/dist/package/src/views/base/role/index.vue +24 -17
  50. package/dist/package/src/views/base/tenant/index.vue +7 -6
  51. package/dist/package/src/views/base/tenant-project-grant/index.vue +44 -27
  52. package/dist/package/src/views/base/user/components/dept-tree.vue +4 -9
  53. package/dist/package/src/views/base/user/index.vue +39 -28
  54. package/dist/package/src/views/message/inbox/index.vue +8 -3
  55. package/dist/package/src/views/profile/components/base.vue +1 -1
  56. package/dist/package/src/views/profile/index.vue +1 -1
  57. package/dist/package/src/views/tool/cache/index.vue +1 -1
  58. package/dist/package/src/views/tool/code-gen/columns/index.vue +35 -16
  59. package/dist/package/src/views/tool/code-gen/table/index.vue +58 -31
  60. package/package.json +2 -2
@@ -208,22 +208,33 @@ async function requestProjectGrantTable(params: Record<string, unknown>) {
208
208
 
209
209
  /** 打开项目授权新增或编辑弹窗。 */
210
210
  async function handleOpenDialog(row?: BaseTenantProjectGrant) {
211
- resetForm();
212
- dialog.editing = Boolean(row);
213
- dialog.titleKey = row ? "common.action.edit_resource" : "common.action.create_resource";
214
211
  loading.value = true;
215
212
  try {
216
- await loadTenantOptions(true);
217
- if (!isDefaultTenant.value) formData.tenant_id = Number(tenantOptions.value[0]?.value) || undefined;
218
- if (row) {
219
- formData.tenant_id = row.tenant_id;
220
- formData.subject_type = row.subject_type;
221
- formData.subject_id = row.subject_id;
222
- formData.all = row.project_id.length === 1 && row.project_id[0] === 0;
223
- formData.project_id = formData.all ? [] : [...row.project_id];
224
- }
225
- await Promise.all([loadProjectOptions(), loadSubjectOptions()]);
226
- dialog.visible = true;
213
+ await formDialogRef.value?.open({
214
+ load: async () => {
215
+ await loadTenantOptions(true);
216
+ const nextForm = {
217
+ tenant_id: row?.tenant_id ?? (isDefaultTenant.value ? undefined : Number(tenantOptions.value[0]?.value) || undefined),
218
+ subject_type: row?.subject_type ?? DEFAULT_SUBJECT_TYPE,
219
+ subject_id: row?.subject_id,
220
+ project_id: row && !(row.project_id.length === 1 && row.project_id[0] === 0) ? [...row.project_id] : [],
221
+ all: Boolean(row && row.project_id.length === 1 && row.project_id[0] === 0)
222
+ } satisfies ProjectGrantFormState;
223
+ const [projects, subjects] = await Promise.all([
224
+ requestProjectOptions(nextForm.tenant_id),
225
+ requestSubjectOptions(nextForm.tenant_id, nextForm.subject_type)
226
+ ]);
227
+ return { nextForm, projects, subjects };
228
+ },
229
+ commit: ({ nextForm, projects, subjects }) => {
230
+ resetForm();
231
+ dialog.editing = Boolean(row);
232
+ dialog.titleKey = row ? "common.action.edit_resource" : "common.action.create_resource";
233
+ Object.assign(formData, nextForm);
234
+ projectOptions.value = projects;
235
+ subjectOptions.value = subjects;
236
+ }
237
+ });
227
238
  } finally {
228
239
  loading.value = false;
229
240
  }
@@ -231,28 +242,34 @@ async function handleOpenDialog(row?: BaseTenantProjectGrant) {
231
242
 
232
243
  /** 加载目标租户项目选项。 */
233
244
  async function loadProjectOptions() {
234
- projectOptions.value = formData.tenant_id
235
- ? (await defBaseTenantProjectService.OptionBaseTenantProject({ tenant_id: toRequestTenantId(formData.tenant_id) })).list ?? []
236
- : [];
245
+ projectOptions.value = await requestProjectOptions(formData.tenant_id);
246
+ }
247
+
248
+ /** 请求目标租户项目选项。 */
249
+ async function requestProjectOptions(tenantId?: number) {
250
+ if (!tenantId) return [];
251
+ return (await defBaseTenantProjectService.OptionBaseTenantProject({ tenant_id: toRequestTenantId(tenantId) })).list ?? [];
237
252
  }
238
253
 
239
254
  /** 根据授权类型加载岗位、角色、部门或用户主体选项。 */
240
255
  async function loadSubjectOptions() {
241
- subjectOptions.value = [];
242
- if (!formData.tenant_id || formData.subject_type === BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_UNSPECIFIED) return;
243
- switch (formData.subject_type) {
256
+ subjectOptions.value = await requestSubjectOptions(formData.tenant_id, formData.subject_type);
257
+ }
258
+
259
+ /** 请求指定租户和主体类型的主体选项。 */
260
+ async function requestSubjectOptions(tenantId: number | undefined, subjectType: BaseTenantProjectGrantSubjectType) {
261
+ if (!tenantId || subjectType === BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_UNSPECIFIED) return [];
262
+ switch (subjectType) {
244
263
  case BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_POST:
245
- subjectOptions.value = (await defBasePostService.OptionBasePost({ tenant_id: formData.tenant_id })).list ?? [];
246
- return;
264
+ return (await defBasePostService.OptionBasePost({ tenant_id: tenantId })).list ?? [];
247
265
  case BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_ROLE:
248
- subjectOptions.value = (await defBaseRoleService.OptionBaseRole({ tenant_id: formData.tenant_id })).list ?? [];
249
- return;
266
+ return (await defBaseRoleService.OptionBaseRole({ tenant_id: tenantId })).list ?? [];
250
267
  case BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_DEPT:
251
- subjectOptions.value = ((await defBaseDeptService.OptionBaseDept({ tenant_id: formData.tenant_id })).list ?? []) as unknown as ProFormOption[];
252
- return;
268
+ return ((await defBaseDeptService.OptionBaseDept({ tenant_id: tenantId })).list ?? []) as unknown as ProFormOption[];
253
269
  case BaseTenantProjectGrantSubjectType.BASE_TENANT_PROJECT_GRANT_SUBJECT_TYPE_USER:
254
- subjectOptions.value = (await defBaseUserService.OptionBaseUser({ keyword: "", tenant_id: formData.tenant_id })).list ?? [];
270
+ return (await defBaseUserService.OptionBaseUser({ keyword: "", tenant_id: tenantId })).list ?? [];
255
271
  }
272
+ return [];
256
273
  }
257
274
 
258
275
  /** 切换目标租户时重置主体和项目选择。 */
@@ -22,7 +22,7 @@
22
22
  </template>
23
23
 
24
24
  <script setup lang="ts">
25
- import { onBeforeMount, ref, watchEffect } from "vue";
25
+ import { nextTick, onBeforeMount, ref, watch } from "vue";
26
26
  import { useVModel } from "@vueuse/core";
27
27
  import { ElTree } from "element-plus";
28
28
  import { defBaseDeptService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_dept";
@@ -43,14 +43,9 @@ const emits = defineEmits(["nodeClick"]);
43
43
 
44
44
  const baseDeptId = useVModel(props, "modelValue", emits);
45
45
 
46
- watchEffect(
47
- () => {
48
- baseDeptTreeRef.value?.filter(name.value);
49
- },
50
- {
51
- flush: "post" // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
52
- }
53
- );
46
+ watch([name, baseDeptList], () => {
47
+ void nextTick(() => baseDeptTreeRef.value?.filter(name.value));
48
+ }, { flush: "post" });
54
49
 
55
50
  /**
56
51
  * 部门筛选
@@ -169,7 +169,7 @@ const formData = reactive<BaseUserFormState>({
169
169
  /** 密码 */
170
170
  pwd: "",
171
171
  /** 性别 */
172
- gender: 3,
172
+ gender: 1,
173
173
  /** 头像 */
174
174
  avatar: "",
175
175
  /** 用户状态 */
@@ -649,23 +649,30 @@ function refreshTable() {
649
649
  * 加载用户表单依赖的角色和部门选项。
650
650
  */
651
651
  async function loadFormOptions() {
652
+ const options = await requestFormOptions();
653
+ baseRoleOptions.value = options.roleOptions;
654
+ updateUndeletableRoleIds(baseRoleOptions.value);
655
+ basePostOptions.value = options.postOptions;
656
+ basedDeptOptions.value = options.deptOptions;
657
+ }
658
+
659
+ /** 请求用户表单依赖的角色和部门选项。 */
660
+ async function requestFormOptions(tenantId = formData.tenant_id) {
652
661
  // 默认租户必须先选择目标租户,避免角色和部门选项跨租户混用。
653
- if (isDefaultTenant.value && !formData.tenant_id) {
654
- baseRoleOptions.value = [];
655
- basePostOptions.value = [];
656
- basedDeptOptions.value = [];
657
- return;
662
+ if (isDefaultTenant.value && !tenantId) {
663
+ return { roleOptions: [], postOptions: [], deptOptions: [] };
658
664
  }
659
- const tenantId = toRequestTenantId(formData.tenant_id);
665
+ const requestTenantId = toRequestTenantId(tenantId);
660
666
  const [optionBaseRoleResponse, optionBaseDeptResponse, optionBasePostResponse] = await Promise.all([
661
- defBaseRoleService.OptionBaseRole({ tenant_id: tenantId }),
662
- defBaseDeptService.OptionBaseDept({ tenant_id: tenantId }),
663
- defBasePostService.OptionBasePost({ tenant_id: tenantId })
667
+ defBaseRoleService.OptionBaseRole({ tenant_id: requestTenantId }),
668
+ defBaseDeptService.OptionBaseDept({ tenant_id: requestTenantId }),
669
+ defBasePostService.OptionBasePost({ tenant_id: requestTenantId })
664
670
  ]);
665
- baseRoleOptions.value = optionBaseRoleResponse.list || [];
666
- updateUndeletableRoleIds(baseRoleOptions.value);
667
- basePostOptions.value = optionBasePostResponse.list || [];
668
- basedDeptOptions.value = optionBaseDeptResponse.list || [];
671
+ return {
672
+ roleOptions: optionBaseRoleResponse.list || [],
673
+ postOptions: optionBasePostResponse.list || [],
674
+ deptOptions: optionBaseDeptResponse.list || []
675
+ };
669
676
  }
670
677
 
671
678
  /**
@@ -682,18 +689,22 @@ async function handleFormTenantChange() {
682
689
  * 打开用户弹窗,并加载角色和部门下拉选项。
683
690
  */
684
691
  async function handleOpenDialog(id?: number) {
685
- resetForm();
686
- await loadTenantOptions();
687
- dialog.editing = Boolean(id);
688
- dialog.visible = true;
689
- if (!id) {
690
- await loadFormOptions();
691
- return;
692
- }
693
-
694
- defBaseUserService.GetBaseUser({ id }).then(async data => {
695
- Object.assign(formData, data);
696
- await loadFormOptions();
692
+ await formDialogRef.value?.open({
693
+ load: async () => {
694
+ await loadTenantOptions();
695
+ const data = id ? await defBaseUserService.GetBaseUser({ id }) : undefined;
696
+ const options = await requestFormOptions(data?.tenant_id);
697
+ return { data, options };
698
+ },
699
+ commit: ({ data, options }) => {
700
+ resetForm();
701
+ dialog.editing = Boolean(id);
702
+ if (data) Object.assign(formData, data);
703
+ baseRoleOptions.value = options.roleOptions;
704
+ updateUndeletableRoleIds(baseRoleOptions.value);
705
+ basePostOptions.value = options.postOptions;
706
+ basedDeptOptions.value = options.deptOptions;
707
+ }
697
708
  });
698
709
  }
699
710
 
@@ -701,7 +712,7 @@ async function handleOpenDialog(id?: number) {
701
712
  * 关闭用户弹窗并恢复默认表单值。
702
713
  */
703
714
  function handleCloseDialog() {
704
- dialog.visible = false;
715
+ formDialogRef.value?.close();
705
716
  resetForm();
706
717
  }
707
718
 
@@ -724,7 +735,7 @@ function resetForm() {
724
735
  formData.id_type = BaseUserIDType.BASE_USER_ID_TYPE_UNSPECIFIED;
725
736
  formData.id_code = "";
726
737
  formData.pwd = "";
727
- formData.gender = 3;
738
+ formData.gender = 1;
728
739
  formData.avatar = "";
729
740
  formData.status = Status.STATUS_ENABLE;
730
741
  formData.remark = "";
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="table-box">
3
3
  <ProTable ref="proTable" row-key="id" :columns="columns" :header-actions="headerActions" :request-api="requestTable" />
4
- <ProDialog v-model="detailVisible" :title="detail?.title" width="720px" destroy-on-close :show-footer="false">
4
+ <ProDialog ref="detailDialogRef" v-model="detailVisible" :title="detail?.title" width="720px" destroy-on-close :show-footer="false">
5
5
  <div v-if="detail" class="message-detail">
6
6
  <div class="message-meta">
7
7
  <span class="message-category" :style="{ color: detail.category_color || undefined }">
@@ -56,6 +56,7 @@ defineOptions({ name: "NotificationInbox", inheritAttrs: false });
56
56
 
57
57
  const proTable = ref<ProTableInstance>();
58
58
  const router = useRouter();
59
+ const detailDialogRef = ref<InstanceType<typeof ProDialog>>();
59
60
  const detailVisible = ref(false);
60
61
  const detail = ref<Notification>();
61
62
  const categoryOptions = ref<NotificationCategory[]>([]);
@@ -177,8 +178,12 @@ async function loadCategoryOptions() {
177
178
 
178
179
  /** 打开消息详情并标记已读。 */
179
180
  async function openDetail(row: Notification) {
180
- detail.value = await defNotificationService.GetNotification({ id: row.id });
181
- detailVisible.value = true;
181
+ await detailDialogRef.value?.open({
182
+ load: () => defNotificationService.GetNotification({ id: row.id }),
183
+ commit: data => {
184
+ detail.value = data;
185
+ }
186
+ });
182
187
  if (!row.read_at) {
183
188
  await defNotificationService.MarkNotificationRead({ ids: [row.id] });
184
189
  proTable.value?.getTableList();
@@ -120,7 +120,7 @@ const submitLoading = ref(false);
120
120
  const avatarSrc = ref(defaultAvatar);
121
121
  const accountForm = reactive<Pick<UserProfileForm, "nick_name" | "gender" | "email" | "id_type" | "id_code">>({
122
122
  nick_name: "",
123
- gender: 3,
123
+ gender: 1,
124
124
  email: "",
125
125
  id_type: BaseUserIDType.BASE_USER_ID_TYPE_UNSPECIFIED,
126
126
  id_code: ""
@@ -102,7 +102,7 @@ const userProfileForm = reactive<UserProfileForm>({
102
102
  user_name: "",
103
103
  nick_name: "",
104
104
  avatar: "",
105
- gender: 3,
105
+ gender: 1,
106
106
  phone: "",
107
107
  email: "",
108
108
  id_type: 0,
@@ -95,7 +95,7 @@ const columns = computed<ColumnProps[]>(() => [
95
95
  prop: "key",
96
96
  label: t("system.cache.field.key"),
97
97
  minWidth: 280,
98
- search: { el: "input", props: { clearable: true } },
98
+ search: { el: "input", key: "keyword", props: { clearable: true } },
99
99
  render: scope => h("code", { class: "cache-key-cell", title: scope.row.key }, scope.row.key)
100
100
  },
101
101
  {
@@ -261,6 +261,7 @@
261
261
  </el-card>
262
262
 
263
263
  <ProDialog
264
+ ref="optionDialogRef"
264
265
  v-model="optionDialog.visible"
265
266
  :title="optionDialogTitle"
266
267
  width="560px"
@@ -591,6 +592,7 @@ const staticOptions = reactive(new Map<string, CodeGenStaticOption[]>());
591
592
  const loadingDictionaries = ref(false);
592
593
  const loadingDatabaseTables = ref(false);
593
594
  const loadingDatabaseColumns = reactive(new Set<string>());
595
+ const optionDialogRef = ref<InstanceType<typeof ProDialog>>();
594
596
  let dictionariesLoaded = false;
595
597
  let databaseTablesLoaded = false;
596
598
  let columnSortable: Sortable | undefined;
@@ -868,22 +870,39 @@ function handleFormEnabledChange(row: CodeGenColumnView) {
868
870
  /** 打开查询、列表或表单自己的选项编辑弹窗。 */
869
871
  async function openOptionDialog(row: CodeGenColumnView, scope: CodeGenOptionScope) {
870
872
  const config = getCodeGenOptionContainer(row, scope);
871
- syncOptionKind(config, scope);
872
- optionDialog.scope = scope;
873
- optionDialog.columnName = row.name;
874
- optionDialog.component = config.component;
875
- optionDialog.isJSONColumn = row.db_type.trim().toLowerCase() === "json";
876
- optionDialog.cacheKey = `${row.table_id}:${row.name}:${scope}`;
877
- optionDialog.option = config.option;
878
- optionDialog.formConfig = scope === "form" && config.component === "tree-select" ? row.form_config : null;
879
- optionDialog.visible = true;
880
- await prepareOptionEditor();
873
+ const draft = {
874
+ scope,
875
+ columnName: row.name,
876
+ component: config.component,
877
+ isJSONColumn: row.db_type.trim().toLowerCase() === "json",
878
+ cacheKey: `${row.table_id}:${row.name}:${scope}`,
879
+ option: { ...config.option },
880
+ formConfig:
881
+ scope === "form" && config.component === "tree-select"
882
+ ? { ...row.form_config, option: { ...row.form_config.option } }
883
+ : null
884
+ } satisfies Omit<CodeGenOptionDialog, "visible">;
885
+ await optionDialogRef.value?.open({
886
+ load: async () => {
887
+ syncOptionKind({ ...config, option: draft.option }, scope);
888
+ await prepareOptionEditor(draft);
889
+ return draft;
890
+ },
891
+ commit: loaded => {
892
+ Object.assign(optionDialog, loaded);
893
+ }
894
+ });
881
895
  }
882
896
 
883
897
  /** 保存选项配置并关闭弹窗。 */
884
898
  function handleSaveOptionDialog() {
885
899
  const row = columns.value.find(item => item.name === optionDialog.columnName);
886
- if (row) copyCodeGenOptionToEmptyMatches(row, optionDialog.scope);
900
+ if (row && optionDialog.option) {
901
+ const config = getCodeGenOptionContainer(row, optionDialog.scope);
902
+ Object.assign(config.option, optionDialog.option);
903
+ if (optionDialog.formConfig) Object.assign(row.form_config, optionDialog.formConfig, { option: config.option });
904
+ copyCodeGenOptionToEmptyMatches(row, optionDialog.scope);
905
+ }
887
906
  optionDialog.visible = false;
888
907
  }
889
908
 
@@ -894,12 +913,12 @@ function handleOptionDialogClosed() {
894
913
  }
895
914
 
896
915
  /** 按当前选项来源准备弹窗所需数据。 */
897
- async function prepareOptionEditor() {
898
- const option = optionDialog.option;
916
+ async function prepareOptionEditor(context: Pick<CodeGenOptionDialog, "option" | "cacheKey" | "component"> = optionDialog) {
917
+ const option = context.option;
899
918
  if (!option) return;
900
919
  if (option.source_type === "static") {
901
- if (!staticOptions.has(optionDialog.cacheKey)) {
902
- staticOptions.set(optionDialog.cacheKey, parseCodeGenStaticOptions(option.source_value));
920
+ if (!staticOptions.has(context.cacheKey)) {
921
+ staticOptions.set(context.cacheKey, parseCodeGenStaticOptions(option.source_value));
903
922
  }
904
923
  return;
905
924
  }
@@ -912,7 +931,7 @@ async function prepareOptionEditor() {
912
931
  if (option.source_type === "table") {
913
932
  await loadDatabaseTables();
914
933
  await loadDatabaseColumns(option.source_value);
915
- applyTableOptionDefaultFields(option, optionDialog.component);
934
+ applyTableOptionDefaultFields(option, context.component);
916
935
  }
917
936
  }
918
937
 
@@ -789,33 +789,58 @@ function refreshTable() {
789
789
 
790
790
  /** 打开新增或编辑弹窗,并加载当前表单所需选项。 */
791
791
  async function handleOpenDialog(tableId?: number) {
792
- resetForm();
793
- await loadSourceOptions();
794
- const detail = tableId ? await defCodeGenTableService.GetCodeGenTable({ id: tableId }) : undefined;
795
- if (detail) Object.assign(formData, detail);
796
- if (!formData.source_name) formData.source_name = String(sourceOptions.value[0]?.value ?? "");
797
- const [tableData, menuData, dictionaryData] = await Promise.all([
798
- loadDatabaseTables(formData.source_name),
799
- defBaseMenuService.TreeBaseMenu({}),
800
- defBaseDictService.OptionBaseDict({})
801
- ]);
802
- databaseTables.value = tableData.tables ?? [];
803
- parentMenuOptions.value = convertMenuOptions(menuData.base_menus ?? []);
804
- businessModuleItems.value = dictionaryData.base_dicts?.find(item => item.code === "business_module")?.items ?? [];
805
- if (detail) {
806
- formData.parent_menu_id = detail.parent_menu_id || undefined;
807
- formData.left_tree_config ??= createDefaultCodeGenLeftTreeConfig();
808
- if (!formData.comment) {
809
- formData.comment = databaseTables.value.find(item => item.name === formData.name)?.comment ?? "";
810
- }
811
- if (!formData.left_tree_config.comment) {
812
- formData.left_tree_config.comment =
813
- databaseTables.value.find(item => item.name === formData.left_tree_config?.table_name)?.comment ?? "";
792
+ await formDialogRef.value?.open({
793
+ load: async () => {
794
+ await loadSourceOptions();
795
+ const detail = tableId ? await defCodeGenTableService.GetCodeGenTable({ id: tableId }) : undefined;
796
+ const sourceName = detail?.source_name || String(sourceOptions.value[0]?.value ?? "");
797
+ const [tableData, menuData, dictionaryData] = await Promise.all([
798
+ loadDatabaseTables(sourceName),
799
+ defBaseMenuService.TreeBaseMenu({}),
800
+ defBaseDictService.OptionBaseDict({})
801
+ ]);
802
+ const tables = tableData.tables ?? [];
803
+ const form = {
804
+ ...createDefaultCodeGenTableForm(),
805
+ ...(detail ?? {}),
806
+ source_name: sourceName,
807
+ parent_menu_id: detail?.parent_menu_id || undefined,
808
+ left_tree_config: detail?.left_tree_config
809
+ ? { ...detail.left_tree_config }
810
+ : createDefaultCodeGenLeftTreeConfig()
811
+ };
812
+ if (detail) {
813
+ if (!form.comment) form.comment = tables.find(item => item.name === form.name)?.comment ?? "";
814
+ if (!form.left_tree_config.comment) {
815
+ form.left_tree_config.comment = tables.find(item => item.name === form.left_tree_config?.table_name)?.comment ?? "";
816
+ }
817
+ }
818
+ const [columns, leftTreeColumns] = detail
819
+ ? await Promise.all([
820
+ requestDatabaseColumns(form.source_name, form.name),
821
+ form.page_type === "left_tree" ? requestDatabaseColumns(form.source_name, form.left_tree_config.table_name) : Promise.resolve([])
822
+ ])
823
+ : [[], []];
824
+ return {
825
+ form,
826
+ tables,
827
+ menuOptions: convertMenuOptions(menuData.base_menus ?? []),
828
+ businessModuleItems: dictionaryData.base_dicts?.find(item => item.code === "business_module")?.items ?? [],
829
+ columns,
830
+ leftTreeColumns
831
+ };
832
+ },
833
+ commit: ({ form, tables, menuOptions, businessModuleItems: items, columns, leftTreeColumns }) => {
834
+ resetForm();
835
+ Object.assign(formData, form);
836
+ databaseTables.value = tables;
837
+ parentMenuOptions.value = menuOptions;
838
+ businessModuleItems.value = items;
839
+ databaseColumns.value = columns;
840
+ leftTreeDatabaseColumns.value = leftTreeColumns;
841
+ dialog.editing = Boolean(tableId);
814
842
  }
815
- await Promise.all([loadDatabaseColumns(databaseColumns, formData.source_name, formData.name), loadLeftTreeDatabaseColumns()]);
816
- dialog.editing = true;
817
- }
818
- dialog.visible = true;
843
+ });
819
844
  }
820
845
 
821
846
  /** 加载已初始化的数据源选项。 */
@@ -971,12 +996,14 @@ async function loadDatabaseTables(sourceName: string) {
971
996
 
972
997
  /** 查询指定数据源的数据表字段选项。 */
973
998
  async function loadDatabaseColumns(target: { value: CodeGenDatabaseColumn[] }, sourceName: string, tableName: string) {
974
- if (!tableName) {
975
- target.value = [];
976
- return;
977
- }
999
+ target.value = await requestDatabaseColumns(sourceName, tableName);
1000
+ }
1001
+
1002
+ /** 请求指定数据源和数据表的字段选项。 */
1003
+ async function requestDatabaseColumns(sourceName: string, tableName: string) {
1004
+ if (!tableName) return [];
978
1005
  const data = await defCodeGenColumnService.ListCodeGenDatabaseColumn({ source_name: sourceName, table_name: tableName });
979
- target.value = data.columns ?? [];
1006
+ return data.columns ?? [];
980
1007
  }
981
1008
 
982
1009
  /** 查询左树来源表字段选项。 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@liujitcn/kratos-admin-system",
3
3
  "private": false,
4
- "version": "0.0.51",
4
+ "version": "0.0.53",
5
5
  "type": "module",
6
6
  "description": "kratos-admin system management module",
7
7
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "sortablejs": "^1.15.2",
17
17
  "swagger-ui-dist": "^5.32.15",
18
18
  "vue-element-plus-x": "^2.0.3",
19
- "@liujitcn/kratos-admin-core": "0.0.51"
19
+ "@liujitcn/kratos-admin-core": "0.0.53"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@element-plus/icons-vue": "^2.3.1",