依据:
市场进栏登记功能需求.md(同目录)
实现参照:baqing-admin模块com.ruoyi.web.modules.trading(BizMarketEntry*)
| 层级 | 说明 |
|---|---|
| 整体 | RuoYi v3.9.2(springboot2 分支)单体后端 + 若依 Vue2 前端(与分支配套) |
| 运行时 | JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 | MySQL 5.7.39,存储引擎 InnoDB,字符集 utf8mb4 |
后端分层(与若依一致)
BizMarketEntryController:参数绑定、权限注解、返回 AjaxResult / TableDataInfoIBizMarketEntryService / BizMarketEntryServiceImpl:事务、主从表保存、R1~R6 校验编排MarketEntryValidation、MarketEntryEarTagResolver、MarketEntryReferenceChecker:规则与可选耳标池BizMarketEntryMapper、BizMarketEntryEarTagMapper + XML:持久化domain:BizMarketEntry、BizMarketEntryEarTag;复用 EarTagCodec业务摘要(与功能需求对齐)
| 场景 | 行为 |
|---|---|
| 新增/修改 | 校验栏位、供应商;R1~R6;主表落库 → 子表 batchInsert;修改时先按 entry_id 删子表再插入;quantity = 子表行数 |
| 列表/详情 | 主表 del_flag=0;supplier_name JOIN;子表聚合 earTags / 组装 earTagList |
| 删除 | 主表 del_flag=2;子表保留;占用查询以主表 del_flag 过滤 |
| 辅助接口 | stallOptions;supplierEarTags(A−B,仅 supplierId,见 §5) |
初始化脚本:sql/biz_market_entry.sql
| 类型 | 路径 |
|---|---|
| Controller | baqing-admin/src/main/java/com/ruoyi/web/modules/trading/controller/BizMarketEntryController.java |
| Service | .../service/IBizMarketEntryService.java、.../service/impl/BizMarketEntryServiceImpl.java |
| 校验/解析 | .../support/MarketEntryValidation.java、MarketEntryEarTagResolver.java、MarketEntryRules.java |
| Mapper | .../mapper/BizMarketEntryMapper.java、BizMarketEntryEarTagMapper.java |
| XML | baqing-admin/src/main/resources/mapper/trading/BizMarketEntryMapper.xml、BizMarketEntryEarTagMapper.xml |
| 实体 | .../domain/BizMarketEntry.java、BizMarketEntryEarTag.java |
| VO | .../domain/vo/MarketStallOptionVo.java |
biz_market_entry(进栏记录)| 字段名 | 类型 | 非空 | 默认值 | 说明 |
|---|---|---|---|---|
id |
bigint(20) |
Y | 自增 | 主键 |
entry_time |
datetime |
Y | — | 进栏时间 |
stall_id |
bigint(20) |
Y | — | 关联 biz_market_stall.id |
stall_code |
char(2) |
Y | — | 栏位编号冗余,列表模糊筛选 |
supplier_id |
bigint(20) |
Y | — | 关联 biz_supplier.id |
quantity |
int(11) |
Y | — | 数量(头),= 子表耳标行数 |
del_flag |
char(1) |
Y | '0' |
删除标记,见 3.4 |
create_by / create_time / update_by / update_time |
若依惯例 | — | — | 审计 |
remark |
varchar(500) |
N | NULL | 备注 |
索引:PRIMARY KEY (id);KEY idx_entry_time;KEY idx_stall_code;KEY idx_supplier;KEY idx_del_flag。
主表不存
ear_tags文本字段;耳标明细见 3.2。
biz_market_entry_ear_tag(耳标明细)| 字段名 | 类型 | 非空 | 默认值 | 说明 |
|---|---|---|---|---|
id |
bigint(20) |
Y | 自增 | 主键 |
entry_id |
bigint(20) |
Y | — | 关联主表 biz_market_entry.id |
supplier_id |
bigint(20) |
Y | — | 供应商 ID(与主表一致,便于占用查询) |
ear_tag |
varchar(32) |
Y | — | 耳标号,单段 1~32 字 |
索引与约束
PRIMARY KEY (id)UNIQUE KEY uk_entry_ear (entry_id, ear_tag) — 同单内耳标不重复KEY idx_entry_id (entry_id)、KEY idx_supplier_id (supplier_id)、KEY idx_ear_tag (ear_tag)维护策略:新增/修改主表成功后批量插入子表;修改时 DELETE FROM biz_market_entry_ear_tag WHERE entry_id=? 后重插。
| 表 | 用途 |
|---|---|
biz_market_stall |
栏位下拉、stall_code 冗余写入 |
biz_supplier |
供应商校验、列表 supplier_name |
biz_entry_isolation |
可选耳标池 A(主表 ear_tags,隔离已结束) |
biz_entry_isolation_alloc |
入场隔离分圈(本模块耳标池 B 不使用) |
biz_isolation_patrol |
可选耳标池 B(全表病死病害耳标,selectSickDeadEarTagRows) |
del_flag(主表)| 值 | 含义 |
|---|---|
0 |
正常 |
2 |
已逻辑删除 |
完整脚本见 sql/biz_market_entry.sql。核心结构如下:
CREATE TABLE `biz_market_entry` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`entry_time` datetime NOT NULL,
`stall_id` bigint(20) NOT NULL,
`stall_code` char(2) NOT NULL,
`supplier_id` bigint(20) NOT NULL,
`quantity` int(11) NOT NULL,
`del_flag` char(1) NOT NULL DEFAULT '0',
`create_by` varchar(64) DEFAULT '',
`create_time` datetime DEFAULT NULL,
`update_by` varchar(64) DEFAULT '',
`update_time` datetime DEFAULT NULL,
`remark` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_entry_time` (`entry_time`),
KEY `idx_stall_code` (`stall_code`),
KEY `idx_supplier` (`supplier_id`),
KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='市场进栏登记';
CREATE TABLE `biz_market_entry_ear_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`entry_id` bigint(20) NOT NULL,
`supplier_id` bigint(20) NOT NULL,
`ear_tag` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_entry_ear` (`entry_id`,`ear_tag`),
KEY `idx_entry_id` (`entry_id`),
KEY `idx_supplier_id` (`supplier_id`),
KEY `idx_ear_tag` (`ear_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='市场进栏登记耳标明细';
与前端、持久化 小驼峰(camelCase) 对齐;库表为下划线。
| 前端 / JSON(camelCase) | 库表字段 | 说明 |
|---|---|---|
id |
id |
主键 |
entryTime |
entry_time |
进栏时间 |
stallId |
stall_id |
市场栏位 ID |
stallCode |
stall_code |
栏位编号(服务端冗余写入) |
supplierId |
supplier_id |
供应商 ID |
supplierName |
— | 列表/详情 JOIN 展示,非主表列 |
quantity |
quantity |
头数 |
earTagList |
子表 ear_tag |
请求/响应数组;入库拆为多行 |
earTags |
子表聚合 | 列表/详情逗号拼接展示用 |
entryDateStart / entryDateEnd |
— | 列表筛选,映射 DATE(entry_time) |
earTag |
子表 ear_tag |
列表筛选,子表 LIKE |
remark |
remark |
备注 |
子表行(内部/扩展):entryId、supplierId、earTag。
MarketEntryEarTagResolver)与功能需求 §4 一致。耳标字段均为逗号分隔文本,经 EarTagCodec.parse 拆分去重。
| 集合 | 规则 | 实现要点 |
|---|---|---|
| A | 入场隔离主表耳标;supplier_id;del_flag=0;隔离已结束 |
BizEntryIsolationMapper.selectEndedMainEarTagRowsBySupplier;expected_release_date <= CURDATE() |
| B | 全部巡查;del_flag=0;sick_dead_qty>0 且耳标非空 |
BizIsolationPatrolMapper.selectSickDeadEarTagRows(无 supplierId 条件) |
| C | 他单进栏占用 | BizMarketEntryEarTagMapper.selectOccupiedEarTags;主表 del_flag=0;entry_id <> excludeEntryId |
隔离已结束:当前日期 ≥ 预计解除日期。
listSupplierEarTagOptions(GET /supplierEarTags)supplierId(必填);校验供应商存在且未删除。string[]。listEligible(新增/修改 R4)excludeEntryId:新增为 null;修改传当前主表 id,释放本条已选耳标占用。MarketEntryValidation(保存时 R1~R6)
| 规则 | 实现要点 |
|---|---|
| R1 | 进栏时间、栏位、供应商、至少 1 个耳标 |
| R2 | entry_time <= now() |
| R3 | biz_market_stall、biz_supplier 存在且 del_flag=0 |
| R4 | 每个耳标 ∈ listEligible(supplierId, excludeEntryId) |
| R5 | EarTagCodec 去重,单段 1~32 字 |
| R6 | quantity = earTagList.size() |
事务:insert / update 使用 @Transactional;主表与子表在同一事务内提交。
删除:MarketEntryReferenceChecker.hasReference(id) 为 true 时拒绝;否则主表 del_flag=2。
统一响应:AjaxResult(code、msg、data)/ TableDataInfo(rows、total)。
权限标识:tradeMarket:marketEntry:list|query|add|edit|remove
Base Path:/tradeMarket/marketEntry
路由注册顺序:
/stallOptions、/supplierEarTags须在/{id}之前。
| 接口说明 | HTTP | URI(相对 Base Path) | 权限 |
|---|---|---|---|
| 分页列表 | GET | /list |
list |
| 详情 | GET | /{id} |
query |
| 新增 | POST | / |
add |
| 修改 | PUT | / |
edit |
| 删除 | DELETE | /{ids} |
remove |
| 栏位下拉 | GET | /stallOptions |
list 或 query |
| 可选耳标 | GET | /supplierEarTags |
list 或 query |
GET /list| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum / pageSize |
int | N | 默认 1 / 20 |
entryDateStart / entryDateEnd |
string | N | yyyy-MM-dd;闭区间;均填时须 start <= end |
stallCode |
string | N | stall_code LIKE %stallCode% |
supplierId |
long | N | 精确 |
earTag |
string | N | 子表 ear_tag LIKE %earTag%(EXISTS) |
条件:del_flag='0'。排序:entry_time DESC, id DESC。
行字段:id、entryTime、stallId、stallCode、supplierId、supplierName、earTags、earTagList(可选)、quantity、审计字段。
GET /{id}data:主表全字段 + earTagList + supplierName(子表组装)。
POST /| Body 字段 | 必填 | 说明 |
|---|---|---|
entryTime |
Y | yyyy-MM-dd HH:mm:ss,≤ 当前时间 |
stallId |
Y | 服务端写入 stallCode |
supplierId |
Y | — |
earTagList |
Y | ≥1;或与 earTags 逗号串二选一,经 EarTagCodec 解析 |
quantity |
N | 服务端以耳标数为准覆盖 |
remark |
N | ≤500 字 |
PUT /同 7.3;id 必填;保存时服务端以 id 作为 excludeEntryId 参与 §5.2 占用校验(与 supplierEarTags 无关)。
DELETE /{ids}单条可只传一个 id;更新主表 del_flag='2';有下游引用返回「存在关联业务,无法删除」。
GET /stallOptionsdata:[{ stallId, stallCode }],biz_market_stall 且 del_flag=0,stall_code ASC。
GET /supplierEarTags| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
supplierId |
long | Y | 供应商 |
data:string[](A−B,见 §5.1)。供应商无效时业务异常。
计算步骤(与需求 §4.1、§4.2 一致)
supplierId 查 biz_entry_isolation:del_flag=0、expected_release_date <= CURDATE(),汇总主表 ear_tags(逗号拆分去重)→ Abiz_isolation_patrol:del_flag=0、sick_dead_qty>0、耳标非空(全表,不按 supplierId),汇总 ear_tags → B登记表单模糊搜索:复用 /tradeMarket/supplier/list(supplierName 模糊);列表筛选使用本模块 supplierId 精确条件。
| 类型 | 名称 | 权限标识 |
|---|---|---|
| 菜单 | 市场进栏登记 | tradeMarket:marketEntry:list |
| 按钮 | 查询 | tradeMarket:marketEntry:query |
| 按钮 | 新增 | tradeMarket:marketEntry:add |
| 按钮 | 修改 | tradeMarket:marketEntry:edit |
| 按钮 | 删除 | tradeMarket:marketEntry:remove |
组件路径(前端):tradeMarket/marketEntry/index。
sql/biz_market_entry.sql(主表 + 子表)BizMarketEntry、BizMarketEntryEarTag、Mapper/XML、Service、ControllerMarketEntryValidation、MarketEntryEarTagResolver、MarketEntryRulescom.ruoyi.web.modules.trading.**.*MarketEntry*)| 日期 | 说明 |
|---|---|
| — | 初稿:单表 ear_tags 文本存储 |
| — | v2.0:耳标池 A−B−C;关联入场隔离、隔离巡查 |
| — | v2.1:主从表 biz_market_entry + biz_market_entry_ear_tag |
| — | 版式对齐《养殖标准管理技术方案》《养殖标准管理技术前端方案》;接口/库表/源码路径分章 |
| — | v2.2:supplierEarTags 仅 supplierId,返回 A−B;B 为全表巡查病死耳标;保存 (A−B)−C |