From 191811b643dd06e09be91da0d13e2304ee9a481e Mon Sep 17 00:00:00 2001 From: wangziqi Date: Thu, 30 Jul 2026 14:10:52 +0800 Subject: [PATCH] fix(education): align Flyway delivery review --- .claude/skills/design/api-designer.yaml | 709 --------- .claude/skills/design/crud-designer.yaml | 518 ------- .claude/skills/design/db-designer.yaml | 654 -------- .claude/skills/design/entity-designer.yaml | 836 ---------- .claude/skills/index.yaml | 152 -- .claude/skills/modules/ai/skill-ai.yaml | 706 --------- .claude/skills/modules/bpm/skill-bpm.yaml | 719 --------- .claude/skills/modules/crm/skill-crm.yaml | 861 ----------- .claude/skills/modules/erp/skill-erp.yaml | 968 ------------ .claude/skills/modules/im/skill-im.yaml | 748 --------- .claude/skills/modules/infra/skill-infra.yaml | 662 -------- .claude/skills/modules/iot/skill-iot.yaml | 722 --------- .claude/skills/modules/mall/skill-mall.yaml | 654 -------- .../skills/modules/member/skill-member.yaml | 609 -------- .claude/skills/modules/mes/skill-mes.yaml | 964 ------------ .claude/skills/modules/mp/skill-mp.yaml | 638 -------- .claude/skills/modules/pay/skill-pay.yaml | 654 -------- .../skills/modules/report/skill-report.yaml | 345 ----- .../skills/modules/system/skill-system.yaml | 840 ----------- .claude/skills/modules/wms/skill-wms.yaml | 832 ---------- .claude/skills/patterns/factory-pattern.yaml | 91 -- .claude/skills/patterns/index.yaml | 58 - .claude/skills/patterns/strategy-pattern.yaml | 136 -- .../patterns/template-method-pattern.yaml | 119 -- .claude/skills/templates/extraction-prompt.md | 139 -- .claude/skills/templates/skill-template.yaml | 161 -- .claude/skills/usage/entity-implementation.md | 1237 --------------- .claude/skills/usage/extend-module.md | 1083 ------------- .claude/skills/usage/index.md | 363 ----- .claude/skills/usage/new-module.md | 1212 --------------- .claude/skills/usage/pattern-usage.md | 1341 ----------------- .claude/skills/usage/quick-start.md | 594 -------- .claude/skills/usage/refactor-module.md | 1307 ---------------- .../EDU-002-practice-regression-baseline.md | 1 - .../issues/EDU-006-practice-schema-flyway.md | 8 +- .../008-education-catalog-rollback.sql | 21 - sql/mysql/education/008-education-catalog.sql | 349 ----- sql/mysql/member-init.sql | 174 --- .../education/000-education-rollback.sql | 8 - .../education/000-education-schema.sql | 7 - .../education/000-education-seed.sql | 15 - .../001-education-tenant-rollback.sql | 1 - .../education/001-education-tenant-seed.sql | 3 - ...02-education-practice-session-rollback.sql | 32 - .../002-education-practice-session.sql | 105 -- ...-education-answer-idempotency-rollback.sql | 35 - .../003-education-answer-idempotency.sql | 113 -- .../004-education-submit-report-rollback.sql | 50 - .../education/004-education-submit-report.sql | 220 --- .../005-education-wrong-question-rollback.sql | 25 - .../005-education-wrong-question.sql | 156 -- .../007-education-favorite-rollback.sql | 25 - .../education/007-education-favorite.sql | 95 -- .../008-education-catalog-rollback.sql | 17 - .../education/008-education-catalog.sql | 530 ------- ...education-idempotency-unified-rollback.sql | 13 - .../009-education-idempotency-unified.sql | 103 -- ...V4050__document_practice_state_columns.sql | 13 + ...ucationFlywayMigrationIntegrationTest.java | 4 +- 59 files changed, 19 insertions(+), 23736 deletions(-) delete mode 100644 .claude/skills/design/api-designer.yaml delete mode 100644 .claude/skills/design/crud-designer.yaml delete mode 100644 .claude/skills/design/db-designer.yaml delete mode 100644 .claude/skills/design/entity-designer.yaml delete mode 100644 .claude/skills/index.yaml delete mode 100644 .claude/skills/modules/ai/skill-ai.yaml delete mode 100644 .claude/skills/modules/bpm/skill-bpm.yaml delete mode 100644 .claude/skills/modules/crm/skill-crm.yaml delete mode 100644 .claude/skills/modules/erp/skill-erp.yaml delete mode 100644 .claude/skills/modules/im/skill-im.yaml delete mode 100644 .claude/skills/modules/infra/skill-infra.yaml delete mode 100644 .claude/skills/modules/iot/skill-iot.yaml delete mode 100644 .claude/skills/modules/mall/skill-mall.yaml delete mode 100644 .claude/skills/modules/member/skill-member.yaml delete mode 100644 .claude/skills/modules/mes/skill-mes.yaml delete mode 100644 .claude/skills/modules/mp/skill-mp.yaml delete mode 100644 .claude/skills/modules/pay/skill-pay.yaml delete mode 100644 .claude/skills/modules/report/skill-report.yaml delete mode 100644 .claude/skills/modules/system/skill-system.yaml delete mode 100644 .claude/skills/modules/wms/skill-wms.yaml delete mode 100644 .claude/skills/patterns/factory-pattern.yaml delete mode 100644 .claude/skills/patterns/index.yaml delete mode 100644 .claude/skills/patterns/strategy-pattern.yaml delete mode 100644 .claude/skills/patterns/template-method-pattern.yaml delete mode 100644 .claude/skills/templates/extraction-prompt.md delete mode 100644 .claude/skills/templates/skill-template.yaml delete mode 100644 .claude/skills/usage/entity-implementation.md delete mode 100644 .claude/skills/usage/extend-module.md delete mode 100644 .claude/skills/usage/index.md delete mode 100644 .claude/skills/usage/new-module.md delete mode 100644 .claude/skills/usage/pattern-usage.md delete mode 100644 .claude/skills/usage/quick-start.md delete mode 100644 .claude/skills/usage/refactor-module.md delete mode 100644 sql/mysql/education/008-education-catalog-rollback.sql delete mode 100644 sql/mysql/education/008-education-catalog.sql delete mode 100644 sql/mysql/member-init.sql delete mode 100644 sql/postgresql/education/000-education-rollback.sql delete mode 100644 sql/postgresql/education/000-education-schema.sql delete mode 100644 sql/postgresql/education/000-education-seed.sql delete mode 100644 sql/postgresql/education/001-education-tenant-rollback.sql delete mode 100644 sql/postgresql/education/001-education-tenant-seed.sql delete mode 100644 sql/postgresql/education/002-education-practice-session-rollback.sql delete mode 100644 sql/postgresql/education/002-education-practice-session.sql delete mode 100644 sql/postgresql/education/003-education-answer-idempotency-rollback.sql delete mode 100644 sql/postgresql/education/003-education-answer-idempotency.sql delete mode 100644 sql/postgresql/education/004-education-submit-report-rollback.sql delete mode 100644 sql/postgresql/education/004-education-submit-report.sql delete mode 100644 sql/postgresql/education/005-education-wrong-question-rollback.sql delete mode 100644 sql/postgresql/education/005-education-wrong-question.sql delete mode 100644 sql/postgresql/education/007-education-favorite-rollback.sql delete mode 100644 sql/postgresql/education/007-education-favorite.sql delete mode 100644 sql/postgresql/education/008-education-catalog-rollback.sql delete mode 100644 sql/postgresql/education/008-education-catalog.sql delete mode 100644 sql/postgresql/education/009-education-idempotency-unified-rollback.sql delete mode 100644 sql/postgresql/education/009-education-idempotency-unified.sql create mode 100644 yudao-module-education/src/main/resources/db/migration/education/V4050__document_practice_state_columns.sql diff --git a/.claude/skills/design/api-designer.yaml b/.claude/skills/design/api-designer.yaml deleted file mode 100644 index e4637f6a..00000000 --- a/.claude/skills/design/api-designer.yaml +++ /dev/null @@ -1,709 +0,0 @@ -# API 设计规范知识库 - -convention: - id: "api-designer" - name: "API 设计规范" - category: "设计规范" - description: "定义项目 REST API 的设计规范,包括接口命名、请求响应格式、权限控制、文档注解等,确保 API 设计的统一性和规范性" - -# ============================================ -# 第一部分:设计原则 -# ============================================ -philosophy: - design_principles: - - principle: "操作式 URL 设计" - description: "使用动词表达操作意图,而非 RESTful 资源式命名" - example: "/system/user/create 而非 POST /users" - - principle: "统一响应格式" - description: "所有接口使用 CommonResult 包装,确保响应格式一致" - - principle: "权限分级控制" - description: "通过 @PermitAll 和 @PreAuthorize 实现公开接口与权限接口的分离" - - principle: "文档即代码" - description: "使用 OpenAPI 3.0 注解,接口文档与代码同步维护" - -# ============================================ -# 第二部分:接口规范 -# ============================================ -interface_conventions: - # URL 命名规范 - url_naming: - format: "/{模块}/{功能}/{操作}" - rules: - - "模块名与功能名使用小写字母" - - "操作名使用动词或动词短语" - - "多词使用连字符分隔(如 update-status)" - examples: - - path: "/system/user/create" - description: "创建用户" - - path: "/system/user/page" - description: "用户分页列表" - - path: "/pay/order/get" - description: "获取订单详情" - - path: "/system/user/update-status" - description: "更新用户状态" - - # HTTP 方法映射 - http_methods: - - method: "POST" - operations: ["create", "import", "send", "login", "logout"] - description: "创建类操作" - idempotent: false - - method: "PUT" - operations: ["update", "update-status", "update-password"] - description: "更新类操作" - idempotent: true - - method: "DELETE" - operations: ["delete", "delete-list"] - description: "删除类操作" - idempotent: true - - method: "GET" - operations: ["get", "page", "list", "export-excel", "get-import-template"] - description: "查询类操作" - idempotent: true - safe: true - - # 标准端点定义 - standard_endpoints: - - endpoint: "/create" - method: "POST" - purpose: "创建单个实体" - request: "@RequestBody @Valid XxxSaveReqVO" - response: "CommonResult" - permission: "{模块}:{功能}:create" - - - endpoint: "/update" - method: "PUT" - purpose: "更新单个实体" - request: "@RequestBody @Valid XxxSaveReqVO" - response: "CommonResult" - permission: "{模块}:{功能}:update" - - - endpoint: "/delete" - method: "DELETE" - purpose: "删除单个实体" - request: "@RequestParam(\"id\") Long id" - response: "CommonResult" - permission: "{模块}:{功能}:delete" - parameter_annotation: "@Parameter(name = \"id\", description = \"编号\", required = true)" - - - endpoint: "/delete-list" - method: "DELETE" - purpose: "批量删除实体" - request: "@RequestParam(\"ids\") List ids" - response: "CommonResult" - permission: "{模块}:{功能}:delete" - parameter_annotation: "@Parameter(name = \"ids\", description = \"编号列表\", required = true)" - - - endpoint: "/get" - method: "GET" - purpose: "获取单个实体详情" - request: "@RequestParam(\"id\") Long id" - response: "CommonResult" - permission: "{模块}:{功能}:query" - parameter_annotation: "@Parameter(name = \"id\", description = \"编号\", required = true)" - - - endpoint: "/page" - method: "GET" - purpose: "分页查询列表" - request: "@Valid XxxPageReqVO" - response: "CommonResult>" - permission: "{模块}:{功能}:query" - - - endpoint: "/list" - method: "GET" - purpose: "列表查询(不分页)" - request: "@RequestParam(\"ids\") List ids 或无参数" - response: "CommonResult>" - permission: "{模块}:{功能}:query" - - - endpoint: "/export-excel" - method: "GET" - purpose: "导出 Excel" - request: "@Valid XxxPageReqVO" - response: "void(直接写入 HttpServletResponse)" - permission: "{模块}:{功能}:export" - special_annotation: "@ApiAccessLog(operateType = EXPORT)" - - - endpoint: "/get-import-template" - method: "GET" - purpose: "获取导入模板" - request: "无参数" - response: "void(直接写入 HttpServletResponse)" - permission: "通常无需权限或 {模块}:{功能}:import" - - - endpoint: "/import" - method: "POST" - purpose: "导入 Excel" - request: "@RequestParam(\"file\") MultipartFile file, @RequestParam(\"updateSupport\") Boolean updateSupport" - response: "CommonResult" - permission: "{模块}:{功能}:import" - parameter_annotation: "@Parameters({...})" - -# ============================================ -# 第三部分:注解规范 -# ============================================ -annotation_standards: - # Controller 类注解 - class_annotations: - - annotation: "@Tag" - format: "@Tag(name = \"管理后台 - {模块名}\")" - purpose: "OpenAPI 3.0 文档分组" - import: "io.swagger.v3.oas.annotations.tags.Tag" - - annotation: "@RestController" - purpose: "REST 控制器" - import: "org.springframework.web.bind.annotation.RestController" - - annotation: "@RequestMapping" - format: "@RequestMapping(\"/{模块}/{功能}\")" - purpose: "路由前缀" - import: "org.springframework.web.bind.annotation.RequestMapping" - - annotation: "@Validated" - purpose: "参数校验支持" - import: "org.springframework.validation.annotation.Validated" - - # 方法注解 - method_annotations: - - annotation: "@Operation" - format: "@Operation(summary = \"{操作描述}\")" - purpose: "接口文档说明" - import: "io.swagger.v3.oas.annotations.Operation" - examples: - - "@Operation(summary = \"创建用户\")" - - "@Operation(summary = \"获得用户分页列表\")" - - "@Operation(summary = \"导出用户 Excel\")" - - - annotation: "@PermitAll" - purpose: "公开接口(无需登录)" - import: "cn.iocoder.yudao.framework.security.core.annotations.PermitAll" - when_to_use: "登录、登出、注册、验证码等无需认证的接口" - - - annotation: "@PreAuthorize" - format: "@PreAuthorize(\"@ss.hasPermission('{模块}:{功能}:{操作}')\")" - purpose: "权限控制" - import: "org.springframework.security.access.prepost.PreAuthorize" - examples: - - "@PreAuthorize(\"@ss.hasPermission('system:user:create')\")" - - "@PreAuthorize(\"@ss.hasPermission('pay:order:query')\")" - - - annotation: "@Parameter" - format: "@Parameter(name = \"{参数名}\", description = \"{描述}\", required = {是否必填}, example = \"{示例}\")" - purpose: "单参数文档" - import: "io.swagger.v3.oas.annotations.Parameter" - when_to_use: "单个 @RequestParam 参数时使用" - - - annotation: "@Parameters" - format: "@Parameters({ @Parameter(name = \"xxx\", ...), @Parameter(name = \"yyy\", ...) })" - purpose: "多参数文档" - import: "io.swagger.v3.oas.annotations.Parameters" - when_to_use: "多个 @RequestParam 参数时使用" - - - annotation: "@ApiAccessLog" - format: "@ApiAccessLog(operateType = EXPORT)" - purpose: "操作日志记录" - import: "cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog" - when_to_use: "导出、导入等需要记录日志的操作" - constants_import: "static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT" - - # 参数注解 - parameter_annotations: - - annotation: "@RequestBody" - purpose: "接收 JSON 请求体" - import: "org.springframework.web.bind.annotation.RequestBody" - usage: "@RequestBody @Valid XxxReqVO reqVO" - - annotation: "@RequestParam" - purpose: "接收 URL 查询参数" - import: "org.springframework.web.bind.annotation.RequestParam" - usage: "@RequestParam(\"id\") Long id" - - annotation: "@Valid" - purpose: "参数校验" - import: "javax.validation.Valid" - usage: "@Valid @RequestBody XxxReqVO reqVO" - -# ============================================ -# 第四部分:请求响应规范 -# ============================================ -request_response: - # 统一响应结构 - common_result: - class: "cn.iocoder.yudao.framework.common.pojo.CommonResult" - structure: - code: "Integer(0 表示成功)" - msg: "String(错误提示信息)" - data: "T(返回数据)" - usage: - success: "return success(data)" - success_boolean: "return success(true)" - success_id: "return success(id)" - import: "static cn.iocoder.yudao.framework.common.pojo.CommonResult.success" - - # 分页响应结构 - page_result: - class: "cn.iocoder.yudao.framework.common.pojo.PageResult" - structure: - total: "Long(总记录数)" - list: "List(当前页数据列表)" - usage: "CommonResult> getXxxPage(...)" - empty: "new PageResult<>(pageResult.getTotal())" - - # 分页请求参数 - page_param: - class: "cn.iocoder.yudao.framework.common.pojo.PageParam" - fields: - pageNo: "Integer(页码,从 1 开始,默认 1,最小值 1)" - pageSize: "Integer(每页条数,默认 10,范围 1-200)" - constants: - PAGE_NO: "1" - PAGE_SIZE: "10" - PAGE_SIZE_NONE: "-1(不分页,用于导出等场景)" - usage: "分页查询 VO 继承 PageParam" - - # 请求 VO 类型 - request_vo_types: - - type: "SaveReqVO" - purpose: "新增/修改请求" - naming: "XxxSaveReqVO" - features: - - "修改时包含 id 字段" - - "包含 @NotBlank/@NotNull 校验注解" - - "使用 @Schema 注解描述字段" - - type: "PageReqVO" - purpose: "分页查询请求" - naming: "XxxPageReqVO" - features: - - "继承 PageParam" - - "包含查询条件字段" - - "时间字段使用 @DateTimeFormat" - - type: "ImportReqVO" - purpose: "导入请求" - naming: "XxxImportReqVO 或使用 @RequestParam 接收 file" - features: - - "包含 file 和 updateSupport 参数" - - type: "RespVO" - purpose: "响应对象" - naming: "XxxRespVO" - features: - - "包含 @Schema 注解描述字段" - - "包含 createTime 等只读字段" - - # VO 注解规范 - vo_annotations: - - annotation: "@Schema" - purpose: "OpenAPI 3.0 字段描述" - format: "@Schema(description = \"{字段描述}\", requiredMode = Schema.RequiredMode.REQUIRED, example = \"{示例}\")" - import: "io.swagger.v3.oas.annotations.media.Schema" - - annotation: "@ExcelProperty" - purpose: "Excel 导出字段" - format: "@ExcelProperty(\"{列名}\")" - import: "com.alibaba.excel.annotation.ExcelProperty" - - annotation: "@DictFormat" - purpose: "字典转换" - format: "@DictFormat(\"{字典类型}\")" - -# ============================================ -# 第五部分:权限标识规范 -# ============================================ -permission_naming: - format: "{模块}:{功能}:{操作}" - rules: - - "模块名与功能名使用小写字母" - - "操作名使用标准动词" - standard_operations: - - operation: "query" - description: "查询权限(包括 get、page、list)" - - operation: "create" - description: "新增权限" - - operation: "update" - description: "修改权限" - - operation: "delete" - description: "删除权限" - - operation: "export" - description: "导出权限" - - operation: "import" - description: "导入权限" - examples: - - "system:user:query" - - "system:user:create" - - "system:user:update" - - "system:user:delete" - - "system:user:export" - - "system:user:import" - - "pay:order:query" - - "pay:order:create" - - # 权限 SQL 配置 - permission_sql: - menu_format: | - INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status) - VALUES ('{功能名称}管理', '', 2, 0, {父菜单ID}, '{功能}', 'ep:document', '{模块}/{功能}/index', 0); - - button_format: | - INSERT INTO system_menu (name, permission, type, sort, parent_id, status) VALUES - ('{功能名称}查询', '{模块}:{功能}:query', 3, 1, @menuId, 0), - ('{功能名称}新增', '{模块}:{功能}:create', 3, 2, @menuId, 0), - ('{功能名称}修改', '{模块}:{功能}:update', 3, 3, @menuId, 0), - ('{功能名称}删除', '{模块}:{功能}:delete', 3, 4, @menuId, 0), - ('{功能名称}导出', '{模块}:{功能}:export', 3, 5, @menuId, 0); - -# ============================================ -# 第六部分:错误码体系 -# ============================================ -error_codes: - format: "1_模块编号_功能编号_错误序号" - success_code: 0 - - # 全局错误码 - global_errors: - - code: 0 - message: "成功" - - code: 400 - message: "请求参数不正确" - - code: 401 - message: "账号未登录" - - code: 403 - message: "没有该操作权限" - - code: 404 - message: "请求未找到" - - code: 405 - message: "请求方法不正确" - - code: 423 - message: "请求失败,请稍后重试" - - code: 429 - message: "请求过于频繁" - - code: 500 - message: "系统异常" - - code: 501 - message: "功能未实现/未开启" - - code: 502 - message: "错误的配置项" - - code: 900 - message: "重复请求" - - code: 901 - message: "演示模式,禁止写操作" - - code: 999 - message: "未知错误" - - # 模块编号速查 - module_codes: - - module: "infra" - code_prefix: "1_001" - description: "基础设施模块" - - module: "system" - code_prefix: "1_002" - description: "系统管理模块" - - module: "member" - code_prefix: "1_003" - description: "会员模块" - - module: "pay" - code_prefix: "1_007" - description: "支付模块" - - module: "product" - code_prefix: "1_008" - description: "商品模块" - - module: "trade" - code_prefix: "1_011" - description: "交易模块" - - module: "promotion" - code_prefix: "1_013" - description: "促销模块" - - # 错误码定义模板 - error_code_template: | - // ========== {实体名称} 相关错误码 1_XXX_XXX_XXX ========== - ErrorCode XXX_NOT_EXISTS = new ErrorCode(1_002_001_000, "{实体名称}不存在"); - ErrorCode XXX_CODE_DUPLICATE = new ErrorCode(1_002_001_001, "已存在该编码的{实体名称}"); - ErrorCode XXX_NAME_DUPLICATE = new ErrorCode(1_002_001_002, "已存在该名称的{实体名称}"); - ErrorCode XXX_CAN_NOT_DELETE = new ErrorCode(1_002_001_003, "{实体名称}不能删除,原因:{}"); - ErrorCode XXX_STATUS_ERROR = new ErrorCode(1_002_001_004, "{实体名称}状态不正确"); - -# ============================================ -# 第七部分:Controller 模板 -# ============================================ -controller_template: - # 基础 CRUD 模板 - basic_crud: | - package cn.iocoder.yudao.module.{模块}.controller.admin.{功能}; - - import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; - import cn.iocoder.yudao.framework.common.pojo.CommonResult; - import cn.iocoder.yudao.framework.common.pojo.PageParam; - import cn.iocoder.yudao.framework.common.pojo.PageResult; - import cn.iocoder.yudao.framework.common.util.object.BeanUtils; - import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; - import cn.iocoder.yudao.module.{模块}.controller.admin.{功能}.vo.*; - import cn.iocoder.yudao.module.{模块}.dal.dataobject.{功能}.XxxDO; - import cn.iocoder.yudao.module.{模块}.service.{功能}.XxxService; - import io.swagger.v3.oas.annotations.Operation; - import io.swagger.v3.oas.annotations.Parameter; - import io.swagger.v3.oas.annotations.tags.Tag; - import org.springframework.security.access.prepost.PreAuthorize; - import org.springframework.validation.annotation.Validated; - import org.springframework.web.bind.annotation.*; - - import javax.annotation.Resource; - import javax.servlet.http.HttpServletResponse; - import javax.validation.Valid; - import java.io.IOException; - import java.util.List; - - import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - - @Tag(name = "管理后台 - {实体名称}") - @RestController - @RequestMapping("/{模块}/{功能}") - @Validated - public class XxxController { - - @Resource - private XxxService xxxService; - - @PostMapping("/create") - @Operation(summary = "创建{实体名称}") - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:create')") - public CommonResult createXxx(@Valid @RequestBody XxxSaveReqVO createReqVO) { - return success(xxxService.createXxx(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新{实体名称}") - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:update')") - public CommonResult updateXxx(@Valid @RequestBody XxxSaveReqVO updateReqVO) { - xxxService.updateXxx(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除{实体名称}") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:delete')") - public CommonResult deleteXxx(@RequestParam("id") Long id) { - xxxService.deleteXxx(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得{实体名称}") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:query')") - public CommonResult getXxx(@RequestParam("id") Long id) { - XxxDO xxx = xxxService.getXxx(id); - return success(BeanUtils.toBean(xxx, XxxRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得{实体名称}分页") - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:query')") - public CommonResult> getXxxPage(@Valid XxxPageReqVO pageReqVO) { - PageResult pageResult = xxxService.getXxxPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, XxxRespVO.class)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出{实体名称} Excel") - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportXxxExcel(@Valid XxxPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = xxxService.getXxxPage(pageReqVO).getList(); - List excelList = BeanUtils.toBean(list, XxxExcelVO.class); - ExcelUtils.write(response, "{实体名称}.xls", "数据", XxxExcelVO.class, excelList); - } - } - - # 公开接口模板 - public_endpoint: | - @PostMapping("/login") - @PermitAll - @Operation(summary = "使用账号密码登录") - public CommonResult login(@RequestBody @Valid AuthLoginReqVO reqVO) { - return success(authService.login(reqVO)); - } - - # 批量操作模板 - batch_operations: | - @DeleteMapping("/delete-list") - @Parameter(name = "ids", description = "编号列表", required = true) - @Operation(summary = "批量删除{实体名称}") - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:delete')") - public CommonResult deleteXxxList(@RequestParam("ids") List ids) { - xxxService.deleteXxxList(ids); - return success(true); - } - - # 导入导出模板 - import_export: | - @GetMapping("/get-import-template") - @Operation(summary = "获得导入{实体名称}模板") - public void importTemplate(HttpServletResponse response) throws IOException { - // 手动创建导出 demo - List list = Arrays.asList( - XxxImportExcelVO.builder().name("示例1").code("TEST1").build(), - XxxImportExcelVO.builder().name("示例2").code("TEST2").build() - ); - ExcelUtils.write(response, "{实体名称}导入模板.xls", "数据", XxxImportExcelVO.class, list); - } - - @PostMapping("/import") - @Operation(summary = "导入{实体名称}") - @Parameters({ - @Parameter(name = "file", description = "Excel 文件", required = true), - @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") - }) - @PreAuthorize("@ss.hasPermission('{模块}:{功能}:import')") - public CommonResult importExcel(@RequestParam("file") MultipartFile file, - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { - List list = ExcelUtils.read(file, XxxImportExcelVO.class); - return success(xxxService.importXxxList(list, updateSupport)); - } - -# ============================================ -# 第八部分:设计流程 -# ============================================ -design_workflow: - steps: - - step: 1 - name: "实体分析" - action: "分析数据库设计或 PRD,确定实体字段和业务含义" - input: ["db_design_file", "prd_file", "模块 skill 文档"] - output: "实体字段清单" - checklist: - - "确认实体所属模块" - - "阅读对应模块的 skill 文档" - - "确定需要哪些标准端点" - - - step: 2 - name: "端点设计" - action: "根据业务需求确定需要的 API 端点" - considerations: - - "是否需要完整 CRUD(create/update/delete/get/page)" - - "是否需要批量操作(delete-list)" - - "是否需要导入导出(export-excel/import)" - - "是否需要状态切换(update-status)" - - "是否有公开接口需求(使用 @PermitAll)" - - - step: 3 - name: "请求响应设计" - action: "设计各端点的请求参数和响应格式" - templates: - - "使用 SaveReqVO 处理新增/修改" - - "使用 PageReqVO 处理分页查询(继承 PageParam)" - - "使用 RespVO 处理响应" - - "使用 CommonResult 包装响应" - - - step: 4 - name: "权限设计" - action: "确定各端点的权限标识" - rules: - - "公开接口使用 @PermitAll" - - "权限接口使用 @PreAuthorize" - - "权限标识格式:模块:功能:操作" - - "查询类接口统一使用 query 权限" - - - step: 5 - name: "错误码设计" - action: "定义业务错误码" - rules: - - "格式:1_模块编号_功能编号_错误序号" - - "常见错误:不存在、重复、状态错误、操作限制" - - - step: 6 - name: "文档生成" - action: "生成 Controller 代码和 API 文档" - output: ["Controller.java", "VO classes", "错误码定义", "权限 SQL"] - -# ============================================ -# 第九部分:检查清单 -# ============================================ -checklist: - before_design: - - "确认实体所属模块" - - "阅读对应模块的 skill 文档" - - "了解现有类似接口的设计模式" - - "准备表结构设计" - - during_design: - - "URL 命名符合规范(/{模块}/{功能}/{操作})" - - "HTTP 方法与操作类型匹配" - - "请求 VO 类型选择正确" - - "响应格式使用 CommonResult" - - "权限标识命名正确" - - "注解使用完整" - - after_design: - - "所有接口添加 @Operation 注解" - - "参数添加 @Parameter 或 @Parameters 注解" - - "权限接口添加 @PreAuthorize 注解" - - "公开接口添加 @PermitAll 注解" - - "导出接口添加 @ApiAccessLog 注解" - - "错误码定义完整" - -# ============================================ -# 第十部分:与 entity-implementation.md 协同 -# ============================================ -collaboration: - relationship: - - doc: "api-designer.yaml" - role: "API 设计阶段规范指导" - focus: "设计决策、端点规划、权限标识" - - doc: "entity-implementation.md" - role: "完整实现流程指导" - focus: "实现细节、模板代码、各层规范" - usage_flow: - - "1. 使用 api-designer.yaml 进行 API 设计决策" - - "2. 参考 entity-implementation.md 进行完整实现" - - "3. 两者 Controller 模板保持一致" - -# ============================================ -# 快速参考 -# ============================================ -quick_reference: - http_methods: - POST: "创建类操作(create, import, send)" - PUT: "更新类操作(update, update-status)" - DELETE: "删除类操作(delete, delete-list)" - GET: "查询类操作(get, page, list, export-excel)" - - standard_endpoints: - /create: "创建 → CommonResult" - /update: "更新 → CommonResult" - /delete: "删除 → CommonResult" - /delete-list: "批量删除 → CommonResult" - /get: "详情 → CommonResult" - /page: "分页 → CommonResult>" - /list: "列表 → CommonResult>" - /export-excel: "导出 → void" - /import: "导入 → CommonResult" - - permission_operations: - query: "查询(get/page/list)" - create: "新增" - update: "修改" - delete: "删除" - export: "导出" - import: "导入" - - response_types: - CommonResult: "创建类响应" - CommonResult: "操作类响应" - CommonResult: "详情类响应" - CommonResult>: "分页类响应" - CommonResult>: "列表类响应" - - vo_types: - XxxSaveReqVO: "新增/修改请求" - XxxPageReqVO: "分页查询请求(继承 PageParam)" - XxxRespVO: "响应对象" - XxxExcelVO: "Excel 导出对象" - XxxImportExcelVO: "Excel 导入对象" - XxxImportRespVO: "导入结果响应" - - imports: - controller_common: - - "io.swagger.v3.oas.annotations.tags.Tag" - - "io.swagger.v3.oas.annotations.Operation" - - "io.swagger.v3.oas.annotations.Parameter" - - "io.swagger.v3.oas.annotations.Parameters" - - "org.springframework.security.access.prepost.PreAuthorize" - - "cn.iocoder.yudao.framework.common.pojo.CommonResult" - - "cn.iocoder.yudao.framework.common.pojo.PageResult" - - "static cn.iocoder.yudao.framework.common.pojo.CommonResult.success" \ No newline at end of file diff --git a/.claude/skills/design/crud-designer.yaml b/.claude/skills/design/crud-designer.yaml deleted file mode 100644 index 454cf9b8..00000000 --- a/.claude/skills/design/crud-designer.yaml +++ /dev/null @@ -1,518 +0,0 @@ -# CRUD 代码生成 Skill -# 整合性入口指南 - 引用已有的模板文档 - -skill: - id: "crud-generator" - name: "CRUD 代码生成" - version: "1.0.0" - category: "design" - description: "根据数据库表结构自动生成符合yudao项目规范的完整CRUD功能代码" - created_at: "2026-03-31" - updated_at: "2026-03-31" - -# ============================================ -# 第一部分:触发条件 -# ============================================ -trigger: - commands: - - "/crud-gen" - - "/generate-crud" - keywords: - - "生成CRUD" - - "创建实体代码" - - "生成增删改查" - - "实体类实现" - events: - - name: "table_created" - condition: "数据库表创建完成" - -# ============================================ -# 第二部分:输入参数 -# ============================================ -input: - parameters: - - name: "module" - type: "string" - required: true - description: "模块编码(system/infra/pay/mes等)" - examples: ["system", "infra", "pay", "mes"] - - - name: "feature" - type: "string" - required: true - description: "功能编码(user/order/process等)" - examples: ["user", "order", "process"] - - - name: "entity_name" - type: "string" - required: true - description: "实体名称(中文)" - examples: ["用户", "订单", "工序"] - - - name: "entity_class" - type: "string" - required: true - description: "实体类名(英文,首字母大写)" - examples: ["User", "Order", "Process"] - - - name: "table_name" - type: "string" - required: true - description: "数据库表名" - examples: ["system_user", "pay_order", "mes_process"] - - - name: "is_tenant" - type: "boolean" - required: false - default: true - description: "是否多租户实体(true使用TenantBaseDO,false使用BaseDO)" - - - name: "fields" - type: "array" - required: true - description: "业务字段列表" - item_schema: - name: "string" - type: "string" - required: "boolean" - description: "string" - - - name: "enable_export" - type: "boolean" - required: false - default: false - description: "是否启用Excel导出功能" - - - name: "enable_import" - type: "boolean" - required: false - default: false - description: "是否启用Excel导入功能" - - - name: "enable_batch" - type: "boolean" - required: false - default: true - description: "是否启用批量删除功能" - -# ============================================ -# 第三部分:执行流程(5阶段) -# ============================================ -workflow: - description: "CRUD代码生成按以下5个阶段顺序执行" - - phases: - # 阶段1:结构分析 - - name: "结构分析" - description: "分析表结构,确定实体属性和生成范围" - duration: "5min" - steps: - - step: "解析表名和字段定义" - action: "读取表结构信息,提取字段列表" - - step: "确定DO基类" - action: "根据is_tenant参数选择BaseDO或TenantBaseDO" - rules: - - "is_tenant=true → TenantBaseDO(含tenantId)" - - "is_tenant=false → BaseDO" - - step: "生成文件清单" - action: "根据参数确定需要创建的文件列表" - decision_table: - - condition: "默认" - files: ["DO", "Mapper", "Service", "ServiceImpl", "Controller", "SaveReqVO", "PageReqVO", "RespVO"] - - condition: "enable_export=true" - add_files: ["ExcelVO", "export-excel接口"] - - condition: "enable_import=true" - add_files: ["ImportExcelVO", "ImportRespVO", "import接口"] - - condition: "enable_batch=true" - add_files: ["delete-list接口"] - - step: "分配错误码编号" - action: "根据模块编号分配错误码段" - reference: "api-designer.yaml 第六部分 module_codes" - - # 阶段2:VO生成 - - name: "VO生成" - description: "生成请求和响应VO类" - duration: "5min" - reference: "entity-implementation.md 第3.6节" - steps: - - step: "生成 SaveReqVO" - description: "新增/修改共用请求对象" - template_path: "entity-implementation.md 第621-657行" - rules: - - "包含id字段(修改时必填)" - - "包含所有可创建/更新字段" - - "排除:creator, createTime, updater, updateTime, deleted, tenantId" - - "添加校验注解(@NotBlank/@NotNull/@Size)" - - step: "生成 PageReqVO" - description: "分页查询请求对象" - template_path: "entity-implementation.md 第661-695行" - rules: - - "继承 PageParam" - - "包含常用查询条件字段" - - "时间字段使用 @DateTimeFormat" - - step: "生成 RespVO" - description: "响应对象" - template_path: "entity-implementation.md 第699-733行" - rules: - - "包含所有展示字段" - - "包含 createTime 等只读字段" - - step: "生成 ExcelVO(可选)" - condition: "enable_export=true 或 enable_import=true" - template_path: "entity-implementation.md 第737-773行" - - # 阶段3:DAL生成 - - name: "DAL生成" - description: "生成数据访问层代码" - duration: "3min" - reference: "entity-implementation.md 第3.2-3.3节" - steps: - - step: "生成 DO实体类" - template_path: "entity-implementation.md 第128-180行" - rules: - - "@TableName 指定表名" - - "@TableId 标注主键" - - "继承正确基类" - - "枚举字段添加引用注释" - - step: "生成 Mapper接口" - template_path: "entity-implementation.md 第234-281行" - rules: - - "继承 BaseMapperX" - - "定义 selectPage 分页查询方法" - - "使用 LambdaQueryWrapperX 构建条件" - - "使用 xxxIfPresent() 方法链" - - # 阶段4:Service生成 - - name: "Service生成" - description: "生成业务逻辑层代码" - duration: "5min" - reference: "entity-implementation.md 第3.4节" - steps: - - step: "生成 Service接口" - template_path: "entity-implementation.md 第313-377行" - methods: - - "createXxx(SaveReqVO) → Long" - - "updateXxx(SaveReqVO) → void" - - "deleteXxx(Long id) → void" - - "getXxx(Long id) → XxxDO" - - "getXxxPage(PageReqVO) → PageResult" - - step: "生成 ServiceImpl实现" - template_path: "entity-implementation.md 第382-485行" - rules: - - "@Service + @Validated 注解" - - "新增方法校验唯一性" - - "更新/删除方法校验存在性" - - "使用 exception(ERROR_CODE) 抛异常" - - "使用 BeanUtils.toBean() 转换对象" - - # 阶段5:Controller生成 - - name: "Controller生成" - description: "生成HTTP接口层代码" - duration: "7min" - reference: "api-designer.yaml 第七部分" - steps: - - step: "生成 Controller类" - template_path: "api-designer.yaml 第420-511行" - annotations: - - "@Tag(name = '管理后台 - {实体名称}')" - - "@RestController" - - "@RequestMapping('/{module}/{feature}')" - - "@Validated" - - step: "生成标准端点" - endpoints: - - endpoint: "/create" - method: "POST" - template_path: "api-designer.yaml 第67-72行" - - endpoint: "/update" - method: "PUT" - template_path: "api-designer.yaml 第74-79行" - - endpoint: "/delete" - method: "DELETE" - template_path: "api-designer.yaml 第81-87行" - - endpoint: "/get" - method: "GET" - template_path: "api-designer.yaml 第97-103行" - - endpoint: "/page" - method: "GET" - template_path: "api-designer.yaml 第105-110行" - - step: "生成扩展端点(可选)" - conditionals: - - condition: "enable_batch=true" - endpoint: "/delete-list" - template_path: "api-designer.yaml 第523-531行" - - condition: "enable_export=true" - endpoint: "/export-excel" - template_path: "api-designer.yaml 第119-126行" - - condition: "enable_import=true" - endpoints: ["/get-import-template", "/import"] - template_path: "api-designer.yaml 第534-557行" - - step: "生成权限SQL" - template_path: "api-designer.yaml 第333-344行" - -# ============================================ -# 第四部分:输出产物 -# ============================================ -output: - base_path: "yudao-module-{module}-biz/src/main/java/cn/iocoder/yudao/module/{module}" - - artifacts: - # DAL层 - - name: "DO实体类" - path: "dal/dataobject/{feature}/{Entity}DO.java" - description: "数据库实体映射类" - - name: "Mapper接口" - path: "dal/mysql/{feature}/{Entity}Mapper.java" - description: "数据访问接口" - - # Service层 - - name: "Service接口" - path: "service/{feature}/{Entity}Service.java" - description: "业务服务接口" - - name: "Service实现" - path: "service/{feature}/{Entity}ServiceImpl.java" - description: "业务服务实现类" - - # Controller层 - - name: "Controller" - path: "controller/admin/{feature}/{Entity}Controller.java" - description: "HTTP API控制器" - - # VO类 - - name: "SaveReqVO" - path: "controller/admin/{feature}/vo/{Entity}SaveReqVO.java" - description: "新增/修改请求对象" - - name: "PageReqVO" - path: "controller/admin/{feature}/vo/{Entity}PageReqVO.java" - description: "分页查询请求对象" - - name: "RespVO" - path: "controller/admin/{feature}/vo/{Entity}RespVO.java" - description: "响应对象" - - # 可选产物 - - name: "ExcelVO" - path: "controller/admin/{feature}/vo/{Entity}ExcelVO.java" - condition: "enable_export=true" - description: "Excel导出对象" - - name: "ImportExcelVO" - path: "controller/admin/{feature}/vo/{Entity}ImportExcelVO.java" - condition: "enable_import=true" - description: "Excel导入对象" - - name: "ImportRespVO" - path: "controller/admin/{feature}/vo/{Entity}ImportRespVO.java" - condition: "enable_import=true" - description: "导入结果响应" - - # 配置文件 - - name: "错误码定义" - path: "enums/ErrorCodeConstants.java" - action: "追加" - description: "业务错误码定义" - - name: "权限配置SQL" - path: "sql/menu/{module}_{feature}_menu.sql" - description: "菜单和按钮权限SQL" - -# ============================================ -# 第五部分:命名规范速查 -# ============================================ -naming_standards: - # 文件命名 - files: - do: "{Entity}DO" - mapper: "{Entity}Mapper" - service: "{Entity}Service" - service_impl: "{Entity}ServiceImpl" - controller: "{Entity}Controller" - vo_save: "{Entity}SaveReqVO" - vo_page: "{Entity}PageReqVO" - vo_resp: "{Entity}RespVO" - vo_excel: "{Entity}ExcelVO" - vo_import: "{Entity}ImportExcelVO" - - # 权限标识 - permission: - format: "{module}:{feature}:{operation}" - operations: - - "query" - - "create" - - "update" - - "delete" - - "export" - - "import" - example: "system:user:create" - - # 错误码 - error_code: - format: "1_{module_code}_{feature_code}_{seq}" - module_codes: - infra: "001" - system: "002" - member: "003" - pay: "007" - product: "008" - trade: "011" - promotion: "013" - example: "1_002_001_000" - - # 数据库表名 - table: - format: "{module}_{feature}" - example: "system_user" - -# ============================================ -# 第六部分:关联文档引用 -# ============================================ -references: - primary: - - path: "skills/design/api-designer.yaml" - description: "API设计规范、Controller模板、权限标识、错误码体系" - sections: - - "第二部分:接口规范(标准端点定义)" - - "第五部分:权限标识规范" - - "第六部分:错误码体系" - - "第七部分:Controller模板" - - - path: "skills/usage/entity-implementation.md" - description: "实体类实现完整流程、各层代码模板" - sections: - - "3.2节:DO实体类模板" - - "3.3节:Mapper层模板" - - "3.4节:Service层模板" - - "3.5节:Controller层模板" - - "3.6节:VO类模板" - - "3.7节:错误码定义" - - "3.8节:权限配置SQL" - - - path: "skills/design/db-designer.yaml" - relationship: "前置依赖" - description: "数据库表结构设计规范" - - secondary: - - path: "skills/modules/{module}/skill-{module}.yaml" - relationship: "模块参考" - description: "具体模块的技术规范和扩展指南" - example: "skills/modules/system/skill-system.yaml" - -# ============================================ -# 第七部分:质量检查清单 -# ============================================ -checklist: - before_generate: - - item: "确认模块编码正确" - check: "module参数在module_codes中有对应编号" - - item: "确认表名符合命名规范" - check: "表名格式为 {module}_{feature}" - - item: "阅读对应模块的skill文档" - reference: "skills/modules/{module}/skill-{module}.yaml" - - item: "确认字段类型映射正确" - check: "数据库类型与Java类型对应" - - during_generate: - - item: "DO类继承正确的基类" - check: "TenantBaseDO(多租户)或 BaseDO(单租户)" - - item: "Mapper使用BaseMapperX和LambdaQueryWrapperX" - check: "继承BaseMapperX,条件构建使用xxxIfPresent()" - - item: "Service包含业务校验方法" - check: "新增校验唯一性,更新/删除校验存在性" - - item: "Controller注解完整" - check: "@Tag/@RestController/@RequestMapping/@Validated" - - item: "接口方法注解完整" - check: "@Operation/@PreAuthorize/@Parameter" - - after_generate: - - item: "错误码编号符合规范" - format: "1_{module_code}_{feature_code}_{seq}" - - item: "权限标识格式正确" - format: "{module}:{feature}:{operation}" - - item: "所有文件包路径正确" - base: "cn.iocoder.yudao.module.{module}" - - item: "VO类添加@Schema注解" - check: "所有字段有description" - - item: "导入语句无缺失" - check: "所有注解有对应import" - -# ============================================ -# 第八部分:与原skill的差异调整 -# ============================================ -migration_notes: - # 命名规范调整 - naming_adjustments: - - original: "CreateDTO" - target: "XxxSaveReqVO" - reason: "yudao系统新增/修改共用一个VO" - - original: "UpdateDTO" - target: "XxxSaveReqVO" - reason: "与CreateDTO合并,通过id字段区分" - - original: "QueryDTO" - target: "XxxPageReqVO" - reason: "yudao系统分页查询VO继承PageParam" - - original: "VO" - target: "XxxRespVO" - reason: "响应对象命名规范" - - original: "ListVO" - target: "XxxRespVO" - reason: "分页列表使用同一响应VO" - - # 技术栈调整 - tech_adjustments: - - original: "BaseMapper" - target: "BaseMapperX" - reason: "yudao扩展的Mapper基类" - - original: "LambdaQueryWrapper" - target: "LambdaQueryWrapperX" - reason: "支持xxxIfPresent()简化条件构建" - - original: "Result" - target: "CommonResult" - reason: "yudao统一响应包装类" - - original: "Page" - target: "PageResult" - reason: "yudao分页结果类" - - original: "@Api (Swagger 2)" - target: "@Tag (OpenAPI 3)" - reason: "Swagger版本升级" - - original: "@ApiOperation" - target: "@Operation" - reason: "OpenAPI 3.0注解" - - # 目录结构调整 - path_adjustments: - - original: "controller/{Entity}Controller.java" - target: "controller/admin/{feature}/{Entity}Controller.java" - - original: "dto/{Entity}DTO.java" - target: "controller/admin/{feature}/vo/{Entity}VO.java" - - original: "mapper/{Entity}Mapper.java" - target: "dal/mysql/{feature}/{Entity}Mapper.java" - - original: "entity/{Entity}.java" - target: "dal/dataobject/{feature}/{Entity}DO.java" - -# ============================================ -# 快速参考 -# ============================================ -quick_reference: - standard_endpoints: - POST_create: "创建 → CommonResult" - PUT_update: "更新 → CommonResult" - DELETE_delete: "删除 → CommonResult" - GET_get: "详情 → CommonResult" - GET_page: "分页 → CommonResult>" - DELETE_delete-list: "批量删除 → CommonResult" - GET_export-excel: "导出 → void" - POST_import: "导入 → CommonResult" - - permission_operations: - query: "查询(get/page/list)" - create: "新增" - update: "修改" - delete: "删除" - export: "导出" - import: "导入" - - base_classes: - BaseDO: "单租户场景 - creator/createTime/updater/updateTime/deleted" - TenantBaseDO: "多租户场景 - 额外含tenantId" - - mapper_methods: - selectPage: "分页查询" - selectOne: "查询单条" - selectList: "查询列表" - insert: "插入" - updateById: "更新" - deleteById: "删除" \ No newline at end of file diff --git a/.claude/skills/design/db-designer.yaml b/.claude/skills/design/db-designer.yaml deleted file mode 100644 index 95e185b4..00000000 --- a/.claude/skills/design/db-designer.yaml +++ /dev/null @@ -1,654 +0,0 @@ -# 数据库设计 Skill -# 根据业务需求生成符合项目规范的 PostgreSQL 表结构 -# 本项目默认且唯一首选数据库方言为 PostgreSQL;除非用户明确指定,否则禁止生成 MySQL 语法。 - -skill: - id: "db-designer" - name: "数据库设计 Skill" - version: "1.0.0" - category: "design" - description: "根据业务需求自动生成符合项目规范的 PostgreSQL 数据库设计,包括表结构、索引、ER图等" - created_at: "2026-03-31" - updated_at: "2026-03-31" - -# ============================================ -# 触发条件 -# ============================================ -trigger: - commands: - - "/db-design" - - "/db-designer" - - keywords: - - "设计数据库" - - "生成表结构" - - "创建数据模型" - - "建表" - - "DDL" - - events: - - name: "prd_approved" - condition: "PRD文档审核通过" - - name: "architecture_defined" - condition: "系统架构设计完成" - -# ============================================ -# 输入参数 -# ============================================ -input: - parameters: - - name: "module_code" - type: "string" - required: true - description: "模块编码(如 mes、erp、crm、bpm 等)" - examples: ["mes", "erp", "crm", "bpm", "pay", "fz"] - - - name: "table_name" - type: "string" - required: true - description: "表名(不含前缀)" - examples: ["work_order", "product", "customer", "letter"] - - - name: "business_fields" - type: "array" - required: true - description: "业务字段列表" - - - name: "indexes" - type: "array" - required: false - default: [] - description: "额外索引定义" - - - name: "create_date" - type: "string" - required: false - default: "today" - description: "创建日期(用于文件命名)" - -# ============================================ -# 设计理念 -# ============================================ -philosophy: - business_position: "数据库设计是业务建模的核心环节,将业务需求转化为可存储的数据结构" - - design_principles: - - "多租户隔离:所有业务表包含 tenant_id 字段,索引必须包含 tenant_id" - - "审计追踪:标准化审计字段,支持数据变更追踪" - - "逻辑删除:使用 deleted 字段实现软删除,避免数据物理删除" - - "索引优化:根据查询场景设计索引,遵循最左匹配原则" - - "命名规范:统一的表名、字段名、索引名命名规则" - -# ============================================ -# 目录结构规范 -# ============================================ -directory_structure: - base_path: "sql/postgresql" - layout: | - sql/postgresql/ - ├── {module}/ # 按模块组织 PostgreSQL 迁移脚本 - ├── table/ # 通用表结构定义 - │ ├── create/ # 建表脚本 - │ └── update/ # 表结构更新脚本 - ├── index/ # 索引定义 - ├── view/ # 视图定义 - ├── data/ # 初始数据 - └── init/ # 模块初始化脚本 - - directories: - - name: "table/create" - purpose: "存放建表 SQL 脚本" - note: "每个表一个文件,按日期命名" - - name: "table/update" - purpose: "存放表结构更新 SQL 脚本" - note: "ALTER TABLE、ADD COLUMN 等增量变更" - - name: "sequence" - purpose: "需要显式序列时存放序列脚本" - note: "默认优先使用 GENERATED BY DEFAULT AS IDENTITY;仅兼容既有 @KeySequence 约定时显式建序列" - - name: "index" - purpose: "存放索引创建脚本" - note: "可按表名组织子目录" - - name: "view" - purpose: "存放视图创建脚本" - note: "复杂查询可封装为视图" - - name: "data" - purpose: "存放初始数据 SQL 脚本" - note: "INSERT 语句,初始化字典、菜单等" - - name: "init" - purpose: "存放模块初始化脚本" - note: "按模块组织,如 bpm.sql, quartz.sql" - -# ============================================ -# 文件命名规范 -# ============================================ -file_naming: - # 建表文件命名 - create_table: - format: "YYYY_MM_DD_{表名}_create.sql" - examples: - - "2025_08_09_fz_letter_create.sql" - - "2026_03_25_mes_work_order_create.sql" - rules: - - "日期前缀使用实际创建日期" - - "表名使用小写字母和下划线" - - "统一使用 _create.sql 后缀" - - # 更新文件命名 - update_table: - format: "YYYY_MM_DD_{表名}_update.sql" - examples: - - "2025_08_15_fz_metaletter_update.sql" - - "2026_01_07_fz_attachment_rel_update.sql" - rules: - - "日期前缀使用实际更新日期" - - "同一表多次更新使用不同日期" - - "统一使用 _update.sql 后缀" - special_cases: - - pattern: "YYYY_MM_DD_{表名}_index_update.sql" - purpose: "专门用于索引更新" - - # 序列文件命名 - sequence: - format: "YYYY_MM_DD_{表名}_seq_create.sql" - examples: - - "2025_07_24_fz_metaletter_seq_create.sql" - rules: - - "与建表日期保持一致" - - "序列名通常为 表名_seq" - - # 初始数据文件命名 - initial_data: - format: "模块名.sql" - examples: - - "fazhi.sql" - - "bpm.sql" - - "quartz.sql" - - "ruoyi-vue-pro.sql" - rules: - - "按模块或功能命名" - - "包含该模块的初始数据" - -# ============================================ -# 表命名规范 -# ============================================ -table_naming: - # 表名前缀规范 - prefixes: - - prefix: "sys_" - usage: "系统核心表" - examples: ["sys_user", "sys_role", "sys_menu", "sys_dict_data"] - - prefix: "mes_" - usage: "制造执行系统表" - examples: ["mes_work_order", "mes_product", "mes_workshop"] - - prefix: "erp_" - usage: "企业资源计划表" - examples: ["erp_purchase", "erp_sale", "erp_inventory"] - - prefix: "crm_" - usage: "客户关系管理表" - examples: ["crm_customer", "crm_contract", "crm_clue"] - - prefix: "bpm_" - usage: "工作流表" - examples: ["bpm_process_definition", "bpm_process_instance"] - - prefix: "pay_" - usage: "支付模块表" - examples: ["pay_order", "pay_refund", "pay_channel"] - - prefix: "member_" - usage: "会员模块表" - examples: ["member_user", "member_level", "member_address"] - - prefix: "infra_" - usage: "基础设施表" - examples: ["infra_file", "infra_config"] - - prefix: "fz_" - usage: "法制业务表" - examples: ["fz_letter", "fz_replay", "fz_handle_unit"] - - # 表名规则 - rules: - - "使用小写字母,单词间用下划线分隔" - - "使用名词,表示实体或关系" - - "避免使用 PostgreSQL 保留字" - - "长度不超过 64 个字符" - - "关联表命名:主表_关联表_rel,如 fz_letter_label_rel" - - # 字段命名规则 - column_rules: - - "使用小写字母和下划线" - - "布尔类型使用 is_ 前缀,如 is_deleted, is_enabled" - - "时间类型使用 _time 或 _date 后缀" - - "外键使用 关联表_id 格式,如 user_id, dept_id" - - "主键统一命名为 id" - -# ============================================ -# 必需字段规范 -# ============================================ -required_columns: - # 字段定义 - columns: - - name: "id" - type: "BIGINT" - constraint: "GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY" - comment: "主键ID" - position: 1 - - - name: "tenant_id" - type: "BIGINT" - default: "0" - constraint: "NOT NULL" - comment: "租户编号" - position: 2 - note: "所有业务表必须包含,位于 id 之后" - - - name: "creator" - type: "VARCHAR(64)" - default: "''" - comment: "创建者" - - - name: "create_time" - type: "TIMESTAMP" - default: "CURRENT_TIMESTAMP" - constraint: "NOT NULL" - comment: "创建时间" - - - name: "updater" - type: "VARCHAR(64)" - default: "''" - comment: "更新者" - - - name: "update_time" - type: "TIMESTAMP" - default: "CURRENT_TIMESTAMP" - constraint: "NOT NULL" - comment: "更新时间" - note: "PostgreSQL 不支持 ON UPDATE CURRENT_TIMESTAMP,由应用层或触发器维护" - - - name: "deleted" - type: "BOOLEAN" - default: "false" - constraint: "NOT NULL" - comment: "是否删除" - - # 可选备注字段 - remark: - name: "remark" - type: "VARCHAR(500)" - default: "NULL" - comment: "备注" - position: "before_audit" - -# ============================================ -# 索引设计规范 -# ============================================ -index_standards: - # 索引命名规则 - naming: - primary_key: "PRIMARY KEY (id)" - unique_key: "uk_{字段名} 或 uk_{字段1_字段2}" - normal_index: "idx_{字段名} 或 idx_{字段1_字段2}" - - # 索引设计原则 - principles: - - "所有索引必须包含 tenant_id 作为第一列" - - "唯一索引必须包含 deleted 字段(软删除场景)" - - "外键字段必须建立索引" - - "经常用于查询条件的字段建立索引" - - "唯一约束字段建立唯一索引" - - "组合索引注意字段顺序(最左匹配)" - - "避免过多索引,影响写入性能" - - # 索引模板 - templates: - unique_with_tenant: - pattern: "CREATE UNIQUE INDEX uk_tenant_{col} ON {table} (tenant_id, {col}) WHERE deleted = false" - example: "CREATE UNIQUE INDEX uk_tenant_order ON mes_work_order (tenant_id, order_no) WHERE deleted = false" - - normal_with_tenant: - pattern: "CREATE INDEX idx_tenant_{col} ON {table} (tenant_id, {col})" - example: "CREATE INDEX idx_tenant_status ON mes_work_order (tenant_id, status)" - - foreign_key: - pattern: "CREATE INDEX idx_tenant_{fk} ON {table} (tenant_id, {fk})" - example: "CREATE INDEX idx_tenant_line ON mes_work_order (tenant_id, line_id)" - -# ============================================ -# 建表模板 -# ============================================ -create_table_template: - structure: | - -- ============================================ - -- 文件名:{filename} - -- 描述:{table_comment} - -- 作者:{author} - -- 日期:{date} - -- ============================================ - - CREATE TABLE {table_name} ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - tenant_id BIGINT NOT NULL DEFAULT 0, - -- 业务字段 - {business_columns} - -- 通用字段 - remark VARCHAR(500) DEFAULT NULL, - creator VARCHAR(64) DEFAULT '', - create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updater VARCHAR(64) DEFAULT '', - update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - deleted BOOLEAN NOT NULL DEFAULT false - ); - - COMMENT ON TABLE {table_name} IS '{table_comment}'; - {column_comments} - {indexes} - - # 字段类型推荐 - column_types: - string_short: "VARCHAR(64)" - string_medium: "VARCHAR(255)" - string_long: "VARCHAR(500)" - text: "TEXT" - integer: "INT" - bigint: "BIGINT" - decimal_amount: "DECIMAL(18,2)" - decimal_quantity: "DECIMAL(10,4)" - boolean: "BOOLEAN" - datetime: "TIMESTAMP" - date: "DATE" - status: "SMALLINT" - -# ============================================ -# 更新脚本规范 -# ============================================ -update_standards: - # 更新文件命名 - naming: "YYYY_MM_DD_{表名}_update.sql" - - # 字段操作模板 - operations: - add_column: | - -- 新增字段并添加字段注释 - ALTER TABLE {table} ADD COLUMN {column} {type}; - COMMENT ON COLUMN {table}.{column} IS '{comment}'; - -- 示例 - ALTER TABLE fz_letter ADD COLUMN priority SMALLINT DEFAULT 0; - COMMENT ON COLUMN fz_letter.priority IS '优先级'; - - modify_column: | - -- 修改字段类型 - ALTER TABLE {table} ALTER COLUMN {column} TYPE {new_type} USING {column}::{new_type}; - COMMENT ON COLUMN {table}.{column} IS '{comment}'; - -- 示例 - ALTER TABLE fz_letter ALTER COLUMN content TYPE TEXT USING content::TEXT; - COMMENT ON COLUMN fz_letter.content IS '信件内容'; - - drop_column: | - -- 删除字段(确保无业务依赖) - ALTER TABLE {table} DROP COLUMN {column}; - - add_index: | - -- 添加普通索引 - CREATE INDEX idx_tenant_{col} ON {table} (tenant_id, {col}); - -- 添加软删除唯一索引 - CREATE UNIQUE INDEX uk_tenant_{col} ON {table} (tenant_id, {col}) WHERE deleted = false; - - # 文件头部模板 - header: | - -- ============================================ - -- 更新说明:{更新目的} - -- 更新日期:{YYYY-MM-DD} - -- 更新人:{姓名} - -- ============================================ - - # 注释规范 - comment_standards: - - "文件头部说明更新目的" - - "每个变更语句添加注释" - - "危险操作(删除字段、删除数据)添加警告注释" - -# ============================================ -# 数据初始化规范 -# ============================================ -data_standards: - # INSERT 语句格式 - insert_format: | - -- 插入菜单数据 - INSERT INTO `sys_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) - VALUES - (1001, '信件管理', '', 2, 1, 0, 'letter', 'ep:document', 'fazhi/letter/index', 0), - (1002, '信件查询', 'fz:letter:query', 3, 1, 1001, '', '', '', 0); - - # 字典数据 - dict_data: | - -- 字典类型 - INSERT INTO `sys_dict_type` (`name`, `type`, `status`, `remark`) - VALUES ('信件状态', 'fz_letter_status', 0, '信件流转状态'); - - -- 字典数据 - INSERT INTO `sys_dict_data` (`sort`, `label`, `value`, `dict_type`, `status`) - VALUES - (1, '待处理', '0', 'fz_letter_status', 0), - (2, '处理中', '1', 'fz_letter_status', 0), - (3, '已完成', '2', 'fz_letter_status', 0); - -# ============================================ -# 编写规范 -# ============================================ -coding_standards: - # SQL 格式 - formatting: - - "关键字使用大写:SELECT, FROM, WHERE, JOIN, ORDER BY" - - "表名、字段名使用小写;仅在名称冲突或保留字场景使用双引号" - - "每个字段占一行,逗号放在行尾" - - "复杂查询使用缩进和换行提高可读性" - - # 注释规范 - comments: - file_header: | - -- ============================================ - -- 文件名:{文件名} - -- 描述:{功能描述} - -- 作者:{作者} - -- 日期:{YYYY-MM-DD} - -- ============================================ - table_comment: "CREATE TABLE 后必须使用 COMMENT ON TABLE 添加表注释" - column_comment: "每个字段必须使用 COMMENT ON COLUMN 添加字段注释" - index_comment: "复杂索引添加注释说明用途" - - # 事务处理 - transaction: - - "多条关联语句使用事务包裹" - - "DDL 语句(部分数据库)自动提交,注意顺序" - - "大数据量操作分批执行" - -# ============================================ -# 版本管理 -# ============================================ -version_control: - principles: - - "建表后表结构变更使用 update 脚本,不修改原文件" - - "每个变更独立文件,便于追踪和回滚" - - "日期前缀确保文件顺序和变更时间线" - - "版本升级时按日期顺序执行所有脚本" - - change_log: - format: | - -- 变更记录: - -- 2025-08-09:创建表 - -- 2025-11-11:新增 priority 字段 - -- 2026-01-07:新增 category 字段,添加索引 - -# ============================================ -# 执行流程 -# ============================================ -workflow: - phases: - - name: "需求分析" - description: "解析业务需求,提取实体和关系" - steps: - - "识别核心业务实体" - - "分析实体间关系(一对多、多对多)" - - "确定实体属性列表" - - "确定表名前缀(模块编码)" - - - name: "实体设计" - description: "设计实体属性和字段" - steps: - - "设计业务属性字段" - - "添加系统必需字段(审计字段)" - - "定义主键策略(BIGINT GENERATED BY DEFAULT AS IDENTITY;兼容既有代码时配合 @KeySequence)" - - "设置外键关系" - - - name: "多租户设计" - description: "添加租户隔离字段和索引" - steps: - - "添加 tenant_id 字段(第二位置)" - - "确保所有索引包含 tenant_id" - - "唯一索引包含 deleted 字段" - - - name: "索引设计" - description: "根据查询场景设计索引" - steps: - - "分析查询场景(列表、详情、关联、搜索)" - - "设计主键索引" - - "设计唯一索引(业务唯一键)" - - "设计普通索引(查询优化)" - - "设计外键索引" - - - name: "文件生成" - description: "生成符合规范的 SQL 文件" - steps: - - "确定文件命名(日期前缀)" - - "生成文件头部注释" - - "生成 CREATE TABLE 语句" - - "生成索引定义" - - "添加表注释" - -# ============================================ -# 质量检查清单 -# ============================================ -quality_check: - before_create: - - "确认表名符合命名规范" - - "确认包含所有必需字段" - - "确认字段类型和长度合理" - - "确认添加了必要的索引" - - "确认添加了表注释和字段注释" - - "确认文件命名符合规范" - - after_create: - - "测试建表脚本可正常执行" - - "确认所有索引包含 tenant_id" - - "确认唯一索引包含 deleted" - - "确认外键字段有索引" - - "检查索引是否生效" - - "更新相关文档" - - before_update: - - "确认变更的必要性" - - "评估对现有数据的影响" - - "准备回滚方案" - - "选择低峰期执行" - -# ============================================ -# 快速参考 -# ============================================ -quick_reference: - table_prefixes: - sys_: "系统表" - mes_: "制造执行系统表" - erp_: "企业资源计划表" - crm_: "客户关系管理表" - bpm_: "工作流表" - pay_: "支付表" - member_: "会员表" - infra_: "基础设施表" - fz_: "法制业务表" - - file_suffixes: - _create.sql: "建表脚本" - _update.sql: "更新脚本" - _seq_create.sql: "序列脚本" - - common_columns: - id: "主键ID(BIGINT)" - tenant_id: "租户编号(BIGINT)" - creator: "创建者(VARCHAR(64))" - create_time: "创建时间(TIMESTAMP)" - updater: "更新者(VARCHAR(64))" - update_time: "更新时间(TIMESTAMP)" - deleted: "逻辑删除(BOOLEAN)" - remark: "备注(VARCHAR(500))" - -# ============================================ -# 示例 -# ============================================ -examples: - work_order: - input: - module_code: "mes" - table_name: "mes_work_order" - table_comment: "生产工单表" - business_fields: - - name: "order_no" - type: "VARCHAR(64)" - required: true - comment: "工单编号" - unique: true - - name: "product_id" - type: "BIGINT" - required: true - comment: "产品ID" - - name: "status" - type: "TINYINT" - required: true - default: "0" - comment: "状态:0-待下发,1-已下发,2-生产中,3-已完成,4-已关闭" - - output_file: "2026_03_25_mes_work_order_create.sql" - - output_sql: | - -- PostgreSQL 示例(字段注释通过 COMMENT ON COLUMN 补充) - CREATE TABLE mes_work_order ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - tenant_id BIGINT NOT NULL DEFAULT 0, - order_no VARCHAR(64) NOT NULL, - product_id BIGINT NOT NULL, - status SMALLINT NOT NULL DEFAULT 0, - plan_start_time TIMESTAMP NOT NULL, - plan_end_time TIMESTAMP NOT NULL, - remark VARCHAR(500) DEFAULT NULL, - creator VARCHAR(64) DEFAULT '', - create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updater VARCHAR(64) DEFAULT '', - update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - deleted BOOLEAN NOT NULL DEFAULT false - ); - - COMMENT ON TABLE mes_work_order IS '生产工单表'; - CREATE UNIQUE INDEX uk_tenant_order - ON mes_work_order (tenant_id, order_no) WHERE deleted = false; - CREATE INDEX idx_tenant_status ON mes_work_order (tenant_id, status); - CREATE INDEX idx_tenant_time ON mes_work_order (tenant_id, plan_start_time); - -# ============================================ -# 错误处理 -# ============================================ -error_handling: - errors: - - code: "DB001" - message: "表名不符合命名规范" - solution: "检查表名前缀和格式" - - - code: "DB002" - message: "缺少必需字段" - solution: "确保包含 id, tenant_id, 审计字段" - - - code: "DB003" - message: "索引缺少 tenant_id" - solution: "所有索引必须包含 tenant_id 作为第一列" - - - code: "DB004" - message: "文件命名不符合规范" - solution: "使用 YYYY_MM_DD_{表名}_create.sql 格式" - - - code: "DB005" - message: "唯一索引缺少 deleted" - solution: "唯一索引必须包含 deleted 字段" \ No newline at end of file diff --git a/.claude/skills/design/entity-designer.yaml b/.claude/skills/design/entity-designer.yaml deleted file mode 100644 index 5f2b0020..00000000 --- a/.claude/skills/design/entity-designer.yaml +++ /dev/null @@ -1,836 +0,0 @@ -# 实体类设计 Skill -# 根据 PostgreSQL 表结构生成符合 yudao-vue-pro 规范的实体类(DO) -# 本项目默认数据库方言为 PostgreSQL,类型映射不得回退为 MySQL 默认。 - -skill: - id: "design-entity" - name: "实体类设计 Skill" - version: "1.0.0" - category: "design" - description: "根据 PostgreSQL 表结构自动生成符合 yudao 项目规范的实体类(DO),支持多租户、审计字段、JSONB 字段等特性" - created_at: "2026-03-31" - updated_at: "2026-03-31" - -# ============================================ -# 触发条件 -# ============================================ -trigger: - # 命令触发 - commands: - - "/entity-design" - - "/design-entity" - - "/entity-generator" - - # 自然语言触发 - keywords: - - "生成实体类" - - "创建DO" - - "生成DO实体" - - "实体类设计" - - "数据对象" - - # 事件触发 - events: - - name: "db_design_completed" - condition: "数据库表结构设计完成" - - name: "sql_created" - condition: "建表 SQL 文件创建完成" - -# ============================================ -# 输入参数 -# ============================================ -input: - parameters: - - name: "module_code" - type: "string" - required: true - description: "模块编码(如 mes、erp、crm、system)" - examples: ["mes", "erp", "crm", "system", "pay"] - - - name: "table_name" - type: "string" - required: true - description: "表名(含前缀,如 mes_work_order)" - examples: ["mes_work_order", "erp_product", "system_user"] - - - name: "table_comment" - type: "string" - required: true - description: "表注释/描述" - - - name: "business_fields" - type: "array" - required: true - description: "业务字段列表(不含通用字段)" - schema: - - name: "字段名" - type: "数据类型" - required: "是否必填" - comment: "字段注释" - enum_ref: "枚举引用(可选)" - json_field: "是否JSON字段(可选)" - java_type: "JSON字段的Java类型(可选,如 Set)" - - - name: "tenant_type" - type: "string" - required: false - default: "multi" - description: "租户类型:single-单租户,multi-多租户,ignore-忽略租户" - examples: ["single", "multi", "ignore"] - - - name: "entity_name" - type: "string" - required: false - default: "auto" - description: "实体类名称(默认根据表名自动生成)" - - - name: "feature" - type: "string" - required: false - default: "auto" - description: "功能子目录名(默认根据实体名推断)" - -# ============================================ -# 设计理念 -# ============================================ -philosophy: - business_position: "实体类(DO)是数据库表与业务逻辑之间的桥梁,将关系型数据映射为对象" - - design_principles: - - "继承体系:多租户继承 TenantBaseDO,单租户继承 BaseDO" - - "审计字段:由基类提供,业务实体不重复定义" - - "字段注释:使用 JavaDoc 格式,不使用 Swagger 注解" - - "JSON 字段:使用 JacksonTypeHandler 处理复杂类型" - - "命名规范:实体类以 DO 结尾,与表名保持映射关系" - - "枚举引用:在注释中说明枚举类,字段使用 Integer 类型" - - inheritance_model: - base_hierarchy: - BaseDO: - package: "cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO" - fields: ["createTime", "updateTime", "creator", "updater", "deleted"] - use_case: "单租户业务表" - note: "deleted 字段为 Boolean 类型" - TenantBaseDO: - package: "cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO" - parent: "BaseDO" - extra_fields: ["tenantId"] - use_case: "多租户业务表(绝大多数场景)" - special_annotation: - TenantIgnore: - package: "cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore" - use_case: "租户表、套餐表等需要忽略多租户过滤的实体" - -# ============================================ -# 命名转换规则 -# ============================================ -naming: - # 表名 -> 实体类名转换 - table_to_class: - rules: - - "去除表前缀(如 mes_、erp_、system_、crm_、bpm_、pay_)" - - "snake_case 转 PascalCase" - - "添加 DO 后缀" - - "特殊表名特殊处理" - examples: - - table: "mes_work_order" - class: "WorkOrderDO" - - table: "erp_product" - class: "ProductDO" - - table: "system_users" - class: "AdminUserDO" - - table: "system_role" - class: "RoleDO" - - table: "crm_customer" - class: "CustomerDO" - - # 字段名 -> 属性名转换 - column_to_field: - rules: - - "snake_case 转 camelCase" - - "保持与数据库字段映射" - examples: - - column: "work_order_no" - field: "workOrderNo" - - column: "create_time" - field: "createTime" - - column: "tenant_id" - field: "tenantId" - - # 特殊表名映射 - special_mappings: - system_users: "AdminUserDO" - system_menu: "MenuDO" - system_tenant: "TenantDO" - system_dict_data: "DictDataDO" - system_dict_type: "DictTypeDO" - - # 表前缀映射(模块编码) - prefix_mapping: - sys: "system" - mes: "mes" - erp: "erp" - crm: "crm" - bpm: "bpm" - pay: "pay" - member: "member" - infra: "infra" - -# ============================================ -# 类型映射规则 -# ============================================ -type_mapping: - postgresql_to_java: - - postgresql: "BIGINT" - java: "Long" - note: "主键、外键、数量类字段" - - - postgresql: "INT / INTEGER" - java: "Integer" - note: "状态、排序、计数类字段" - - - postgresql: "TINYINT" - java: "Integer" - note: "枚举字段、开关字段" - - - postgresql: "SMALLINT" - java: "Integer" - note: "小范围数值" - - - postgresql: "DECIMAL(p,s)" - java: "BigDecimal" - note: "金额、精确数值" - import: "java.math.BigDecimal" - - - postgresql: "FLOAT / DOUBLE" - java: "Double" - note: "浮点数" - - - postgresql: "VARCHAR / CHAR" - java: "String" - note: "字符串" - - - postgresql: "TEXT / LONGTEXT" - java: "String" - note: "大文本" - - - postgresql: "TIMESTAMP / TIMESTAMPTZ" - java: "LocalDateTime" - note: "日期时间" - import: "java.time.LocalDateTime" - - - postgresql: "DATE" - java: "LocalDate" - note: "日期" - import: "java.time.LocalDate" - - - postgresql: "TIME" - java: "LocalTime" - note: "时间" - import: "java.time.LocalTime" - - - postgresql: "BOOLEAN" - java: "Boolean" - note: "布尔值" - - - postgresql: "BLOB / LONGBLOB" - java: "byte[]" - note: "二进制数据" - - - postgresql: "JSON" - java: "复杂类型" - handler: "JacksonTypeHandler" - note: "JSON 数据,需特殊处理" - - # JSON 字段类型映射 - json_type_mapping: - - pattern: "ID数组" - java_type: "Set" - import: "java.util.Set" - - pattern: "字符串数组" - java_type: "List" - import: "java.util.List" - - pattern: "键值对对象" - java_type: "Map" - import: "java.util.Map" - -# ============================================ -# 注解规范 -# ============================================ -annotations: - # 类级别注解 - class_annotations: - required: - - annotation: "@TableName" - format: "@TableName(value = \"{table_name}\", autoResultMap = true)" - import: "com.baomidou.mybatisplus.annotation.TableName" - note: "autoResultMap = true 用于支持 TypeHandler" - - - annotation: "@KeySequence" - format: "@KeySequence(\"{table_name}_seq\")" - import: "com.baomidou.mybatisplus.annotation.KeySequence" - note: "PostgreSQL 主键约定;与项目既有 @KeySequence 规范保持一致" - - - annotation: "@Data" - import: "lombok.Data" - note: "Lombok getter/setter" - - - annotation: "@EqualsAndHashCode" - format: "@EqualsAndHashCode(callSuper = true)" - import: "lombok.EqualsAndHashCode" - note: "必须 callSuper = true 以包含基类字段" - - optional: - - annotation: "@Builder" - import: "lombok.Builder" - note: "构建器模式" - - - annotation: "@NoArgsConstructor" - import: "lombok.NoArgsConstructor" - note: "无参构造(与 Builder 配合)" - - - annotation: "@AllArgsConstructor" - import: "lombok.AllArgsConstructor" - note: "全参构造(与 Builder 配合)" - - - annotation: "@TenantIgnore" - import: "cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore" - note: "忽略多租户过滤(仅用于租户表等特殊场景)" - - # 字段级别注解 - field_annotations: - primary_key: - - annotation: "@TableId" - import: "com.baomidou.mybatisplus.annotation.TableId" - note: "主键字段,默认使用雪花算法" - - json_field: - - annotation: "@TableField" - format: "@TableField(typeHandler = JacksonTypeHandler.class)" - import: "com.baomidou.mybatisplus.annotation.TableField" - handler_import: "com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" - note: "JSON 类型字段,需要 @TableName 包含 autoResultMap = true" - -# ============================================ -# 代码模板 -# ============================================ -templates: - # 多租户实体模板(最常用) - tenant_entity: - description: "多租户业务表实体类" - base_class: "TenantBaseDO" - code: | - package cn.iocoder.yudao.module.{module}.dal.dataobject.{feature}; - - import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import lombok.*; - {additional_imports} - - /** - * {table_comment} DO - * - * @author {author} - */ - @TableName(value = "{table_name}", autoResultMap = true) - @KeySequence("{table_name}_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class {EntityName}DO extends TenantBaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - {business_fields} - - } - - # 单租户实体模板 - single_entity: - description: "单租户业务表实体类" - base_class: "BaseDO" - code: | - package cn.iocoder.yudao.module.{module}.dal.dataobject.{feature}; - - import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import lombok.*; - {additional_imports} - - /** - * {table_comment} DO - * - * @author {author} - */ - @TableName(value = "{table_name}", autoResultMap = true) - @KeySequence("{table_name}_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class {EntityName}DO extends BaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - {business_fields} - - } - - # 忽略多租户实体模板 - tenant_ignore_entity: - description: "需要忽略多租户过滤的实体类(如租户表、套餐表)" - base_class: "BaseDO" - extra_annotation: "@TenantIgnore" - code: | - package cn.iocoder.yudao.module.{module}.dal.dataobject.{feature}; - - import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; - import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import lombok.*; - {additional_imports} - - /** - * {table_comment} DO - * - * @author {author} - */ - @TenantIgnore - @TableName(value = "{table_name}", autoResultMap = true) - @KeySequence("{table_name}_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class {EntityName}DO extends BaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - {business_fields} - - } - - # 业务字段模板 - business_field: - normal: | - /** - * {字段注释} - {enum_reference} - */ - private {JavaType} {fieldName}; - - json_field: | - /** - * {字段注释} - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private {JavaType} {fieldName}; - -# ============================================ -# 输出规范 -# ============================================ -output: - # 文件输出位置 - file_location: - path_pattern: "yudao-module-{module}/src/main/java/cn/iocoder/yudao/module/{module}/dal/dataobject/{feature}/{EntityName}DO.java" - example: "yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/workorder/WorkOrderDO.java" - - # 导入语句规范 - imports: - base_imports: - - "com.baomidou.mybatisplus.annotation.TableName" - - "com.baomidou.mybatisplus.annotation.TableId" - - "com.baomidou.mybatisplus.annotation.KeySequence" - - "lombok.Data" - - "lombok.EqualsAndHashCode" - - tenant_imports: - - "cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO" - - single_imports: - - "cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO" - - json_handler_import: - - "com.baomidou.mybatisplus.annotation.TableField" - - "com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" - - builder_imports: - - "lombok.Builder" - - "lombok.NoArgsConstructor" - - "lombok.AllArgsConstructor" - - # 产物清单 - artifacts: - - name: "实体类文件" - type: "code" - path: "dal/dataobject/{feature}/{EntityName}DO.java" - -# ============================================ -# 执行流程 -# ============================================ -workflow: - phases: - - name: "表结构解析" - description: "解析数据库表结构,提取元数据" - steps: - - "识别表名、表前缀、表注释" - - "提取业务字段列表(排除通用字段:id, tenant_id, creator, create_time, updater, update_time, deleted)" - - "识别主键、索引信息" - - "识别 JSON 字段、枚举字段" - - - name: "命名转换" - description: "将数据库命名转换为 Java 命名" - steps: - - "表名 -> 实体类名(去除前缀 + PascalCase + DO 后缀)" - - "字段名 -> 属性名(camelCase)" - - "处理特殊表名映射" - - - name: "类型映射" - description: "将 MySQL 类型映射为 Java 类型" - steps: - - "标准类型映射(BIGINT -> Long 等)" - - "JSON 字段识别和处理" - - "枚举字段处理(Integer + 注释引用)" - - - name: "继承选择" - description: "确定实体类继承的基类" - steps: - - "判断租户类型(multi/single/ignore)" - - "选择对应基类(TenantBaseDO/BaseDO)" - - "判断是否需要 @TenantIgnore" - - - name: "代码生成" - description: "生成实体类代码" - steps: - - "生成类注释和注解" - - "生成主键字段" - - "生成业务字段(含 JavaDoc 注释)" - - "生成导入语句(按规范分组排序)" - - "格式化代码" - - - name: "质量检查" - description: "验证生成的实体类" - steps: - - "检查注解完整性" - - "检查字段注释格式" - - "检查继承正确性" - - "检查命名规范" - -# ============================================ -# 质量检查清单 -# ============================================ -quality_check: - before_generate: - - "确认表名符合命名规范" - - "确认业务字段列表完整" - - "确认租户类型选择正确" - - "确认字段类型映射正确" - - after_generate: - - "实体类名称以 DO 结尾" - - "@TableName 注解包含 autoResultMap = true" - - "@EqualsAndHashCode 包含 callSuper = true" - - "继承正确的基类" - - "主键字段使用 @TableId 注解" - - "所有字段使用 JavaDoc 注释格式" - - "JSON 字段使用 JacksonTypeHandler" - - "枚举字段注释包含枚举引用" - - "不包含 Swagger @Schema 注解" - - "不重复定义审计字段(已在基类中)" - -# ============================================ -# 示例 -# ============================================ -examples: - # 多租户实体示例 - work_order: - input: - module_code: "mes" - table_name: "mes_work_order" - table_comment: "生产工单" - tenant_type: "multi" - business_fields: - - name: "order_no" - type: "VARCHAR(64)" - comment: "工单编号" - unique: true - - name: "product_id" - type: "BIGINT" - comment: "产品ID" - - name: "status" - type: "TINYINT" - comment: "状态" - enum_ref: "WorkOrderStatusEnum" - - name: "plan_qty" - type: "INT" - comment: "计划数量" - - output_class_name: "WorkOrderDO" - output_file: "yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/workorder/WorkOrderDO.java" - - output_code: | - package cn.iocoder.yudao.module.mes.dal.dataobject.workorder; - - import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; - import cn.iocoder.yudao.module.mes.enums.WorkOrderStatusEnum; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import lombok.*; - - /** - * 生产工单 DO - * - * @author yudao - */ - @TableName(value = "mes_work_order", autoResultMap = true) - @KeySequence("mes_work_order_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class WorkOrderDO extends TenantBaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - /** - * 工单编号 - */ - private String orderNo; - - /** - * 产品ID - */ - private Long productId; - - /** - * 状态 - * - * 枚举 {@link WorkOrderStatusEnum} - */ - private Integer status; - - /** - * 计划数量 - */ - private Integer planQty; - - } - - # JSON 字段实体示例 - role_entity: - input: - module_code: "system" - table_name: "system_role" - table_comment: "角色" - tenant_type: "multi" - business_fields: - - name: "name" - type: "VARCHAR(100)" - comment: "角色名称" - - name: "code" - type: "VARCHAR(50)" - comment: "角色标识" - - name: "data_scope_dept_ids" - type: "JSON" - comment: "数据范围部门ID数组" - json_field: true - java_type: "Set" - - output_code: | - package cn.iocoder.yudao.module.system.dal.dataobject.permission; - - import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableField; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; - import lombok.*; - - import java.util.Set; - - /** - * 角色 DO - * - * @author yudao - */ - @TableName(value = "system_role", autoResultMap = true) - @KeySequence("system_role_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class RoleDO extends TenantBaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - /** - * 角色名称 - */ - private String name; - - /** - * 角色标识 - */ - private String code; - - /** - * 数据范围(指定部门数组) - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private Set dataScopeDeptIds; - - } - - # 忽略租户实体示例 - tenant_entity: - input: - module_code: "system" - table_name: "system_tenant" - table_comment: "租户" - tenant_type: "ignore" - business_fields: - - name: "name" - type: "VARCHAR(100)" - comment: "租户名称" - - name: "contact_name" - type: "VARCHAR(50)" - comment: "联系人" - - name: "status" - type: "TINYINT" - comment: "状态" - enum_ref: "CommonStatusEnum" - - output_code: | - package cn.iocoder.yudao.module.system.dal.dataobject.tenant; - - import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; - import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; - import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; - import com.baomidou.mybatisplus.annotation.KeySequence; - import com.baomidou.mybatisplus.annotation.TableId; - import com.baomidou.mybatisplus.annotation.TableName; - import lombok.*; - - /** - * 租户 DO - * - * @author yudao - */ - @TenantIgnore - @TableName(value = "system_tenant", autoResultMap = true) - @KeySequence("system_tenant_seq") - @Data - @EqualsAndHashCode(callSuper = true) - @Builder - @NoArgsConstructor - @AllArgsConstructor - public class TenantDO extends BaseDO { - - /** - * 主键ID - */ - @TableId - private Long id; - - /** - * 租户名称 - */ - private String name; - - /** - * 联系人 - */ - private String contactName; - - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - - } - -# ============================================ -# 与其他 Skill 的关系 -# ============================================ -related_skills: - upstream: - - skill: "db-designer" - relationship: "依赖" - description: "依赖数据库表结构设计,从 SQL 解析表信息" - path: "skills/design/db-designer.yaml" - - downstream: - - skill: "api-designer" - relationship: "输出" - description: "实体类作为 API 设计的输入" - path: "skills/design/api-designer.yaml" - - collaboration: - - path: "skills/usage/entity-implementation.md" - relationship: "协同" - description: "entity-designer 专注实体类设计规范,entity-implementation 提供完整实现流程(含 Mapper、Service 等)" - -# ============================================ -# 错误处理 -# ============================================ -error_handling: - errors: - - code: "ENT001" - message: "表名不符合命名规范" - solution: "检查表名前缀和格式,确保包含模块前缀(如 mes_、erp_)" - - - code: "ENT002" - message: "缺少必需的表注释" - solution: "提供 table_comment 参数" - - - code: "ENT003" - message: "字段类型无法映射" - solution: "使用默认 String 类型,手动调整" - - - code: "ENT004" - message: "JSON 字段缺少 java_type" - solution: "为 JSON 字段指定 java_type,如 Set" - - - code: "ENT005" - message: "租户类型选择错误" - solution: "multi 使用 TenantBaseDO,single 使用 BaseDO,ignore 使用 @TenantIgnore" - - - code: "ENT006" - message: "枚举字段缺少 enum_ref" - solution: "为枚举字段提供 enum_ref 参数,在注释中引用枚举类" \ No newline at end of file diff --git a/.claude/skills/index.yaml b/.claude/skills/index.yaml deleted file mode 100644 index 990fc291..00000000 --- a/.claude/skills/index.yaml +++ /dev/null @@ -1,152 +0,0 @@ -# Skill 索引文件 -# 记录所有模块的Skill文档位置和状态 - -skills: - # 核心模块 - system: - name: "系统管理模块" - path: "skills/modules/system/skill-system.yaml" - status: "completed" - priority: 1 - lines: 839 - - infra: - name: "基础设施模块" - path: "skills/modules/infra/skill-infra.yaml" - status: "completed" - priority: 1 - lines: 700+ - - pay: - name: "支付模块" - path: "skills/modules/pay/skill-pay.yaml" - status: "completed" - priority: 1 - lines: 654 - - # 业务模块 - member: - name: "会员模块" - path: "skills/modules/member/skill-member.yaml" - status: "completed" - priority: 2 - lines: 608 - - mall: - name: "商城模块" - path: "skills/modules/mall/skill-mall.yaml" - status: "completed" - priority: 2 - lines: 650+ - - crm: - name: "CRM模块" - path: "skills/modules/crm/skill-crm.yaml" - status: "completed" - priority: 2 - lines: 850+ - - erp: - name: "ERP模块" - path: "skills/modules/erp/skill-erp.yaml" - status: "completed" - priority: 3 - lines: 900+ - - # 技术/平台模块 - bpm: - name: "工作流模块" - path: "skills/modules/bpm/skill-bpm.yaml" - status: "completed" - priority: 2 - lines: 650+ - - ai: - name: "AI模块" - path: "skills/modules/ai/skill-ai.yaml" - status: "completed" - priority: 3 - lines: 670+ - - iot: - name: "物联网模块" - path: "skills/modules/iot/skill-iot.yaml" - status: "completed" - priority: 3 - lines: 721 - - mp: - name: "微信公众号模块" - path: "skills/modules/mp/skill-mp.yaml" - status: "completed" - priority: 3 - lines: 660+ - - report: - name: "报表模块" - path: "skills/modules/report/skill-report.yaml" - status: "completed" - priority: 3 - lines: 320+ - -# 设计规范 -design: - db: - name: "数据库设计" - path: "skills/design/db-designer.yaml" - status: "completed" - description: "数据库表结构设计规范、SQL文件规范、编写规范" - lines: 450 - entity: - name: "实体类设计" - path: "skills/design/entity-designer.yaml" - status: "completed" - description: "yudao 实体类(DO)设计规范,包括继承体系、注解规范、命名转换" - lines: 520 - api: - name: "API 设计" - path: "skills/design/api-designer.yaml" - status: "completed" - description: "REST API 设计规范、注解、请求响应格式、权限标识" - crud: - name: "CRUD 代码生成" - path: "skills/design/crud-designer.yaml" - status: "completed" - description: "根据数据库表结构自动生成完整CRUD功能代码" - lines: 517 - -# 使用样例自动引用说明 -# 使用样例文档(usage/目录)通过 YAML front matter 声明需要引用的规范文件 -# AI 读取使用样例时会自动加载相关规范,确保生成的代码符合项目标准 -usage_auto_reference: - description: "使用样例通过 YAML front matter 自动引用设计规范" - mechanism: | - 每个使用样例文档头部包含 references 配置,声明该场景需要引用的规范文件: - - design: 设计规范(db-designer, entity-designer, api-designer, crud-designer) - - module_guide: 模块引用提示(用户指定模块后加载对应 skill) - - patterns: 设计模式引用(factory, strategy, template-method) - - templates: 模板文件引用 - example: | - --- - references: - design: - - skills/design/db-designer.yaml - - skills/design/entity-designer.yaml - module_guide: - prompt: "请指定目标模块" - mapping: - mes: skills/modules/mes/skill-mes.yaml - --- - -# 提取进度 -progress: - total: 12 - completed: 12 - in_progress: 0 - pending: 0 - -# 最后更新时间 -metadata: - created_at: "2026-03-18" - updated_at: "2026-03-31" - completed_at: "2026-03-18" \ No newline at end of file diff --git a/.claude/skills/modules/ai/skill-ai.yaml b/.claude/skills/modules/ai/skill-ai.yaml deleted file mode 100644 index 9cdf7fe8..00000000 --- a/.claude/skills/modules/ai/skill-ai.yaml +++ /dev/null @@ -1,706 +0,0 @@ -# Skill 文件 - AI 模块 -# 用于提取模块知识的标准格式 - -skill: - id: "skill-ai" - name: "AI Skill" - version: "1.0.0" - module_path: "yudao-module-ai" - created_at: "2026-03-18" - updated_at: "2026-03-18" - -# ============================================ -# 第一阶段:设计理念 -# ============================================ -philosophy: - # 业务定位:模块解决什么业务问题?在整个系统中的定位? - business_position: | - AI 模块是系统的智能化核心,提供大模型集成能力,支持多种 AI 能力: - 1. 聊天对话:支持多模型切换、流式响应、知识库增强、联网搜索 - 2. 图像生成:支持 OpenAI DALL-E、Stable Diffusion、Midjourney、硅基流动等 - 3. 音乐生成:支持 Suno AI 音乐创作 - 4. 知识库:RAG 检索增强生成,支持文档分片、向量存储、语义检索 - 5. 写作助手:AI 辅助写作 - 6. 思维导图:AI 生成思维导图 - 7. 工作流:可视化 AI 工作流编排 - - # 设计原则:遵循了哪些设计原则(SOLID、DDD)?有哪些架构决策? - design_principles: - - "策略模式:通过 AiModelFactory 统一创建不同平台的 AI 模型实例" - - "工厂模式:AiModelFactoryImpl 负责创建 ChatModel、ImageModel、EmbeddingModel 等" - - "单例缓存:使用 Hutool Singleton 缓存 AI 客户端实例,避免重复创建" - - "Spring AI 集成:基于 Spring AI 框架,实现多模型统一抽象" - - "开放-封闭原则:新增 AI 平台只需扩展 AiPlatformEnum 和工厂方法" - - "接口隔离:Service 层接口按领域划分,职责单一" - - # 领域模型:核心领域对象有哪些?领域对象之间的关系?聚合根是什么? - domain_model: - aggregates: - - name: "聊天会话" - type: "聚合根" - entities: ["AiChatMessageDO"] - description: "用户发起的对话,包含多条消息" - - name: "知识库" - type: "聚合根" - entities: ["AiKnowledgeDocumentDO", "AiKnowledgeSegmentDO"] - description: "知识库包含多个文档,文档包含多个分段" - - name: "AI 模型配置" - type: "聚合根" - entities: ["AiApiKeyDO"] - description: "模型配置关联 API 密钥" - - value_objects: - - name: "AiPlatformEnum" - description: "AI 平台枚举,定义支持的 AI 服务商" - - name: "AiModelTypeEnum" - description: "模型类型枚举:对话、图像、语音、视频、向量、重排序" - - services: - - name: "AiChatMessageService" - description: "聊天消息服务,处理对话生成" - - name: "AiImageService" - description: "图像生成服务" - - name: "AiKnowledgeService" - description: "知识库管理服务" - - name: "AiModelService" - description: "模型配置管理服务" - - name: "AiMusicService" - description: "音乐生成服务" - -# ============================================ -# 第二阶段:架构设计 -# ============================================ -architecture: - # 分层架构 - layers: - - name: "controller" - purpose: "HTTP 接口层" - components: - - "AiChatMessageController: 聊天消息接口" - - "AiChatConversationController: 对话管理接口" - - "AiImageController: 图像生成接口" - - "AiKnowledgeController: 知识库管理接口" - - "AiModelController: 模型配置接口" - - "AiMusicController: 音乐生成接口" - - "AiWriteController: 写作助手接口" - - "AiMindMapController: 思维导图接口" - - "AiWorkflowController: 工作流接口" - - - name: "service" - purpose: "业务逻辑层" - components: - - "chat/: 聊天相关服务" - - "image/: 图像生成服务" - - "knowledge/: 知识库服务" - - "model/: 模型配置服务" - - "music/: 音乐生成服务" - - "write/: 写作服务" - - "mindmap/: 思维导图服务" - - "workflow/: 工作流服务" - - - name: "dal" - purpose: "数据访问层" - components: - - "dataobject/: DO 实体类" - - "mysql/: MyBatis Mapper 接口" - - - name: "framework/ai" - purpose: "AI 框架集成层" - components: - - "core/model/: 模型工厂和多平台适配" - - "core/webserch/: 联网搜索客户端" - - "config/: 自动配置类" - - # 设计模式应用 - design_patterns: - - pattern: "工厂模式" - location: "framework/ai/core/model/AiModelFactory.java" - purpose: "统一创建各平台 AI 模型实例,屏蔽创建细节" - - pattern: "策略模式" - location: "framework/ai/core/model/AiModelFactoryImpl.java" - purpose: "根据平台类型选择不同的模型创建策略" - - pattern: "单例模式" - location: "framework/ai/core/model/AiModelFactoryImpl.java" - purpose: "使用 Hutool Singleton 缓存 AI 客户端,避免重复创建连接" - - pattern: "模板方法" - location: "service/chat/AiChatMessageServiceImpl.java" - purpose: "聊天消息处理的统一流程" - - # 模块间通信 - communication: - apis: [] - # 暂无对外暴露的 RPC API - consumers: - - module: "system" - api: "AdminUserApi" - purpose: "获取用户信息" - mq: [] - # 暂未使用消息队列 - -# ============================================ -# 第三阶段:数据表设计 -# ============================================ -data_model: - # 实体继承体系 - entity_hierarchy: - base: "BaseDO" - description: "所有实体继承 BaseDO,包含 id、creator、createTime、updater、updateTime、deleted 字段" - - # 核心数据表 - tables: - # ========== 模型配置 ========== - - name: "ai_api_key" - comment: "AI API 密钥表" - entity: "AiApiKeyDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "name", type: "String", comment: "名称" } - - { name: "api_key", type: "String", comment: "密钥" } - - { name: "platform", type: "String", comment: "平台,枚举 AiPlatformEnum" } - - { name: "url", type: "String", comment: "API 地址" } - - { name: "status", type: "Integer", comment: "状态" } - - - name: "ai_model" - comment: "AI 模型配置表" - entity: "AiModelDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "key_id", type: "Long", comment: "API 密钥编号" } - - { name: "name", type: "String", comment: "模型名称" } - - { name: "model", type: "String", comment: "模型标识" } - - { name: "platform", type: "String", comment: "平台" } - - { name: "type", type: "Integer", comment: "类型:1对话 2图片 3语音 4视频 5向量 6重排序" } - - { name: "sort", type: "Integer", comment: "排序值" } - - { name: "status", type: "Integer", comment: "状态" } - - { name: "temperature", type: "Double", comment: "温度参数" } - - { name: "max_tokens", type: "Integer", comment: "最大 Token 数" } - - { name: "max_contexts", type: "Integer", comment: "最大上下文数" } - - - name: "ai_chat_role" - comment: "AI 聊天角色表" - entity: "AiChatRoleDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "name", type: "String", comment: "角色名称" } - - { name: "avatar", type: "String", comment: "角色头像" } - - { name: "category", type: "String", comment: "角色分类" } - - { name: "description", type: "String", comment: "角色描述" } - - { name: "system_message", type: "String", comment: "角色设定" } - - { name: "user_id", type: "Long", comment: "用户编号" } - - { name: "model_id", type: "Long", comment: "模型编号" } - - { name: "knowledge_ids", type: "List", comment: "知识库编号列表" } - - { name: "tool_ids", type: "List", comment: "工具编号列表" } - - { name: "mcp_client_names", type: "List", comment: "MCP Client 名字列表" } - - { name: "public_status", type: "Boolean", comment: "是否公开" } - - { name: "sort", type: "Integer", comment: "排序值" } - - { name: "status", type: "Integer", comment: "状态" } - - - name: "ai_tool" - comment: "AI 工具表" - entity: "AiToolDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "name", type: "String", comment: "工具名称(Bean 名字)" } - - { name: "description", type: "String", comment: "工具描述" } - - { name: "status", type: "Integer", comment: "状态" } - - # ========== 聊天对话 ========== - - name: "ai_chat_conversation" - comment: "AI 聊天对话表" - entity: "AiChatConversationDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "user_id", type: "Long", comment: "用户编号" } - - { name: "title", type: "String", comment: "对话标题" } - - { name: "pinned", type: "Boolean", comment: "是否置顶" } - - { name: "pinned_time", type: "LocalDateTime", comment: "置顶时间" } - - { name: "role_id", type: "Long", comment: "角色编号" } - - { name: "model_id", type: "Long", comment: "模型编号" } - - { name: "model", type: "String", comment: "模型标识" } - - { name: "system_message", type: "String", comment: "角色设定" } - - { name: "temperature", type: "Double", comment: "温度参数" } - - { name: "max_tokens", type: "Integer", comment: "最大 Token 数" } - - { name: "max_contexts", type: "Integer", comment: "最大上下文数" } - - - name: "ai_chat_message" - comment: "AI 聊天消息表" - entity: "AiChatMessageDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "conversation_id", type: "Long", comment: "对话编号" } - - { name: "reply_id", type: "Long", comment: "回复消息编号" } - - { name: "type", type: "String", comment: "消息类型(USER/ASSISTANT/SYSTEM)" } - - { name: "user_id", type: "Long", comment: "用户编号" } - - { name: "role_id", type: "Long", comment: "角色编号" } - - { name: "model", type: "String", comment: "模型标识" } - - { name: "model_id", type: "Long", comment: "模型编号" } - - { name: "content", type: "String", comment: "聊天内容" } - - { name: "reasoning_content", type: "String", comment: "推理内容" } - - { name: "use_context", type: "Boolean", comment: "是否携带上下文" } - - { name: "segment_ids", type: "List", comment: "知识库段落编号数组" } - - { name: "web_search_pages", type: "List", comment: "联网搜索网页内容" } - - { name: "attachment_urls", type: "List", comment: "附件 URL 数组" } - - # ========== 图像生成 ========== - - name: "ai_image" - comment: "AI 绘画表" - entity: "AiImageDO" - extends: "BaseDO" - columns: - - { name: "id", type: "Long", comment: "编号" } - - { name: "user_id", type: "Long", comment: "用户编号" } - - { name: "prompt", type: "String", comment: "提示词" } - - { name: "platform", type: "String", comment: "平台" } - - { name: "model_id", type: "Long", comment: "模型编号" } - - { name: "model", type: "String", comment: "模型标识" } - - { name: "width", type: "Integer", comment: "图片宽度" } - - { name: "height", type: "Integer", comment: "图片高度" } - - { name: "status", type: "Integer", comment: "生成状态" } - - { name: "finish_time", type: "LocalDateTime", comment: "完成时间" } - - { name: "error_message", type: "String", comment: "错误信息" } - - { name: "pic_url", type: "String", comment: "图片地址" } - - { name: "public_status", type: "Boolean", comment: "是否公开" } - - { name: "options", type: "Map", comment: "绘制参数" } - - { name: "buttons", type: "List