|
|
@@ -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 |
|