Parcourir la Source

牦牛资产档案

wwh il y a 1 mois
Parent
commit
410f53e7bd

+ 3 - 3
doc/大屏/首页/大屏首页功能需求-草稿.md

@@ -3,9 +3,9 @@
3 3
 1. 参考 养殖产业数据、牧业疫病诊疗服务、牧业养殖科技服务、产业政策、养殖标准 等模块
4 4
 2. 以下各项为统计当前年份的数据。
5 5
 3. 产业总览包括:牦牛存栏总量(头)、牦牛年出栏量(头)、牧场数量(个)、草场数量(个)、草场面积(亩)、供应商数量(个)、承销商数量(个)、交易市场数量(个);统计当前年份的数据。
6
-4. 牦牛存栏变动:包括公牛数量(头)、母牛数量(头)两个维度,按月统计牦牛存栏数量的变动趋势
7
-5. 牦牛年龄结构:统计1-6月龄、7-12月龄、12月龄以上3个阶段的占比
8
-6. 牦牛出栏统计:按月统计牦牛出栏的数量,柱状图展示
6
+4. 牦牛存栏变动:包括公牛数量(头)、母牛数量(头)两个维度,按最近 12 个自然月统计全县填报合计变动趋势;横轴仅显示月份,悬停显示年月
7
+5. 牦牛年龄结构:统计母牛 1岁以下、1~3岁、3~12岁、12岁以上 4 个阶段的占比(取自存栏填报最近年月)
8
+6. 牦牛出栏统计:按最近 12 个自然月统计全县出栏数量,柱状图展示(无趋势折线);横轴仅显示月份,悬停显示年月
9 9
 7.  草场类型占比:统计可用、使用中的草场数量;2、通过未退化、轻度、中度、重度、极重度等维度统计草场的数量和占比。
10 10
 8. 线下服务预约:按月分兽医人员、专家人员、诊疗机构等3个维度统计各自的预约人数;柱状图展示。
11 11
 9. 惠农补贴发放:按补贴类型(1农业生产2住房基建3民生保障)统计当前年份所有补贴发放记录中的补贴总金额。

+ 55 - 40
doc/大屏/首页/大屏首页功能需求.md

@@ -34,9 +34,24 @@
34 34
 
35 35
 ### 2.3 统计月份(按月图表)
36 36
 
37
-- 凡「按月统计」的图表,横轴固定为 **1 月~12 月** 共 12 个刻度。
38
-- **缺月规则:** 该月在 **Y 年** 内无任何纳入统计的业务记录时,当月指标按 **0** 参与展示;**不**省略该月刻度、**不**断线留空、**不**用相邻月插值。
39
-- **当前年未到来月份:** 当 **Y** 为当前年时,**晚于统计日** 的月份在趋势图/柱状图中按 **0** 展示(与缺月规则统一,保证横轴恒为 12 月)。
37
+大屏存在两类按月图表,横轴刻度规则**不同**:
38
+
39
+| 类型 | 适用区块 | 横轴规则 |
40
+| --- | --- | --- |
41
+| **统计年 Y 内 12 月** | 线下服务预约堆叠柱、实战培训报名趋势等 | 固定 **1 月~12 月** 共 12 个刻度,数据范围限定在 **Y 年** |
42
+| **滚动最近 12 个月** | **牦牛存栏变动**、**牦牛出栏统计** | 以服务器当前年月为锚点,取**含当月在内向前连续 12 个自然月**;**不**随页面「统计年份 **Y**」切换 |
43
+
44
+**统计年 Y 内 12 月(预约、培训等)**
45
+
46
+- **缺月规则:** 该月在 **Y 年** 内无任何纳入统计的业务记录时,当月指标按 **0** 展示;**不**省略刻度、**不**断线留空、**不**插值。
47
+- **当前年未到来月份:** 当 **Y** 为当前年时,**晚于统计日** 的月份按 **0** 展示。
48
+
49
+**滚动最近 12 个月(存栏变动、出栏统计)**
50
+
51
+- 接口每条记录含 **`statYear`(自然年)**、**`month`(1~12)**;按时间升序固定返回 **12** 条。
52
+- 某自然月在填报表中无全县合计数据时,该月 **`bullCount`/`cowCount`/`outboundCount` 为 0**。
53
+- **前端横轴**仅展示月份(如 `8月`);**鼠标悬停**展示完整年月(如 `2025年8月`)及数值。
54
+- 切换统计年份 **Y** 时,上述两区块**仍展示同一滚动窗口**(与 **Y** 无关)。
40 55
 
41 56
 ### 2.4 指标类型与年份关系(总览)
42 57
 
@@ -46,27 +61,24 @@
46 61
 | **时点/还原** | 牦牛存栏总量、公母牛数、年龄结构、牧场/草场数量与面积 | 按 **§2.2** 时点或月末还原 |
47 62
 | **主数据实时快照** | 供应商数量、承销商数量、交易市场数量 | **不随 Y 切换**;始终为当前有效主数据条数(见 **§2.6**) |
48 63
 
49
-> 草稿写「产业总览统计当前年份」;对**主数据条数**三类,正式口径收束为**实时快照**,避免历史年无法追溯版本导致误导;牦牛存栏、出栏等仍严格按 **Y** 与 **§2.2** 计算。
64
+> 草稿写「产业总览统计当前年份」;对**主数据条数**三类,正式口径收束为**实时快照**;牦牛存栏/出栏/农牧户取填报表**最近年月**;存栏变动/出栏统计为**滚动 12 月**(与 **Y** 无关);预约、补贴、培训等仍按 **Y** 与 **§2.2** 计算。
50 65
 
51
-### 2.5 牦牛产业口径(对齐《养殖产业数据功能需求》
66
+### 2.5 牦牛产业口径(大屏首页
52 67
 
53
-以下与养殖产业看板**保持一致**,大屏仅只读引用,不在此重复维护台账
68
+大屏首页牦牛相关指标取自**乡镇填报表**(`biz_yak_herd_inventory`、`biz_yak_outbound_report`),全县乡镇合计;**不**直接按牦牛资产档案月末还原(档案口径仍用于「养殖产业数据」专看板)
54 69
 
55 70
 | 主题 | 规则摘要 |
56 71
 | --- | --- |
57
-| **存栏** | 「牦牛资产档案」未逻辑删除且资产状态为**正常**的个体计入存栏;死淘、丢失、出栏不计入 |
58
-| **性别** | 公、母按档案性别;无法映射公/母的计入存栏总量、不计入公/母分项 |
59
-| **月龄** | 优先档案「月龄」;缺失时由出生日期与统计时点计算**整月龄** |
60
-| **年出栏量** | **Y 年** 1 月 1 日 0:00 至(**Y 为当前年**则统计日 24:00,**Y 为历史年**则 **Y-12-31** 24:00)内,状态为**出栏**且**状态变更日期**落在上述区间内的档案,按头计 1;变更日期为空的不计入 |
61
-| **按月存栏趋势** | 各月数值为该月**月末**(当前月用统计日代替月末)按 **§2.3 存栏认定** 还原的头数;分**公牛**、**母牛**两系列 |
62
-| **按月出栏** | **Y 年** 各自然月内,满足出栏认定且**状态变更日期**落在该月的头数合计 |
63
-| **年龄结构** | 在 **§2.2** 时点上,按整月龄分档:**1~6 月龄**、**7~12 月龄**、**12 月龄以上**(含 12 月龄边界以产品全局月龄规则为准,三档互斥且覆盖全部纳入存栏个体);展示各档**头数占比** |
64
-| **牧场** | 未逻辑删除且**经营状态**为**正常**的牧场条数 |
65
-| **草场** | 未逻辑删除的草场条数;**草场面积**为有效草场面积字段之和,面积为空不计入求和 |
66
-| **可用/使用中草场** | 同《养殖产业数据》**§2.7** |
67
-| **退化等级结构** | 对未逻辑删除的全部草场按退化等级(未退化、轻度、中度、重度、极重度)统计条数及占草场总条数的**占比** |
68
-
69
-**数据权限:** 牦牛、牧场纳入范围与《养殖产业数据》**§2.9** 一致(可见牧场范围内档案;`pasture_id` 为空的档案不参与牦牛类统计);草场按授权区域全县(或授权范围)台账统计。
72
+| **产业总览·存栏** | 各表**最近填报年月**(`stat_year` + `stat_month` 最大)全县 `yak_total` 合计;接口字段 **`inventoryTotal`** |
73
+| **产业总览·出栏 / 农牧户** | 出栏表**最近填报年月**全县 `yak_outbound_count` / `farmer_household_count` 合计;接口字段 **`annualOutbound`** / **`pastureCount`** |
74
+| **存栏变动·当前公母** | 存栏表**最近填报年月**全县 `bull_total`、`cow_total`;`unknownGenderCount = yak_total − bull − cow`(不足为 0) |
75
+| **存栏变动·趋势** | **§2.3 滚动 12 月**;各月全县 `bull_total`、`cow_total` 合计 |
76
+| **年龄结构** | 存栏表**最近填报年月**母牛分龄四档:`1岁以下`、`1~3岁`、`3~12岁`、`12岁以上`(对应填报字段合计) |
77
+| **出栏统计** | **§2.3 滚动 12 月**;各月全县 `yak_outbound_count` 合计 |
78
+| **地图标注** | 各乡镇在各自表**最近填报年月**下的 `yak_total` / `yak_outbound_count`;**不**随 **Y** 切换 |
79
+| **牧场 / 草场** | 同《养殖产业数据》**§2.7** 等(档案/台账口径) |
80
+
81
+**数据权限:** 填报表按全县乡镇汇总;草场等仍按授权范围统计。
70 82
 
