依据:同目录
入场隔离登记功能需求.md。主表 + 分圈明细子表;保存时校验 R1~R5;检疫证文件走若依上传;逻辑删除。
| 项 | 说明 |
|---|---|
| 后端 | RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 | MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 | 若依 Vue2;字段 小驼峰(页面见前端技术方案,本文不展开) |
| 文件 | 复用 /common/upload;存 cert_file_url、cert_file_path(/profile/...) |
分层:Controller → Service(EntryIsolationValidation、EarTagCodec、ReleaseDateCalculator、EntryIsolationReferenceChecker)→ Mapper/XML → domain。
代码包(建议):com.ruoyi.web.modules.trading
初始化脚本:sql/biz_entry_isolation.sql
业务摘要
| 场景 | 行为 |
|---|---|
| 新增/修改 | 校验供应商、圈位存在且未删;解析耳标;校验 R1~R5;计算 expected_release_date;主表 + 子表同事务保存 |
| 修改分圈 | 先删该登记下全部子表行,再批量插入新分圈明细 |
| 列表/详情 | 主表 del_flag=0;详情带子表 penAllocList |
| 列表筛选 | 进场日期区间、检疫证号模糊、supplier_id 精确 |
| 删除 | del_flag=2;下游引用时拒绝 |
预计解除日期:expected_release_date = DATE(entry_time) + isolation_days(自然日相加,与功能需求默认一致)。
biz_entry_isolation(入场隔离登记主表)| 字段 | 类型 | 非空 | 默认值 | 说明 |
|---|---|---|---|---|
id |
bigint(20) |
Y | 自增 | 主键 |
entry_time |
datetime |
Y | — | 进场时间 |
supplier_id |
bigint(20) |
Y | — | 关联 biz_supplier.id |
cert_file_url |
varchar(512) |
N | NULL | 检疫证访问 URL |
cert_file_path |
varchar(512) |
N | NULL | 检疫证存储路径 |
cert_no |
varchar(50) |
Y | — | 检疫证号 |
quantity |
int(11) |
Y | — | 总数量(头),正整数 |
ear_tags |
text |
Y | — | 主表耳标,逗号分隔入库 |
isolation_days |
int(11) |
Y | — | 隔离天数,1~3650 |
expected_release_date |
date |
Y | — | 预计解除日期(服务端计算) |
del_flag |
char(1) |
Y | '0' |
0 存在 2 删除 |
create_by / create_time / update_by / update_time |
若依惯例 | — | — | 审计 |
remark |
varchar(500) |
N | NULL | 备注 |
索引:PRIMARY KEY (id);KEY idx_entry_time (entry_time);KEY idx_cert_no (cert_no);KEY idx_supplier (supplier_id);KEY idx_del_flag (del_flag)。
biz_entry_isolation_alloc(分圈明细)| 字段 | 类型 | 非空 | 默认值 | 说明 |
|---|---|---|---|---|
id |
bigint(20) |
Y | 自增 | 主键 |
entry_id |
bigint(20) |
Y | — | 关联主表 id |
pen_id |
bigint(20) |
Y | — | 关联 biz_isolation_pen.id |
quantity |
int(11) |
Y | — | 本圈数量(头) |
ear_tags |
text |
Y | — | 本圈耳标,逗号分隔 |
sort_order |
int(11) |
Y | 0 |
展示排序 |
索引:PRIMARY KEY (id);KEY idx_entry_id (entry_id);UNIQUE KEY uk_entry_pen (entry_id, pen_id)(同一登记内圈位不可重复)。
说明:
pen_id冗余存储便于关联;列表/详情通过 JOIN 带出pen_code展示。
CREATE TABLE `biz_entry_isolation` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`entry_time` datetime NOT NULL COMMENT '进场时间',
`supplier_id` bigint(20) NOT NULL COMMENT '供应商ID',
`cert_file_url` varchar(512) DEFAULT NULL COMMENT '检疫证URL',
`cert_file_path` varchar(512) DEFAULT NULL COMMENT '检疫证路径',
`cert_no` varchar(50) NOT NULL COMMENT '检疫证号',
`quantity` int(11) NOT NULL COMMENT '总数量头',
`ear_tags` text NOT NULL COMMENT '耳标号逗号分隔',
`isolation_days` int(11) NOT NULL COMMENT '隔离天数',
`expected_release_date` date NOT NULL COMMENT '预计解除日期',
`del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '0存在 2删除',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `idx_entry_time` (`entry_time`),
KEY `idx_cert_no` (`cert_no`),
KEY `idx_supplier` (`supplier_id`),
KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='入场隔离登记';
CREATE TABLE `biz_entry_isolation_alloc` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`entry_id` bigint(20) NOT NULL COMMENT '登记主表ID',
`pen_id` bigint(20) NOT NULL COMMENT '圈位ID',
`quantity` int(11) NOT NULL COMMENT '本圈数量头',
`ear_tags` text NOT NULL COMMENT '本圈耳标逗号分隔',
`sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
PRIMARY KEY (`id`),
KEY `idx_entry_id` (`entry_id`),
UNIQUE KEY `uk_entry_pen` (`entry_id`,`pen_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='入场隔离分圈明细';
| 关联 | 说明 |
|---|---|
supplier_id |
biz_supplier,del_flag=0 方可选用 |
pen_id |
biz_isolation_pen,del_flag=0 方可选用 |
删除标记 del_flag(主表)
| 值 | 含义 |
|---|---|
| 0 | 正常 |
| 2 | 已逻辑删除 |
EarTagCodec)ear_tags;去空白、去重、过滤空段。earTagList(string[]);主表同时返回 earTags(原文)与 earTagList。quantity(R1)。EntryIsolationValidation)| 规则 | 实现要点 |
|---|---|
| R1 | quantity == earTagList.size() |
| R2 | sum(alloc.quantity) == quantity |
| R3 | 分圈耳标并集 = 主表耳标集合 |
| R4 | 分圈耳标无交集重复 |
| R5 | 每条 alloc.quantity == alloc.earTagList.size() |
| 其他 | 分圈 ≥1 条;pen_id 不重复;供应商/圈位有效;检疫证后缀与 30MB(上传阶段校验) |
统一响应:AjaxResult / TableDataInfo(code、msg、data / rows、total)。
权限标识:tradeMarket:entryIsolation:list|query|add|edit|remove
Base Path:/tradeMarket/entryIsolation
| # | 说明 | Method | URI | 权限 |
|---|---|---|---|---|
| 3.1 | 分页列表 | GET | /tradeMarket/entryIsolation/list |
list |
| 3.2 | 详情 | GET | /tradeMarket/entryIsolation/{id} |
query |
| 3.3 | 新增 | POST | /tradeMarket/entryIsolation |
add |
| 3.4 | 修改 | PUT | /tradeMarket/entryIsolation |
edit |
| 3.5 | 删除 | DELETE | /tradeMarket/entryIsolation/{ids} |
remove |
Query(驼峰)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum / pageSize |
int | N | 默认 1 / 20 |
entryDateStart |
string | N | yyyy-MM-dd,进场日期 ≥ |
entryDateEnd |
string | N | yyyy-MM-dd,进场日期 ≤ |
certNo |
string | N | 检疫证号模糊 LIKE %certNo% |
supplierId |
long | N | 供应商 精确 |
条件:del_flag='0';日期对 DATE(entry_time) 过滤。
排序:entry_time DESC, id DESC。
行字段(驼峰):id、entryTime、supplierId、supplierName、certNo、quantity、isolationDays、expectedReleaseDate、penAllocSummary(可选,如「3 个圈位」)+ 审计字段。
data主表全字段 + supplierName + earTagList + penAllocList:
penAllocList[] |
类型 | 说明 |
|---|---|---|
id |
long | 子表主键(修改时前端可不带,以全量覆盖为准) |
penId |
long | 圈位 ID |
penCode |
string | 圈位编号 |
quantity |
int | 本圈数量 |
earTagList |
string[] | 本圈耳标 |
earTags |
string | 逗号拼接(展示用) |
| 字段 | 新增 | 修改 | 说明 |
|---|---|---|---|
id |
— | Y | 主键 |
entryTime |
Y | Y | yyyy-MM-dd HH:mm:ss |
supplierId |
Y | Y | 有效供应商 |
certFileUrl / certFilePath |
N | N | 检疫证;有路径时校验后缀 |
certNo |
Y | Y | 1~50 字,trim |
quantity |
Y | Y | 正整数 |
earTagList |
Y | Y | 耳标数组(优先);或与 earTags 二选一,服务端统一解析 |
earTags |
N | N | 逗号分隔字符串(兼容) |
isolationDays |
Y | Y | 1~3650 |
penAllocList |
Y | Y | 至少 1 条,见下表 |
remark |
N | N | ≤500 字 |
penAllocList[]
| 字段 | 必填 | 说明 |
|---|---|---|
penId |
Y | 圈位 ID,同登记内不可重复 |
earTagList |
Y | 本圈耳标,≥1;须属于主表耳标集合 |
quantity由服务端按earTagList.size()写入子表,可不传或传了也以服务端为准(R5)。
服务端流程
EarTagCodec 规范化主表耳标 → 写 ear_tags。ReleaseDateCalculator 写 expected_release_date。entry_id 子表行后 批量插入 新分圈。DELETE /tradeMarket/entryIsolation/{ids},单条传一个 id。EntryIsolationReferenceChecker.hasReference(id) 为 true 时失败。del_flag='2';子表可保留(查询带主表 del_flag)或同步逻辑删除(默认保留子表,仅主表删)。| 项 | 规则 |
|---|---|
| 供应商 | 存在且 biz_supplier.del_flag=0 |
| 圈位 | 每条 pen_id 存在且 biz_isolation_pen.del_flag=0 |
| 检疫证文件 | 后缀 pdf,md,doc,docx,xls,xlsx,ppt,pptx;路径 /profile 前缀 |
| 修改/删除 | 主表存在且 del_flag=0 |
| 失败文案 | 与功能需求 §8 对齐,如「总数量须与耳标个数一致」 |
| 类型 | 名称 | 权限标识 |
|---|---|---|
| 菜单 | 入场隔离登记 | tradeMarket:entryIsolation:list |
| 按钮 | 查询 | tradeMarket:entryIsolation:query |
| 按钮 | 新增 | tradeMarket:entryIsolation:add |
| 按钮 | 修改 | tradeMarket:entryIsolation:edit |
| 按钮 | 删除 | tradeMarket:entryIsolation:remove |
组件路径:tradeMarket/entryIsolation/index(「交易市场平台」目录下)。
sql/biz_entry_isolation.sql、菜单权限 SQLtrading 包)EntryIsolationValidation、EarTagCodec、ReleaseDateCalculator| 版本 | 说明 |
|---|---|
| 1.0 | 初稿:主表+分圈子表、R1~R5、接口 CRUD;对齐功能需求与 RuoYi/MySQL 5.7 |