java-ylsw-bw.md 27 KB


name: crud-by-controller-ylsw-bw

description: 基于仪陇表务(ylsw-bw / water-meter)ledger 模块风格生成 CRUD、台账查询与导出接口。参考 com.tofly.wm.ledger.meter 等既有实现,统一 ResultResponse、MPJ、PageHelper 与权限注解。用户提到表务、水表台账、ledger、出入库、生成接口时使用。

CRUD 生成 Skill(仪陇表务 ylsw-bw)

适用场景

当用户要求在 business/water-meter 或表务相关模块中新增/补全接口时,优先对齐 com.tofly.wm.ledger 下既有代码(首选参考 ledger/meter,台账类参考 ledger/purchaseledger/arriveledger/verify)。

公共 Skill 引用

代码落点与包结构(对齐 com.tofly.wm

模块根包 com.tofly.wm,按业务分层;新建代码必须落在与职责匹配的包下,禁止全部堆在 ledger 或单一层级。

包树与职责(参考 ledger / manage 存量)

com.tofly.wm
├── cons/                         # 模块常量(字典目录码、业务编码前缀等)
│   └── MeterConstant.java
├── ledger/                       # 台账、出入库、只读汇总(少写或不写主数据)
│   ├── meter/                    # 水表出入库 CRUD
│   │   ├── enums/                # 域内枚举(BoundTypeEnum、CompanyTypeEnum…)
│   │   └── app/                  # 子场景(App 入库、领用等),*Controller/*Service/*Vo
│   ├── purchase/                 # 采购台账(Vo + Query + Service,无独立 Entity 表)
│   ├── arrive/                   # 到货台账
│   └── verify/                   # 落地检台账
├── manage/                       # 管理端业务写操作、主数据维护
│   ├── puachase/                # 采购(存量包名 puachase,新建子包沿用勿改拼写)
│   │   ├── apply/                # 采购申请
│   │   │   └── list/             # 申请明细子表
│   │   ├── plan/                 # 采购计划
│   │   │   ├── arrive/           # 到货单
│   │   │   └── arriveList/       # 到货明细
│   │   └── claim/                # 领用
│   ├── brand/                    # 厂家
│   ├── verify/                   # 检定管理(含 giveback 等子包)
│   └── warehouse/
├── workorder/                    # 工单
└── api/                          # 对外/第三方接口(verify 等)

单包内文件组织(以 ledger/meter 为准)

类型 命名 位置
接口 {Domain}Controller 域包根目录
服务接口/实现 {Domain}Service / {Domain}ServiceImpl 域包根目录;台账可无接口,仅 {Domain}LedgerService
实体 {Domain} 域包根目录
查询 {Domain}Query / {Domain}LedgerQuery 域包根目录
展示 {Domain}Vo / {Domain}LedgerVo 域包根目录
Mapper {Domain}Mapper 域包根目录
枚举 *Enum {domain}/enums/
App/专项 App*Claim* {domain}/app/ 等子包
  • 同包平铺为主,不按 controller/service/entity 再分子包(与 ledger 一致)。
  • 子表/明细:独立子包 listarriveList 等,类名与主表关联清晰。
  • 常量:字典目录、流水号类型等放 com.tofly.wm.cons.MeterConstant,禁止魔法字符串。
  • 表名前缀 TF_WM_*,业务表多为 _Wmapper.xmlsrc/main/resources/mapper/

选型:ledger 还是 manage?

场景 推荐包
分页/列表/导出台账、跨表只读汇总 ledger.{domain}
主表 CRUD、流程、审批、写入业务表 manage.{业务域}
移动端/专项入口 ledger.{domain}.appmanage.*.app

ylsw-bw 专项约束

接口与返回

  • 返回体统一 ResultResponse<T>(带泛型,禁止裸类型)。
  • Controller:@RestController + @RequestMapping("/xxx") + @Api(tags = "...")
  • 依赖注入:@RequiredArgsConstructor + @FieldDefaults(level = PRIVATE, makeFinal = true)(Controller 常见);Service 可用 @AllArgsConstructor@Service 无接口实现类。

路由习惯(对齐 meter)

能力 方法 路径 说明
分页 GET /page /list 共用 {Domain}Query(含 pageNum/pageSize
列表 GET /list /page 同一 Query、同一 Service 条件;不分页,返回 List
详情 GET /{id}
新增 POST / @RequestBody 实体
修改 POST /update 本模块用 POST 而非 PUT
删除 DELETE /deleteByIds ids 请求参数,逗号分隔主键;禁止单条 DELETE /{id}
导出 GET /export 返回 voidEasyPoiUtil.download(台账类)
  • 禁止提供 DELETE /{id}removeById 对外接口;删除统一走 DELETE /deleteByIds(单条删除传 ids=1 即可)。
  • 生成 Controller 时不得保留 @DeleteMapping("/{id}") 模板代码。

接口文档生成(强制)

编制或生成各 PRD-04 功能需求说明 §接口设计(研发)公共接口说明 时:

  1. 标准 CRUD 类资源须按上表 全量列出 模板接口(pagelist{id}POST /updatedeleteByIds),不得因 PRD 未写或业务暂未实现而省略。
  2. 台账只读类须列出模板:GET /pageGET /list(若适用)、GET /{id}(若适用)、GET /export;不写 POST/deleteByIds 时在文档中标注「台账只读,无写接口」。
  3. 业务专属接口(工单发起、派单、App 回传等)在模板接口 之后 追加列出。
  4. 文档中 禁止 出现 DELETE /{resource}/{id};删除统一写 DELETE /{resource}/deleteByIds

工具类与空值判断

场景 用法 禁止/避免
字符串为空 StrUtil.isNotBlank(s) / StrUtil.isBlank(s) 手写 s != null && !s.isEmpty()
集合为空 CollUtil.isEmpty(list) / CollUtil.isNotEmpty(list) list == null
对象拷贝 BeanUtil.copyProperties(...) 大段手动 set(无业务差异时)
对象是否为 null Objects.nonNull(x) / Objects.isNull(x) 对象用 == null 写在条件首参外且无一致性时
枚举入库条件 Optional.ofNullable(enum).map(Enumerable::getKey).orElse(null) 直接 .eq(field, enum) 未取 key
范围时间 .between(Objects.nonNull(q.getStartDate()), ...) 未判空即 between
  • Hutool 包名:cn.hutool.core.*StrUtilCollUtilBeanUtil 等),与项目存量一致。
  • 字符串用 Hutool;引用类型对象(实体字段、枚举、Long、OrganizationEntry 等)用 Objects

分页与查询

  • 查询类继承 PageQuery,Swagger @ApiModel / @ApiModelProperty
  • Query 字段类型:筛选用 Long/String/枚举/LocalDate 等基础类型;OrganizationEntryUserNameEntryDictEntry 仅出现在 Entity/Vo,不出现在 Query(字典筛选可用字典 code 的 String)。
  • 单表条件:Wrappers.<Entity>lambdaQuery(),条件首参遵循上表;枚举用 Enumerable.getKey()
  • 列表:list(query) 与分页共用 buildWrapperpage(query) 内部 PageHelper.startPage(query, () -> list(query))
  • 批量删除:Service deleteByIds(String ids) 解析逗号分隔主键后 removeByIds,需 @Transactional
  • 多表台账只读:MPJWrappers.lambdaJoin() + selectJoinList(见 purchase/verify 台账),不强行拆 XML。
  • 关键条件行加简短行尾注释(见注释规范),如 //出厂编码//需求部门

Service / Mapper 基类

  • 实体 CRUD:MPJBaseService<Entity> / MPJBaseServiceImpl<Mapper, Entity>
  • Mapper:MPJBaseMapper<Entity>;简单查询不写 XML。
  • 复杂统计、窗口函数、批量状态更新:在 *Mapper.xml 编写,禁止 Mapper 注解 SQL。

实体与 BaseEntity(强制)

database-design.mdc 的关系:公司通用规范写 create_user/is_delete 等;本仓库(ylsw-bw / Oracle 11)以 com.tofly.entity.pojo.BaseEntity 映射为准,逻辑删除列名为 DELETEDNUMBER(1)),创建/更新人为 NUMBER(19)。建表、实体、Skill 自检均以本节为准。