71 83
 ### 2.6 交易市场主数据(供应商 / 承销商 / 交易市场)
72 84
 
@@ -266,9 +278,9 @@ flowchart TB
266 278
 
267 279
 | 序号 | 指标名称 | 单位 | 统计口径 |
268 280
 | --- | --- | --- | --- |
269
-| 1 | 牦牛存栏总量 | 头 | `biz_yak_herd_inventory.yak_total` 全县乡镇合计;统计年 = **当前自然年 − 1**;接口字段沿用 **`inventoryTotal`** |
270
-| 2 | 牦牛年出栏量 | 头 | `biz_yak_outbound_report.yak_outbound_count` 全县乡镇合计;统计年 = **当前自然年**;接口字段沿用 **`annualOutbound`** |
271
-| 3 | 农牧户 | 户 | `biz_yak_outbound_report.farmer_household_count` 全县乡镇合计;统计年 = **当前自然年**;接口字段沿用 **`pastureCount`** |
281
+| 1 | 牦牛存栏总量 | 头 | `biz_yak_herd_inventory.yak_total` 全县合计;取**最近填报年月**;接口字段 **`inventoryTotal`** |
282
+| 2 | 牦牛年出栏量 | 头 | `biz_yak_outbound_report.yak_outbound_count` 全县合计;取**最近填报年月**;接口字段 **`annualOutbound`** |
283
+| 3 | 农牧户 | 户 | `biz_yak_outbound_report.farmer_household_count` 全县合计;取**最近填报年月**;接口字段 **`pastureCount`** |
272 284
 | 4 | 草场数量 | 个 | **§2.5** |
273 285
 | 5 | 草场面积 | 亩 | **§2.5** |
274 286
 | 6 | 供应商数量 | 个 | **§2.6** 实时快照 |
@@ -287,9 +299,10 @@ flowchart TB
287 299
 | --- | --- |
288 300
 | 图表类型 | **折线图**(或面积图,以原型为准) |
289 301
 | 数据系列 | **公牛数量**、**母牛数量**(头) |
290
-| 横轴 | **§2.3** 1~12 月 |
291
-| 辅助展示 | 可在图例区或标题旁展示 **§2.2** 时点的公、母牛当前数量(与趋势图一致口径) |
292
-| 交互 | 至少支持悬停查看「月份 + 公牛数 + 母牛数」 |
302
+| 数据范围 | **§2.3 滚动最近 12 个月**(存栏填报表全县按月合计) |
303
+| 横轴 | 12 个刻度,**仅显示月份**(如 `8月`);跨年窗口内可出现重复月份标签 |
304
+| 辅助展示 | 标题旁展示存栏表**最近填报年月**的公、母牛当前数量 |
305
+| 交互 | 悬停展示 **「YYYY年M月 + 公牛数 + 母牛数」** |
293 306
 
294 307
 ---
295 308
 
@@ -298,9 +311,10 @@ flowchart TB
298 311
 | 项 | 规则 |
299 312
 | --- | --- |
300 313
 | 图表类型 | 饼图/环形图(以原型为准) |
301
-| 分档 | **1~6 月龄**、**7~12 月龄**、**12 月龄以上** |
314
+| 分档 | **1岁以下**、**1~3岁**、**3~12岁**、**12岁以上**(母牛分龄,取自存栏填报) |
302 315
 | 展示内容 | 各档**头数**及**占比(%)** |
303
-| 无存栏 | **§2.5** 时点存栏为 0 时 **§7.1** 空态 |
316
+| 时点 | 存栏表**最近填报年月** |
317
+| 无存栏 | 四档均为 0 时走 **§7.1** 空态 |
304 318
 
305 319
 ---
306 320
 
@@ -308,10 +322,10 @@ flowchart TB
308 322
 
309 323
 | 项 | 规则 |
310 324
 | --- | --- |
311
-| 图表类型 | **柱状图** |
312
-| 指标 | **Y 年**各月出栏头数 |
313
-| 横轴 | **§2.3** 1~12 月 |
314
-| 交互 | 悬停展示月份与出栏头数 |
325
+| 图表类型 | **柱状图**(无趋势折线) |
326
+| 数据范围 | **§2.3 滚动最近 12 个月**(出栏填报表全县按月合计) |
327
+| 横轴 | 12 个刻度,**仅显示月份** |
328
+| 交互 | 悬停展示 **「YYYY年M月 + 出栏头数」** |
315 329
 
316 330
 ---
317 331
 
@@ -385,10 +399,10 @@ flowchart TB
385 399
 | 展示位置 | 首页地图各乡镇标注(以原型为准) |
386 400
 | 乡镇范围 | `sys_dept` 中 `parent_id=100` 且 `order_num>12` 的有效乡镇 |
387 401
 | 标注字段 | **所属乡镇** `dept_id`、**乡镇名称**、**牦牛存栏数**(头)、**牦牛出栏数**(头) |
388
-| 存栏口径 | `biz_yak_herd_inventory.yak_total`;统计年 = **当前自然年 − 1** |
389
-| 出栏口径 | `biz_yak_outbound_report.yak_outbound_count`;统计年 = **当前自然年** |
390
-| 无填报 | 对应乡镇该年未填报时展示 **0** |
391
-| 与看板年份 | **不**随页面「统计年份 **Y**」切换;始终按服务器当前自然年取上一年存栏、当年出栏 |
402
+| 存栏口径 | `biz_yak_herd_inventory.yak_total`;取该表**最近填报年月** |
403
+| 出栏口径 | `biz_yak_outbound_report.yak_outbound_count`;取该表**最近填报年月** |
404
+| 无填报 | 对应乡镇该年未填报时展示 **0** |
405
+| 与看板年份 | **不**随页面「统计年份 **Y**」切换;随填报表最新年月更新 |
392 406
 
393 407
 ---
394 408
 
@@ -409,8 +423,8 @@ flowchart TB
409 423
 
410 424
 | 场景 | 展示要求 |
411 425
 | --- | --- |
412
-| **Y** 年无出栏记录 | 出栏柱状图空态;年出栏量卡片可为 **0** |
413
-| **Y** 年时点无存栏 | 年龄结构、存栏趋势空态;存栏总量为 **0** |
426
+| **Y** 年无出栏记录 | 预约/补贴等随 **Y** 变;**出栏滚动 12 月图**与 **Y** 无关,按填报缺月补 0 |
427
+| **Y** 年时点无存栏 | 年龄结构、存栏趋势空态或补 0;产业总览存栏取最近填报,无填报为 **0** |
414 428
 | **Y** 年无预约 | 预约区空态;三类年度卡片为 **0** |
