diff --git a/locales/en.yaml b/locales/en.yaml index 3fc8111..22f9e53 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -32,6 +32,8 @@ buttons:Export: Export buttons:Import: Import buttons:DownLoded: DownLoded buttons:DownLodedTemplate: DownLoded Template +buttons:DownLodedAll: All DownLoded +buttons:Copy: Copy buttons:Hide: Hide buttons:ConfirmUpload: Confirm Upload buttons:Save: Save @@ -51,6 +53,10 @@ buttons:RoleAllocation: Role Allocation buttons:PermissionDetails: Permission Details buttons:ForceToExit: Force Exit buttons:DataAdmin: Data Admin +buttons:TableList: Table List +buttons:UpdateTableColumns: Update Table Columns +buttons:Preview: Preview +buttons:Sync: Synchroniztion search:Total: Total search:History: History search:Collect: Collect @@ -114,6 +120,7 @@ menus:FourZeroFour: "404" menus:FourZeroOne: "403" menus:Five: "500" menus:SystemConfig: System Config +menus:GenerateCode: Generate Code status:Load: Loading... status:Message: Message status:Notify: Notify diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 189344b..9a231fd 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -31,6 +31,8 @@ buttons:Delete: 删除 buttons:Export: 导出 buttons:Import: 导入 buttons:DownLoded: 下载 +buttons:DownLodedAll: 全部下载 +buttons:Copy: 复制 buttons:DownLodedTemplate: 下载模版 buttons:Hide: 隐藏 buttons:ConfirmUpload: 确认上传 @@ -51,6 +53,10 @@ buttons:PermissionDetails: 权限详情 buttons:ForceToExit: 强制退出 buttons:ExitInBatches: 批量强退 buttons:DataAdmin: 数据管理 +buttons:TableList: 数据表列表 +buttons:UpdateTableColumns: 更新数据表列信息 +buttons:Preview: 预览 +buttons:Sync: 同步 search:Total: 共 search:History: 搜索历史 search:Collect: 收藏 @@ -114,6 +120,7 @@ menus:FourZeroFour: "404" menus:FourZeroOne: "403" menus:Five: "500" menus:SystemConfig: 系统配置 +menus:GenerateCode: 代码生成 status:Load: 加载中... status:Message: 消息 status:Notify: 通知 diff --git a/package.json b/package.json index b8e31f6..15c4d45 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,10 @@ "dayjs": "^1.11.13", "echarts": "^5.5.1", "element-plus": "^2.9.0", + "file-saver": "^2.0.5", + "highlight.js": "^11.11.1", "js-cookie": "^3.0.5", + "jszip": "^3.10.1", "localforage": "^1.10.0", "mitt": "^3.0.1", "nprogress": "^0.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b7ffcb..586728d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,9 +44,18 @@ importers: element-plus: specifier: ^2.9.0 version: 2.9.0(vue@3.5.13(typescript@5.6.3)) + file-saver: + specifier: ^2.0.5 + version: 2.0.5 + highlight.js: + specifier: ^11.11.1 + version: 11.11.1 js-cookie: specifier: ^3.0.5 version: 3.0.5 + jszip: + specifier: ^3.10.1 + version: 3.10.1 localforage: specifier: ^1.10.0 version: 1.10.0 @@ -1565,6 +1574,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, tarball: https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz} + cosmiconfig-typescript-loader@5.1.0: resolution: {integrity: sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==} engines: {node: '>=v16'} @@ -1960,6 +1972,9 @@ packages: resolution: {integrity: sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==} engines: {node: '>=18'} + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==, tarball: https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2149,6 +2164,10 @@ packages: hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==, tarball: https://registry.npmmirror.com/highlight.js/-/highlight.js-11.11.1.tgz} + engines: {node: '>=12.0.0'} + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -2177,7 +2196,7 @@ packages: engines: {node: '>= 4'} immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==, tarball: https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz} immutable@5.0.3: resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} @@ -2196,6 +2215,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, tarball: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz} + ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} @@ -2266,6 +2288,9 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==, tarball: https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2334,6 +2359,9 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==, tarball: https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2361,6 +2389,9 @@ packages: lie@3.1.1: resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==, tarball: https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -2678,6 +2709,9 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==, tarball: https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -3043,6 +3077,9 @@ packages: engines: {node: '>=14'} hasBin: true + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==, tarball: https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -3068,6 +3105,9 @@ packages: read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==, tarball: https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -3144,6 +3184,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz} + sass@1.82.0: resolution: {integrity: sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==} engines: {node: '>=14.0.0'} @@ -3168,6 +3211,9 @@ packages: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==, tarball: https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -3246,6 +3292,9 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==, tarball: https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -5159,6 +5208,8 @@ snapshots: convert-source-map@2.0.0: {} + core-util-is@1.0.3: {} + cosmiconfig-typescript-loader@5.1.0(@types/node@20.17.9)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): dependencies: '@types/node': 20.17.9 @@ -5611,6 +5662,8 @@ snapshots: dependencies: flat-cache: 5.0.0 + file-saver@2.0.5: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -5818,6 +5871,8 @@ snapshots: hey-listen@1.0.8: {} + highlight.js@11.11.1: {} + hookable@5.5.3: optional: true @@ -5856,6 +5911,8 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + ini@1.3.8: {} ini@4.1.1: {} @@ -5906,6 +5963,8 @@ snapshots: dependencies: is-docker: 2.2.1 + isarray@1.0.0: {} + isexe@2.0.0: {} jackspeak@3.4.3: @@ -5962,6 +6021,13 @@ snapshots: jsonparse@1.3.1: {} + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -5990,6 +6056,10 @@ snapshots: dependencies: immediate: 3.0.6 + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -6288,6 +6358,8 @@ snapshots: package-json-from-dist@1.0.1: {} + pako@1.0.11: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6613,6 +6685,8 @@ snapshots: prettier@3.4.2: {} + process-nextick-args@2.0.1: {} + proxy-from-env@1.1.0: {} punycode@2.3.1: {} @@ -6639,6 +6713,16 @@ snapshots: dependencies: pify: 2.3.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -6725,6 +6809,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + sass@1.82.0: dependencies: chokidar: 4.0.1 @@ -6751,6 +6837,8 @@ snapshots: gopd: 1.2.0 has-property-descriptors: 1.0.2 + setimmediate@1.0.5: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -6823,6 +6911,10 @@ snapshots: get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 diff --git a/src/api/generate.ts b/src/api/generate.ts new file mode 100644 index 0000000..cdf6d69 --- /dev/null +++ b/src/api/generate.ts @@ -0,0 +1,110 @@ +import { http } from "@/utils/http"; +import type { + GenerateCodeResult, + GenerateTableInfo, + TableColumnInfo, + TableInfo +} from "types/generate"; +import { filterEmptyObject } from "./utils"; + +/**获取数据库中所有表信息 */ +export const getTableListAPI = () => { + return http.request>( + "GET", + "/api/generate/tables" + ); +}; + +/** + * 添加生成表参数 + */ +interface AddGenerateTableParams { + /**表名 */ + table_name: string; + /**表注释 */ + table_comment: string; + /**作者 */ + author: string; + /**类名 */ + class_name: string; + /**权限ID */ + permission_id: string; + /**API前缀 */ + prefix: string; + /**备注 */ + remark: string; + /**描述 */ + description: string; +} + +/** + * 添加生成表 + */ +export const postAddGenerateTableAPI = (data: AddGenerateTableParams) => { + return http.request("POST", "/api/generate/add", { data }); +}; + +/**删除生成表信息 */ +export const deleteGenerateTableAPI = (id: string) => { + return http.request("DELETE", `/api/generate/delete/${id}`); +}; + +/**批量删除生成表 */ +export const deleteGenerateTableListAPI = (ids: string[]) => { + return http.request("DELETE", `/api/generate/delete`, { + data: { ids } + }); +}; + +/** + * 修改生成表参数 + */ +interface UpdateGenerateTableParams { + columns: TableColumnInfo[]; +} + +/**修改生成表 */ +export const putUpdateGenerateTableAPI = ( + data: AddGenerateTableParams, + id: string +) => { + return http.request("PUT", `/api/generate/update/${id}`, { data }); +}; +/**修改生成表列信息 */ +export const putUpdateGenerateTableColumnAPI = ( + data: UpdateGenerateTableParams, + id: string +) => { + return http.request("PUT", `/api/generate/updateColumns/${id}`, { + data + }); +}; + +/**获取生成表信息 */ +export const getGenerateTableInfoAPI = (id: string) => { + return http.request( + "GET", + `/api/generate/info/${id}` + ); +}; + +/**获取生成表列表 */ +export const getGenerateTableListAPI = (params: { + page: number; + pageSize: number; + table_comment?: string; + permission_id?: string; +}) => { + return http.request< + QueryListResult + >("GET", "/api/generate/list", { + params: filterEmptyObject(params) + }); +}; + +/** + * 获取生成的代码 + */ +export const getGenerateCodeAPI = (id: string) => { + return http.request("GET", `/api/generate/code/${id}`); +}; diff --git a/src/views/system/generate/components/form.vue b/src/views/system/generate/components/form.vue new file mode 100644 index 0000000..c4f7fee --- /dev/null +++ b/src/views/system/generate/components/form.vue @@ -0,0 +1,158 @@ + + diff --git a/src/views/system/generate/components/info.vue b/src/views/system/generate/components/info.vue new file mode 100644 index 0000000..b07259c --- /dev/null +++ b/src/views/system/generate/components/info.vue @@ -0,0 +1,216 @@ + + diff --git a/src/views/system/generate/components/preview.vue b/src/views/system/generate/components/preview.vue new file mode 100644 index 0000000..b44ed2b --- /dev/null +++ b/src/views/system/generate/components/preview.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/src/views/system/generate/index.vue b/src/views/system/generate/index.vue new file mode 100644 index 0000000..557c0a7 --- /dev/null +++ b/src/views/system/generate/index.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/src/views/system/generate/utils/hook.tsx b/src/views/system/generate/utils/hook.tsx new file mode 100644 index 0000000..453e449 --- /dev/null +++ b/src/views/system/generate/utils/hook.tsx @@ -0,0 +1,472 @@ +import dayjs from "dayjs"; +import InfoForm from "../components/info.vue"; +import editForm from "../components/form.vue"; +import previewForm from "../components/preview.vue"; +import { message } from "@/utils/message"; +import { type Ref, ref, reactive, onMounted, h, toRaw } from "vue"; +import type { PaginationProps } from "@pureadmin/table"; +import { addDialog } from "@/components/ReDialog"; +import type { + GenerateTableInfo, + TableColumnInfo, + TableInfo +} from "types/generate"; +import { + deleteGenerateTableAPI, + deleteGenerateTableListAPI, + getGenerateTableListAPI, + getTableListAPI, + postAddGenerateTableAPI, + putUpdateGenerateTableAPI, + putUpdateGenerateTableColumnAPI +} from "@/api/generate"; +import { cloneDeep, getKeyList, handleTree } from "@pureadmin/utils"; +import type { PermissionInfo } from "types/system"; +import { getPermissionListAPI } from "@/api/system"; + +export const useGenerate = (tableRef: Ref) => { + /** + * 查询表单 + */ + const form = reactive({ + table_comment: "", + permission_id: "" + }); + /** + * 表单Ref + */ + const formRef = ref(null); + /**生成表类型 */ + type DataInfo = GenerateTableInfo & { columns: TableColumnInfo[] }; + /** + * 数据列表 + */ + const dataList = ref([]); + /** + * 加载状态 + */ + const loading = ref(true); + /**数据表列表 */ + const tableList = ref([]); + + /** + * 已选数量 + */ + const selectedNum = ref(0); + /** + * 分页参数 + */ + const pagination = reactive({ + total: 0, + pageSize: 10, + currentPage: 1, + background: true, + pageSizes: [10, 20, 30, 40, 50] + }); + /** + * 表格列设置 + */ + const columns: TableColumnList = [ + { + label: "勾选列", // 如果需要表格多选,此处label必须设置 + type: "selection", + fixed: "left", + reserveSelection: true // 数据刷新后保留选项 + }, + { + label: "数据表名称", + prop: "table_name" + }, + { + label: "数据表注释", + prop: "table_comment" + }, + { + label: "描述", + prop: "description" + }, + { + label: "备注", + prop: "remark" + }, + { + label: "创建时间", + prop: "create_time", + formatter: ({ create_time }) => + create_time ? dayjs(create_time).format("YYYY-MM-DD HH:mm:ss") : "" + }, + { + label: "更新时间", + prop: "update_time", + formatter: ({ update_time }) => + update_time ? dayjs(update_time).format("YYYY-MM-DD HH:mm:ss") : "" + }, + { + label: "操作", + fixed: "right", + width: 380, + slot: "operation" + } + ]; + /** + * 初次查询 + */ + const onSearch = async () => { + loading.value = true; + const res = await getGenerateTableListAPI({ + page: pagination.currentPage, + pageSize: pagination.pageSize, + ...toRaw(form) + }); + if (res.success) { + dataList.value = res.data.result; + pagination.total = res.data.total; + pagination.currentPage = res.data.page; + pagination.pageSize = res.data.pageSize; + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + loading.value = false; + }; + /** + * 重置表单 + * @param formEl 表单ref + * @returns + */ + const resetForm = async (formEl: any) => { + if (!formEl) return; + formEl.resetFields(); + await onSearch(); + }; + /** + * 处理删除 + * @param row + */ + const handleDelete = async (row: DataInfo) => { + const res = await deleteGenerateTableAPI(row.id); + if (res.success) { + onSearch(); + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + }; + /** + * 处理每页数量变化 + */ + const handleSizeChange = async (val: number) => { + loading.value = true; + const res = await getGenerateTableListAPI({ + page: pagination.currentPage, + pageSize: val, + ...toRaw(form) + }); + if (res.success) { + dataList.value = res.data.result; + pagination.total = res.data.total; + pagination.currentPage = res.data.page; + pagination.pageSize = res.data.pageSize; + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + loading.value = false; + }; + + /** + * 处理页码变化 + * @param val + */ + const handleCurrentChange = async (val: number) => { + loading.value = true; + const res = await getGenerateTableListAPI({ + page: val, + pageSize: pagination.pageSize, + ...toRaw(form) + }); + if (res.success) { + dataList.value = res.data.result; + pagination.total = res.data.total; + pagination.currentPage = res.data.page; + pagination.pageSize = res.data.pageSize; + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + loading.value = false; + }; + /** 当CheckBox选择项发生变化时会触发该事件 */ + const handleSelectionChange = async (val: any) => { + selectedNum.value = val.length; + // 重置表格高度 + tableRef.value.setAdaptive(); + }; + + /** 取消选择 */ + const onSelectionCancel = async () => { + selectedNum.value = 0; + // 用于多选表格,清空用户的选择 + tableRef.value.getTableRef().clearSelection(); + }; + /** + * 批量删除 + */ + const onbatchDel = async () => { + // 返回当前选中的行 + const curSelected = tableRef.value.getTableRef().getSelectionRows(); + const res = await deleteGenerateTableListAPI(getKeyList(curSelected, "id")); + if (res.success) { + message(res.msg, { + type: "success" + }); + tableRef.value.getTableRef().clearSelection(); + onSearch(); + } else { + message(res.msg, { type: "error", duration: 5000 }); + } + }; + /**处理添加修改 */ + const handleEdit = async (way: string = "新增", row?: DataInfo) => { + addDialog({ + title: `${way}表信息`, + props: { + formInline: { + /**方式 */ + way: way, + /**数据表列表 */ + tables: tableList.value ?? [], + /**权限列表 */ + permissions: permissions.value ?? [], + /**数据ID */ + id: row?.id ?? "", + /**作者 */ + author: row?.author ?? "", + /**类名 */ + class_name: row?.class_name ?? "", + /**权限ID */ + permission_id: row?.permission_id ?? "", + /**API前缀 */ + prefix: row?.prefix ?? "", + /**备注 */ + remark: row?.remark ?? "", + /**表名 */ + table_name: row?.table_name ?? "", + /**表注释 */ + table_comment: row?.table_comment ?? "", + /**创建时间 */ + create_time: row?.create_time ?? "", + /**修改时间 */ + update_time: row?.update_time ?? "", + /**描述 */ + description: row?.description ?? "" + } + }, + width: "45%", + draggable: true, + fullscreenIcon: true, + closeOnClickModal: false, + contentRenderer: () => + h(InfoForm, { + formInline: { + /**方式 */ + way: way, + /**数据表列表 */ + tables: tableList.value ?? [], + /**权限列表 */ + permissions: permissions.value ?? [], + /**数据ID */ + id: row?.id ?? "", + /**作者 */ + author: row?.author ?? "", + /**类名 */ + class_name: row?.class_name ?? "", + /**权限ID */ + permission_id: row?.permission_id ?? "", + /**API前缀 */ + prefix: row?.prefix ?? "", + /**备注 */ + remark: row?.remark ?? "", + /**表名 */ + table_name: row?.table_name ?? "", + /**表注释 */ + table_comment: row?.table_comment ?? "", + /**创建时间 */ + create_time: row?.create_time ?? "", + /**修改时间 */ + update_time: row?.update_time ?? "", + /**描述 */ + description: row?.description ?? "" + }, + ref: formRef + }), + beforeSure: async (done, {}) => { + const FormData = formRef.value.newFormInline; + let form = { + /**表名 */ + table_name: FormData.table_name ?? "", + /**表注释 */ + table_comment: FormData.table_comment ?? "", + /**作者 */ + author: FormData.author ?? "", + /**类名 */ + class_name: FormData.class_name ?? "", + /**权限ID */ + permission_id: FormData.permission_id ?? "", + /**API前缀 */ + prefix: FormData.prefix ?? "", + /**备注 */ + remark: FormData.remark ?? "", + /**描述 */ + description: FormData.description ?? "" + }; + if (way === "新增") { + const res = await postAddGenerateTableAPI(form); + if (res.success) { + done(); + await onSearch(); + } + message(res.msg, { type: res.success ? "success" : "error" }); + } else { + const res = await putUpdateGenerateTableAPI(form, row.id); + if (res.success) { + done(); + await onSearch(); + } + message(res.msg, { type: res.success ? "success" : "error" }); + } + } + }); + }; + /**获取数据表列表 */ + const getTableList = async () => { + const res = await getTableListAPI(); + if (res.success) { + tableList.value = res.data.result; + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + }; + /**权限列表 */ + const permissions = ref([]); + const formatHigherOptions = treeList => { + // 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示(实际开发中也是如此,不可能前端需要的每个字段后端都会返回,这时需要前端自行根据后端返回的某些字段做逻辑处理) + if (!treeList || !treeList.length) return; + const newTreeList = []; + for (let i = 0; i < treeList.length; i++) { + treeList[i].disabled = treeList[i].status === 0 ? true : false; + formatHigherOptions(treeList[i].children); + newTreeList.push(treeList[i]); + } + return newTreeList; + }; + /**获取权限列表 */ + const getPermissions = async () => { + const res = await getPermissionListAPI({ page: 1, pageSize: 9999 }); + if (res.success) { + let data = cloneDeep(res.data.result).map(item => { + return { + id: item.id, + parent_id: item.parent_id, + name: item.title + }; + }); + permissions.value = formatHigherOptions( + handleTree(data, "id", "parent_id") + ); + } + message(res.msg, { + type: res.success ? "success" : "error" + }); + }; + /**处理字段设置 */ + const handleColumn = async (row: DataInfo) => { + addDialog({ + title: `配置信息`, + props: { + formInline: { + columns: row.columns ?? [] + } + }, + width: "90%", + draggable: true, + fullscreenIcon: true, + closeOnClickModal: false, + contentRenderer: () => + h(editForm, { + formInline: { + columns: row.columns ?? [] + }, + ref: formRef + }), + beforeSure: async (done, {}) => { + const FormData = formRef.value.newFormInline; + const res = await putUpdateGenerateTableColumnAPI( + { columns: FormData.columns }, + row.id + ); + if (res.success) { + done(); + } + message(res.msg, { type: res.success ? "success" : "error" }); + } + }); + }; + /**处理代码预览 */ + const handlePreview = async (row: DataInfo) => { + addDialog({ + title: `代码预览`, + props: { + formInline: { + id: row?.id ?? "", + table_name: row?.table_name ?? "" + } + }, + width: "65%", + draggable: true, + fullscreenIcon: true, + closeOnClickModal: false, + contentRenderer: () => + h(previewForm, { + formInline: { + id: row?.id ?? "", + table_name: row?.table_name ?? "" + }, + ref: formRef + }), + beforeSure: async (done, {}) => { + done(); + } + }); + }; + /** + * 页面加载执行 + */ + onMounted(async () => { + await onSearch(); + await getTableList(); + await getPermissions(); + }); + return { + form, + dataList, + loading, + pagination, + columns, + selectedNum, + tableList, + permissions, + onSearch, + resetForm, + handleDelete, + handleSizeChange, + handleEdit, + handleCurrentChange, + handleSelectionChange, + onSelectionCancel, + onbatchDel, + handleColumn, + handlePreview + }; +}; diff --git a/types/generate.d.ts b/types/generate.d.ts new file mode 100644 index 0000000..4a4814b --- /dev/null +++ b/types/generate.d.ts @@ -0,0 +1,107 @@ +/**生成表基本信息 */ +export interface TableInfo { + /**数据ID*/ + id: string; + /**表名 */ + table_name: string; + /**表注释 */ + table_comment: string; + /**数据表行数 */ + table_rows: number; + /**数据表大小 */ + data_length: string; + /**索引大小 */ + index_length: string; + /**创建时间 */ + create_time: string; + /**修改时间 */ + update_time: string; +} + +/**生成表信息 */ +export interface GenerateTableInfo { + /**数据ID */ + id: string; + /**作者 */ + author: string; + /**类名 */ + class_name: string; + /**权限ID */ + permission_id: string; + /**API前缀 */ + prefix: string; + /**备注 */ + remark: string; + /**描述 */ + description: string; + /**表名 */ + table_name: string; + /**表注释 */ + table_comment: string; + /**创建时间 */ + create_time: string; + /**修改时间 */ + update_time: string; +} + +/**生成表字段信息 */ +export interface TableColumnInfo { + /**数据ID */ + id: string; + /**表ID */ + table_id: string; + /**表名 */ + table_name: string; + /**字段名 */ + column_name: string; + /**字段注释 */ + column_comment: string; + /**字段类型 */ + column_type: string; + /**python 类型 */ + python_type: string; + /**python字段名 */ + python_name: string; + /**是否插入 */ + is_insert: boolean; + /**是否编辑 */ + is_edit: boolean; + /**是否查询 */ + is_query: boolean; + /**是否列表显示 */ + is_list: boolean; + /**是否隐藏 */ + is_hide: boolean; + /**是否必填 */ + is_required: boolean; + /**查询方式 */ + query_way: string; + /**展示类型 */ + show_type: string; + /**索引 */ + index: number; + /**创建时间 */ + create_time: string; + /**修改时间 */ + update_time: string; +} + +/** + * 代码生成信息 + */ +export type GenerateCodeInfo = { + label: string; + value: string; + type: string; + path: string; +}; + +/**代码生成结果 */ +export type GenerateCodeResult = { + /**后端代码 */ + backend: GenerateCodeInfo[]; + /**前端代码 */ + frontend: GenerateCodeInfo[]; + /**SQL代码*/ + sql: GenerateCodeInfo[]; +};