建表:每张业务表必须包含的公共列

新建 TF_WM_* 主表、明细表时,在 CREATE TABLE 语句内与主键 ID、业务字段一并声明下列列(Oracle 11),不要单独用 ALTER TABLE ... ADD 事后补列。

CREATE TABLE TF_WM_XXX_W (
    ID                  NUMBER(19)    NOT NULL,
    -- BaseEntity 公共列(主表/明细表均须包含)
    CREATE_USER         NUMBER(19),
    CREATE_TIME         TIMESTAMP,
    UPDATE_USER         NUMBER(19),
    UPDATE_TIME         TIMESTAMP,
    DELETED             NUMBER(1)     DEFAULT 0,
    CREATE_COMPANY_ID   NUMBER(19),
    CREATE_COMPANY_NAME VARCHAR2(200),
    CREATE_DEPT_ID      NUMBER(19),
    CREATE_DEPT_NAME    VARCHAR2(200),
    CREATE_POST_ID      NUMBER(19),
    CREATE_POST_NAME    VARCHAR2(200),
    CREATE_USER_NAME    VARCHAR2(100),
    CUR_COMPANY_ID      NUMBER(19),
    CUR_DEPT_ID         NUMBER(19),
    -- 业务字段 …
    CONSTRAINT PK_TF_WM_XXX_W PRIMARY KEY (ID)
);

