依据:同目录
牦牛资产档案管理功能需求.md。档案 列表/详情只读 + 第三方同步写入;本期无手工增删改接口。
| 项 | 说明 |
|---|---|
| 后端 | RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 | MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 | 若依 Vue2(本方案不展开) |
| 第三方 | HTTP/RPC 客户端(RestTemplate / OkHttp 等,实现期选型);配置项:地址、鉴权、超时 |
| 关联主数据 | biz_pasture(牧场,可选 pasture_id 映射) |
分层:Controller → LivestockFinanceMasterSyncService(全量编排)→ 各 *SyncService / *SyncTxService → Mapper/XML → domain;IoT 数据由 IotDataIncrementalSyncTask 定时触发,不经列表页「同步」按钮。
代码位置:baqing-admin → com.ruoyi.web.modules.industryservice。
业务摘要
| 场景 | 行为 |
|---|---|
| 同步(手动) | POST /dataModel/yakAsset/sync 触发五段基础全量:养殖场→圈舍→生产计划→批次→入栏建档;不含 IoT |
| IoT 同步(定时) | 每日 凌晨 1:00 Quartz 任务;称重/定位项圈/环境监测;见 §3.9 |
| 列表/详情 | del_flag='0';排序 status_change_date DESC, id DESC(或与 last_sync_time 统一) |
| 月龄 | 列表/详情可展示库字段;同步时可写入,亦可用 birth_date 现场计算 |
| 删除 | 第三方下架策略默认不物理删除:仅更新状态或 del_flag(若第三方提供「离场」状态则映射为已出售/死亡等);全量对账删除须评审 |
biz_yak_asset(牦牛资产档案)| 字段 | 类型 | 非空 | 说明 |
|---|---|---|---|
id |
bigint(20) |
Y | 主键 |
external_id |
bigint(20) |
N | 第三方牛只 ID(OpenYakEntryDto.cattleId),唯一 |
yak_no |
varchar(64) |
Y | 场内牛只编号(OpenYakEntryDto.cattleNo),唯一 |
ear_tag_number |
varchar(64) |
N | 耳标编号(OpenYakEntryDto.earTagNumber) |
pasture_id |
bigint(20) |
N | 关联 biz_pasture.id(映射成功时) |
pasture_name |
varchar(128) |
N | 所属牧场名称(同步冗余展示) |
farm_external_id |
bigint(20) |
N | 第三方养殖场 ID(farmId) |
enclosure_external_id |
bigint(20) |
N | 第三方圈舍 ID(farmEnclosureId) |
enclosure_id |
bigint(20) |
N | 本地圈舍 biz_farm_enclosure.id |
enclosure_name |
varchar(128) |
N | 圈舍名称 |
batch_no |
varchar(64) |
N | 批次编号;由 batch_external_id 关联 biz_farming_batch.batch_no |
batch_external_id |
bigint(20) |
N | 第三方养殖批次 ID(batchId) |
batch_id |
bigint(20) |
N | 本地养殖批次 biz_farming_batch.id |
entry_cycle |
varchar(64) |
N | 入栏周期(entryCycle) |
gender |
varchar(16) |
N | 性别 |
cattle_variety |
varchar(128) |
N | 牛只品种 |
cattle_picture |
varchar(512) |
N | 牛只图片 URL |
registrant |
varchar(64) |
N | 登记人 |
remark |
varchar(500) |
N | 备注 |
birth_date |
date |
N | 出生日期 |
age_months |
int(11) |
N | 月龄(月) |
entry_date |
datetime |
N | 入栏时间(OpenYakEntryDto.entryTime) |
entry_weight_kg |
decimal(10,2) |
N | 入栏体重 kg |
source |
varchar(64) |
N | 来源 |
breeding_method |
varchar(64) |
N | 养殖方式 |
asset_status |
tinyint(4) |
Y | 资产状态 §2.6 |
status_change_date |
date |
N | 变更日期 |
status_change_reason |
varchar(256) |
N | 状态变更原因 |
pen_location |
varchar(128) |
N | 圈舍位置 |
expected_out_date |
date |
N | 预计出栏日期 |
supplement_plan |
varchar(512) |
N | 补饲方案 |
realtime_temp |
decimal(6,2) |
N | 实时体温 ℃ |
realtime_steps |
int(11) |
N | 实时运动量 |
env_temp |
decimal(6,2) |
N | 环境温度 ℃(详情当前值) |
location |
varchar(256) |
N | 位置 |
physio_collect_time |
datetime |
N | 生理快照采集时间 |
father_yak_no |
varchar(64) |
N | 父亲编号 |
mother_yak_no |
varchar(64) |
N | 母亲编号 |
last_sync_time |
datetime |
N | 最近同步时间 |
del_flag |
char(1) |
Y | 0 存在 2 删除 |
create_time / update_time |
datetime | — | 审计 |
索引:UNIQUE uk_external_id (external_id);UNIQUE uk_yak_no (yak_no);KEY idx_asset_status;KEY idx_pasture_id;KEY idx_status_change_date;KEY idx_last_sync_time;KEY idx_del_flag。
OpenYakEntryDto → biz_yak_asset)| OpenAPI 字段 | 库字段 | 说明 |
|---|---|---|
cattleId |
external_id |
同步 upsert 主键 |
cattleNo |
yak_no |
场内牛只编号 |
earTagNumber |
ear_tag_number |
耳标编号 |
farmId |
farm_external_id / pasture_id |
前者直存;后者经 biz_pasture.external_id 解析 |
farmName |
pasture_name |
冗余展示 |
farmEnclosureId |
enclosure_external_id / enclosure_id |
后者经 biz_farm_enclosure.external_id 解析 |
farmEnclosureName |
enclosure_name / pen_location |
兼容保留 pen_location |
batchId |
batch_external_id / batch_id / batch_no |
batch_id、batch_no 经 biz_farming_batch.external_id 解析 |
entryCycle |
entry_cycle |
|
farmLocation |
location |
|
cattleSex |
gender |
归一公/母 |
cattleSource |
source |
|
cattleVariety |
cattle_variety |
|
cattlePicture |
cattle_picture |
|
registrant |
registrant |
|
fatherNumber |
father_yak_no |
|
motherNumber |
mother_yak_no |
|
weight |
entry_weight_kg |
当前体重 |
entryTime |
entry_date |
|
birthDate |
birth_date |
月龄由同步时计算写入 age_months |
remark |
remark |
列表接口未返回的字段(asset_status、实时体温/运动量等)保持库内原值或默认「正常」。
biz_yak_physio_series(生理时序,曲线图)| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint(20) |
主键 |
yak_asset_id |
bigint(20) |
关联主表 |
collect_time |
datetime |
采集时间 |
body_temp |
decimal(6,2) |
体温 ℃ |
steps |
int(11) |
运动量 |
env_temp |
decimal(6,2) |
环境温度 ℃ |
索引:KEY idx_yak_collect (yak_asset_id, collect_time)。
biz_yak_growth_record(生长性状)| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint(20) |
主键 |
yak_asset_id |
bigint(20) |
关联主表 |
day_age |
int(11) |
日龄(天) |
weight_kg |
decimal(10,2) |
体重 |
height_cm |
decimal(10,2) |
体高 |
chest_cm |
decimal(10,2) |
胸围 |
length_cm |
decimal(10,2) |
体长 |
collect_time |
datetime |
采集时间 |
data_kind |
tinyint(4) |
1 实测 2 预测 |
索引:KEY idx_yak_growth (yak_asset_id, collect_time)。
biz_yak_reproduction_record(繁殖性能)| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint(20) |
主键 |
yak_asset_id |
bigint(20) |
关联主表 |
day_age |
int(11) |
日龄 |
parity |
int(11) |
胎次 |
calving_interval_days |
int(11) |
产犊间隔(天) |
calf_count |
int(11) |
产犊数量(头) |
calf_survival_rate |
decimal(6,4) |
犊牛成活率 0~1 |
calf_birth_weight_kg |
decimal(10,2) |
犊牛出生体重 |
dystocia_flag |
char(1) |
0 否 1 是 |
索引:KEY idx_yak_repro (yak_asset_id, parity)。
biz_yak_feeding_record(饲喂数据)| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint(20) |
主键 |
yak_asset_id |
bigint(20) |
关联主表 |
start_day_age |
int(11) |
开始日龄 |
end_day_age |
int(11) |
结束日龄 |
daily_supplement_kg |
decimal(10,2) |
日补饲量 kg |
feed_type |
varchar(64) |
饲料类型 |
索引:KEY idx_yak_feeding (yak_asset_id)。
biz_yak_pen_rel / biz_yak_batch_rel圈舍、批次信息已合并入主表字段 pen_location、batch_no;上述关联子表已废弃删除。
| 表名 | 第三方接口 | 唯一键 | DDL |
|---|---|---|---|
biz_yak_weighing_record |
GET /open-api/v1/iot/weighings |
external_id |
sql/biz_yak_weighing_record.sql |
biz_yak_weighing_record 字段映射:earTagNumber→ear_tag_number,cattleNo 参与 yak_no 与资产关联解析;cattleId→cattle_external_id,farmId/enclosureId/weight/weighingTime 等按接口落库。
| biz_yak_ear_tag_record | GET /open-api/v1/iot/ear-tags | external_id | sql/biz_yak_ear_tag_record.sql |
biz_yak_ear_tag_record 字段映射:earTagNumber→ear_tag_number,cattleNo 参与 yak_no 与资产关联解析;actualTemperature/temperature/steps/reportTime 同名落库。
| biz_yak_collar_location | GET /open-api/v1/iot/collar-locations | (yak_no, report_time) | sql/biz_yak_collar_location.sql |
| biz_env_monitoring_record | GET /open-api/v1/iot/env-monitoring | external_id | sql/biz_env_monitoring_record.sql |
关联解析:称重/项圈可关联 biz_yak_asset(优先 cattleId→external_id,其次 earTagNumber→ear_tag_number,再次 cattleNo→yak_no);环境/称重可关联 biz_pasture、biz_farm_enclosure。
asset_status| 值 | 含义 |
|---|---|
1 |
正常 |
2 |
死淘 |
3 |
丢失 |
4 |
出栏 |
第三方旧码(如在养/死亡/已出售等)由 YakAssetStatusMapper 归一;存量库执行 sql/biz_yak_asset_migrate_v2.sql。
data_kind(生长):1 实测,2 预测。
CREATE TABLE `biz_yak_asset` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`yak_no` varchar(64) NOT NULL COMMENT '牦牛编号',
`pasture_id` bigint(20) DEFAULT NULL,
`pasture_name` varchar(128) DEFAULT NULL,
`batch_no` varchar(64) DEFAULT NULL,
`gender` varchar(16) DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`age_months` int(11) DEFAULT NULL,
`entry_date` datetime DEFAULT NULL,
`entry_weight_kg` decimal(10,2) DEFAULT NULL,
`source` varchar(64) DEFAULT NULL,
`breeding_method` varchar(64) DEFAULT NULL,
`asset_status` tinyint(4) NOT NULL DEFAULT '1',
`status_change_date` date DEFAULT NULL,
`realtime_temp` decimal(6,2) DEFAULT NULL,
`realtime_steps` int(11) DEFAULT NULL,
`env_temp` decimal(6,2) DEFAULT NULL,
`location` varchar(256) DEFAULT NULL,
`physio_collect_time` datetime DEFAULT NULL,
`father_yak_no` varchar(64) DEFAULT NULL,
`mother_yak_no` varchar(64) DEFAULT NULL,
`last_sync_time` datetime DEFAULT NULL,
`del_flag` char(1) NOT NULL DEFAULT '0',
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_yak_no` (`yak_no`),
KEY `idx_asset_status` (`asset_status`),
KEY `idx_status_change_date` (`status_change_date`),
KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牦牛资产档案';
-- 子表及迁移见 sql/biz_yak_asset.sql、sql/biz_yak_asset_migrate_v2.sql
统一响应:AjaxResult / TableDataInfo。
权限:dataModel:yakAsset:list|query|sync
Base Path:/dataModel/yakAsset
| # | 说明 | Method | URI | 权限 | 要点 |
|---|---|---|---|---|---|
| 3.1 | 分页列表 | GET | /dataModel/yakAsset/list |
list |
Query 3.1.1 |
| 3.2 | 档案详情 | GET | /dataModel/yakAsset/{id} |
query |
主表 + 六类子表列表 |
| 3.3 | 按编号查详情 | GET | /dataModel/yakAsset/byNo/{yakNo} |
query |
系谱跳转父/母 |
| 3.4 | 生理曲线 | GET | /dataModel/yakAsset/{id}/physioChart |
query |
Query days 默认 30 |
| 3.5 | 生长曲线 | GET | /dataModel/yakAsset/{id}/growthChart |
query |
实测+预测分 dataKind |
| 3.6 | 第三方全量同步 | POST | /dataModel/yakAsset/sync |
sync |
返回 3.6.1(五段统计;顶层 insertCount 兼容旧前端,取自入栏建档) |
本期不提供 POST/PUT/DELETE 档案维护接口。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum / pageSize |
int | N | 默认 1 / 20 |
keyword |
string | N | yak_no 模糊 |
assetStatus |
int | N | 1~4 精确 |
data)| 节点 | 内容 |
|---|---|
asset |
主表字段(驼峰,含 yakNo、pastureName、assetStatus 等) |
physioSeries |
生理时序数组(近一月可由独立接口或详情内截断) |
growthRecords |
生长列表(含 dataKind) |
reproductionRecords |
繁殖列表 |
feedingRecords |
饲喂列表 |
penRecords |
圈舍列表 |
batchRecords |
批次列表 |
| 参数 | 说明 |
|---|---|
days |
默认 30;按 collect_time 倒序取最近 N 天 |
返回序列:[{ collectTime, bodyTemp, steps, envTemp }, ...],供 ECharts 多折线。
| 参数 | 说明 |
|---|---|
metric |
可选 weight/height/chest/length,默认 weight |
返回:{ actual: [...], forecast: [...] },按 data_kind 分组。
data)编排类:LivestockFinanceMasterSyncService.syncAll()。
| 字段 | 说明 |
|---|---|
pasture / enclosure / plan / batch / yakAsset |
各步骤 { insertCount, updateCount, failCount, failMessages?, syncTime } |
insertCount / updateCount / failCount |
兼容旧前端:取值自 yakAsset 步骤(入栏建档头数) |
syncTime |
本次全量同步开始时间 |
同步顺序:biz_pasture → biz_farm_enclosure → biz_farming_plan → biz_farming_batch → biz_yak_asset。
IoT 三类数据不在此接口内执行,见 §3.9。
| 项 | 说明 |
|---|---|
| 配置 | application.yml:third-party.farming(与牧场管理同源) |
| 接口 | GET /open-api/v1/farming/entry-filings;分页 OpenApiPageResult<OpenYakEntryDto> |
| 客户端 | ThirdPartyYakClientImpl → YakEntryOpenApiMapper.toBundles() → YakAssetBundleSyncTxService |
| 映射 | 字段对照 §2.1.1;YakAssetStatusMapper 供后续含状态字段的接口 |
| 牧场 | farmId → biz_pasture.external_id;失败则仅写 farmName |
| 事务 | 每头牦牛独立事务(REQUIRES_NEW);子表仅当 bundle 携带对应列表时覆盖 |
| Stub | thirdparty/stub-yak-entries.json(OpenAPI 记录样例) |
| 并发 | 全量编排 syncLock;各子步骤 AtomicBoolean 防重入 |
del_flag = '0'。status_change_date DESC, id DESC。collect_time 或业务字段倒序。| 项 | 说明 |
|---|---|
| 触发 | Quartz:iotDataIncrementalSyncTask.syncIncremental |
| Cron | 0 0 1 * * ?(每天凌晨 1:00) |
| 初始化 SQL | sql/biz_sys_job_iot_data_incremental_sync.sql(sys_job + sys_config 水印) |
| 编排 | IotDataIncrementalSyncService → YakWeighingSyncService / YakEarTagSyncService / YakCollarLocationSyncService / EnvMonitoringSyncService |
| 配置 | 同源 third-party.farming(base-url、app-key、app-secret、mode=http\|stub) |
| 水印 | sys_config.third_party.iot.last_sync_time;增量时作为 updatedAfter;任务成功后更新 |
全量 / 增量策略(按表独立)
本地表行数 count(*) |
模式 | HTTP 查询参数 |
|---|---|---|
| = 0(表已清空) | 全量 | 不传 startTime / endTime / updatedAfter,分页拉取全部 |
| > 0 | 增量 | startTime = 最大事件时间 − 5 分钟;endTime = 当前;updatedAfter = 配置水印 |
行数统计不按 del_flag 过滤;仅 TRUNCATE/DELETE 清空整表后才会对该表走全量。
Stub 样例:thirdparty/stub-iot-weighings.json、stub-iot-ear-tags.json、stub-iot-collar-locations.json、stub-iot-env-monitoring.json。
日志:任务开始/结束写入应用日志;结束行输出 IotDataIncrementalSyncResultVo JSON。
| 类型 | 名称 | 权限标识 |
|---|---|---|
| 菜单 | 牦牛资产档案 | dataModel:yakAsset:list |
| 按钮 | 查询 | dataModel:yakAsset:query |
| 按钮 | 同步 | dataModel:yakAsset:sync |
组件路径:livestockFinance/yakAsset/index(挂载「牧业金融 · 生物资产」目录下)。
sql/biz_yak_asset.sql(主表 + 4 子表 + 可选同步日志表)LivestockFinanceMasterSyncService、IoT IotDataIncrementalSyncTasksql/biz_yak_weighing_record.sql 等 IoT 三表 + sql/biz_sys_job_iot_data_incremental_sync.sqlThirdPartyYakClient、YakAssetSyncServiceBizYakAsset Domain / Mapper / IYakAssetService / BizYakAssetController| 版本 | 说明 |
|---|---|
| 1.0 | 初稿:主表+四子表;只读查询+同步接口;生长实测/预测分 data_kind;对接可配置 |
| 1.1 | 对齐入栏建档 OpenAPI:OpenYakEntryDto、external_id、分页拉取、字段映射 §2.1.1 |
| 1.2 | 全量同步扩展为五段编排;IoT 三表独立定时同步 §2.7、§3.9;全量/增量按表 count(*) 判断 |