依据:同目录
养殖产业数据功能需求.md。本期为只读看板:全页指标由既有台账聚合计算,无业务台账 CRUD、无第三方同步接口。
| 项 | 说明 |
|---|---|
| 后端 | RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 | MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 | 若依 Vue2;见 养殖产业数据前端技术方案.md |
| 时区 | Asia/Shanghai(自然年、统计日、预警时间范围) |
分层:Controller → IBreedingIndustryDashboardService(口径编排、数据权限)→ BreedingIndustryStatsMapper(聚合 SQL)→ 既有 biz_* 表。
代码位置(建议):baqing-admin → com.ruoyi.web.modules.industryservice(BreedingIndustryDashboardController、BreedingIndustryStatsMapper、VO)。
| 场景 | 行为 |
|---|---|
| 看板加载/刷新 | 一次请求返回四块数据;statDate 取服务器当前日期 |
| 数据权限 | Service 注入用户可见 pastureId 列表;牦牛、预警按 §2.2 过滤;草场全县台账不按牧场过滤 |
| 月末存栏趋势(档案) | 历史能力保留于 BreedingIndustryCalculator;看板趋势已改填报表,见 §2.11 |
| 存栏变动/年龄/趋势 | 复用 HomeScreenStatsMapper + HomeScreenSupport;按所选年最大填报月与 1~N 月趋势,与大屏首页一致 |
| 性能 | 数据量大时启用 §2.3 可选快照表 + 短 TTL 缓存;本期可先实时聚合;月末 12 点目标 ≤3s(1 万级档案,评审可调) |
依赖模块(只读)
| 表 | 模块 |
|---|---|
biz_pasture |
牧场管理 |
biz_grassland |
草场管理 |
biz_yak_asset |
牦牛资产档案 |
biz_yak_disease_warning |
牦牛疾病预警 |
biz_yak_herd_inventory |
牦牛存栏数据填报(存栏变动、存栏结构、总览存栏) |
biz_yak_outbound_report |
牦牛出栏数据填报(总览出栏) |
biz_farmer_household |
农牧户填报(总览农牧户、草场面积) |
本模块不新增业务台账表;指标均通过对上表 SELECT 聚合 得到,口径以功能需求 §2 为准。
biz_pasture(牧场数量)| 指标 | SQL 条件要点 |
|---|---|
| 牧场数量 | del_flag='0' AND biz_status=1 AND id IN (可见牧场ID集合) |
biz_grassland(草场数量、面积、可用/使用中、退化占比)| 指标 | SQL 条件要点 |
|---|---|
| 草场数量 | del_flag='0' |
| 草场面积 | SUM(area_mu),area_mu IS NOT NULL |
| 可用草场 | del_flag='0' AND degradation_level IN (1,2)(1未退化 2轻度) |
| 使用中草场 | del_flag='0' AND (utilization_type IN (2,3) OR (utilization_type=1 AND 统计日 NOT BETWEEN grazing_ban_start_date AND grazing_ban_end_date)) |
| 退化分组 | GROUP BY degradation_level(1~5) |
枚举(与草场管理一致)
| 字段 | 值 | 含义 |
|---|---|---|
degradation_level |
1~5 | 未退化、轻度、中度、重度、极重度 |
utilization_type |
1/2/3 | 禁牧、轮牧、全年放牧 |
biz_yak_asset(存栏、出栏、性别、年龄、月趋势)| 指标 | SQL 条件要点 |
|---|---|
| 当前存栏 | del_flag='0' AND pasture_id IN (...) AND pasture_id IS NOT NULL AND asset_status=1 |
| 年出栏 | 同上牧场范围 AND asset_status=4 AND status_change_date 在当年且 ≤ 统计日 AND status_change_date IS NOT NULL |
| 公牛/母牛 | 在存栏集合上 gender='公' / gender='母' |
| 未标注性别 | 存栏总量 − 公牛 − 母牛 |
| 年龄分档 | 在存栏集合上按 age_months(或 birth_date 计算月龄)分 0~6、7~12、≥13 |
| 月末存栏 | 对每条档案用 §2.2 月末存栏判定(见下),非仅 asset_status=1 |
asset_status:1 正常 2 死淘 3 丢失 4 出栏。
月末时点计入存栏(单头判定,记月末日为 M)
计入 ⇔ del_flag='0'
AND pasture_id IN (可见牧场)
AND pasture_id IS NOT NULL
AND NOT (asset_status IN (2,3,4) AND status_change_date IS NOT NULL AND status_change_date <= M)
AND asset_status 可识别(1 或 2/3/4 且 change_date > M)
当前月:M 替换为 统计日。
biz_yak_disease_warning(预警牦牛数量)-- 口径示意:当年 1/1 0:00 ~ 统计日 23:59:59,去重 yak_no,牦牛须在纳入集合内
SELECT COUNT(DISTINCT w.yak_no)
FROM biz_yak_disease_warning w
INNER JOIN biz_yak_asset y ON y.yak_no = w.yak_no AND y.del_flag = '0'
WHERE w.alert_time >= ? AND w.alert_time <= ?
AND y.pasture_id IN (...)
AND y.pasture_id IS NOT NULL;
biz_breeding_dashboard_cache(性能优化)数据量较大或刷新慢时启用;非本期必建。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint(20) |
主键 |
scope_key |
varchar(64) |
权限范围键,如 all 或 user:{userId} |
stat_date |
date |
统计日 |
payload_json |
mediumtext |
看板完整 JSON(与 §3.2 data 结构一致) |
expire_time |
datetime |
过期时间 |
create_time |
datetime |
写入时间 |
索引:UNIQUE uk_scope_stat (scope_key, stat_date)。
刷新时:先查未过期缓存命中则直接返回;否则实时计算后 UPSERT。TTL 建议 5~15 分钟(可配置)。
若统计偏慢,确认已存在(sql/biz_yak_asset.sql 等已含大部分):
| 表 | 建议索引 |
|---|---|
biz_yak_asset |
(pasture_id, del_flag, asset_status)、status_change_date |
biz_yak_disease_warning |
(alert_time)、(yak_no, alert_time) |
biz_grassland |
(del_flag, degradation_level)、(del_flag, utilization_type) |
biz_pasture |
(del_flag, biz_status) |
CREATE TABLE IF NOT EXISTS `biz_breeding_dashboard_cache` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`scope_key` varchar(64) NOT NULL COMMENT '权限范围键',
`stat_date` date NOT NULL COMMENT '统计日',
`payload_json` mediumtext NOT NULL COMMENT '看板JSON',
`expire_time` datetime NOT NULL COMMENT '过期时间',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_scope_stat` (`scope_key`,`stat_date`),
KEY `idx_expire_time` (`expire_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='养殖产业看板缓存(可选)';
与「牦牛疾病预警」列表一致:聚合前解析可见牧场 ID 集合 allowedPastureIds,传入 BreedingIndustryStatsMapper 的 IN (...) 条件(牦牛、预警、牧场数量);草场统计不加牧场条件。
建议类:com.ruoyi.web.modules.industryservice.support.BreedingIndustryPastureScope(或复用后续统一的 IndustryPastureScopeHelper)。
| 步骤 | 说明 |
|---|---|
| 1 | 查询 biz_pasture:del_flag='0' AND biz_status=1,得到候选 ID 列表 |
| 2 | 按当前登录用户应用项目数据权限(部门/角色自定义范围,与预警 allowedPastureIds 同源);县级全量角色得到全部候选 ID |
| 3 | 将结果写入统计上下文 BreedingIndustryStatsContext.allowedPastureIds |
三种语义(实现须区分)
allowedPastureIds |
牦牛 / 预警 / 牧场数 | 草场 |
|---|---|---|
null(未限制,全量管理员) |
候选列表 = 步骤 1 全部正常牧场 ID | 全县 del_flag=0 |
| 非空列表 | pasture_id IN (...) 且 pasture_id IS NOT NULL |
不变 |
空列表 [](有权限框架但无可见牧场) |
牦牛类、预警、牧场数 均为 0 | 仍全县统计 |
Controller 示例
List<Long> allowed = pastureScope.resolveAllowedPastureIds();
return success(dashboardService.loadDashboard(allowed, forceRefresh));
Mapper 约定:与 BizYakDiseaseWarningMapper.xml 相同写法——仅当 allowedPastureIds != null && size > 0 时追加 pasture_id in (...);全量管理员传完整 ID 列表(勿传 null 跳过牦牛过滤,以免误统计 pasture_id 为空的档案)。
预警:biz_yak_disease_warning 与 biz_yak_asset 按 yak_no 关联后,再限制 y.pasture_id IN (...)(见 §2.2 SQL)。
统一响应:AjaxResult(code / msg / data)。
权限:dataModel:breedingIndustry:query(查看与刷新共用)。
Base Path:/dataModel/breedingIndustry
本期仅 1 个业务接口;不提供 POST/PUT/DELETE 维护接口。
| # | 说明 | Method | URI | 权限 |
|---|---|---|---|---|
| 3.1 | 看板全量数据 | GET | /dashboard |
query |
前端进入页与点击「刷新」均调用 3.1。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
forceRefresh |
boolean | N | 默认 false;true 时跳过 §2.3 缓存 |
statYear |
string | N | 四位年份;空则当前自然年 |
data 结构| 节点 | 类型 | 说明 |
|---|---|---|
statDate |
string | 统计日 yyyy-MM-dd(所选年为当年则当日,历史年为 12-31) |
statYear |
int | 回显所选年 |
overview |
object | 产业总览 §3.1.3 |
inventoryChange |
object | 牦牛存栏变动 §3.1.4 |
yakInventoryStructure |
array | 牦牛存栏结构 §3.1.5(与大屏一致) |
grassland |
object | 草场类型占比 §3.1.6 |
overview| 字段 | 类型 | 说明 |
|---|---|---|
inventoryTotal |
int | 牦牛存栏总量(头);所选年最大填报月全县 yak_total |
annualOutbound |
int | 牦牛年出栏量(头);所选年最大填报月全县 yak_outbound_count |
warningYakCount |
int | 预警牦牛数量(头);§2.5 档案口径 |
pastureCount |
int | 农牧户(户);所选年最大填报月 biz_farmer_household.household_count |
grasslandCount |
int | 草场数量(个);台账块数 |
grasslandAreaMu |
decimal | 草场面积(亩);所选年最大填报月 pasture_contract_area |
inventoryChange| 字段 | 类型 | 说明 |
|---|---|---|
bullCount |
int | 公牛数量(头);所选年最大填报月全县 bull_total |
cowCount |
int | 母牛数量(头);所选年最大填报月全县 cow_total |
unknownGenderCount |
int | max(0, yak−bull−cow) |
monthlyTrend |
array | 所选年 1~填报最大月;无填报为空 |
monthlyTrend[] 元素:
| 字段 | 类型 | 说明 |
|---|---|---|
statYear |
int | 所属自然年 |
month |
int | 所属月份 1~12 |
bullCount |
int | 该月全县公牛合计;无数据为 0 |
cowCount |
int | 该月全县母牛合计;无数据为 0 |
yakInventoryStructure[]与大屏首页 yakInventoryStructure 完全一致:内环三类(BULL/COW/INSURED),外环细分(种公牛、公牛/阉畜、0~1.5岁、1.5岁以上、保险);所选年最大填报月全县合计;count=0 也返回三类。
大类字段:categoryCode、categoryLabel、count、ratio、details[]。
明细字段:detailCode、detailLabel、count、ratio。
grassland| 字段 | 类型 | 说明 |
|---|---|---|
availableCount |
int | 可用草场(个) |
inUseCount |
int | 使用中草场(个) |
degradationStats |
array | 退化等级统计 |
degradationStats[] 元素:
| 字段 | 类型 | 说明 |
|---|---|---|
degradationLevel |
int | 1~5 |
degradationLabel |
string | 未退化、轻度… |
count |
int | 个数 |
ratio |
decimal | 占比 % |
五档固定返回;count 之和应等于 overview.grasslandCount。
{
"code": 200,
"msg": "操作成功",
"data": {
"statDate": "2026-05-20",
"statYear": 2026,
"overview": {
"inventoryTotal": 120,
"annualOutbound": 8,
"warningYakCount": 5,
"pastureCount": 12,
"grasslandCount": 80,
"grasslandAreaMu": 12500.50
},
"inventoryChange": {
"bullCount": 45,
"cowCount": 60,
"unknownGenderCount": 0,
"monthlyTrend": [
{ "statYear": 2025, "month": 8, "bullCount": 40, "cowCount": 55 },
{ "statYear": 2026, "month": 5, "bullCount": 45, "cowCount": 60 }
]
},
"yakInventoryStructure": [
{
"categoryCode": "BULL",
"categoryLabel": "公牛",
"count": 45,
"ratio": 37.5,
"details": [
{ "detailCode": "BREEDING_BULL", "detailLabel": "种公牛", "count": 20, "ratio": 16.7 },
{ "detailCode": "BULL_CASTRATED", "detailLabel": "公牛/阉畜", "count": 25, "ratio": 20.8 }
]
}
],
"grassland": {
"availableCount": 50,
"inUseCount": 40,
"degradationStats": [
{ "degradationLevel": 1, "degradationLabel": "未退化", "count": 30, "ratio": 37.5 }
]
}
}
}
| 场景 | 处理 |
|---|---|
| 无查询权限 | 403 或 AjaxResult.error 无权限 |
| 聚合异常 | AjaxResult.error("加载失败,请稍后重试"),data 为空 |
| 可见牧场为空 | 牦牛类指标均为 0;草场类仍按全县统计 |
| 刷新中重复点击 | 前端防重;后端可选短锁(与资产同步类似) |
| 项 | 说明 |
|---|---|
| 月龄 | COALESCE(age_months, TIMESTAMPDIFF(MONTH, birth_date, statDate)),birth_date 空则 0 |
| 性别 | 入库值 trim 后精确匹配 公/母;第三方若写「公牛」「母牛」等,Service 层归一后再统计 |
| 存栏变动/年龄/趋势 | HomeScreenStatsMapper + HomeScreenSupport.buildRolling12MonthBullCowTrend / buildCowAgeStructureFromHerdReport;BreedingIndustryDashboardSupport 做 VO 转换 |
| 总览填报三项 | overview.inventoryTotal / annualOutbound / pastureCount 取各表最近填报年月全县合计 |
| 预警 | 仍用 biz_yak_asset + biz_yak_disease_warning,按 §2.9 可见牧场过滤 |
| 比率 | ratio = count * 100.0 / NULLIF(total, 0),分母为 0 时 ratio=0 |
| 月末性能 | 优先 1 条 SQL + CASE WHEN 按月末分组,或 Java 循环 12 次;超过 3s 启用 §2.3 缓存 |
| 日志 | 看板接口可 @Log(title="养殖产业数据", businessType=OTHER) 或仅记录慢查询 |
前端:见同目录 养殖产业数据前端技术方案.md。
| 类型 | 名称 | 权限标识 |
|---|---|---|
| 目录/菜单 | 养殖产业数据 | dataModel:breedingIndustry:query |
| 按钮 | 刷新(与查看共用) | dataModel:breedingIndustry:query |
组件路径:livestockIndustry/breedingIndustry/index(挂载「产业数据模型」或同级目录,与菜单配置一致)。
sys_menu 示例(menu_id 按环境递增)
-- 父菜单 parent_id 替换为「产业数据模型」实际 ID
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
VALUES ('养殖产业数据', {parentId}, 10, 'breedingIndustry', 'livestockIndustry/breedingIndustry/index', 1, 0, 'C', '0', '0', 'dataModel:breedingIndustry:query', 'chart', 'admin', sysdate(), '养殖产业看板');
本期无 add/edit/remove/sync 按钮权限。
| 功能需求 | 技术落点 |
|---|---|
| §5.2 产业总览 | overview + §2.2 SQL |
| §5.3 存栏变动 | inventoryChange + 所选年 1~N 月趋势(与大屏一致) |
| §5.4 牦牛存栏结构 | yakInventoryStructure 双层饼(与大屏一致;默认当前年) |
| §5.5 草场占比 | grassland |
| §5.1 刷新 | 3.1 forceRefresh |
| §2.9 数据权限 | §2.6 BreedingIndustryPastureScope(仅预警等档案类指标) |
| §2.5 预警 | §2.2 warning SQL |
| 版本 | 日期 | 说明 |
|---|---|---|
| 1.5 | 2026-07-24 | 看板「年龄结构」改为 yakInventoryStructure,与大屏牦牛存栏结构一致 |
| 1.4 | 2026-07-24 | 产业总量/存栏变动/年龄与大屏按所选年对齐;默认当前年;农牧户与草场面积改农牧户填报 |
| 1.3 | 2026-07-17 | 年龄结构两档 COW_YOUNG/COW_ADULT |
| 1.2 | 2026-07-04 | 存栏变动/年龄/趋势改 biz_yak_herd_inventory 填报表;滚动 12 月;与大屏字段对齐 |
| 1.1 | (既有) | 总览三项改填报合计 |