大屏 — 首页统计 — 技术方案
依据:同目录 大屏首页功能需求.md;数据来自养殖产业、流通交易、服务预约、补贴发放、养殖标准五类子表、科技资源与实战培训等既有表。本模块为大屏只读看板,无业务台账 CRUD。
1. 技术架构
| 项 |
说明 |
| 后端 |
RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 |
MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 |
大屏独立首页;切换 statYear 拉看板主数据,养殖标准分页单独请求 |
| 代码包 |
com.ruoyi.web.modules.screen(HomeScreenController / IHomeScreenService / vo / support) |
分层:Controller → IHomeScreenService(口径编排、按 Y 计算统计日)→ 扩展 Mapper / 复用 BreedingIndustryStatsMapper + BreedingIndustryCalculator(只读)。
| 场景 |
行为 |
进入 / 切换 statYear |
调用 §3.1 + §3.2(pageNum=1) |
| 标准列表翻页 / 切 Tab |
仅 §3.2 |
| 数据权限 |
全县聚合:牦牛、牧场取全部 biz_status=1 且 del_flag=0 的牧场 ID(与疫病风险大屏一致,不按登录用户牧场过滤);草场全县 del_flag=0 |
| 统计日 |
Y = 当前年 → statDate = 今日;Y 为历史年 → statDate = Y-12-31(时点、月末还原、年出栏上界均据此) |
| 主数据三项 |
供应商 / 承销商 / 交易市场实时快照,不随 statYear 变 |
| 按月图表 |
横轴固定 12 月;缺月、当前年未来月均为 0 |
| 性能 |
默认实时聚合;可选 §2.3 缓存表 |
依赖表(只读)
| 表 |
用途 |
biz_yak_asset / biz_pasture / biz_grassland |
产业总览、存栏趋势、年龄结构、出栏、草场 |
biz_supplier / biz_distributor / biz_trade_market |
流通主数据条数(实时) |
biz_service_appointment |
线下服务预约 |
biz_subsidy_grant_record |
惠农补贴 |
biz_breeding_standard 等 5 张标准表 |
养殖标准分页列表 |
biz_tech_resource |
视频课程(004008) |
biz_practical_training |
实战培训场次与报名趋势 |
2. 数据库设计
2.1 本模块业务表
无新增业务台账表。 DDL 以各业务 sql/*.sql 为准。
2.2 公共参数
记 statYear = Y,statDate 见 §1。
| 边界 |
表达式 |
| 年区间起 |
Y-01-01 00:00:00 |
| 年区间止(年内累计) |
Y 为当前年:statDate 23:59:59;历史年:Y-12-31 23:59:59 |
| 按月分组键 |
MONTH(日期字段),应用层补全 1~12 |
2.3 可选表 biz_home_screen_cache(性能优化)
非本期必建。
| 字段 |
类型 |
说明 |
id |
bigint(20) |
主键 |
stat_year |
int(11) |
统计年份 |
payload_json |
mediumtext |
§3.1 响应 JSON(不含标准分页列表) |
expire_time |
datetime |
过期时间 |
create_time |
datetime |
写入时间 |
索引:UNIQUE uk_stat_year (stat_year)。TTL 建议 1~5 分钟。
2.4 查询口径(按表)
养殖产业(对齐《养殖产业数据技术方案》§2.2,按 Y + statDate)
实现复用 BreedingIndustryStatsMapper、BreedingIndustryCalculator;大屏传入全县 allowedPastureIds(全部正常牧场 ID)。
| 指标 |
要点 |
| 存栏 / 公母牛 / 年龄结构 |
statDate 时点;asset_status=1,pasture_id 非空且在可见牧场内 |
| 年出栏 |
asset_status=4,status_change_date 在 §2.2 年区间 且非空 |
| 按月存栏趋势 |
每月末 M(当前月用 statDate);公牛、母牛两系列(gender 公/母),非总量一条线 |
| 按月出栏 |
status_change_date 落在该自然月 |
| 年龄分档 |
M1_6 / M7_12 / M13_PLUS(与养殖产业看板编码一致,对应需求 1~6 / 7~12 / 12 月龄以上) |
| 牧场数 |
del_flag=0 AND biz_status=1 |
| 草场 |
del_flag=0;面积 SUM(area_mu);可用/使用中/退化分组同养殖产业 |
首页不含预警牦牛;不查 biz_yak_disease_warning。
流通主数据(实时,与 Y 无关)
| 表 |
指标 |
条件 |
biz_supplier |
供应商数 |
del_flag='0' |
biz_distributor |
承销商数 |
del_flag='0' |
biz_trade_market |
交易市场数 |
del_flag='0' AND operate_status=1 |
服务预约 biz_service_appointment
| 项 |
条件 |
| 按年 |
appoint_date >= Y-01-01 AND appoint_date <= Y-12-31 |
| 状态 |
status NOT IN (2,3)(排除已拒绝、已取消);表无 del_flag |
| 分类 |
provider_type:1 兽医 → 展示「兽医人员」;3 专家 →「专家人员」;2 机构 →「诊疗机构」 |
| 统计 |
每条记录计 1 人次;年度卡片为三类合计;按月 GROUP BY MONTH(appoint_date), provider_type |
补贴发放 biz_subsidy_grant_record
| 项 |
条件 |
| 按年 |
grant_date 在 Y 年内(含起止日) |
| 分组 |
subsidy_type:1 农业生产、2 住房基建、3 民生保障 |
| 指标 |
SUM(subsidy_amount);服务端换算 万元(÷10000,保留 2 位小数) |
农技课堂
| 指标 |
表 |
条件 |
| 课程视频数 |
biz_tech_resource |
del_flag='0' AND publish_status=1 AND resource_type='004008' AND publish_time 落在 Y 年 |
| 实战培训场次 |
biz_practical_training |
del_flag='0' AND publish_status=1 AND publish_time 落在 Y 年 |
| 培训内容合计 |
— |
视频数 + 场次数(应用层相加) |
实战培训报名趋势 biz_practical_training
| 系列 |
条件 |
| 活动数/月 |
del_flag='0' AND publish_status=1 AND YEAR(training_time)=Y AND MONTH(training_time)=m → COUNT(*) |
| 报名人数/月 |
同上月的培训行,SUM(actual_enrolled_count) |
| 无培训 |
hasTrainingData=false(§3.1),前端走空态,不强行全 0 曲线 |
养殖标准(分页,§3.2)
纳入:publish_status=1;DATE(create_time) 落在 Y 年内(与功能需求 §2.9 一致)。
Tab → 物理表与 standard_type 白名单
category(请求枚举) |
表 |
standard_type IN |
BREEDING_MGMT |
biz_breeding_standard |
001001,001002,001003,001004 |
FEEDING |
biz_feeding_standard |
001005,001006 |
EQUIPMENT |
biz_equipment_work_standard |
001007,001008,001009,001010 |
TREATMENT |
biz_epidemic_treatment_standard |
001013 |
GROWTH |
biz_growth_slaughter_standard |
001011,001012 |
排序:create_time DESC, id DESC。
2.5 索引建议(既有表)
| 表 |
建议 |
biz_yak_asset |
(pasture_id, del_flag, asset_status)、status_change_date |
biz_service_appointment |
沿用 idx_appoint_date、idx_provider |
biz_subsidy_grant_record |
沿用 idx_grant_date、idx_subsidy_type |
biz_tech_resource |
(resource_type, publish_status, publish_time) |
biz_practical_training |
沿用 idx_training_time、idx_publish |
各 biz_*_standard |
沿用 idx_create_time、idx_type |
2.6 Mapper 扩展(建议)
| Mapper |
方法 |
说明 |
BreedingIndustryStatsMapper |
(复用 + 可选新增) |
countMonthlyOutboundByMonth、selectYakSnapshotsInScope 等;按月公/母牛趋势在 Service 用快照 + BreedingIndustryCalculator |
BizSupplierMapper / BizDistributorMapper / BizTradeMarketMapper |
countForScreen() |
主数据条数 |
BizServiceAppointmentMapper |
selectStatsByYear(int y) |
返回 appoint_date、provider_type 明细或按月聚合行 |
BizSubsidyGrantRecordMapper |
sumAmountByTypeForYear(int y) |
三类金额 |
BizTechResourceMapper |
countPublishedVideoByYear(int y) |
004008 |
BizPracticalTrainingMapper |
countPublishedByYear / selectPublishedByYear |
场次与按月趋势 |
HomeScreenStandardMapper |
selectListForScreen(category, y, ...) |
按 §2.4 Tab 路由到对应表 |
禁止大屏单独实现一套牦牛月末还原公式;须调用 BreedingIndustryCalculator。
3. 接口设计
统一响应:AjaxResult(code / msg / data);标准列表用 TableDataInfo(rows / total)。
权限标识(示例):bigScreen:home:query
Base Path:/bigScreen/home
| # |
说明 |
Method |
URI |
权限 |
| 3.1 |
看板主数据(除标准分页外全部区块) |
GET |
/bigScreen/home/dashboard |
bigScreen:home:query |
| 3.2 |
养殖标准分页列表 |
GET |
/bigScreen/home/standards |
同上 |
前端:切换 statYear → 3.1 + 3.2(pageNum=1);仅翻页 / 切 Tab → 3.2。
3.1 看板主数据
Query
| 参数 |
类型 |
必填 |
说明 |
statYear |
string |
Y |
四位年份;非法 → 业务异常(复用 AchievementReportValidation.parseStatYear) |
forceRefresh |
boolean |
N |
默认 false;true 时跳过 §2.3 缓存 |
响应 data(顶层)
| 字段 |
类型 |
说明 |
statYear |
int |
回显 |
statDate |
string |
统计时点 yyyy-MM-dd |
availableYears |
int[] |
各业务表出现过的年份并集 + 当前年,降序 |
industryOverview |
object |
产业总览八项 §3.1.1 |
inventoryChange |
object |
存栏变动 §3.1.2 |
ageStructure |
array |
年龄结构 §3.1.3 |
outboundMonthly |
array |
出栏按月 §3.1.4 |
grassland |
object |
草场 §3.1.5 |
appointment |
object |
预约 §3.1.6 |
subsidy |
object |
补贴 §3.1.7 |
agriClassroom |
object |
农技课堂 §3.1.8 |
trainingTrend |
object |
实战培训报名 §3.1.9 |
3.1.1 industryOverview
| 字段 |
说明 |
inventoryTotal |
牦牛存栏(头),时点 |
annualOutbound |
年出栏(头),Y 年内 |
pastureCount / grasslandCount / grasslandAreaMu |
牧场、草场、面积 |
supplierCount / distributorCount / tradeMarketCount |
流通三项实时快照 |
3.1.2 inventoryChange
| 字段 |
说明 |
bullCount / cowCount / unknownGenderCount |
statDate 时点公/母/未标注 |
monthlyTrend |
固定 12 条 |
monthlyTrend[]:month(1~12)、bullCount、cowCount(该月末还原;Y 为当前年时,month > statDate.month 均为 0)。
3.1.3 ageStructure[]
| 字段 |
说明 |
bandCode |
M1_6 / M7_12 / M13_PLUS |
bandLabel |
展示名 |
count / ratio |
头数;占比 0~100 数值(如 37.5 表示 37.5%) |
三档固定返回;无存栏时 count=0,ratio=0。
3.1.4 outboundMonthly[]
| 字段 |
说明 |
month |
1~12 |
outboundCount |
该月出栏头数 |
固定 12 条;未来月规则同 §1。
3.1.5 grassland
| 字段 |
说明 |
availableCount / inUseCount |
可用 / 使用中(个) |
degradationStats[] |
degradationLevel(1~5)、degradationLabel、count、ratio(% 数值) |
五档固定返回。
3.1.6 appointment
| 字段 |
说明 |
annualVetCount / annualExpertCount / annualOrgCount |
三类年度合计 |
monthlyStacked[] |
12 条:month、vetCount、expertCount、orgCount |
3.1.7 subsidy
| 字段 |
说明 |
typeStats[] |
固定 3 条:subsidyType(1~3)、subsidyTypeName、amountWan(万元) |
hasSubsidyData |
Y 年是否存在任一条发放记录 |
3.1.8 agriClassroom
| 字段 |
说明 |
videoCourseCount |
视频课程数 |
practicalTrainingCount |
实战培训场次 |
trainingContentTotal |
二者之和 |
hasAgriData |
两项是否均为 0 |
3.1.9 trainingTrend
| 字段 |
说明 |
hasTrainingData |
Y 年是否存在已发布培训 |
monthly[] |
12 条:month、activityCount、enrolledCount |
hasTrainingData=false 时 monthly 可为 [] 或全 0(前端以 hasTrainingData 走空态)。
响应示例(节选)
{
"statYear": 2026,
"statDate": "2026-05-20",
"availableYears": [2026, 2025],
"industryOverview": {
"inventoryTotal": 120,
"annualOutbound": 8,
"pastureCount": 12,
"grasslandCount": 80,
"grasslandAreaMu": 12500.50,
"supplierCount": 5,
"distributorCount": 3,
"tradeMarketCount": 2
},
"inventoryChange": {
"bullCount": 45,
"cowCount": 60,
"unknownGenderCount": 15,
"monthlyTrend": [
{ "month": 1, "bullCount": 40, "cowCount": 55 },
{ "month": 12, "bullCount": 0, "cowCount": 0 }
]
},
"appointment": {
"annualVetCount": 10,
"annualExpertCount": 5,
"annualOrgCount": 8,
"monthlyStacked": [{ "month": 1, "vetCount": 2, "expertCount": 1, "orgCount": 0 }]
},
"trainingTrend": { "hasTrainingData": true, "monthly": [{ "month": 3, "activityCount": 1, "enrolledCount": 20 }] }
}
服务端逻辑(摘要)
1. year = parseStatYear(statYear); statDate = resolveStatDate(year)
2. allowedPastureIds = selectAllActivePastureIds() // 全县
3. industry + inventory + age + outbound + grassland = breeding 聚合(statDate, year, allowedPastureIds)
4. tradeCounts = supplier/distributor/market countForScreen() // 与 year 无关
5. appointment = appointmentMapper stats by year
6. subsidy = grantMapper sum by type; hasSubsidyData
7. agriClassroom = tech video count + training publish count by year
8. trainingTrend = training by month; hasTrainingData
9. availableYears = union(distinct years from各源表, current year)
10. return AjaxResult.success(vo)
3.2 养殖标准分页列表
Query
| 参数 |
类型 |
必填 |
说明 |
statYear |
string |
Y |
同 3.1 |
category |
string |
Y |
BREEDING_MGMT / FEEDING / EQUIPMENT / TREATMENT / GROWTH |
pageNum |
int |
N |
默认 1 |
pageSize |
int |
N |
默认 10;建议 5~10 |
响应
TableDataInfo:rows 为 §3.2.1 数组,total 为当前 Tab 下符合条件的总数。
不提供大屏专用 GET /standards/{id};行内详情字段一次返回(对齐共同富裕列表约定)。
3.2.1 rows[]
| 字段 |
类型 |
说明 |
id |
long |
标准 ID |
standardName |
string |
标准名称 |
standardType |
string |
类型编码 |
standardTypeName |
string |
类型展示名(字典/资讯类别) |
introduction |
string |
简介 |
contentFileUrl |
string |
正文附件 URL |
coverFileUrl |
string |
封面 URL,可空 |
createTime |
string |
创建时间 |
publishTime |
string |
发布时间 |
默认排序:create_time DESC, id DESC。
4. 菜单与权限(示例)
| 类型 |
名称 |
权限标识 |
| 菜单 |
大屏首页 |
bigScreen:home:query |
SQL 示例:sql/big_screen_home_perm.sql(挂载「大屏」父菜单下)。
5. 交付清单
6. 修订记录
| 版本 |
日期 |
说明 |
| 1.0 |
2026-05-20 |
初稿:无新表;双接口;对齐 大屏首页功能需求.md v1.0 |