415 429
 | **Y** 年无补贴发放 | 补贴图空态或三类型均为 **0** |
416 430
 | 某标准分类无已发布标准 | 该 Tab 列表空态 |
@@ -440,9 +454,9 @@ flowchart TB
440 454
 | SY-01 | 默认年份 | 进入首页默认当前年,各区块口径一致 |
441 455
 | SY-02 | 切换年份 | 切换 **Y** 后各区块同步更新,无旧年残留 |
442 456
 | SY-03 | 产业总览 | 八项指标与手工按 **§2.5、§2.6** 核算一致(主数据三项不随 **Y** 变) |
443
-| SY-04 | 存栏趋势 | 折线 12 月;缺月/未来月为 0;公/母系列区分 |
444
-| SY-05 | 年龄结构 | 三档占比之和为 100%(有存栏时) |
445
-| SY-06 | 出栏按月 | 与 **Y** 年各月出栏手工核算一致 |
457
+| SY-04 | 存栏趋势 | 滚动 12 月;含 `statYear`+`month`;公/母两系列;缺月补 0;横轴仅月、悬停显年月 |
458
+| SY-05 | 年龄结构 | 母牛四档占比之和为 100%(有数据时) |
459
+| SY-06 | 出栏按月 | 滚动 12 月出栏合计与填报表手工核算一致;纯柱状图 |
446 460
 | SY-07 | 草场占比 | 可用/使用中及五档退化与《养殖产业数据》一致 |
447 461
 | SY-08 | 预约统计 | 三类年度合计与按月堆叠与 **§2.7** 一致 |
448 462
 | SY-09 | 补贴金额 | 三类金额为 **Y** 年发放日记录金额合计 |
@@ -458,6 +472,7 @@ flowchart TB
458 472
 
459 473
 | 版本 | 日期 | 说明 |
460 474
 | --- | --- | --- |
475
+| 1.1 | 2026-07-04 | 存栏变动/出栏统计改为填报表滚动 12 月;接口增 `statYear`;前端横轴仅月、悬停显年月;年龄结构改为母牛四档;地图/总览取最近填报年月 |
461 476
 | 1.0 | 2026-05-25 | 由草稿优化:补全流程、边界、十区块需求;对齐养殖产业/预约/补贴/标准/培训口径;不涉及库表与接口;保留草稿不修改 |
462 477
 
463 478
 ---

+ 87 - 52
doc/大屏/首页/大屏首页技术方案.md

@@ -10,7 +10,7 @@
10 10
 | --- | --- |