COMMENT ON TABLE TF_WM_XXX_W IS '表说明';
COMMENT ON COLUMN TF_WM_XXX_W.ID IS '主键';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_USER IS '创建人';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_TIME IS '创建时间';
COMMENT ON COLUMN TF_WM_XXX_W.UPDATE_USER IS '更新人';
COMMENT ON COLUMN TF_WM_XXX_W.UPDATE_TIME IS '更新时间';
COMMENT ON COLUMN TF_WM_XXX_W.DELETED IS '删除状态:0未删除 1已删除';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_COMPANY_ID IS '创建公司ID';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_COMPANY_NAME IS '创建公司名称';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_DEPT_ID IS '创建部门ID';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_DEPT_NAME IS '创建部门名称';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_POST_ID IS '创建岗位ID';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_POST_NAME IS '创建岗位名称';
COMMENT ON COLUMN TF_WM_XXX_W.CREATE_USER_NAME IS '创建用户名称';
COMMENT ON COLUMN TF_WM_XXX_W.CUR_COMPANY_ID IS '当前公司ID';
COMMENT ON COLUMN TF_WM_XXX_W.CUR_DEPT_ID IS '当前部门ID';
-- 业务列 COMMENT 逐列补充
列名 类型 说明
CREATE_USER NUMBER(19) 创建人 ID
CREATE_TIME TIMESTAMP 创建时间
UPDATE_USER NUMBER(19) 更新人 ID
UPDATE_TIME TIMESTAMP 更新时间
DELETED NUMBER(1) 逻辑删除:0 未删,1 已删(Java 侧见下节 deleted
CREATE_COMPANY_ID / CREATE_COMPANY_NAME 创建时公司
CREATE_DEPT_ID / CREATE_DEPT_NAME 创建时部门
CREATE_POST_ID / CREATE_POST_NAME 创建时岗位
CREATE_USER_NAME VARCHAR2(100) 创建人姓名
CUR_COMPANY_ID / CUR_DEPT_ID NUMBER(19) 当前公司/部门(数据权限)

填充由平台 MetaObjectHandler / 会话上下文自动写入,业务代码禁止在子类重复声明上述字段。

逻辑外键列注释(强制)

关联表 ID 列(通常为 *_id,以及 BaseEntity 的 create_user/update_user),COMMENT ON COLUMN 须写明 业务含义 + 关联目标

COMMENT ON COLUMN wssmet_meterlife_w.operator_id IS '操作人ID,关联tf_user表的id字段';
COMMENT ON COLUMN wssmet_meter_w.warehouse_id IS '仓库ID,关联wssmet_warehouse_w表的id字段';
COMMENT ON COLUMN wssmet_purapplylist_w.apply_id IS '采购申请ID,关联wssmet_purapply_w表的id字段';
关联类型 目标表示例 说明
平台用户 tf_user.id UserNameEntry、操作人/执行人/签收人等
平台组织 tf_org.id OrganizationEntry、部门/公司/管辖组织等
平台岗位 tf_post.id BaseEntity create_post_id
本模块业务表 wssmet_{x2}_w.id 水表、仓库、申请主表、任务主表、明细父表等
workflow/外部 注释单独说明 process_instance_id,不写伪外键
  • 禁止仅写「水表」「申请」「操作人」等简称而不写关联表。
  • 多态关联(ref_table_name + ref_table_id)须说明与 ref_table_name 配合解析。
  • 生成 DDL 时逐列自检;设计文档 business/water-meter/doc/design/数据库设计-V1.0.md 须与本节一致。

字典 / 枚举列注释(强制)

字典DictEntry + @DictDirectory)或 业务枚举(Java *Enum implements Enumerable)落库列(多为 VARCHAR2*_code*_status),COMMENT ON COLUMN 须标明类型:

