@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.
- package/README.md +137 -0
- package/dist/package/declarations/index.d.ts +1 -0
- package/dist/package/declarations/src/ai.d.ts +10 -0
- package/dist/package/declarations/src/api/base/ai_message.d.ts +27 -0
- package/dist/package/declarations/src/api/base/ai_session.d.ts +17 -0
- package/dist/package/declarations/src/api/base/ai_tool.d.ts +7 -0
- package/dist/package/declarations/src/api/base/oauth.d.ts +13 -0
- package/dist/package/declarations/src/api/base/sse.d.ts +31 -0
- package/dist/package/declarations/src/api/system/auth.d.ts +17 -0
- package/dist/package/declarations/src/api/system/base_api.d.ts +22 -0
- package/dist/package/declarations/src/api/system/base_area.d.ts +19 -0
- package/dist/package/declarations/src/api/system/base_config.d.ts +20 -0
- package/dist/package/declarations/src/api/system/base_dept.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_dict.d.ts +32 -0
- package/dist/package/declarations/src/api/system/base_job.d.ts +28 -0
- package/dist/package/declarations/src/api/system/base_log.d.ts +9 -0
- package/dist/package/declarations/src/api/system/base_menu.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_migration.d.ts +10 -0
- package/dist/package/declarations/src/api/system/base_post.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_role.d.ts +23 -0
- package/dist/package/declarations/src/api/system/base_tenant.d.ts +21 -0
- package/dist/package/declarations/src/api/system/base_user.d.ts +23 -0
- package/dist/package/declarations/src/api/system/code_gen.d.ts +14 -0
- package/dist/package/declarations/src/api/system/code_gen_column.d.ts +12 -0
- package/dist/package/declarations/src/api/system/code_gen_proto.d.ts +10 -0
- package/dist/package/declarations/src/api/system/code_gen_sse.d.ts +8 -0
- package/dist/package/declarations/src/api/system/code_gen_table.d.ts +18 -0
- package/dist/package/declarations/src/api/system/project_document.d.ts +9 -0
- package/dist/package/declarations/src/components/Ai.vue.d.ts +3 -0
- package/dist/package/declarations/src/index.d.ts +3 -0
- package/dist/package/declarations/src/module.d.ts +2 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_message.d.ts +82 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +176 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +59 -0
- package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +167 -0
- package/dist/package/declarations/src/rpc/base/v1/sse.d.ts +13 -0
- package/dist/package/declarations/src/rpc/common/v1/common.d.ts +57 -0
- package/dist/package/declarations/src/rpc/common/v1/enum.d.ts +58 -0
- package/dist/package/declarations/src/rpc/common/v1/types.d.ts +60 -0
- package/dist/package/declarations/src/rpc/google/protobuf/empty.d.ts +11 -0
- package/dist/package/declarations/src/rpc/google/protobuf/timestamp.d.ts +107 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +156 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_api.d.ts +193 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_area.d.ts +82 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dept.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +215 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +177 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +87 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +151 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +64 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_post.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +128 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_tenant.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +161 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +155 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +143 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_proto.d.ts +86 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +149 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/project_document.d.ts +64 -0
- package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +67 -0
- package/dist/package/declarations/src/views/ai/chat/attachment.d.ts +14 -0
- package/dist/package/declarations/src/views/ai/chat/components/AiMarkdown.vue.d.ts +13 -0
- package/dist/package/declarations/src/views/ai/chat/components/ChatPanel.vue.d.ts +45 -0
- package/dist/package/declarations/src/views/ai/chat/components/SessionPanel.vue.d.ts +34 -0
- package/dist/package/declarations/src/views/ai/chat/components/XSender.vue.d.ts +12 -0
- package/dist/package/declarations/src/views/ai/chat/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/ai/chat/message.d.ts +59 -0
- package/dist/package/declarations/src/views/ai/chat/stream.d.ts +10 -0
- package/dist/package/declarations/src/views/ai/chat/types.d.ts +115 -0
- package/dist/package/declarations/src/views/base/api/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/area/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/config/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dept/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dict/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/dict/item.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/job/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/job/log.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/log/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/menu/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/migration/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/base/post/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/role/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/tenant/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/base/user/components/dept-tree.vue.d.ts +19 -0
- package/dist/package/declarations/src/views/base/user/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/profile/components/base.vue.d.ts +13 -0
- package/dist/package/declarations/src/views/profile/components/password.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/profile/components/security.vue.d.ts +15 -0
- package/dist/package/declarations/src/views/profile/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/api-doc/index.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/tool/code-gen/code-preview/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/columns/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/columns/option-copy.d.ts +25 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenProgressDialog.vue.d.ts +16 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodePreviewPane.vue.d.ts +9 -0
- package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +32 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/capabilities.d.ts +20 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/data.d.ts +42 -0
- package/dist/package/declarations/src/views/tool/code-gen/preview/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/proto/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/table/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/project-doc/index.vue.d.ts +4 -0
- package/dist/package/src/ai.ts +16 -0
- package/dist/package/src/api/base/ai_message.ts +139 -0
- package/dist/package/src/api/base/ai_session.ts +77 -0
- package/dist/package/src/api/base/ai_tool.ts +22 -0
- package/dist/package/src/api/base/oauth.ts +47 -0
- package/dist/package/src/api/base/sse.ts +192 -0
- package/dist/package/src/api/system/auth.ts +65 -0
- package/dist/package/src/api/system/base_api.ts +95 -0
- package/dist/package/src/api/system/base_area.ts +73 -0
- package/dist/package/src/api/system/base_config.ts +82 -0
- package/dist/package/src/api/system/base_dept.ts +83 -0
- package/dist/package/src/api/system/base_dict.ts +144 -0
- package/dist/package/src/api/system/base_job.ts +125 -0
- package/dist/package/src/api/system/base_log.ts +32 -0
- package/dist/package/src/api/system/base_menu.ts +83 -0
- package/dist/package/src/api/system/base_migration.ts +35 -0
- package/dist/package/src/api/system/base_post.ts +83 -0
- package/dist/package/src/api/system/base_role.ts +93 -0
- package/dist/package/src/api/system/base_tenant.ts +83 -0
- package/dist/package/src/api/system/base_user.ts +93 -0
- package/dist/package/src/api/system/code_gen.ts +56 -0
- package/dist/package/src/api/system/code_gen_column.ts +43 -0
- package/dist/package/src/api/system/code_gen_proto.ts +32 -0
- package/dist/package/src/api/system/code_gen_sse.ts +33 -0
- package/dist/package/src/api/system/code_gen_table.ts +74 -0
- package/dist/package/src/api/system/project_document.ts +33 -0
- package/dist/package/src/components/Ai.vue +57 -0
- package/dist/package/src/index.ts +3 -0
- package/dist/package/src/module.ts +17 -0
- package/dist/package/src/rpc/base/v1/ai_message.ts +98 -0
- package/dist/package/src/rpc/base/v1/ai_session.ts +214 -0
- package/dist/package/src/rpc/base/v1/ai_tool.ts +74 -0
- package/dist/package/src/rpc/base/v1/oauth.ts +199 -0
- package/dist/package/src/rpc/base/v1/sse.ts +22 -0
- package/dist/package/src/rpc/common/v1/common.ts +71 -0
- package/dist/package/src/rpc/common/v1/enum.ts +71 -0
- package/dist/package/src/rpc/common/v1/types.ts +77 -0
- package/dist/package/src/rpc/google/protobuf/empty.ts +19 -0
- package/dist/package/src/rpc/google/protobuf/timestamp.ts +115 -0
- package/dist/package/src/rpc/system/admin/v1/auth.ts +208 -0
- package/dist/package/src/rpc/system/admin/v1/base_api.ts +241 -0
- package/dist/package/src/rpc/system/admin/v1/base_area.ts +105 -0
- package/dist/package/src/rpc/system/admin/v1/base_config.ts +140 -0
- package/dist/package/src/rpc/system/admin/v1/base_dept.ts +140 -0
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +249 -0
- package/dist/package/src/rpc/system/admin/v1/base_job.ts +206 -0
- package/dist/package/src/rpc/system/admin/v1/base_log.ts +101 -0
- package/dist/package/src/rpc/system/admin/v1/base_menu.ts +195 -0
- package/dist/package/src/rpc/system/admin/v1/base_migration.ts +81 -0
- package/dist/package/src/rpc/system/admin/v1/base_post.ts +134 -0
- package/dist/package/src/rpc/system/admin/v1/base_role.ts +151 -0
- package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +134 -0
- package/dist/package/src/rpc/system/admin/v1/base_user.ts +190 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen.ts +176 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +170 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_proto.ts +104 -0
- package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +179 -0
- package/dist/package/src/rpc/system/admin/v1/project_document.ts +79 -0
- package/dist/package/src/rpc/system/common/v1/enum.ts +80 -0
- package/dist/package/src/typings/swagger-ui-dist.d.ts +28 -0
- package/dist/package/src/typings/x-markdown-vue.d.ts +1 -0
- package/dist/package/src/views/ai/chat/attachment.ts +65 -0
- package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +162 -0
- package/dist/package/src/views/ai/chat/components/ChatPanel.vue +1861 -0
- package/dist/package/src/views/ai/chat/components/SessionPanel.vue +316 -0
- package/dist/package/src/views/ai/chat/components/XSender.vue +554 -0
- package/dist/package/src/views/ai/chat/index.vue +848 -0
- package/dist/package/src/views/ai/chat/message.ts +416 -0
- package/dist/package/src/views/ai/chat/stream.ts +115 -0
- package/dist/package/src/views/ai/chat/types.ts +126 -0
- package/dist/package/src/views/base/api/index.vue +455 -0
- package/dist/package/src/views/base/area/index.vue +269 -0
- package/dist/package/src/views/base/config/index.vue +530 -0
- package/dist/package/src/views/base/dept/index.vue +461 -0
- package/dist/package/src/views/base/dict/index.vue +304 -0
- package/dist/package/src/views/base/dict/item.vue +373 -0
- package/dist/package/src/views/base/job/index.vue +535 -0
- package/dist/package/src/views/base/job/log.vue +202 -0
- package/dist/package/src/views/base/log/index.vue +317 -0
- package/dist/package/src/views/base/menu/index.vue +944 -0
- package/dist/package/src/views/base/migration/index.vue +791 -0
- package/dist/package/src/views/base/post/index.vue +324 -0
- package/dist/package/src/views/base/role/index.vue +684 -0
- package/dist/package/src/views/base/tenant/index.vue +328 -0
- package/dist/package/src/views/base/user/components/dept-tree.vue +75 -0
- package/dist/package/src/views/base/user/index.vue +783 -0
- package/dist/package/src/views/profile/components/base.vue +320 -0
- package/dist/package/src/views/profile/components/password.vue +269 -0
- package/dist/package/src/views/profile/components/security.vue +443 -0
- package/dist/package/src/views/profile/index.vue +199 -0
- package/dist/package/src/views/tool/api-doc/index.vue +275 -0
- package/dist/package/src/views/tool/code-gen/code-preview/index.vue +233 -0
- package/dist/package/src/views/tool/code-gen/columns/index.vue +1456 -0
- package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +125 -0
- package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +328 -0
- package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +42 -0
- package/dist/package/src/views/tool/code-gen/config.ts +175 -0
- package/dist/package/src/views/tool/code-gen/preview/capabilities.ts +34 -0
- package/dist/package/src/views/tool/code-gen/preview/data.ts +331 -0
- package/dist/package/src/views/tool/code-gen/preview/index.vue +831 -0
- package/dist/package/src/views/tool/code-gen/proto/index.vue +703 -0
- package/dist/package/src/views/tool/code-gen/table/index.vue +864 -0
- package/dist/package/src/views/tool/project-doc/index.vue +561 -0
- package/package.json +60 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
<!-- 代码生成表配置 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="table-box">
|
|
4
|
+
<ProTable
|
|
5
|
+
ref="proTable"
|
|
6
|
+
class="code-gen-table"
|
|
7
|
+
row-key="id"
|
|
8
|
+
:columns="columns"
|
|
9
|
+
:header-actions="headerActions"
|
|
10
|
+
:restore-selected-row-keys="progressSelectedTableIds"
|
|
11
|
+
:request-api="requestCodeGenTable"
|
|
12
|
+
/>
|
|
13
|
+
|
|
14
|
+
<FormDialog
|
|
15
|
+
v-model="dialog.visible"
|
|
16
|
+
ref="formDialogRef"
|
|
17
|
+
:title="dialog.title"
|
|
18
|
+
width="min(920px, calc(100vw - 32px))"
|
|
19
|
+
top="4vh"
|
|
20
|
+
:model="formData"
|
|
21
|
+
:fields="formFields"
|
|
22
|
+
:rules="codeGenTableRules"
|
|
23
|
+
:confirm-loading="saving"
|
|
24
|
+
label-width="116px"
|
|
25
|
+
:gutter="16"
|
|
26
|
+
:col-span="12"
|
|
27
|
+
@confirm="handleSubmit"
|
|
28
|
+
@close="handleCloseDialog"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<CodeGenProgressDialog
|
|
32
|
+
v-model="progressDialogVisible"
|
|
33
|
+
:task-id="progressTaskId"
|
|
34
|
+
@update:model-value="handleProgressDialogVisibleChange"
|
|
35
|
+
@completed="handleProgressCompleted"
|
|
36
|
+
@unavailable="handleProgressUnavailable"
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup lang="ts">
|
|
42
|
+
import { computed, nextTick, reactive, ref } from "vue";
|
|
43
|
+
import { useRouter } from "vue-router";
|
|
44
|
+
import { CirclePlus, Clock, Connection, Delete, Document, EditPen, Promotion, RefreshRight, SetUp, View } from "@element-plus/icons-vue";
|
|
45
|
+
import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
|
|
46
|
+
import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
|
|
47
|
+
import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
|
|
48
|
+
import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
|
|
49
|
+
import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
|
|
50
|
+
import { defBaseMenuService } from "@liujitcn/kratos-admin-system/api/system/base_menu";
|
|
51
|
+
import { defBaseDictService } from "@liujitcn/kratos-admin-system/api/system/base_dict";
|
|
52
|
+
import { defCodeGenService } from "@liujitcn/kratos-admin-system/api/system/code_gen";
|
|
53
|
+
import { defCodeGenColumnService } from "@liujitcn/kratos-admin-system/api/system/code_gen_column";
|
|
54
|
+
import { defCodeGenTableService } from "@liujitcn/kratos-admin-system/api/system/code_gen_table";
|
|
55
|
+
import type { CodeGenDatabaseColumn } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
|
|
56
|
+
import type {
|
|
57
|
+
CodeGenDatabaseTable,
|
|
58
|
+
CodeGenTable,
|
|
59
|
+
CodeGenTableForm,
|
|
60
|
+
PageCodeGenTableRequest
|
|
61
|
+
} from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_table";
|
|
62
|
+
import type { BaseMenu } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_menu";
|
|
63
|
+
import type { OptionBaseDictResponse_BaseDictItem } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
|
|
64
|
+
import { BaseMenuType, CodeGenTableStatus } from "@liujitcn/kratos-admin-system/rpc/system/common/v1/enum";
|
|
65
|
+
import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
|
|
66
|
+
import CodeGenProgressDialog from "../components/CodeGenProgressDialog.vue";
|
|
67
|
+
import {
|
|
68
|
+
codeGenPageTypeOptions,
|
|
69
|
+
codeGenTableRules,
|
|
70
|
+
createDefaultCodeGenLeftTreeConfig,
|
|
71
|
+
createDefaultCodeGenTableForm,
|
|
72
|
+
isCodeGenTreePageType
|
|
73
|
+
} from "../config";
|
|
74
|
+
|
|
75
|
+
defineOptions({
|
|
76
|
+
name: "CodeGenTable",
|
|
77
|
+
inheritAttrs: false
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/** 代码生成表配置删除入参。 */
|
|
81
|
+
type CodeGenDeleteTarget = number | string | Array<number | string> | CodeGenTable | CodeGenTable[];
|
|
82
|
+
|
|
83
|
+
/** 代码生成单项或批量目标。 */
|
|
84
|
+
type CodeGenGenerateTarget = CodeGenTable | CodeGenTable[];
|
|
85
|
+
|
|
86
|
+
/** 代码生成单项或批量还原目标。 */
|
|
87
|
+
type CodeGenRestoreTarget = CodeGenTable | CodeGenTable[];
|
|
88
|
+
|
|
89
|
+
/** 代码生成表配置弹窗状态,未选择父级菜单时保持空白。 */
|
|
90
|
+
type CodeGenTableFormState = Omit<CodeGenTableForm, "parent_menu_id"> & {
|
|
91
|
+
/** 父级菜单ID。 */
|
|
92
|
+
parent_menu_id?: number;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const codeGenTaskStorageKey = "code-gen-progress-task-id";
|
|
96
|
+
const codeGenProgressDialogVisibleStorageKey = "code-gen-progress-dialog-visible";
|
|
97
|
+
const codeGenProgressSelectedTableIdsStorageKey = "code-gen-progress-selected-table-ids";
|
|
98
|
+
const codeGenStatusDisabled = CodeGenTableStatus.DISABLED_CGTS;
|
|
99
|
+
|
|
100
|
+
const { BUTTONS } = useAuthButtons();
|
|
101
|
+
const router = useRouter();
|
|
102
|
+
const proTable = ref<ProTableInstance>();
|
|
103
|
+
const formDialogRef = ref<InstanceType<typeof FormDialog>>();
|
|
104
|
+
const saving = ref(false);
|
|
105
|
+
const databaseTables = ref<CodeGenDatabaseTable[]>([]);
|
|
106
|
+
const businessModuleItems = ref<OptionBaseDictResponse_BaseDictItem[]>([]);
|
|
107
|
+
const databaseColumns = ref<CodeGenDatabaseColumn[]>([]);
|
|
108
|
+
const leftTreeDatabaseColumns = ref<CodeGenDatabaseColumn[]>([]);
|
|
109
|
+
const parentMenuOptions = ref<ProFormOption[]>([]);
|
|
110
|
+
const progressTaskId = ref(typeof window === "undefined" ? "" : (window.sessionStorage.getItem(codeGenTaskStorageKey) ?? ""));
|
|
111
|
+
const progressDialogVisible = ref(
|
|
112
|
+
!!progressTaskId.value &&
|
|
113
|
+
typeof window !== "undefined" &&
|
|
114
|
+
window.sessionStorage.getItem(codeGenProgressDialogVisibleStorageKey) === "true"
|
|
115
|
+
);
|
|
116
|
+
const progressTaskAvailable = ref(!!progressTaskId.value);
|
|
117
|
+
const generating = ref(!!progressTaskId.value);
|
|
118
|
+
const progressSelectedTableIds = ref<Array<string | number>>(readProgressSelectedTableIds());
|
|
119
|
+
|
|
120
|
+
const dialog = reactive({
|
|
121
|
+
title: "",
|
|
122
|
+
visible: false
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const formData = reactive<CodeGenTableFormState>({ ...createDefaultCodeGenTableForm(), parent_menu_id: undefined });
|
|
126
|
+
|
|
127
|
+
/** 当前业务表选择项。 */
|
|
128
|
+
const databaseTableOptions = computed<ProFormOption[]>(() =>
|
|
129
|
+
databaseTables.value.map(item => ({
|
|
130
|
+
label: item.comment ? `${item.name}(${item.comment})` : item.name,
|
|
131
|
+
value: item.name,
|
|
132
|
+
disabled: item.disabled && item.name !== formData.name
|
|
133
|
+
}))
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
/** 左树来源表选择项。 */
|
|
137
|
+
const leftTreeTableOptions = computed<ProFormOption[]>(() =>
|
|
138
|
+
databaseTables.value.map(item => ({
|
|
139
|
+
label: item.comment ? `${item.name}(${item.comment})` : item.name,
|
|
140
|
+
value: item.name
|
|
141
|
+
}))
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
/** 业务模块选择项,仅允许新增或编辑时选择启用项;已保存的停用项保留为只读选项。 */
|
|
145
|
+
const businessModuleOptions = computed<ProFormOption[]>(() => {
|
|
146
|
+
const options: ProFormOption[] = businessModuleItems.value.map(item => ({ label: item.label, value: item.value }));
|
|
147
|
+
if (formData.business_module && !options.some(item => item.value === formData.business_module)) {
|
|
148
|
+
options.push({ label: `${formData.business_module}(已停用)`, value: formData.business_module, disabled: true });
|
|
149
|
+
}
|
|
150
|
+
return options;
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
/** 当前业务表字段选择项。 */
|
|
154
|
+
const databaseColumnOptions = computed<ProFormOption[]>(() => createDatabaseColumnOptions(databaseColumns.value));
|
|
155
|
+
|
|
156
|
+
/** 左树来源表字段选择项。 */
|
|
157
|
+
const leftTreeColumnOptions = computed<ProFormOption[]>(() => createDatabaseColumnOptions(leftTreeDatabaseColumns.value));
|
|
158
|
+
|
|
159
|
+
/** 代码生成表配置表单字段。 */
|
|
160
|
+
const formFields = computed<ProFormField[]>(() => [
|
|
161
|
+
// 标签提示与当前生成器的实际读写逻辑保持一致,方便配置时判断影响范围。
|
|
162
|
+
{
|
|
163
|
+
prop: "name",
|
|
164
|
+
label: "业务表名",
|
|
165
|
+
component: "select",
|
|
166
|
+
options: databaseTableOptions.value,
|
|
167
|
+
colSpan: 24,
|
|
168
|
+
labelTooltip: "选择代码生成的源数据库表。生成器据此读取字段元数据、定位数据模型和生成目标;同一张表不能重复配置。",
|
|
169
|
+
props: {
|
|
170
|
+
placeholder: "请选择数据库表",
|
|
171
|
+
clearable: true,
|
|
172
|
+
filterable: true,
|
|
173
|
+
style: { width: "100%" },
|
|
174
|
+
onChange: handleTableNameChange
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
prop: "comment",
|
|
179
|
+
label: "业务表描述",
|
|
180
|
+
component: "input",
|
|
181
|
+
colSpan: 24,
|
|
182
|
+
labelTooltip: "业务的中文描述。生成器优先用它写入 Proto、后端和前端文案,并作为生成菜单标题;修改后在下次生成生效。",
|
|
183
|
+
props: { placeholder: "选择业务表后自动带出,可修改" }
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
prop: "business_module",
|
|
187
|
+
label: "业务模块",
|
|
188
|
+
component: "select",
|
|
189
|
+
options: businessModuleOptions.value,
|
|
190
|
+
labelTooltip: "选择业务模块后,Proto、后端服务、前端 API 与页面路径均由模块和表名自动推导。",
|
|
191
|
+
props: { placeholder: "请选择业务模块", filterable: true, style: { width: "100%" } }
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
prop: "parent_menu_id",
|
|
195
|
+
label: "父级菜单",
|
|
196
|
+
component: "tree-select",
|
|
197
|
+
options: parentMenuOptions.value,
|
|
198
|
+
labelTooltip:
|
|
199
|
+
"选择一级模块目录或二级业务目录作为挂载点。仅当同时生成前端、开启“生成SQL”且页面接口完整时,生成流程才会同步页面菜单和按钮权限。",
|
|
200
|
+
props: {
|
|
201
|
+
placeholder: "请选择生成页面挂载菜单",
|
|
202
|
+
clearable: true,
|
|
203
|
+
filterable: true,
|
|
204
|
+
checkStrictly: true,
|
|
205
|
+
renderAfterExpand: false,
|
|
206
|
+
style: { width: "100%" }
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
prop: "page_type",
|
|
211
|
+
label: "页面类型",
|
|
212
|
+
component: "segmented",
|
|
213
|
+
options: codeGenPageTypeOptions,
|
|
214
|
+
labelTooltip: "普通表格生成分页 CRUD;树形表格生成完整层级列表;树形懒加载按节点请求子列表;左树右表生成左侧树筛选与右侧列表。",
|
|
215
|
+
props: { onChange: handlePageTypeChange }
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
prop: "parent_column",
|
|
219
|
+
label: "父节点字段",
|
|
220
|
+
component: "select",
|
|
221
|
+
options: databaseColumnOptions.value,
|
|
222
|
+
labelTooltip: "树形表格中指向父记录的字段,例如 parent_id。它决定生成的树查询和选项接口如何组织父子层级。",
|
|
223
|
+
props: { placeholder: "请选择父节点字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
224
|
+
visible: model => isCodeGenTreePageType(model.page_type)
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
prop: "tree_label_column",
|
|
228
|
+
label: "树显示字段",
|
|
229
|
+
component: "select",
|
|
230
|
+
options: databaseColumnOptions.value,
|
|
231
|
+
labelTooltip: "树节点显示的文字字段,例如 name。它会写入生成的树查询和选项接口响应,并显示在前端树节点上。",
|
|
232
|
+
props: { placeholder: "请选择树显示字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
233
|
+
visible: model => isCodeGenTreePageType(model.page_type)
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
prop: "left_tree_config.table_name",
|
|
237
|
+
label: "左树数据表",
|
|
238
|
+
component: "select",
|
|
239
|
+
options: leftTreeTableOptions.value,
|
|
240
|
+
labelTooltip: "左侧树的数据来源。它决定要调用哪个实体的树选项接口,并限定左树父、显示和值字段的可选范围。",
|
|
241
|
+
props: {
|
|
242
|
+
placeholder: "请选择左树数据表",
|
|
243
|
+
clearable: true,
|
|
244
|
+
filterable: true,
|
|
245
|
+
style: { width: "100%" },
|
|
246
|
+
onChange: handleLeftTreeTableNameChange
|
|
247
|
+
},
|
|
248
|
+
visible: model => model.page_type === "left_tree"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
prop: "left_tree_config.comment",
|
|
252
|
+
label: "左树描述",
|
|
253
|
+
component: "input",
|
|
254
|
+
labelTooltip: "左侧树的中文说明。页面预览会优先显示该标题;它不改变生成接口、路由或文件路径。",
|
|
255
|
+
props: { placeholder: "选择左树数据表后自动带出,可修改" },
|
|
256
|
+
visible: model => model.page_type === "left_tree"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
prop: "left_tree_config.filter_column",
|
|
260
|
+
label: "筛选字段",
|
|
261
|
+
labelTooltip: "当前业务表中关联左树节点值的字段。点击左树节点后,生成页面会把节点值作为该字段的查询条件传给右侧列表。",
|
|
262
|
+
component: "select",
|
|
263
|
+
options: databaseColumnOptions.value,
|
|
264
|
+
props: { placeholder: "请选择当前表筛选字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
265
|
+
visible: model => model.page_type === "left_tree"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
prop: "left_tree_config.parent_column",
|
|
269
|
+
label: "左树父字段",
|
|
270
|
+
component: "select",
|
|
271
|
+
options: leftTreeColumnOptions.value,
|
|
272
|
+
labelTooltip: "左树数据表中指向父节点的字段,例如 parent_id。它决定左侧选项接口如何返回层级 children。",
|
|
273
|
+
props: { placeholder: "请选择左树父字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
274
|
+
visible: model => model.page_type === "left_tree"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
prop: "left_tree_config.label_column",
|
|
278
|
+
label: "左树显示字段",
|
|
279
|
+
component: "select",
|
|
280
|
+
options: leftTreeColumnOptions.value,
|
|
281
|
+
labelTooltip: "左树节点显示的文字字段,例如 name。它会映射为左侧 TreeFilter 组件的节点标签。",
|
|
282
|
+
props: { placeholder: "请选择左树显示字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
283
|
+
visible: model => model.page_type === "left_tree"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
prop: "left_tree_config.value_column",
|
|
287
|
+
label: "左树值字段",
|
|
288
|
+
component: "select",
|
|
289
|
+
options: leftTreeColumnOptions.value,
|
|
290
|
+
labelTooltip: "左树节点的唯一值字段,通常为主键 id。它作为点击节点后传给右侧列表筛选字段的值。",
|
|
291
|
+
props: { placeholder: "请选择左树值字段", clearable: true, filterable: true, style: { width: "100%" } },
|
|
292
|
+
visible: model => model.page_type === "left_tree"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
prop: "left_tree_config.lazy",
|
|
296
|
+
label: "左树懒加载",
|
|
297
|
+
component: "switch",
|
|
298
|
+
labelTooltip: "开启后左树只请求当前展开节点的子节点,适合层级较深或数据量较大的树。",
|
|
299
|
+
props: { activeText: "懒加载", inactiveText: "全部加载" },
|
|
300
|
+
visible: model => model.page_type === "left_tree"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
prop: "gen_backend",
|
|
304
|
+
label: "生成后端",
|
|
305
|
+
component: "switch",
|
|
306
|
+
labelTooltip: "开启后生成 Proto、后端 Biz/Service 及注册代码;关闭后本次任务不会写入这些后端文件。",
|
|
307
|
+
// 三个生成开关始终从新行开始并排展示。
|
|
308
|
+
rowBreakBefore: true,
|
|
309
|
+
colSpan: 8,
|
|
310
|
+
props: { activeText: "生成", inactiveText: "跳过" }
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
prop: "gen_frontend",
|
|
314
|
+
label: "生成前端",
|
|
315
|
+
component: "switch",
|
|
316
|
+
labelTooltip: "开启后生成前端 API 和 Vue 页面;同时它也是同步页面菜单与按钮权限的前置条件。",
|
|
317
|
+
colSpan: 8,
|
|
318
|
+
props: { activeText: "生成", inactiveText: "跳过" }
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
prop: "gen_sql",
|
|
322
|
+
label: "生成SQL",
|
|
323
|
+
component: "switch",
|
|
324
|
+
colSpan: 8,
|
|
325
|
+
labelTooltip: "开启后在满足前端生成与页面接口完整的条件下,同时同步菜单和按钮权限到数据库,并复用或新增当前未执行的数据库迁移脚本。",
|
|
326
|
+
props: { activeText: "生成", inactiveText: "跳过" }
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
prop: "status",
|
|
330
|
+
label: "状态",
|
|
331
|
+
component: "dict",
|
|
332
|
+
colSpan: 24,
|
|
333
|
+
props: { code: "code_gen_table_status", codeType: "number", type: "radio" },
|
|
334
|
+
labelTooltip: "草稿和已生成配置均可再次生成;停用后只能查看,生成任务会拒绝写入任何文件。成功生成后状态自动更新为“已生成”。"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
prop: "remark",
|
|
338
|
+
label: "备注",
|
|
339
|
+
component: "textarea",
|
|
340
|
+
colSpan: 24,
|
|
341
|
+
labelTooltip: "仅保存给维护人员的配置备注,不参与生成文件、接口、路由或权限的命名。",
|
|
342
|
+
props: { placeholder: "请输入备注", rows: 3 }
|
|
343
|
+
}
|
|
344
|
+
]);
|
|
345
|
+
|
|
346
|
+
/** 代码生成表配置列表列。 */
|
|
347
|
+
const columns: ColumnProps[] = [
|
|
348
|
+
{ type: "selection", width: 55 },
|
|
349
|
+
{ prop: "name", label: "业务表名", minWidth: 160, search: { el: "input" } },
|
|
350
|
+
{ prop: "comment", label: "业务表描述", minWidth: 160, showOverflowTooltip: true },
|
|
351
|
+
{
|
|
352
|
+
prop: "business_module",
|
|
353
|
+
label: "业务模块",
|
|
354
|
+
minWidth: 140,
|
|
355
|
+
dictCode: "business_module",
|
|
356
|
+
dictValueType: "string",
|
|
357
|
+
search: { el: "select" }
|
|
358
|
+
},
|
|
359
|
+
{ prop: "page_type", label: "页面类型", minWidth: 120, enum: codeGenPageTypeOptions, search: { el: "select" } },
|
|
360
|
+
{ prop: "status", label: "状态", width: 100, dictCode: "code_gen_table_status", search: { el: "select" } },
|
|
361
|
+
{ prop: "remark", label: "备注", minWidth: 180, showOverflowTooltip: true },
|
|
362
|
+
{ prop: "created_at", label: "创建时间", minWidth: 180 },
|
|
363
|
+
{
|
|
364
|
+
prop: "operation",
|
|
365
|
+
label: "操作",
|
|
366
|
+
width: 660,
|
|
367
|
+
fixed: "right",
|
|
368
|
+
cellType: "actions",
|
|
369
|
+
actions: [
|
|
370
|
+
{
|
|
371
|
+
label: "字段配置",
|
|
372
|
+
type: "success",
|
|
373
|
+
link: true,
|
|
374
|
+
icon: SetUp,
|
|
375
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:column"],
|
|
376
|
+
onClick: scope => handleOpenColumnConfig((scope.row as CodeGenTable).id)
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
label: "Proto配置",
|
|
380
|
+
type: "warning",
|
|
381
|
+
link: true,
|
|
382
|
+
icon: Connection,
|
|
383
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:proto"],
|
|
384
|
+
onClick: scope => handleOpenProtoConfig((scope.row as CodeGenTable).id)
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
label: "页面预览",
|
|
388
|
+
type: "primary",
|
|
389
|
+
link: true,
|
|
390
|
+
icon: View,
|
|
391
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:preview"],
|
|
392
|
+
onClick: scope => handleOpenPreview((scope.row as CodeGenTable).id)
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
label: "代码预览",
|
|
396
|
+
type: "primary",
|
|
397
|
+
link: true,
|
|
398
|
+
icon: Document,
|
|
399
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:code-preview"],
|
|
400
|
+
onClick: scope => handleOpenCodePreview((scope.row as CodeGenTable).id)
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
label: "生成",
|
|
404
|
+
type: "success",
|
|
405
|
+
link: true,
|
|
406
|
+
icon: Promotion,
|
|
407
|
+
disabled: () => generating.value,
|
|
408
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:generate"],
|
|
409
|
+
onClick: scope => handleGenerate(scope.row as CodeGenTable)
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
label: "还原",
|
|
413
|
+
type: "warning",
|
|
414
|
+
link: true,
|
|
415
|
+
icon: RefreshRight,
|
|
416
|
+
disabled: scope => !(scope.row as CodeGenTable).restore_available,
|
|
417
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:restore"],
|
|
418
|
+
onClick: scope => handleRestore(scope.row as CodeGenTable)
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
label: "编辑",
|
|
422
|
+
type: "primary",
|
|
423
|
+
link: true,
|
|
424
|
+
icon: EditPen,
|
|
425
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:update"],
|
|
426
|
+
onClick: scope => handleOpenDialog((scope.row as CodeGenTable).id)
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
label: "删除",
|
|
430
|
+
type: "danger",
|
|
431
|
+
link: true,
|
|
432
|
+
icon: Delete,
|
|
433
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:delete"],
|
|
434
|
+
onClick: scope => handleDelete(scope.row as CodeGenTable)
|
|
435
|
+
}
|
|
436
|
+
]
|
|
437
|
+
}
|
|
438
|
+
];
|
|
439
|
+
|
|
440
|
+
/** 打开已经保存的代码生成页面预览。 */
|
|
441
|
+
async function handleOpenPreview(tableId: number) {
|
|
442
|
+
await router.push(`/code/gen/preview/${tableId}`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** 打开字段配置页面。 */
|
|
446
|
+
async function handleOpenColumnConfig(tableId: number) {
|
|
447
|
+
await router.push(`/code/gen/column/${tableId}`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** 打开Proto接口配置页面。 */
|
|
451
|
+
async function handleOpenProtoConfig(tableId: number) {
|
|
452
|
+
await router.push(`/code/gen/proto/${tableId}`);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/** 代码生成表配置列表顶部操作。 */
|
|
456
|
+
const headerActions: HeaderActionProps[] = [
|
|
457
|
+
{
|
|
458
|
+
label: "新增",
|
|
459
|
+
type: "success",
|
|
460
|
+
icon: CirclePlus,
|
|
461
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:create"],
|
|
462
|
+
onClick: () => handleOpenDialog()
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
label: "批量生成",
|
|
466
|
+
type: "primary",
|
|
467
|
+
icon: Promotion,
|
|
468
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:generate"],
|
|
469
|
+
disabled: scope => generating.value || !scope.selectedList.length,
|
|
470
|
+
onClick: scope => handleGenerate(scope.selectedList as CodeGenTable[])
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
label: "批量还原",
|
|
474
|
+
type: "warning",
|
|
475
|
+
icon: RefreshRight,
|
|
476
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:restore"],
|
|
477
|
+
disabled: scope => scope.selectedList.every(item => !(item as CodeGenTable).restore_available),
|
|
478
|
+
onClick: scope => handleRestore(scope.selectedList as CodeGenTable[])
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
label: "最近任务",
|
|
482
|
+
icon: Clock,
|
|
483
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:generate"],
|
|
484
|
+
disabled: () => !progressTaskAvailable.value,
|
|
485
|
+
onClick: handleOpenProgress
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
label: "删除",
|
|
489
|
+
type: "danger",
|
|
490
|
+
icon: Delete,
|
|
491
|
+
hidden: () => !BUTTONS.value["tool:code-gen-table:delete"],
|
|
492
|
+
disabled: scope => !scope.selectedList.length,
|
|
493
|
+
onClick: scope => handleDelete(scope.selectedList as CodeGenTable[])
|
|
494
|
+
}
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
/** 打开已经保存的代码生成文件预览。 */
|
|
498
|
+
async function handleOpenCodePreview(tableId: number) {
|
|
499
|
+
await router.push(`/code/gen/code/preview/${tableId}`);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/** 创建单项或批量代码生成任务。 */
|
|
503
|
+
async function handleGenerate(selected: CodeGenGenerateTarget) {
|
|
504
|
+
const tables = Array.isArray(selected) ? selected : [selected];
|
|
505
|
+
if (!tables.length) {
|
|
506
|
+
ElMessage.warning("请勾选生成项");
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
const disabledTable = tables.find(table => table.status === codeGenStatusDisabled);
|
|
510
|
+
if (disabledTable) {
|
|
511
|
+
ElMessage.warning(`代码生成表配置 ${disabledTable.name} 已停用`);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
const message = tables.length === 1 ? `确认生成业务表:${tables[0].name}?` : `确认按勾选顺序生成 ${tables.length} 个业务表?`;
|
|
515
|
+
try {
|
|
516
|
+
await ElMessageBox.confirm(message, "提示", {
|
|
517
|
+
confirmButtonText: "确认",
|
|
518
|
+
cancelButtonText: "取消",
|
|
519
|
+
type: "warning"
|
|
520
|
+
});
|
|
521
|
+
} catch {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
generating.value = true;
|
|
525
|
+
try {
|
|
526
|
+
const data = await defCodeGenService.StartCodeGenTask({
|
|
527
|
+
table_ids: tables.map(table => table.id)
|
|
528
|
+
});
|
|
529
|
+
progressTaskId.value = data.task_id;
|
|
530
|
+
progressTaskAvailable.value = true;
|
|
531
|
+
progressSelectedTableIds.value = tables.map(table => table.id);
|
|
532
|
+
window.sessionStorage.setItem(codeGenTaskStorageKey, data.task_id);
|
|
533
|
+
window.sessionStorage.setItem(codeGenProgressSelectedTableIdsStorageKey, JSON.stringify(progressSelectedTableIds.value));
|
|
534
|
+
handleProgressDialogVisibleChange(true);
|
|
535
|
+
} catch (error) {
|
|
536
|
+
generating.value = false;
|
|
537
|
+
throw error;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/** 还原单项或批量代码生成结果。 */
|
|
542
|
+
async function handleRestore(selected: CodeGenRestoreTarget) {
|
|
543
|
+
const tables = Array.isArray(selected) ? selected : [selected];
|
|
544
|
+
const restorableTables = tables.filter(table => table.restore_available);
|
|
545
|
+
if (!restorableTables.length) {
|
|
546
|
+
ElMessage.warning("请选择有可用还原快照的代码生成项");
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const message =
|
|
550
|
+
restorableTables.length === 1
|
|
551
|
+
? `确认还原业务表:${restorableTables[0].name}?生成文件、页面菜单和按钮权限将恢复到生成前状态。`
|
|
552
|
+
: `确认批量还原 ${restorableTables.length} 个业务表?批量生成的共享文件必须整批还原。`;
|
|
553
|
+
try {
|
|
554
|
+
await ElMessageBox.confirm(message, "警告", {
|
|
555
|
+
confirmButtonText: "确认还原",
|
|
556
|
+
cancelButtonText: "取消",
|
|
557
|
+
type: "warning"
|
|
558
|
+
});
|
|
559
|
+
} catch {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
await defCodeGenService.RestoreCodeGen({ table_ids: restorableTables.map(table => table.id) });
|
|
563
|
+
ElMessage.success("还原代码生成结果成功");
|
|
564
|
+
progressSelectedTableIds.value = [];
|
|
565
|
+
proTable.value?.clearSelection();
|
|
566
|
+
refreshTable();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/** 打开最近一次代码生成任务。 */
|
|
570
|
+
function handleOpenProgress() {
|
|
571
|
+
if (progressTaskId.value) handleProgressDialogVisibleChange(true);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** 同步进度弹窗可见状态,确保热更新后仅恢复任务运行期间主动打开的弹窗。 */
|
|
575
|
+
function handleProgressDialogVisibleChange(visible: boolean) {
|
|
576
|
+
progressDialogVisible.value = visible;
|
|
577
|
+
if (visible) {
|
|
578
|
+
window.sessionStorage.setItem(codeGenProgressDialogVisibleStorageKey, "true");
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
window.sessionStorage.removeItem(codeGenProgressDialogVisibleStorageKey);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/** 生成任务结束后刷新列表。 */
|
|
585
|
+
function handleProgressCompleted() {
|
|
586
|
+
generating.value = false;
|
|
587
|
+
window.sessionStorage.removeItem(codeGenProgressDialogVisibleStorageKey);
|
|
588
|
+
progressSelectedTableIds.value = [];
|
|
589
|
+
proTable.value?.clearSelection();
|
|
590
|
+
removeProgressSelectedTableIds();
|
|
591
|
+
refreshTable();
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/** 清理不可恢复的最近任务。 */
|
|
595
|
+
function handleProgressUnavailable() {
|
|
596
|
+
generating.value = false;
|
|
597
|
+
progressTaskId.value = "";
|
|
598
|
+
progressTaskAvailable.value = false;
|
|
599
|
+
progressSelectedTableIds.value = [];
|
|
600
|
+
proTable.value?.clearSelection();
|
|
601
|
+
handleProgressDialogVisibleChange(false);
|
|
602
|
+
removeProgressSelectedTableIds();
|
|
603
|
+
window.sessionStorage.removeItem(codeGenTaskStorageKey);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** 读取上次页面重建前的批量生成选择项。 */
|
|
607
|
+
function readProgressSelectedTableIds(): Array<string | number> {
|
|
608
|
+
if (typeof window === "undefined") return [];
|
|
609
|
+
try {
|
|
610
|
+
const selectedTableIds = JSON.parse(window.sessionStorage.getItem(codeGenProgressSelectedTableIdsStorageKey) ?? "[]");
|
|
611
|
+
return Array.isArray(selectedTableIds) ? selectedTableIds.filter(id => typeof id === "string" || typeof id === "number") : [];
|
|
612
|
+
} catch {
|
|
613
|
+
return [];
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/** 清理跨热更新恢复选择所需的会话记录,保留当前页面的选择状态。 */
|
|
618
|
+
function removeProgressSelectedTableIds() {
|
|
619
|
+
window.sessionStorage.removeItem(codeGenProgressSelectedTableIdsStorageKey);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/** 请求代码生成表配置列表。 */
|
|
623
|
+
async function requestCodeGenTable(params: PageCodeGenTableRequest) {
|
|
624
|
+
const data = await defCodeGenTableService.PageCodeGenTable(buildPageRequest(params));
|
|
625
|
+
return { data: { ...data, list: data.code_gen_tables ?? [] } };
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/** 刷新代码生成表配置列表。 */
|
|
629
|
+
function refreshTable() {
|
|
630
|
+
proTable.value?.getTableList();
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/** 打开新增或编辑弹窗,并加载当前表单所需选项。 */
|
|
634
|
+
async function handleOpenDialog(tableId?: number) {
|
|
635
|
+
resetForm();
|
|
636
|
+
const [tableData, menuData, dictionaryData] = await Promise.all([
|
|
637
|
+
defCodeGenTableService.ListCodeGenDatabaseTable({}),
|
|
638
|
+
defBaseMenuService.TreeBaseMenu({}),
|
|
639
|
+
defBaseDictService.OptionBaseDict({})
|
|
640
|
+
]);
|
|
641
|
+
databaseTables.value = tableData.tables ?? [];
|
|
642
|
+
parentMenuOptions.value = convertMenuOptions(menuData.base_menus ?? []);
|
|
643
|
+
businessModuleItems.value = dictionaryData.base_dicts?.find(item => item.code === "business_module")?.items ?? [];
|
|
644
|
+
if (tableId) {
|
|
645
|
+
const detail = await defCodeGenTableService.GetCodeGenTable({ id: tableId });
|
|
646
|
+
Object.assign(formData, detail);
|
|
647
|
+
formData.parent_menu_id = detail.parent_menu_id || undefined;
|
|
648
|
+
formData.left_tree_config ??= createDefaultCodeGenLeftTreeConfig();
|
|
649
|
+
if (!formData.comment) {
|
|
650
|
+
formData.comment = databaseTables.value.find(item => item.name === formData.name)?.comment ?? "";
|
|
651
|
+
}
|
|
652
|
+
if (!formData.left_tree_config.comment) {
|
|
653
|
+
formData.left_tree_config.comment =
|
|
654
|
+
databaseTables.value.find(item => item.name === formData.left_tree_config?.table_name)?.comment ?? "";
|
|
655
|
+
}
|
|
656
|
+
await Promise.all([loadDatabaseColumns(databaseColumns, formData.name), loadLeftTreeDatabaseColumns()]);
|
|
657
|
+
dialog.title = "编辑代码生成表配置";
|
|
658
|
+
} else {
|
|
659
|
+
dialog.title = "新增代码生成表配置";
|
|
660
|
+
}
|
|
661
|
+
dialog.visible = true;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/** 关闭弹窗并清理表单状态。 */
|
|
665
|
+
function handleCloseDialog() {
|
|
666
|
+
dialog.visible = false;
|
|
667
|
+
resetForm();
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/** 重置弹窗表单和字段选项。 */
|
|
671
|
+
function resetForm() {
|
|
672
|
+
Object.assign(formData, { ...createDefaultCodeGenTableForm(), parent_menu_id: undefined });
|
|
673
|
+
databaseColumns.value = [];
|
|
674
|
+
leftTreeDatabaseColumns.value = [];
|
|
675
|
+
void nextTick(() => {
|
|
676
|
+
formDialogRef.value?.resetFields();
|
|
677
|
+
formDialogRef.value?.clearValidate();
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** 选择业务表后同步数据库注释、默认命名、字段选项和树字段默认值。 */
|
|
682
|
+
async function handleTableNameChange(tableName: string) {
|
|
683
|
+
const table = databaseTables.value.find(item => item.name === tableName);
|
|
684
|
+
formData.comment = table?.comment ?? "";
|
|
685
|
+
await loadDatabaseColumns(databaseColumns, tableName);
|
|
686
|
+
resetUnavailableTableColumns();
|
|
687
|
+
formData.parent_column = resolveDefaultColumn(databaseColumns.value, "parent_id");
|
|
688
|
+
formData.tree_label_column = resolveDefaultColumn(databaseColumns.value, "name");
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/** 页面类型变化时清理不再生效的页面字段。 */
|
|
692
|
+
function handlePageTypeChange(pageType: string) {
|
|
693
|
+
if (!isCodeGenTreePageType(pageType)) {
|
|
694
|
+
formData.parent_column = "";
|
|
695
|
+
formData.tree_label_column = "";
|
|
696
|
+
}
|
|
697
|
+
if (pageType !== "left_tree") {
|
|
698
|
+
resetLeftTreeConfig();
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/** 左树来源表变化时覆盖描述、加载字段选项并设置约定默认字段。 */
|
|
703
|
+
async function handleLeftTreeTableNameChange(tableName: string) {
|
|
704
|
+
const config = ensureLeftTreeConfig();
|
|
705
|
+
const table = databaseTables.value.find(item => item.name === tableName);
|
|
706
|
+
config.comment = table?.comment ?? "";
|
|
707
|
+
await loadLeftTreeDatabaseColumns();
|
|
708
|
+
resetUnavailableLeftTreeColumns();
|
|
709
|
+
config.parent_column = resolveDefaultColumn(leftTreeDatabaseColumns.value, "parent_id");
|
|
710
|
+
config.label_column = resolveDefaultColumn(leftTreeDatabaseColumns.value, "name");
|
|
711
|
+
config.value_column = resolveDefaultColumn(leftTreeDatabaseColumns.value, "id");
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/** 提交代码生成表配置。 */
|
|
715
|
+
async function handleSubmit() {
|
|
716
|
+
const valid = await formDialogRef.value?.validate();
|
|
717
|
+
if (!valid) return;
|
|
718
|
+
if (!formData.parent_menu_id) return;
|
|
719
|
+
|
|
720
|
+
const payload: CodeGenTableForm = { ...formData, parent_menu_id: formData.parent_menu_id };
|
|
721
|
+
saving.value = true;
|
|
722
|
+
try {
|
|
723
|
+
if (formData.id) {
|
|
724
|
+
await defCodeGenTableService.UpdateCodeGenTable({ id: formData.id, code_gen_table: payload });
|
|
725
|
+
ElMessage.success("编辑代码生成表配置成功");
|
|
726
|
+
} else {
|
|
727
|
+
await defCodeGenTableService.CreateCodeGenTable({ code_gen_table: payload });
|
|
728
|
+
ElMessage.success("新增代码生成表配置成功");
|
|
729
|
+
}
|
|
730
|
+
handleCloseDialog();
|
|
731
|
+
refreshTable();
|
|
732
|
+
} finally {
|
|
733
|
+
saving.value = false;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/** 删除单项或批量代码生成表配置。 */
|
|
738
|
+
async function handleDelete(selected?: CodeGenDeleteTarget) {
|
|
739
|
+
const tableList = Array.isArray(selected)
|
|
740
|
+
? (selected.filter(item => typeof item === "object") as CodeGenTable[])
|
|
741
|
+
: selected && typeof selected === "object"
|
|
742
|
+
? [selected as CodeGenTable]
|
|
743
|
+
: [];
|
|
744
|
+
const tableIds = (
|
|
745
|
+
tableList.length ? tableList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
|
|
746
|
+
).join(",");
|
|
747
|
+
if (!tableIds) {
|
|
748
|
+
ElMessage.warning("请勾选删除项");
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
const confirmMessage =
|
|
752
|
+
tableList.length === 1 ? `确认删除业务表:${tableList[0].name}?` : `确认删除已选中的 ${tableList.length} 条配置?`;
|
|
753
|
+
try {
|
|
754
|
+
await ElMessageBox.confirm(confirmMessage, "警告", {
|
|
755
|
+
confirmButtonText: "确定",
|
|
756
|
+
cancelButtonText: "取消",
|
|
757
|
+
type: "warning"
|
|
758
|
+
});
|
|
759
|
+
} catch {
|
|
760
|
+
ElMessage.info("已取消删除代码生成表配置");
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
await defCodeGenTableService.DeleteCodeGenTable({ ids: tableIds });
|
|
764
|
+
ElMessage.success("删除代码生成表配置成功");
|
|
765
|
+
refreshTable();
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/** 查询数据库表字段选项。 */
|
|
769
|
+
async function loadDatabaseColumns(target: { value: CodeGenDatabaseColumn[] }, tableName: string) {
|
|
770
|
+
if (!tableName) {
|
|
771
|
+
target.value = [];
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
const data = await defCodeGenColumnService.ListCodeGenDatabaseColumn({ table_name: tableName });
|
|
775
|
+
target.value = data.columns ?? [];
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/** 查询左树来源表字段选项。 */
|
|
779
|
+
async function loadLeftTreeDatabaseColumns() {
|
|
780
|
+
const config = ensureLeftTreeConfig();
|
|
781
|
+
if (formData.page_type !== "left_tree") {
|
|
782
|
+
leftTreeDatabaseColumns.value = [];
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
await loadDatabaseColumns(leftTreeDatabaseColumns, config.table_name);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/** 转换数据库字段为 ProForm 选择项。 */
|
|
789
|
+
function createDatabaseColumnOptions(columns: CodeGenDatabaseColumn[]): ProFormOption[] {
|
|
790
|
+
return columns.map(item => ({
|
|
791
|
+
label: item.comment
|
|
792
|
+
? `${item.name}(${item.comment} / ${item.column_type || item.db_type})`
|
|
793
|
+
: `${item.name}(${item.column_type || item.db_type})`,
|
|
794
|
+
value: item.name
|
|
795
|
+
}));
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/** 从字段列表中解析存在的约定默认字段。 */
|
|
799
|
+
function resolveDefaultColumn(columns: CodeGenDatabaseColumn[], columnName: string) {
|
|
800
|
+
return columns.some(item => item.name === columnName) ? columnName : "";
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/** 转换菜单树为 ProForm 树形选择项。 */
|
|
804
|
+
function convertMenuOptions(options: BaseMenu[]): ProFormOption[] {
|
|
805
|
+
return options
|
|
806
|
+
.filter(item => item.type === BaseMenuType.FOLDER)
|
|
807
|
+
.map(item => ({
|
|
808
|
+
label: item.meta?.title || item.name || item.path,
|
|
809
|
+
value: item.id,
|
|
810
|
+
disabled: item.id < 100 || item.id > 99999,
|
|
811
|
+
children: convertMenuOptions(item.children ?? [])
|
|
812
|
+
}));
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/** 清理当前业务表已不存在的字段配置。 */
|
|
816
|
+
function resetUnavailableTableColumns() {
|
|
817
|
+
const columnNames = new Set(databaseColumns.value.map(item => item.name));
|
|
818
|
+
if (formData.parent_column && !columnNames.has(formData.parent_column)) formData.parent_column = "";
|
|
819
|
+
if (formData.tree_label_column && !columnNames.has(formData.tree_label_column)) formData.tree_label_column = "";
|
|
820
|
+
const config = ensureLeftTreeConfig();
|
|
821
|
+
if (config.filter_column && !columnNames.has(config.filter_column)) {
|
|
822
|
+
config.filter_column = "";
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/** 清理左树来源表已不存在的字段配置。 */
|
|
827
|
+
function resetUnavailableLeftTreeColumns() {
|
|
828
|
+
const columnNames = new Set(leftTreeDatabaseColumns.value.map(item => item.name));
|
|
829
|
+
const config = ensureLeftTreeConfig();
|
|
830
|
+
if (config.parent_column && !columnNames.has(config.parent_column)) {
|
|
831
|
+
config.parent_column = "";
|
|
832
|
+
}
|
|
833
|
+
if (config.label_column && !columnNames.has(config.label_column)) {
|
|
834
|
+
config.label_column = "";
|
|
835
|
+
}
|
|
836
|
+
if (config.value_column && !columnNames.has(config.value_column)) {
|
|
837
|
+
config.value_column = "";
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/** 清空左树右表专属配置。 */
|
|
842
|
+
function resetLeftTreeConfig() {
|
|
843
|
+
formData.left_tree_config = createDefaultCodeGenLeftTreeConfig();
|
|
844
|
+
leftTreeDatabaseColumns.value = [];
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/** 确保左树配置对象存在并返回当前配置。 */
|
|
848
|
+
function ensureLeftTreeConfig() {
|
|
849
|
+
formData.left_tree_config ??= createDefaultCodeGenLeftTreeConfig();
|
|
850
|
+
return formData.left_tree_config;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
</script>
|
|
854
|
+
|
|
855
|
+
<style scoped lang="scss">
|
|
856
|
+
/* 固定操作列表头与普通表头使用同一主题背景,并保持行内操作单行展示。 */
|
|
857
|
+
:deep(.code-gen-table) {
|
|
858
|
+
--el-table-header-bg-color: var(--el-fill-color-light);
|
|
859
|
+
|
|
860
|
+
td.el-table-fixed-column--right .cell {
|
|
861
|
+
white-space: nowrap;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
</style>
|