11 11
 | **后端** | RuoYi **v3.9.2**(**springboot2** 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
12 12
 | **数据库** | MySQL **5.7.39**,InnoDB,`utf8mb4` |
13
-| **前端** | 大屏独立首页;**切换 `statYear`** 拉看板主数据,养殖标准**分页**单独请求 |
13
+| **前端** | 大屏独立首页(`ruoyi-screen`);**切换 `statYear`** 拉看板主数据,养殖标准**分页**单独请求;存栏变动/出栏统计图表见 **§4.1** |
14 14
 | **代码包** | `com.ruoyi.web.modules.screen`(`HomeScreenController` / `IHomeScreenService` / `vo` / `support`) |
15 15
 
16 16
 **分层**:`Controller` → `IHomeScreenService`(口径编排、按 **Y** 计算统计日)→ 扩展 Mapper / 复用 `BreedingIndustryStatsMapper` + `BreedingIndustryCalculator`(只读)。
@@ -22,7 +22,8 @@
22 22
 | 数据权限 | **全县**聚合:牦牛、牧场取全部 `biz_status=1` 且 `del_flag=0` 的牧场 ID(与疫病风险大屏一致,**不按**登录用户牧场过滤);草场全县 `del_flag=0` |
23 23
 | 统计日 | `Y = 当前年` → `statDate = 今日`;`Y` 为历史年 → `statDate = Y-12-31`(时点、月末还原、年出栏上界均据此) |
24 24
 | 主数据三项 | 供应商 / 承销商 / 交易市场**实时快照**,**不**随 `statYear` 变 |
25
-| 按月图表 | 横轴固定 **12** 月;缺月、当前年未来月均为 **0** |
25
+| 按月图表(预约、培训等) | 横轴固定 **12** 月(**Y** 年内);缺月、当前年未来月均为 **0** |
26
+| 滚动 12 月图表(存栏变动、出栏统计) | 锚点 = 服务器当前 `YearMonth`(`Asia/Shanghai`);窗口 = 锚点向前 11 月~锚点;固定 **12** 条;**不**随 `statYear` 变 |
26 27
 | 性能 | 默认实时聚合;可选 **§2.3** 缓存表 |
27 28
 
28 29
 **依赖表(只读)**
@@ -36,8 +37,8 @@
36 37
 | `biz_breeding_standard` 等 5 张标准表 | 养殖标准分页列表 |
37 38
 | `biz_tech_resource` | 视频课程(`004008`) |
38 39
 | `biz_practical_training` | 实战培训场次与报名趋势 |
39
-| `biz_yak_herd_inventory` | 地图标注 — 乡镇牦牛存栏(**上一年** `yak_total`) |
40
-| `biz_yak_outbound_report` | 地图标注 — 乡镇牦牛出栏(**当年** `yak_outbound_count`) |
40
+| `biz_yak_herd_inventory` | 产业总览存栏、存栏变动、年龄结构、地图标注;**最近填报年月**全县合计 |
41
+| `biz_yak_outbound_report` | 产业总览出栏/农牧户、出栏统计、地图标注;**最近填报年月**全县合计 |
41 42
 | `sys_dept` | 地图标注 — 乡镇列表(`parent_id=100` 且 `order_num>12`) |
42 43
 
43 44
 ---
@@ -74,18 +75,24 @@
74 75
 
75 76
 ### 2.4 查询口径(按表)
76 77
 
77
-#### 养殖产业(对齐《养殖产业数据技术方案》§2.2,按 **Y** + `statDate`
78
+#### 牦牛填报(大屏首页存栏/出栏/年龄/趋势/地图
78 79
 
79
-实现复用 `BreedingIndustryStatsMapper`、`BreedingIndustryCalculator`;大屏传入**全县** `allowedPastureIds`(全部正常牧场 ID)。
80
+| 指标 | 要点 |
81
+| --- | --- |
82
+| 最近填报年月 | `MAX(stat_year, stat_month)` 全县;存栏与出栏表**可不同** |
83
+| 产业总览三项 | 最近年月全县 `yak_total` / `yak_outbound_count` / `farmer_household_count` |
84
+| 存栏变动 header | 最近年月全县 `bull_total`、`cow_total`、`yak_total` |
85
+| 滚动 12 月存栏趋势 | `biz_yak_herd_inventory` 按 `stat_year+stat_month` 全县 `bull_total`/`cow_total` 合计 |
86
+| 滚动 12 月出栏 | `biz_yak_outbound_report` 按 `stat_year+stat_month` 全县 `yak_outbound_count` 合计 |
87
+| 年龄结构 | 最近年月母牛四档:`cow_under_1_count`、`cow_1_3_count`、`cow_3_12_count`、`cow_over_12_count` |
88
+| 地图标注 | 各乡镇在各自表最近填报年月下的 `yak_total` / `yak_outbound_count` |
89
+
90
+#### 养殖产业档案(草场等,复用 Mapper)
91
+
92
+实现复用 `BreedingIndustryStatsMapper`;大屏传入**全县** `allowedPastureIds`(全部正常牧场 ID)。
80 93
 
81 94
 | 指标 | 要点 |
82 95
 | --- | --- |
83
-| 存栏 / 公母牛 / 年龄结构 | `statDate` 时点;`asset_status=1`,`pasture_id` 非空且在可见牧场内 |
84
-| 年出栏 | `asset_status=4`,`status_change_date` 在 **§2.2 年区间** 且非空 |
85
-| 按月存栏趋势 | 每月末 `M`(当前月用 `statDate`);**公牛**、**母牛**两系列(`gender` 公/母),非总量一条线 |
86
-| 按月出栏 | `status_change_date` 落在该自然月 |
87
-| 年龄分档 | `M1_6` / `M7_12` / `M13_PLUS`(与养殖产业看板编码一致,对应需求 1~6 / 7~12 / 12 月龄以上) |
88
-| 牧场数 | `del_flag=0` AND `biz_status=1` |
89 96
 | 草场 | `del_flag=0`;面积 `SUM(area_mu)`;可用/使用中/退化分组同养殖产业 |
90 97
 
91 98
 > 首页**不含**预警牦牛;不查 `biz_yak_disease_warning`。
@@ -162,7 +169,8 @@
162 169
 
163 170
 | Mapper | 方法 | 说明 |
164 171
 | --- | --- | --- |
165
-| `BreedingIndustryStatsMapper` | (复用 + 可选新增) | `countMonthlyOutboundByMonth`、`selectYakSnapshotsInScope` 等;按月公/母牛趋势在 Service 用快照 + `BreedingIndustryCalculator` |
172
+| `HomeScreenStatsMapper` | `selectLatestHerdInventoryStatPeriod`、`selectLatestOutboundReportStatPeriod`、`selectHerdInventoryBullCowByYearMonthRange`、`selectOutboundReportYakCountByYearMonthRange`、`selectTownMapMarkers` 等 | 填报表聚合 |
173
+| `BreedingIndustryStatsMapper` | (复用) | 草场统计 |
166 174
 | `BizSupplierMapper` / `BizDistributorMapper` / `BizTradeMarketMapper` | `countForScreen()` | 主数据条数 |
167 175
 | `BizServiceAppointmentMapper` | `selectStatsByYear(int y)` | 返回 appoint_date、provider_type 明细或按月聚合行 |
168 176
 | `BizSubsidyGrantRecordMapper` | `sumAmountByTypeForYear(int y)` | 三类金额 |
@@ -170,7 +178,7 @@
170 178
 | `BizPracticalTrainingMapper` | `countPublishedByYear` / `selectPublishedByYear` | 场次与按月趋势 |
171 179
 | `HomeScreenStandardMapper` | `selectListForScreen(category, y, ...)` | 按 **§2.4** Tab 路由到对应表 |
172 180
 
173
-> **禁止**大屏单独实现一套牦牛月末还原公式;须调用 `BreedingIndustryCalculator`
181
+> 大屏首页牦牛趋势/出栏**不**调用 `BreedingIndustryCalculator` 月末还原;填报缺月由 `HomeScreenSupport.buildRolling12Month*` 补 0
174 182
 
175 183
 ---
176 184
 
@@ -222,9 +230,9 @@
222 230
 
223 231
 | 字段 | 说明 |
224 232
 | --- | --- |
225
-| `inventoryTotal` | 牦牛存栏(头),`biz_yak_herd_inventory` 全县 `yak_total` 合计;年份 = 当前自然年 **− 1**;**字段名不变** |
226
-| `annualOutbound` | 年出栏(头),`biz_yak_outbound_report` 全县 `yak_outbound_count` 合计;年份 = 当前自然年;**字段名不变** |
227
-| `pastureCount` | 农牧户(户),`biz_yak_outbound_report` 全县 `farmer_household_count` 合计;年份 = 当前自然年;**字段名不变** |
233
+| `inventoryTotal` | 牦牛存栏(头),`biz_yak_herd_inventory` **最近填报年月**全县 `yak_total` 合计 |
234
+| `annualOutbound` | 年出栏(头),`biz_yak_outbound_report` **最近填报年月**全县 `yak_outbound_count` 合计 |
235
+| `pastureCount` | 农牧户(户),`biz_yak_outbound_report` **最近填报年月**全县 `farmer_household_count` 合计 |
228 236
 | `grasslandCount` / `grasslandAreaMu` | 草场、面积 |
229 237
 | `supplierCount` / `distributorCount` / `tradeMarketCount` | 流通三项**实时**快照 |
230 238
 
@@ -232,29 +240,36 @@
232 240
 
233 241
 | 字段 | 说明 |
234 242
 | --- | --- |
235
-| `bullCount` / `cowCount` / `unknownGenderCount` | **statDate** 时点公/母/未标注 |
236
-| `monthlyTrend` | 固定 **12** 条 |
243
+| `bullCount` / `cowCount` / `unknownGenderCount` | 存栏表**最近填报年月**全县公/母/`yak_total` 合计 |
244
+| `monthlyTrend` | 固定 **12** 条;**滚动最近 12 自然月**;**不**随 `statYear` 变 |
237 245
 
238
-`monthlyTrend[]`:`month`(1~12)、`bullCount`、`cowCount`(该月末还原;**Y** 为当前年时,`month > statDate.month` 均为 0)。
246
+`monthlyTrend[]`:
247
+
248
+| 字段 | 说明 |
249
+| --- | --- |
250
+| `statYear` | 所属自然年 |
251
+| `month` | 所属月份 1~12 |
252
+| `bullCount` / `cowCount` | 该 `statYear-month` 全县填报合计;无数据为 **0** |
239 253
 
240 254
 #### 3.1.3 `ageStructure[]`
241 255
 
242 256
 | 字段 | 说明 |
243 257
 | --- | --- |
244
-| `bandCode` | `M1_6` / `M7_12` / `M13_PLUS` |
245
-| `bandLabel` | 展示名 |
246
-| `count` / `ratio` | 头数;占比 **0~100** 数值(如 `37.5` 表示 37.5%) |
258
+| `bandCode` | `COW_U1` / `COW_1_3` / `COW_3_12` / `COW_O12` |
259
+| `bandLabel` | `1岁以下` / `1~3岁` / `3~12岁` / `12岁以上` |
260
+| `count` / `ratio` | 头数;占比 **0~100** 数值 |
247 261
 
248
-档固定返回;无存栏时 `count=0`,`ratio=0`。
262
+档固定返回;无存栏时 `count=0`,`ratio=0`。
249 263
 
250 264
 #### 3.1.4 `outboundMonthly[]`
251 265
 
252 266
 | 字段 | 说明 |
253 267
 | --- | --- |
254
-| `month` | 1~12 |
255
-| `outboundCount` | 该月出栏头数 |
268
+| `statYear` | 所属自然年 |
269
+| `month` | 所属月份 1~12 |
270
+| `outboundCount` | 该月全县出栏头数;无数据为 **0** |
256 271
 
257
-固定 12 条;未来月规则同 **§1**
272
+固定 **12** 条;滚动窗口规则同 **§3.1.2** `monthlyTrend`
258 273
 
259 274
 #### 3.1.5 `grassland`
260 275
 
@@ -319,10 +334,14 @@
319 334
     "cowCount": 60,
320 335
     "unknownGenderCount": 15,
321 336
     "monthlyTrend": [
322
-      { "month": 1, "bullCount": 40, "cowCount": 55 },
323
-      { "month": 12, "bullCount": 0, "cowCount": 0 }
337
+      { "statYear": 2025, "month": 8, "bullCount": 40, "cowCount": 55 },
338
+      { "statYear": 2026, "month": 7, "bullCount": 45, "cowCount": 60 }
324 339
     ]
325 340
   },