-- 字典:目录码与 MeterConstant 一致
COMMENT ON COLUMN wssmet_meter_w.caliber_code IS '口径编号,字典类型,目录码METER_DIAMETER';
COMMENT ON COLUMN wssmet_meter_w.meter_type_code IS '水表类型编号,字典类型,目录码METER_TYPE';

-- 枚举:写 Java 枚举类名
COMMENT ON COLUMN wssmet_purapply_w.approve_status IS '审批状态,枚举类型,ApproveStatusEnum';
COMMENT ON COLUMN wssmet_purplan_w.arrive_status_code IS '到货状态编号,枚举类型,ArriveStatusEnum';
类型 COMMENT 必含 Java 侧
字典 字典类型,目录码{目录码} DictEntry + @DictDirectory(MeterConstant.*)
枚举 枚举类型,{EnumClassName} {domain}/enums/*Enum implements Enumerable
  • 禁止字典/枚举列仅写「状态编号」「类型编号」而不标明字典或枚举。
  • 业务单号类 VARCHAR2apply_codemeter_codetask_code 等)为普通字段,不要求字典/枚举标注。

非普通字段清单 §2.1(设计文档,强制)

数据库设计文档须含 §2.1 非普通字段清单(按表)仅列出字典列与枚举列,用表格标注 字典 / 枚举说明(字段业务含义)、引用(目录码或 Java 枚举类名);字典项与枚举取值明细须单独维护于设计目录 字典与枚举说明-V1.0.md

§2.1 必须排除(不得出现在按表清单中)

排除项 列示例 说明
BaseEntity 公共列 create_usercreate_dept_idcur_company_iddeleted 见设计文档 §2;COMMENT 仍按 §逻辑外键列注释 编写
主键 / 外键关联列 idmeter_idapply_idapply_dept_id*_id 关联关系在 DDL COMMENT 中说明,不入 §2.1 表
普通业务列 apply_codemeter_code、数量/日期/备注 非字典/枚举

§2.1 应列入(仅此两类)

类型 列示例 说明列 引用列
字典 caliber_codemeter_type_code 口径、水表类型等业务含义 目录码,如 METER_DIAMETER
枚举 task_status_codeapprove_status 任务状态、审批状态等业务含义 Java 枚举类名,如 TaskStatusEnum
### wssmet_purapply_w — 采购申请
| 字段 | 类型 | 说明 | 引用 |
| process_status_code | 枚举 | 流程状态 | ProcessStatusEnum |
| approve_status | 枚举 | 审批状态 | ApproveStatusEnum |

caliber_code 等字典列:说明填业务含义,引用填目录码;禁止在说明列写 DictEntry@DictDirectoryimplements Enumerable 等实现细节。枚举/字典取值字典与枚举说明-V1.0.md。)

  • 某表无字典/枚举业务列时,不设该表小节
  • 清单与 DDL 中字典/枚举列的 COMMENT ON COLUMN 一致;维护时手工同步 §2.1 与 DDL。

持久层实体(强制)

  • 所有映射数据库表的实体类 extends BaseEntity(含主表、明细表、子表,如 PurchaseApplyListGiveBackMeter)。
  • 主键仍在子类声明:@TableId(value = "ID", type = IdType.ASSIGN_ID) Long id
  • 禁止在子类再次声明 createUsercreateTimeupdateUserupdateTimecreateCompanyIdcurDeptId 等 BaseEntity 已映射字段(避免覆盖、类型不一致,如 BigDecimal updateUser)。
  • Lombok:@Data;子类可用 @EqualsAndHashCode(callSuper = true)(按需);@FieldDefaults(level = PRIVATE);业务列 @TableField 大写列名

逻辑删除(deleted / Boolean

约定
数据库 列名 DELETEDNUMBER(1) DEFAULT 0(0 未删,1 已删)
Java 实体 属性名 deleted,类型 Boolean禁止 Integer/Number/is_delete/del_flag
映射 @TableField("DELETED")
MyBatis-Plus 须逻辑删除时加 @TableLogic(参考 PurchasePlan 存量写法)
  • 继承 BaseEntity 且父类已提供 Boolean deleted 时,子类禁止重复声明
  • 父类无 deleted 时,在实体中显式声明(默认值 false):

    @TableLogic
    @TableField("DELETED")
    @ApiModelProperty("删除状态")
    Boolean deleted = false;
    
  • 查询默认过滤已删除数据:依赖 @TableLogic 或 Wrapper 自动带 DELETED = 0;手写 SQL/XML 须显式 DELETED = 0(或布尔映射等价条件)。

值对象与数据库列映射(强制)

Java 类型 数据库类型 实体注解 说明
OrganizationEntry NUMBER(19) @TableField("APPLY_DEPT_ID") 仅存组织/部门/公司 ID;name 由平台解析,禁止再建 *_name 快照列
UserNameEntry NUMBER(19) @TableField("APPLY_USER_ID") 仅存用户 ID禁止再建 *_name 快照列
DictEntry VARCHAR2 @TableField("PRIORITY_CODE") + @DictDirectory 存字典 code(如 METER_JJCD 项编码),列名常用 *_code
FileEntry / FileEntryList 无列 @TableField(exist = false) DDL 不建字段;附件由平台文件服务按业务主键关联
  • 组织/用户列命名:业务语义 + _id(如 apply_dept_idverify_user_id);Java 属性仍用 OrganizationEntry applyDeptUserNameEntry verifyUser
  • 字典列命名:业务语义 + _code(如 priority_codemeter_type_code);与 @DictDirectory(MeterConstant.*) 成对出现。
  • BaseEntity 审计列中的 create_company_namecreate_user_name平台自动填充,与业务字段上的 Entry 规则无关。

附件(FileEntry / FileEntryList

场景 Java 类型 说明
多个附件 com.tofly.entity.pojo.FileEntryList 接口入参/出参、Entity/Vo 展示
单个附件 com.tofly.entity.pojo.FileEntry 仅一个文件时使用
@TableField(exist = false)
@ApiModelProperty("附件")
FileEntryList attach;
  • 禁止CREATE TABLE 中声明 attach/photos/evidence_files 等 CLOB 列;禁止String 存逗号分隔文件 ID、List<Long> 裸 ID、JSON 字符串等替代。
  • DTO/Vo 与 Entity 保持一致:接收、返回附件均用 FileEntryListFileEntry,并标注 @TableField(exist = false)(映射表字段时)。

自检(建表 / 新建实体)

  • 关联列 COMMENT 含「关联{表名}表的{字段}字段」
  • 字典/枚举列 COMMENT 含「字典类型,目录码…」或「枚举类型,…Enum」
  • 设计文档 §2.1 已维护该表字典/枚举清单(不含公共列与关联列)
  • 实体 extends BaseEntity,且无重复审计字段(deleted 若父类已有则不重复)
  • 逻辑删除为 Boolean deleted + 列 DELETED,需要时含 @TableLogic
  • 组织/用户 Entry 对应 NUMBER(19) 单列;字典 Entry 对应 VARCHAR2;附件 @TableField(exist = false) 且无库列
  • 明细表与主表均具备相同公共列(非「纯关系表」例外须在表注释说明)

实体与值对象(部门 / 用户 / 字典)

  • 主键 @TableId(value = "ID", type = IdType.ASSIGN_ID)(雪花)。
  • Lombok:@Accessors(chain = true)(按需);字段 @TableField 大写列名

部门 / 公司(OrganizationEntry)

  • 仅持久层实体、Vo 使用 OrganizationEntry 表示部门/公司;库列类型 NUMBER(19)(如 apply_dept_id),禁止Long deptId + String deptName 双字段落库,禁止为 Entry 再建 apply_dept_name 等快照列。
  • Query / *LedgerQuery 中禁止使用 OrganizationEntry:按部门/公司筛选时用 Long(如 demandCompanyapplyDeptId),按名称模糊筛选用 String(如 deptName,按需);与 PurchasePlanQuery.demandCompany 一致。
  • 新增/修改赋值(Entity)OrganizationEntry.of(部门或公司ID);会话上下文可用 ApplicationSession.getDepartmentId() / getCompanyId()
  • Service 条件拼装:Query 的 Long 与实体 OrganizationEntry 字段对接,例如
    .eq(Objects.nonNull(q.getDemandCompany()), Entity::getDemandCompany, q.getDemandCompany())(见 PurchasePlanServiceImpl)。

用户(UserNameEntry)

  • Entity、Vo 上申请人、入库人等:UserNameEntry;库列类型 NUMBER(19)(如 apply_user_id),禁止 Long userId + String userName 双字段落库。
  • Query 中不使用 UserNameEntry;按用户筛选用 Long userIdString 用户名(如 inboundUser)。
  • 赋值UserNameEntry.of(ApplicationSession.getUserId()) 或业务传入的用户 ID。

字典(DictEntry + @DictDirectory

  • 字典项字段类型 DictEntry;库列类型 VARCHAR2,存字典项 code;字段上必须标注字典目录:

    @DictDirectory(MeterConstant.DICT_METER_JJCD)  // 字典目录码,定义在 MeterConstant
    @TableField("PRIORITY_CODE")
    @ApiModelProperty("紧急程度")
    DictEntry priority;
    
  • 目录常量集中在 com.tofly.wm.cons.MeterConstant,例如:

    • DICT_METER_JJCD — 紧急程度
    • DICT_METER_TYPE — 水表类型
    • DICT_METER_DIAMETER — 口径
    • DICT_WORKER_ORDER — 工单类型
  • 新建字典目录时:先在 MeterConstant 增加常量 → 再在实体/Vo 上使用 @DictDirectory

  • 按字典编码写死业务分支时:DictEntry.of(MeterConstant.PURCHASE_APPLY) 等(见 PurchaseApplyServiceImpl)。

  • Query 中若仅按字典 code 筛选,可用 String + eq回显/入库仍用实体上的 DictEntry

业务枚举(非字典)

  • 状态、出入库类型等:实现 Enumerable<T>getKey() / getLabel(),放 {domain}/enums/

注释规范

层级 要求
JavaDoc:中文业务说明;@author@date(与 ledger 存量一致)
public 方法(Service) JavaDoc:@param@return;说明业务含义,非复述方法名
关键代码 仅对非显而易见逻辑:状态流转、双写出入库、补偿、Wrappers 中每组条件的业务含义(参考 MeterServiceImpl.list 行尾 //总公司/分公司
禁止 无信息注释(// 查询// 保存);大量注释掩盖坏命名

示例(Service 条件注释,摘自 meter):

.eq(Objects.nonNull(q.getCompanyType()), Meter::getCompanyType,
        Optional.ofNullable(q.getCompanyType()).map(CompanyTypeEnum::getKey).orElse(null))
//出厂编码
.like(StrUtil.isNotBlank(q.getFactoryCode()), Meter::getFactoryCode, q.getFactoryCode())

Swagger 与日志

  • @Api(tags);方法 @ApiOperation;路径参数 @ApiParam
  • 写操作按 java-tf-ylsw-backend@ToFlyAppLog(ledger/meter 存量未全覆盖时,新增写接口应补齐)。

生成步骤

  1. 识别域与参考类
    • 标准 CRUD → ledger/meterMeterController ~ MeterMapper)。
    • 只读台账 + 导出 → ledger/purchaseledger/verify
  2. 生成 Query / Vo(分页查询、导出列)。
  3. 生成 Entity + Enum(表结构对齐 TF_WM_*)。
  4. 生成 Mapper + Service(Impl)(单表 Wrappers,多表 MPJJoin)。
  5. 生成 ControllerResultResponse、权限、路由; DELETE /{id})。
  6. 同步接口文档(标准 CRUD 模板接口全量列出,见 §接口文档生成)。
  7. 按需生成 Mapper.xml(仅复杂 SQL)。
  8. 自检(见下)。

输出格式

## CRUD 结果(ylsw-bw)
- 域包:`com.tofly.wm.ledger.{domain}`
- 参考模板:`ledger/meter` | `ledger/purchase` | ...
- 新增/修改文件:`...`

## 接口清单
- `GET /{resource}/page`
- `GET /{resource}/list`
- `GET /{resource}/{id}`
- `POST /{resource}/`
- `POST /{resource}/update`
- `DELETE /{resource}/deleteByIds`(无 `DELETE /{resource}/{id}`)
- ...

## 规范检查
- [x] ResultResponse 带泛型
- [x] 包路径符合 ledger/manage 职责划分
- [x] 字符串用 StrUtil,对象空值用 Objects.nonNull/isNull
- [x] Entity/Vo 使用 OrganizationEntry、UserNameEntry、DictEntry + @DictDirectory;Query 不用 Entry 对象
- [x] 字典目录常量来自 MeterConstant
- [x] 类/方法/关键逻辑注释符合规范
- [x] 分页使用 PageHelper + PageQuery
- [x] 简单查询用 Wrappers / MPJ,复杂 SQL 在 XML
- [x] Mapper 无注解 SQL
- [x] 表含 BaseEntity 全部公共列;实体 `extends BaseEntity` 且无重复审计字段
- [x] 关联列 COMMENT 含「关联{表名}表的{字段}字段」
- [x] 字典/枚举列 COMMENT 含「字典类型,目录码…」或「枚举类型,…Enum」
- [x] 数据库设计 §2.1 仅含字典/枚举列,与 DDL COMMENT 一致
- [x] 无 `DELETE /{id}`;删除仅 `deleteByIds`
- [x] 接口文档已按模板全量列出 CRUD 路径

参考

  • 模板代码见 examples-ylsw-bw.md
  • 仓库实现:business/water-meter/src/main/java/com/tofly/wm/ledger/meter/