From 1965641229cf29c4de62da675fbcb861b7864f01 Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Wed, 12 Aug 2026 14:56:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=8F=9C=E5=8D=95=20m?= =?UTF-8?q?ock=20=E7=BB=84=E4=BB=B6=E6=AD=BB=E9=93=BE,=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=E5=BA=94=E7=94=A8/=E9=85=8D=E7=BD=AE/=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90/=E6=96=87=E4=BB=B6=E6=A8=A1=E5=9D=97=20mock?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/app.mock.ts | 158 +++++++++++++++++++ mock/codegen.mock.ts | 351 +++++++++++++++++++++++++++++++++++++++++++ mock/config.mock.ts | 127 ++++++++++++++++ mock/file.mock.ts | 33 ++++ mock/menu.mock.ts | 2 +- 5 files changed, 670 insertions(+), 1 deletion(-) create mode 100644 mock/app.mock.ts create mode 100644 mock/codegen.mock.ts create mode 100644 mock/config.mock.ts create mode 100644 mock/file.mock.ts diff --git a/mock/app.mock.ts b/mock/app.mock.ts new file mode 100644 index 00000000..46f41b98 --- /dev/null +++ b/mock/app.mock.ts @@ -0,0 +1,158 @@ +import { defineMock } from "./base"; + +/** 应用数据源(内存态,支持增删改与状态切换) */ +const appList: Array> = [ + { + id: "1", + appName: "有来商城", + appCode: "youlai-mall", + platform: "WECHAT_MP", + appId: "wx5d2e1a2b3c4d5e6f7a8b", + appSecret: "c0a8d0c0d1f4a0b1e0f5a2c3d4e5f6a7", + merchantId: "1900000001", + merchantKey: "MCH_KEY_123456", + status: 1, + remark: "有来商城公众号应用", + createTime: "2024-01-15 10:00:00", + }, + { + id: "2", + appName: "有来商城小程序", + appCode: "youlai-mall-mini", + platform: "WECHAT_MINI", + appId: "wx1f2e3d4c5b6a7f8e9d0c", + appSecret: "b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6", + merchantId: "1900000002", + merchantKey: "MCH_KEY_654321", + status: 1, + remark: "有来商城微信小程序应用", + createTime: "2024-02-20 14:30:00", + }, + { + id: "3", + appName: "有来商城App", + appCode: "youlai-mall-app", + platform: "APPLE", + appId: "com.youlai.mall.app", + appSecret: "", + status: 0, + remark: "iOS 端应用(已停用)", + createTime: "2023-11-08 09:12:00", + }, +]; + +export default defineMock([ + // 应用分页列表 + { + url: "apps", + method: ["GET"], + body({ query }) { + const { keywords, platform, status, pageNum = "1", pageSize = "10" } = query; + const filtered = appList.filter((item) => { + if (keywords && !`${item.appName}${item.appCode}${item.appId}`.includes(keywords)) { + return false; + } + if (platform && item.platform !== platform) return false; + if (status && String(item.status) !== String(status)) return false; + return true; + }); + const page = Number(pageNum); + const size = Number(pageSize); + const start = (page - 1) * size; + return { + code: "00000", + data: { + list: filtered.slice(start, start + size), + total: filtered.length, + }, + msg: "一切ok", + }; + }, + }, + + // 获取应用表单数据 + { + url: "apps/:id/form", + method: ["GET"], + body({ params }) { + const data = appList.find((item) => item.id === params.id); + return { + code: "00000", + data: data ?? null, + msg: "一切ok", + }; + }, + }, + + // 新增应用 + { + url: "apps", + method: ["POST"], + body({ body }) { + appList.unshift({ + id: String(appList.length + 1), + status: 1, + createTime: "2024-06-01 10:00:00", + ...body, + }); + return { + code: "00000", + data: null, + msg: "新增成功", + }; + }, + }, + + // 修改应用 + { + url: "apps/:id", + method: ["PUT"], + body({ params, body }) { + const index = appList.findIndex((item) => item.id === params.id); + if (index !== -1) { + appList[index] = { ...appList[index], ...body }; + } + return { + code: "00000", + data: null, + msg: "修改成功", + }; + }, + }, + + // 删除应用(多个 ID 以英文逗号分隔) + { + url: "apps/:ids", + method: ["DELETE"], + body({ params }) { + const idSet = new Set(params.ids.split(",")); + for (let i = appList.length - 1; i >= 0; i--) { + if (idSet.has(appList[i].id)) { + appList.splice(i, 1); + } + } + return { + code: "00000", + data: null, + msg: "删除成功", + }; + }, + }, + + // 修改应用状态 + { + url: "apps/:id/status", + method: ["PUT"], + body({ params, body }) { + const item = appList.find((item) => item.id === params.id); + if (item) { + item.status = body.status; + } + return { + code: "00000", + data: null, + msg: "状态更新成功", + }; + }, + }, +]); diff --git a/mock/codegen.mock.ts b/mock/codegen.mock.ts new file mode 100644 index 00000000..a20b88a2 --- /dev/null +++ b/mock/codegen.mock.ts @@ -0,0 +1,351 @@ +import { defineMock } from "./base"; + +/** 数据表列表 */ +const tableList = [ + { + tableName: "sys_user", + tableComment: "用户表", + engine: "InnoDB", + tableCollation: "utf8mb4_general_ci", + createTime: "2023-06-01 10:00:00", + isConfigured: 1, + }, + { + tableName: "sys_role", + tableComment: "角色表", + engine: "InnoDB", + tableCollation: "utf8mb4_general_ci", + createTime: "2023-06-01 10:05:00", + isConfigured: 1, + }, + { + tableName: "sys_menu", + tableComment: "菜单表", + engine: "InnoDB", + tableCollation: "utf8mb4_general_ci", + createTime: "2023-06-01 10:10:00", + isConfigured: 0, + }, + { + tableName: "sys_dept", + tableComment: "部门表", + engine: "InnoDB", + tableCollation: "utf8mb4_general_ci", + createTime: "2023-06-01 10:15:00", + isConfigured: 0, + }, +]; + +/** 下划线命名转驼峰首字母大写,如 sys_user → SysUser */ +function toPascalCase(name: string): string { + return name + .split("_") + .filter(Boolean) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(""); +} + +/** 默认字段配置 */ +const defaultFieldConfigs = [ + { + columnName: "id", + columnType: "bigint", + fieldName: "id", + fieldType: "Long", + fieldComment: "主键", + isPrimaryKey: 1, + isShowInList: 1, + isShowInForm: 0, + isShowInQuery: 0, + isRequired: 0, + formType: 10, + queryType: 0, + maxLength: 20, + fieldSort: 1, + dictType: "", + }, + { + columnName: "username", + columnType: "varchar(50)", + fieldName: "username", + fieldType: "String", + fieldComment: "用户名", + isShowInList: 1, + isShowInForm: 1, + isShowInQuery: 1, + isRequired: 1, + formType: 1, + queryType: 2, + maxLength: 50, + fieldSort: 2, + dictType: "", + }, + { + columnName: "nickname", + columnType: "varchar(50)", + fieldName: "nickname", + fieldType: "String", + fieldComment: "昵称", + isShowInList: 1, + isShowInForm: 1, + isShowInQuery: 0, + isRequired: 0, + formType: 1, + queryType: 0, + maxLength: 50, + fieldSort: 3, + dictType: "", + }, + { + columnName: "gender", + columnType: "tinyint", + fieldName: "gender", + fieldType: "Integer", + fieldComment: "性别", + isShowInList: 1, + isShowInForm: 1, + isShowInQuery: 0, + isRequired: 0, + formType: 2, + queryType: 0, + maxLength: 3, + fieldSort: 4, + dictType: "gender", + }, + { + columnName: "email", + columnType: "varchar(100)", + fieldName: "email", + fieldType: "String", + fieldComment: "邮箱", + isShowInList: 0, + isShowInForm: 1, + isShowInQuery: 0, + isRequired: 0, + formType: 1, + queryType: 0, + maxLength: 100, + fieldSort: 5, + dictType: "", + }, + { + columnName: "status", + columnType: "tinyint", + fieldName: "status", + fieldType: "Integer", + fieldComment: "状态", + isShowInList: 1, + isShowInForm: 1, + isShowInQuery: 1, + isRequired: 1, + formType: 6, + queryType: 1, + maxLength: 3, + fieldSort: 6, + dictType: "", + }, + { + columnName: "create_time", + columnType: "datetime", + fieldName: "createTime", + fieldType: "LocalDateTime", + fieldComment: "创建时间", + isShowInList: 1, + isShowInForm: 0, + isShowInQuery: 1, + isRequired: 0, + formType: 9, + queryType: 4, + maxLength: 0, + fieldSort: 7, + dictType: "", + }, +]; + +/** 生成配置数据源(内存态,POST 保存、DELETE 重置) */ +const genConfigMap: Record = { + sys_user: { + id: "1", + tableName: "sys_user", + businessName: "user", + moduleName: "system", + packageName: "com.youlai.system", + entityName: "SysUser", + author: "youlai", + parentMenuId: "1", + backendAppName: "youlai-admin", + frontendAppName: "vue3-element-admin", + removeTablePrefix: "sys_", + pageType: "classic", + fieldConfigs: defaultFieldConfigs, + }, + sys_role: { + id: "2", + tableName: "sys_role", + businessName: "role", + moduleName: "system", + packageName: "com.youlai.system", + entityName: "SysRole", + author: "youlai", + parentMenuId: "1", + backendAppName: "youlai-admin", + frontendAppName: "vue3-element-admin", + removeTablePrefix: "sys_", + pageType: "classic", + fieldConfigs: defaultFieldConfigs, + }, +}; + +/** 未配置表的默认生成配置(无 id,进入抽屉后从基础配置步骤开始) */ +function buildDefaultConfig(tableName: string) { + return { + tableName, + businessName: tableName.replace(/^sys_/, ""), + moduleName: "system", + packageName: "com.youlai.system", + entityName: toPascalCase(tableName.replace(/^sys_/, "")), + author: "youlai", + parentMenuId: "1", + backendAppName: "youlai-admin", + frontendAppName: "vue3-element-admin", + removeTablePrefix: "sys_", + pageType: "classic", + fieldConfigs: defaultFieldConfigs, + }; +} + +/** 构造代码生成预览文件列表 */ +function buildPreviewFiles(tableName: string, tableComment: string) { + const bizName = tableName.replace(/^sys_/, ""); + const entityName = toPascalCase(bizName); + return [ + { + path: "src/api/system/", + fileName: `${bizName}.ts`, + content: `import request from "@/utils/request";\n\n/** ${tableComment}相关接口 */\nexport const ${bizName}Api = {\n getPage(params: unknown) {\n return request({ url: "/api/v1/${tableName}s", method: "get", params });\n },\n};\n`, + scope: "frontend", + language: "ts", + }, + { + path: "src/views/system/", + fileName: `${bizName}.vue`, + content: `\n\n\n`, + scope: "frontend", + language: "vue", + }, + { + path: "src/main/java/com/youlai/system/controller/", + fileName: `${entityName}Controller.java`, + content: `package com.youlai.system.controller;\n\nimport org.springframework.web.bind.annotation.RestController;\n\n/**\n * ${tableComment}控制器\n */\n@RestController\npublic class ${entityName}Controller {\n}\n`, + scope: "backend", + language: "java", + }, + { + path: "src/main/resources/mapper/", + fileName: `${entityName}Mapper.xml`, + content: `\n\n\n\n`, + scope: "backend", + language: "xml", + }, + ]; +} + +export default defineMock([ + // 数据表分页列表 + { + url: "codegen/table", + method: ["GET"], + body({ query }) { + const { keywords, pageNum = "1", pageSize = "10" } = query; + const filtered = tableList.filter((item) => { + if (keywords && !`${item.tableName}${item.tableComment}`.includes(keywords)) { + return false; + } + return true; + }); + const page = Number(pageNum); + const size = Number(pageSize); + const start = (page - 1) * size; + return { + code: "00000", + data: { + list: filtered.slice(start, start + size), + total: filtered.length, + }, + msg: "一切ok", + }; + }, + }, + + // 获取代码生成配置 + { + url: "codegen/:tableName/config", + method: ["GET"], + body({ params }) { + return { + code: "00000", + data: genConfigMap[params.tableName] ?? buildDefaultConfig(params.tableName), + msg: "一切ok", + }; + }, + }, + + // 保存代码生成配置 + { + url: "codegen/:tableName/config", + method: ["POST"], + body({ params, body }) { + genConfigMap[params.tableName] = { id: "1", ...body }; + const table = tableList.find((item) => item.tableName === params.tableName); + if (table) { + table.isConfigured = 1; + } + return { + code: "00000", + data: null, + msg: "保存成功", + }; + }, + }, + + // 重置代码生成配置 + { + url: "codegen/:tableName/config", + method: ["DELETE"], + body({ params }) { + delete genConfigMap[params.tableName]; + const table = tableList.find((item) => item.tableName === params.tableName); + if (table) { + table.isConfigured = 0; + } + return { + code: "00000", + data: null, + msg: "重置成功", + }; + }, + }, + + // 获取代码生成预览数据 + { + url: "codegen/:tableName/preview", + method: ["GET"], + body({ params }) { + const table = tableList.find((item) => item.tableName === params.tableName); + return { + code: "00000", + data: buildPreviewFiles(params.tableName, table?.tableComment || params.tableName), + msg: "一切ok", + }; + }, + }, + + // 下载代码生成 ZIP 文件 + { + url: "codegen/:tableName/download", + method: ["GET"], + headers: { + "Content-Disposition": "attachment; filename=codegen.zip", + }, + }, +]); diff --git a/mock/config.mock.ts b/mock/config.mock.ts new file mode 100644 index 00000000..80c6677f --- /dev/null +++ b/mock/config.mock.ts @@ -0,0 +1,127 @@ +import { defineMock } from "./base"; + +/** 配置数据源(内存态,支持增删改) */ +const configList: Array> = [ + { + id: "1", + configName: "系统名称", + configKey: "system.name", + configValue: "vue3-element-admin", + remark: "后台管理系统名称", + }, + { + id: "2", + configName: "系统Logo", + configKey: "system.logo", + configValue: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif", + remark: "后台管理系统 Logo 地址", + }, + { + id: "3", + configName: "系统版本", + configKey: "system.version", + configValue: "4.8.4", + remark: "后台管理系统版本号", + }, +]; + +export default defineMock([ + // 配置分页列表 + { + url: "configs", + method: ["GET"], + body({ query }) { + const { keywords, pageNum = "1", pageSize = "10" } = query; + const filtered = configList.filter((item) => { + if (keywords && !`${item.configName}${item.configKey}`.includes(keywords)) { + return false; + } + return true; + }); + const page = Number(pageNum); + const size = Number(pageSize); + const start = (page - 1) * size; + return { + code: "00000", + data: { + list: filtered.slice(start, start + size), + total: filtered.length, + }, + msg: "一切ok", + }; + }, + }, + + // 获取配置表单数据 + { + url: "configs/:id/form", + method: ["GET"], + body({ params }) { + const data = configList.find((item) => item.id === params.id); + return { + code: "00000", + data: data ?? null, + msg: "一切ok", + }; + }, + }, + + // 新增配置 + { + url: "configs", + method: ["POST"], + body({ body }) { + configList.unshift({ id: String(configList.length + 1), ...body }); + return { + code: "00000", + data: null, + msg: "新增成功", + }; + }, + }, + + // 修改配置 + { + url: "configs/:id", + method: ["PUT"], + body({ params, body }) { + const index = configList.findIndex((item) => item.id === params.id); + if (index !== -1) { + configList[index] = { ...configList[index], ...body }; + } + return { + code: "00000", + data: null, + msg: "修改成功", + }; + }, + }, + + // 删除配置 + { + url: "configs/:id", + method: ["DELETE"], + body({ params }) { + const index = configList.findIndex((item) => item.id === params.id); + if (index !== -1) { + configList.splice(index, 1); + } + return { + code: "00000", + data: null, + msg: "删除成功", + }; + }, + }, + + // 刷新配置缓存 + { + url: "configs/refresh", + method: ["PUT"], + body: { + code: "00000", + data: null, + msg: "刷新成功", + }, + }, +]); diff --git a/mock/file.mock.ts b/mock/file.mock.ts new file mode 100644 index 00000000..177e1c98 --- /dev/null +++ b/mock/file.mock.ts @@ -0,0 +1,33 @@ +import { defineMock } from "./base"; + +export default defineMock([ + // 上传文件 + { + url: "files", + method: ["POST"], + body() { + const name = `mock-upload-${Date.now()}.png`; + return { + code: "00000", + data: { + name, + url: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif", + }, + msg: "上传成功", + }; + }, + }, + + // 删除文件 + { + url: "files", + method: ["DELETE"], + body({ query }) { + return { + code: "00000", + data: null, + msg: query.filePath ? `删除文件 ${query.filePath} 成功` : "删除成功", + }; + }, + }, +]); diff --git a/mock/menu.mock.ts b/mock/menu.mock.ts index 962011a1..e1e00744 100644 --- a/mock/menu.mock.ts +++ b/mock/menu.mock.ts @@ -1474,7 +1474,7 @@ export default defineMock([ type: "M", routeName: null, routePath: "dict-demo", - component: "demo/dict", + component: "demo/dictionary", sort: 4, visible: 1, icon: "",