341
+  "outboundMonthly": [
342
+    { "statYear": 2025, "month": 8, "outboundCount": 0 },
343
+    { "statYear": 2026, "month": 5, "outboundCount": 88 }
344
+  ],
326 345
   "appointment": {
327 346
     "annualVetCount": 10,
328 347
     "annualExpertCount": 5,
@@ -337,16 +356,14 @@
337 356
 
338 357
 ```
339 358
 1. year = parseStatYear(statYear); statDate = resolveStatDate(year)
340
-2. allowedPastureIds = selectAllActivePastureIds()  // 全县
341
-3. industry + inventory + age + outbound + grassland = breeding 聚合(statDate, year, allowedPastureIds)
342
-4. tradeCounts = supplier/distributor/market countForScreen()  // 与 year 无关
343
-5. appointment = appointmentMapper stats by year
344
-6. subsidy = grantMapper sum by type; hasSubsidyData
345
-7. agriClassroom = tech video count + training publish count by year
346
-8. trainingTrend = training by month; hasTrainingData
347
-9. availableYears = union(distinct years from各源表, current year)
348
-10. industryOverview 填报合计填入既有字段:`inventoryTotal` / `annualOutbound` / `pastureCount`(农牧户);原牧场/快照口径在 Service 内暂保留
349
-11. return AjaxResult.success(vo)
359
+2. anchor = YearMonth.now(Asia/Shanghai); startYm/endYm = 锚点向前 11 月~锚点(yyyyMM)
360
+3. latestHerd / latestOutbound = 各表最近 stat_year+stat_month
361
+4. industryOverview 三项 = 最近年月全县合计(与 year 无关)
362
+5. inventoryChange header + ageStructure = latestHerd 年月全县合计
363
+6. monthlyTrend = buildRolling12MonthBullCowTrend(selectHerd...Range(startYm,endYm), anchor)
364
+7. outboundMonthly = buildRolling12MonthOutbound(selectOutbound...Range(startYm,endYm), anchor)
365
+8. grassland / tradeCounts / appointment / subsidy / agri / training = 按 year 或实时(同前)
366
+9. return AjaxResult.success(vo)
350 367
 ```
351 368
 
352 369
 ---
@@ -390,19 +407,19 @@
390 407
 
391 408
 #### Query
392 409
 
393
-无参数。统计年份由服务器当前自然年 `Y` 推导
410
+无参数。存栏/出栏各取填报表**最近 `stat_year` + `stat_month`**(两表可不同)
394 411
 
395
-| 字段 | 年份 |
412
+| 字段 | 说明 |
396 413
 | --- | --- |
397
-| `herdStatYear` | `Y - 1`(存栏取 `biz_yak_herd_inventory.stat_year`) |
398
-| `outboundStatYear` | `Y`(出栏取 `biz_yak_outbound_report.stat_year`) |
414
+| `herdStatYear` / (隐含 `herdStatMonth` 于 SQL) | 存栏表最近填报年 |
415
+| `outboundStatYear` | 出栏表最近填报年 |
399 416
 
400 417
 #### 响应 `data`
401 418
 
402 419
 | 字段 | 类型 | 说明 |
403 420
 | --- | --- | --- |
404
-| `herdStatYear` | int | 存栏数据年份(上一年) |
405
-| `outboundStatYear` | int | 出栏数据年份(当年) |
421
+| `herdStatYear` | int | 存栏数据最近填报年(可空) |
422
+| `outboundStatYear` | int | 出栏数据最近填报年(可空) |
406 423
 | `markers` | array | 乡镇标注列表,见下表 |
407 424
 
408 425
 `markers[]`:
@@ -421,14 +438,31 @@
421 438
 #### 服务端逻辑(摘要)
422 439
 
423 440
 ```
424
-1. outboundStatYear = Year.now(); herdStatYear = outboundStatYear - 1
425
-2. markers = HomeScreenStatsMapper.selectTownMapMarkers(herdStatYear, outboundStatYear)
426
-3. return AjaxResult.success(vo)
441
+1. latestHerd = selectLatestHerdInventoryStatPeriod()
442
+2. latestOutbound = selectLatestOutboundReportStatPeriod()
443
+3. markers = selectTownMapMarkers(herdYear, herdMonth, outboundYear, outboundMonth)
444
+4. return AjaxResult.success(vo)
427 445
 ```
428 446
 
429 447
 ---
430 448
 
431
-## 4. 菜单与权限(示例)
449
+## 4. 前端实现要点
450
+
451
+**工程**:`ruoyi-screen/src/views/home/`(`index.vue`、`chartOptions.js`)。
452
+
453
+### 4.1 存栏变动 / 出栏统计图表
454
+
455
+| 项 | 实现 |
456
+| --- | --- |
457
+| 数据字段 | `inventoryChange.monthlyTrend[]`、`outboundMonthly[]`;按 `statYear`、`month` 升序 |
458
+| 横轴 | **仅月份**标签(`8月`);`buildInventoryTrendOption` / `buildOutboundOption` |
459
+| Tooltip | **完整年月**(`2025年8月`)+ 数值 |
460
+| 出栏图 | **纯柱状图**,无趋势折线 |
461
+| 与 `statYear` | 切换年份**不**改变上述两图数据窗口 |
462
+
463
+---
464
+
465
+## 5. 菜单与权限(示例)
432 466
 
433 467
 | 类型 | 名称 | 权限标识 |
434 468
 | --- | --- | --- |
@@ -438,19 +472,20 @@ SQL 示例:`sql/big_screen_home_perm.sql`(挂载「大屏」父菜单下)
438 472
 
439 473
 ---
440 474
 
441
-## 5. 交付清单
475
+## 6. 交付清单
442 476
 
443 477
 - [ ] `HomeScreenController` + `IHomeScreenService` + VO + `HomeScreenSupport`
444 478
 - [ ] 复用 `BreedingIndustryStatsMapper` / `BreedingIndustryCalculator`(按 **Y** 与全县牧场)
445 479
 - [ ] 预约、补贴、标准、科技资源、实战培训 Mapper 扩展(**§2.6**)
446
-- [ ] 单元测试:历史年 `statDate`、12 月补 0、主数据不随 **Y** 变、补贴万元、无培训空态、标准 Tab 路由
480
+- [ ] 单元测试:滚动 12 月补 0、`statYear`+`month`、主数据不随 **Y** 变、地图最近填报年月
447 481
 - [ ] 接口测试:`/bigScreen/home/dashboard`、`/standards`、`/townMapMarkers`
448 482
 - [ ] 菜单权限 SQL;依赖各业务表 DDL 已执行
449 483
 
450 484
 ---
451 485
 
452
-## 6. 修订记录
486
+## 7. 修订记录
453 487
 
454 488
 | 版本 | 日期 | 说明 |
455 489
 | --- | --- | --- |
490
+| 1.1 | 2026-07-04 | 存栏/出栏改填报表滚动 12 月;VO 增 `statYear`;年龄四档;地图/总览最近填报年月;§4 前端横轴/Tooltip |
456 491
 | 1.0 | 2026-05-20 | 初稿:无新表;双接口;对齐 `大屏首页功能需求.md` v1.0 |

+ 31 - 28
doc/大屏/首页/大屏首页测试用例.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 首页统计 — 测试用例
2 2
 
3
-> 依据:`大屏首页功能需求.md`(v1.0)、`大屏首页技术方案.md`(v1.0
3
+> 依据:`大屏首页功能需求.md`(v1.1)、`大屏首页技术方案.md`(v1.1
4 4
 > **接口 Base Path**:`/bigScreen/home`(含 `context-path`、网关前缀须补齐)。鉴权:若依 Cookie / `Authorization` Token;权限 `bigScreen:home:query`。
5 5
 
6 6
 **通用前置(无特殊说明)**:各业务 `sql/biz_*.sql` 已执行;测试账号具备大屏首页查询权限;时区 `Asia/Shanghai`。
@@ -11,8 +11,9 @@
11 11
 | --- | --- |
12 12
 | 统计年 **Y** | 切换后全页一致;默认当前自然年 |
13 13
 | 统计日 | `Y`=当前年→今日;历史年→`Y-12-31` |
14
-| 按月图表 | 固定 12 月;缺月、当前年未来月=**0** |
15
-| 牦牛/牧场/草场 | 复用养殖产业口径;大屏**全县**正常牧场;`pasture_id` 为空不参与牦牛统计 |
14
+| 按月图表(预约、培训) | 固定 12 月(**Y** 年内);缺月、当前年未来月=**0** |
15
+| 滚动 12 月(存栏变动、出栏统计) | 锚点=当前年月;含 `statYear`+`month`;**不**随 **Y**;缺月=**0** |
16
+| 牦牛填报 | `biz_yak_herd_inventory` / `biz_yak_outbound_report` 全县合计;最近填报年月 |
16 17
 | 流通三项 | 供应商/承销商/交易市场**实时快照**,**不随 Y** |
17 18
 | 预约 | `appoint_date` 在 **Y**;`status NOT IN (2,3)`;`provider_type` 1/3/2→兽医/专家/机构 |
18 19
 | 补贴 | `grant_date` 在 **Y**;三类金额合计转**万元** |
@@ -28,10 +29,9 @@
28 29
 
29 30
 | 代号 | 说明 |
30 31
 | --- | --- |
31
-| **YAK-INV** | 可见牧场内 `asset_status=1` 存栏已知;含公/母/未标注性别 |
32
-| **YAK-OUT-Y** | **Y** 年出栏仅 3、8 月各 1 头(`status_change_date` 非空) |
33
-| **YAK-EMPTY** | **Y** 时点无存栏(或全县无有效档案) |
34
-| **YAK-HIST** | 历史年 **2024** 末还原存栏与 2026 不同 |
32
+| **HERD-R12** | 存栏填报:滚动窗口内仅 **2026-07** 有公 100/母 200;其余月无数据 |
33
+| **OUT-R12** | 出栏填报:滚动窗口内仅 **2026-05** 出栏 88 头 |
34
+| **HERD-EMPTY** | 无存栏填报 |
35 35
 | **GRASS-MIX** | 草场五档退化已知;可用/使用中数量可手工核算 |
36 36
 | **TRADE-SNAP** | 供应商 3、承销商 2、市场正常 1+停业 1(停业不计入) |
37 37
 | **APT-Y** | **2026** 兽医 2、专家 1、机构 1;`appoint_date` 分月 |
@@ -55,11 +55,13 @@
55 55
 | DP-SY-UT-002 | 参数校验 | statYear 非法 | 单元测试 | JUnit5 | 异常入参 | 无 | 空、`26`、`abcd`、`1899` | 抛 `ServiceException` 或等价失败 |
56 56
 | DP-SY-UT-003 | 统计日 | 当前年 statDate | 单元测试 | JUnit5 | §2.2、SY-01 | Mock 当前日 2026-05-20 | `resolveStatDate(2026)` | 返回 `2026-05-20` |
57 57
 | DP-SY-UT-004 | 统计日 | 历史年 statDate | 单元测试 | JUnit5 | §2.2 | 无 | `resolveStatDate(2024)` | 返回 `2024-12-31` |
58
-| DP-SY-UT-005 | 存栏趋势 | 按月 12 条补零 | 单元测试 | JUnit5 | §2.3、SY-04 | Mock 仅 3、8 月有公/母还原值 | `buildInventoryMonthlyTrend(2026, statDate)` | `length=12`;缺月 `bullCount=cowCount=0` |
59
-| DP-SY-UT-006 | 存栏趋势 | 未来月为 0 | 单元测试 | JUnit5 | §2.3 | 当前年 statDate=5 月 | 检查 `month=6..12` | 均为 0 |
60
-| DP-SY-UT-007 | 出栏按月 | 缺月补零 | 单元测试 | JUnit5 | SY-06 | `YAK-OUT-Y` | `buildOutboundMonthly(2026)` | 12 条;非 3/8 月 `outboundCount=0` |
61
-| DP-SY-UT-008 | 年龄结构 | 三档占比之和 | 单元测试 | JUnit5 | SY-05 | `YAK-INV` 三档头数 30/30/60 | `buildAgeStructure` | 三档固定返回;`sum(ratio)≈100`(有存栏时) |
62
-| DP-SY-UT-009 | 年龄结构 | 无存栏 | 单元测试 | JUnit5 | §7.1 | `YAK-EMPTY` | `buildAgeStructure` | 三档 `count=0`、`ratio=0` |
58
+| DP-SY-UT-005 | 存栏趋势 | 滚动 12 月补零 | 单元测试 | JUnit5 | §2.3、SY-04 | Mock 仅锚点月有公/母 | `buildRolling12MonthBullCowTrend(..., 2026-07)` | `length=12`;末条 `statYear=2026,month=7`;缺月 `bullCount=cowCount=0` |
59
+| DP-SY-UT-005b | 存栏趋势 | 窗口起止年月 | 单元测试 | JUnit5 | §2.3 | anchor=2026-07 | 检查首条 | `statYear=2025,month=8` |
60
+| DP-SY-UT-006 | 存栏趋势 | 不随 statYear | 单元测试 | JUnit5 | 技术§3.1 | `loadDashboard(2025)` 与 `2026` | 比较 `monthlyTrend` | 两次 `monthlyTrend` 相同(Mock 填报一致时) |
61
+| DP-SY-UT-007 | 出栏按月 | 滚动 12 月补零 | 单元测试 | JUnit5 | SY-06 | `OUT-R12` | `buildRolling12MonthOutbound(..., 2026-07)` | 12 条;2026-05 对应槽位 `outboundCount=88`;其余 0 |
62
+| DP-SY-UT-007b | 出栏按月 | statYear+month | 单元测试 | JUnit5 | §3.1.4 | 同上 | 检查含 `statYear`、`month` | 每条均含年月 |
63
+| DP-SY-UT-008 | 年龄结构 | 四档占比之和 | 单元测试 | JUnit5 | SY-05 | 四档头数 10/20/30/40 | `buildCowAgeStructureFromHerdReport` | 四档固定返回;`sum(ratio)≈100` |
64
+| DP-SY-UT-009 | 年龄结构 | 无数据 | 单元测试 | JUnit5 | §7.1 | `HERD-EMPTY` | `buildCowAgeStructureFromHerdReport(null)` | 四档 `count=0`、`ratio=0` |
63 65
 | DP-SY-UT-010 | 流通快照 | 切年不变 | 单元测试 | JUnit5 | §2.6、SY-03 | 固定 `TRADE-SNAP` | `loadDashboard(2025)` 与 `2026` | `supplierCount`/`distributorCount`/`tradeMarketCount` 相同 |
64 66
 | DP-SY-UT-011 | 预约 | 状态过滤 | 单元测试 | JUnit5 | 技术§2.4 | `APT-Y`+`APT-EXCL` | `countAppointments(2026)` | 不计入 status 2、3;三条有效计入 |
65 67
 | DP-SY-UT-012 | 预约 | 三类映射 | 单元测试 | JUnit5 | §2.7 | provider_type 1/3/2 各 1 | `buildAppointmentStats` | 兽医/专家/机构年度合计各 1 |
@@ -72,11 +74,11 @@
72 74
 | DP-SY-UT-019 | 养殖标准 | Tab 路由表 | 单元测试 | JUnit5 | §2.9、SY-10 | `category=FEEDING` | `resolveStandardTable` | 指向 `biz_feeding_standard`;type 含 `001005` |
73 75
 | DP-SY-UT-020 | 养殖标准 | 纳入条件 | 单元测试 | JUnit5 | SY-10 | `STD-PUB`+`STD-DRAFT`+`STD-OUT` | `filterStandards(2026)` | 仅 `STD-PUB` 通过 |
74 76
 | DP-SY-UT-021 | 可选年份 | 并集含当前年 | 单元测试 | JUnit5 | §2.1 | Mock 出栏年 `[2025]`,其余空;当前 2026 | `buildAvailableYears` | 含 `2026`;降序 |
75
-| DP-SY-UT-022 | 约束 | 复用 Calculator | 单元测试 | JUnit5 | 技术§2.6 | 检查 HomeScreenService | 月末存栏调用 `BreedingIndustryCalculator` | 无重复实现月末判定 |
77
+| DP-SY-UT-022 | 约束 | 滚动趋势不依赖 Calculator | 单元测试 | JUnit5 | 技术§2.6 | 检查 `buildRolling12Month*` | 填报表聚合 | 不调用 `BreedingIndustryCalculator` |
76 78
 | DP-SY-UT-023 | 约束 | 只读无写 | 单元测试 | JUnit5 | §3.2、SY-14 | 检查 Controller/Service | 无 insert/update/delete | 仅 `dashboard`、`standards`、`townMapMarkers` 查询 |
77 79
 | DP-SY-UT-024 | 约束 | 无标准详情接口 | 单元测试 | JUnit5 | §5.9 | 检查 Controller 映射 | 无 `GET .../standards/{id}` | 仅列表分页 |
78 80
 | DP-SY-UT-025 | 缓存 | forceRefresh | 单元测试 | JUnit5 | 技术§2.3 | 启用缓存未过期 | `loadDashboard(2026,true)` | 跳过缓存重新聚合 |
79
-| DP-SY-UT-026 | 地图标注 | 年份与字段 | 单元测试 | JUnit5 | §5.12 | Mock Mapper 返回 1 乡镇 | `loadTownMapMarkers()` | `herdStatYear=当前年-1`;`outboundStatYear=当前年`;含 `townDeptId`/`townName`/存栏/出栏 |
81
+| DP-SY-UT-026 | 地图标注 | 最近填报年月 | 单元测试 | JUnit5 | §5.12 | Mock 存栏 2025-12、出栏 2026-05 | `loadTownMapMarkers()` | `herdStatYear=2025`;`outboundStatYear=2026`;含乡镇字段 |
80 82
 | DP-SY-UT-027 | 产业总览 | 填报合计 | 单元测试 | JUnit5 | §5.2 | Mock 填报合计 | `loadDashboard` | `inventoryTotal`/`annualOutbound` 取自填报表;与 **Y** 无关 |
81 83
 | DP-SY-UT-028 | 产业总览 | 农牧户合计 | 单元测试 | JUnit5 | §5.2 | Mock 出栏填报农牧户户数 | `loadDashboard` | `pastureCount` 为当年全县农牧户合计(字段名不变) |
82 84
 
@@ -87,12 +89,12 @@
87 89
 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
88 90
 | --- | --- | --- | --- | --- | --- | --- | --- | --- |
89 91
 | DP-SY-API-001 | 看板 | 满数据正常 | 接口测试 | Postman/curl | SY-01 正常流程 | 已登录;2026 各域有样本 | `GET .../dashboard?statYear=2026` | `code` 成功;含 `industryOverview`~`trainingTrend` 全节点;`statDate` 为今日 |
90
-| DP-SY-API-002 | 看板 | 产业总览八项 | 接口测试 | Postman | SY-03 | `YAK-INV`+`GRASS-MIX`+`TRADE-SNAP` | `GET dashboard` | 八项数值与手工/SQL 一致;**无**预警牦牛字段 |
92
+| DP-SY-API-002 | 看板 | 产业总览八项 | 接口测试 | Postman | SY-03 | 填报+`GRASS-MIX`+`TRADE-SNAP` | `GET dashboard` | 八项数值与手工/SQL 一致;存栏/出栏/农牧户取最近填报年月 |
91 93
 | DP-SY-API-003 | 看板 | 主数据切年不变 | 接口测试 | Postman | §2.6 | `TRADE-SNAP` 固定 | `statYear=2025` 与 `2026` | `supplierCount` 等三项相同 |
92
-| DP-SY-API-004 | 看板 | 历史年 statDate | 接口测试 | Postman | §2.2 | `YAK-HIST` | `statYear=2024` | `statDate=2024-12-31`;存栏/出栏按 2024 口径 |
93
-| DP-SY-API-005 | 看板 | 存栏趋势 12 月双系列 | 接口测试 | Postman | SY-04 | 2026 仅部分月有还原值 | `GET dashboard` | `monthlyTrend.length=12`;含 `bullCount`、`cowCount`;未来月为 0 |
94
-| DP-SY-API-006 | 看板 | 年龄结构占比 | 接口测试 | Postman | SY-05 | `YAK-INV` | `GET dashboard` | `ageStructure.length=3`;有存栏时 `sum(ratio)≈100` |
95
-| DP-SY-API-007 | 看板 | 出栏按月 | 接口测试 | Postman | SY-06 | `YAK-OUT-Y` | `GET dashboard` | `outboundMonthly.length=12`;3、8 月=1,其余 0 |
94
+| DP-SY-API-004 | 看板 | 历史年 statDate | 接口测试 | Postman | §2.2 | 已登录 | `statYear=2024` | `statDate=2024-12-31`;预约/补贴等按 2024;滚动 12 月趋势与 **Y** 无关 |
95
+| DP-SY-API-005 | 看板 | 存栏趋势滚动 12 月 | 接口测试 | Postman | SY-04 | `HERD-R12` | `GET dashboard` | `monthlyTrend.length=12`;含 `statYear`、`month`、`bullCount`、`cowCount`;缺月补 0 |
96
+| DP-SY-API-006 | 看板 | 年龄结构四档 | 接口测试 | Postman | SY-05 | 有存栏填报 | `GET dashboard` | `ageStructure.length=4`;有数据时 `sum(ratio)≈100` |
97
+| DP-SY-API-007 | 看板 | 出栏滚动 12 月 | 接口测试 | Postman | SY-06 | `OUT-R12` | `GET dashboard` | `outboundMonthly.length=12`;含 `statYear`、`month`;2026-05=88,其余 0 |
96 98
 | DP-SY-API-008 | 看板 | 草场退化五档 | 接口测试 | Postman | SY-07 | `GRASS-MIX` | `GET dashboard` | `degradationStats.length=5`;`sum(count)=grasslandCount` |
97 99
 | DP-SY-API-009 | 看板 | 预约三类年度+堆叠 | 接口测试 | Postman | SY-08 | `APT-Y`+`APT-EXCL` | `GET dashboard` | 年度合计不含拒绝/取消;`monthlyStacked` 12 条 |
98 100
 | DP-SY-API-010 | 看板 | 补贴万元 | 接口测试 | Postman | SY-09 | `SUB-Y` | `GET dashboard` | `typeStats` 3 项;金额分别为 1.00/2.00/3.00 万;`hasSubsidyData=true` |
@@ -101,7 +103,7 @@
101 103
 | DP-SY-API-013 | 看板 | 无补贴空态 | 接口测试 | Postman | §7.1 | `SUB-EMPTY` 年 | `GET dashboard` | `hasSubsidyData=false`;三类 `amountWan=0` |
102 104
 | DP-SY-API-014 | 看板 | 无农技空态 | 接口测试 | Postman | §7.1 | 无视频无培训发布 | `GET dashboard` | `hasAgriData=false` |
103 105
 | DP-SY-API-015 | 看板 | 无培训趋势空态 | 接口测试 | Postman | §7.1 | `TRAIN-EMPTY` | `GET dashboard` | `hasTrainingData=false` |
104
-| DP-SY-API-016 | 看板 | 无存栏时点 | 接口测试 | Postman | §7.1 | `YAK-EMPTY` | `GET dashboard` | `inventoryTotal=0`;`ageStructure` 全 0 |
106
+| DP-SY-API-016 | 看板 | 无存栏填报 | 接口测试 | Postman | §7.1 | `HERD-EMPTY` | `GET dashboard` | `inventoryTotal=0`;`ageStructure` 全 0;`monthlyTrend` 仍 12 条 |
105 107
 | DP-SY-API-017 | 看板 | 缺 statYear | 接口测试 | Postman | 异常 | 已登录 | 不传 `statYear` | 失败或默认当前年(与实现一致并文档统一) |
106 108
 | DP-SY-API-018 | 看板 | 非法 statYear | 接口测试 | Postman | 异常 | 已登录 | `statYear=abc` | 失败;`msg` 参数错误 |
107 109
 | DP-SY-API-019 | 看板 | statYear 回显 | 接口测试 | Postman | 一致性 | 已登录 | `statYear=2025` | `data.statYear=2025` |
@@ -117,7 +119,7 @@
117 119
 | DP-SY-API-029 | 标准列表 | 非法 category | 接口测试 | Postman | 异常 | 已登录 | `category=INVALID` | 失败或空列表(与实现一致) |
118 120
 | DP-SY-API-030 | 范围 | 无详情接口 | 接口测试 | Postman | §5.9 | 已登录 | `GET .../home/standards/1` | 404/405 |
119 121
 | DP-SY-API-031 | 范围 | 无维护接口 | 接口测试 | Postman | §3.2 | 已登录 | `POST/PUT/DELETE .../bigScreen/home/**` | 404/405 或无权限 |
120
-| DP-SY-API-032 | 联动 | 补录牦牛后 | 接口测试 | Postman | SY-13 | 2026 原 `YAK-EMPTY` | 后台新增存栏→`GET dashboard` | `inventoryTotal` 更新 |
122
+| DP-SY-API-032 | 联动 | 补录填报后 | 接口测试 | Postman | SY-13 | 原 `HERD-EMPTY` | 后台新增存栏填报→`GET dashboard` | `inventoryTotal` 更新 |
121 123
 | DP-SY-API-033 | 联动 | 发布标准后 | 接口测试 | Postman | SY-13 | 2026 原无标准 | 后台发布→`GET standards` | `total` 增加 |
122 124
 | DP-SY-API-034 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET dashboard` | 401 或统一未登录 |
123 125
 | DP-SY-API-035 | 权限 | 无大屏权限 | 接口测试 | Postman | 越权 | 无 `bigScreen:home:query` | `GET dashboard`、`GET standards` | 403 或无权限 |
@@ -136,9 +138,9 @@
136 138
 | DP-SY-UI-003 | 筛选 | 加载中防残留 | UI 测试 | Playwright+Chrome | §7.2 | 已登录 | 切年(可 `route.fulfill` 延迟 dashboard) | Loading/遮罩;完成后仅新年数据 |
137 139
 | DP-SY-UI-004 | 产业总览 | 八项卡片与单位 | UI 测试 | Playwright+Chrome | §5.2、SY-03 | 2026 有完整样本 | 查看产业总览区 | 8 项名称/数值/单位(头、个、亩)正确;**无**预警牦牛卡片 |
138 140
 | DP-SY-UI-005 | 产业总览 | 流通三项切年不变 | UI 测试 | Playwright+Chrome | §2.6 | `TRADE-SNAP` 固定 | 2025→2026 | 供应商/承销商/市场三数不变(未改主数据前提下) |
139
-| DP-SY-UI-006 | 图表 | 存栏公/母双折线 12 月 | UI 测试 | Playwright+Chrome | SY-04 | 2026 缺月样本 | 查看存栏变动图+悬停 | 12 刻度;公/母两图例;缺月/未来月为 0 |
140
-| DP-SY-UI-007 | 图表 | 年龄结构饼图 | UI 测试 | Playwright+Chrome | SY-05 | `YAK-INV` | 查看年龄结构 | 三档标签;占比之和 100%(有存栏时) |
141
-| DP-SY-UI-008 | 图表 | 出栏柱状 12 月 | UI 测试 | Playwright+Chrome | SY-06 | `YAK-OUT-Y` | 查看出栏统计+悬停 | 12 柱;仅 3、8 月有值 |
141
+| DP-SY-UI-006 | 图表 | 存栏公/母双折线 | UI 测试 | Playwright+Chrome | SY-04 | `HERD-R12` | 查看存栏变动图+悬停 | 横轴 12 刻度**仅月份**;悬停显 `YYYY年M月`;公/母两图例 |
142
+| DP-SY-UI-007 | 图表 | 年龄结构饼图 | UI 测试 | Playwright+Chrome | SY-05 | 有存栏填报 | 查看年龄结构 | 四档标签;占比之和 100%(有数据时) |
143
+| DP-SY-UI-008 | 图表 | 出栏柱状 12 月 | UI 测试 | Playwright+Chrome | SY-06 | `OUT-R12` | 查看出栏统计+悬停 | 12 柱、**无趋势折线**;横轴仅月;悬停显年月+头数 |
142 144
 | DP-SY-UI-009 | 图表 | 草场可用/使用中 | UI 测试 | Playwright+Chrome | SY-07 | `GRASS-MIX` | 查看草场区上部 | 两数字区分「可用」「使用中」;不与退化表简单相加为总量 |
143 145
 | DP-SY-UI-010 | 图表 | 退化等级占比 | UI 测试 | Playwright+Chrome | SY-07 | 五档均有 | 查看退化表/环图 | 五档名称与 API 一致;占比为 % |
144 146
 | DP-SY-UI-011 | 图表 | 预约堆叠柱 | UI 测试 | Playwright+Chrome | SY-08 | `APT-Y` | 查看预约区 | 左侧三类年度卡片;右侧 12 月堆叠;图例兽医/专家/机构 |
@@ -146,7 +148,7 @@
146 148
 | DP-SY-UI-013 | 指标 | 农技课堂 | UI 测试 | Playwright+Chrome | SY-11 | `VIDEO-Y`+培训 | 查看农技课堂 | 视频数、培训场次、培训内容合计正确 |
147 149
 | DP-SY-UI-014 | 图表 | 培训双曲线 | UI 测试 | Playwright+Chrome | SY-12 | `TRAIN-PUB` | 查看培训报名趋势 | 活动数、报名人数两系列;12 月 |
148 150
 | DP-SY-UI-015 | 空态 | 无出栏 | UI 测试 | Playwright+Chrome | §7.1 | 选无出栏年 | 切换该年 | 出栏图空态或全 0;年出栏卡片为 0 |
149
-| DP-SY-UI-016 | 空态 | 无存栏趋势 | UI 测试 | Playwright+Chrome | §7.1 | `YAK-EMPTY` | 切换该年 | 存栏趋势/年龄结构空态;总量 0 |
151
+| DP-SY-UI-016 | 空态 | 无存栏趋势 | UI 测试 | Playwright+Chrome | §7.1 | `HERD-EMPTY` | 打开页 | 趋势图空态或全 0 折线;年龄结构空态 |
150 152
 | DP-SY-UI-017 | 空态 | 无预约 | UI 测试 | Playwright+Chrome | §7.1 | 无预约年 | 切换该年 | 预约区空态;三类年度卡片为 0 |
151 153
 | DP-SY-UI-018 | 空态 | 无补贴 | UI 测试 | Playwright+Chrome | §7.1 | `SUB-EMPTY` 年 | 切换该年 | 补贴图空态或三类型 0 |
152 154
 | DP-SY-UI-019 | 空态 | 无农技 | UI 测试 | Playwright+Chrome | §7.1 | 视频+培训均为 0 | 切换该年 | 农技课堂空态(非假数据) |
@@ -218,9 +220,9 @@ await page.route('**/bigScreen/home/dashboard**', route =>
218 220
 | SY-01 | 默认当前年 | UI-001;API-001 |
219 221
 | SY-02 | 切年一致 | API-021、037;UI-002~003 |
220 222
 | SY-03 | 产业总览八项 | UT-010;API-002~003;UI-004~005 |
221
-| SY-04 | 存栏趋势公/母 12 月 | UT-005~006;API-005;UI-006 |
222
-| SY-05 | 年龄结构占比 | UT-008~009;API-006;UI-007 |
223
-| SY-06 | 出栏按月 | UT-007;API-007;UI-008 |
223
+| SY-04 | 存栏趋势滚动 12 月 | UT-005~006;API-005;UI-006 |
224
+| SY-05 | 年龄结构四档 | UT-008~009;API-006;UI-007 |
225
+| SY-06 | 出栏滚动 12 月 | UT-007、007b;API-007;UI-008 |
224 226
 | SY-07 | 草场占比 | API-008;UI-009~010 |
225 227
 | SY-08 | 预约统计 | UT-011~012;API-009;UI-011 |
226 228
 | SY-09 | 补贴金额 | UT-013~014;API-010、013;UI-012 |
@@ -240,4 +242,5 @@ await page.route('**/bigScreen/home/dashboard**', route =>
240 242
 
241 243
 | 版本 | 说明 |
242 244
 | --- | --- |
245
+| 1.1 | 对齐 v1.1 需求/技术方案:滚动 12 月、`statYear`+`month`、填报表样本、UI 横轴/Tooltip、四档年龄、地图最近填报年月 |
243 246
 | 1.0 | 初版:单元 25、接口 37、UI 29;覆盖 SY-01~14 与正常/异常/约束;Playwright+Chrome;Base `/bigScreen/home` |