wwh vor 1 Monat
Ursprung
Commit
7a1d3e4f87

+ 2 - 2
doc/大屏/交易销售/大屏交易销售功能需求-草稿.md

@@ -7,12 +7,12 @@
7 7
 2. 统计当前年份牦牛交易数据及农资商城订单数据
8 8
 3.  交易总览:牦牛交易订单数(单)、牦牛交易量(头)、牦牛交易总额(元);入驻商铺数(家)、农资订单量(单)、农资销售额(元),暂不实现(缺少农资商城设计)。
9 9
 4. 产地行情:统计牦牛最近7日的均价、最低价、最高价、最近一次行情日期;以曲线图的方式分3个维度展示最近7日牦牛的最低价、最高价、均价的走势。
10
-5. 牦牛交易数额趋势:按月、分两个维度统计当前年份牦牛的销售量(头)、销售额(元)。
10
+5. 牦牛交易数额趋势:按**距当前时间最近 12 个**、分两个维度统计牦牛的销售量(头)、销售额(元)。横轴仅显示月份,悬停显示某年某月。
11 11
 6. 牦牛销售去向:根据承销商的销售去向(本市/本省/外省)统计当前年份已完成的交易订单的交易总头数。
12 12
 7. 品质等级占比:根据已完成的交易订单明细的品质等级分类统计各个等级的占比,饼状图展示。
13 13
 8. 农资品类销售:根据农资商城中农资品类分类统计各个品类销售量与总销售量的占比;饼状图展示;
14 14
 9. 热销农资排行(前5):根据农资商城中农资品类分类统计各个品类销售量,展示销售量前5的热销农资;
15
-10. 商城订单趋势: 按月统计当前年份每月的商城订单数(单),曲线图展示;
15
+10. 商城订单趋势: 按**距当前时间最近 12 个**统计每月的商城订单数(单),曲线图展示;横轴仅显示月份,悬停显示某年某月。
16 16
 11. 店铺入驻:按月统计当前年份每月入驻商城的店铺数(家),饼状图展示;
17 17
 12.   消费区域排名(前5): 根据农资商城的订单的收货城市分类统计各个城市的农资销售额(万),展示前5的消费区域;
18 18
 13.   消费者评价:展示农资商城消费者评价词云;从订单评价表中抽取 content 字段,统计词频,按词频排序,返回前 50 个词;

+ 28 - 12
doc/大屏/交易销售/大屏交易销售功能需求.md

@@ -30,15 +30,28 @@
30 30
 
31 31
 ### 2.3 统计月份(按月图表)
32 32
 
33
-- 凡「按月统计」且与统计年份 **Y** 绑定的图表,横轴固定为 **1 月~12 月** 共 12 个刻度。
34
-- **缺月规则:** 该月在 **Y** 年内无任何纳入统计的业务记录时,当月指标按 **0** 展示;**不**省略刻度、**不**断线留空、**不**插值。
35
-- **当前年未来月:** 当 **Y** 为当前年时,**晚于统计日** 的月份按 **0** 展示(与缺月规则统一)。
33
+按月图表分两类,横轴规则**不同**:
34
+
35
+| 类型 | 适用区块 | 横轴规则 |
36
+| --- | --- | --- |
37
+| **统计年 Y 内 1~12 月** | (本期无;店铺入驻等为年度/实时快照) | — |
38
+| **滚动最近 12 个月** | **牦牛交易数额趋势**、**商城订单趋势** | 以服务器当前年月为锚点,取**含当月在内向前连续 12 个自然月**;**不**随页面「统计年份 **Y**」切换 |
39
+
40
+**滚动最近 12 个月**
41
+
42
+- 接口每条记录含 **`statYear`**、**`month`(1~12)**;按时间升序固定 **12** 条。
43
+- 缺月指标为 **0**;**不**省略刻度。
44
+- **前端横轴**仅展示月份;**鼠标悬停**展示 **YYYY年M月** 及数值。
45
+- 切换 **Y** 时,上述两趋势图**仍展示同一滚动窗口**。
46
+
47
+**农资订单量(总览)** = 滚动 12 月「商城订单趋势」各月 `orderCount` 之和(与趋势图窗口一致)。
36 48
 
37 49
 ### 2.4 指标类型与年份关系
38 50
 
39 51
 | 指标类型 | 代表指标 | 与统计年份 **Y** 的关系 |
40 52
 | --- | --- | --- |
41
-| **年内累计(已完成订单)** | 订单数、交易量、交易额、按月销量/销售额、销售去向、品质占比 | 仅统计 **Y** 年内满足 **§2.6** 的**已完成**交易订单 |
53
+| **年内累计(已完成订单)** | 订单数、交易量、交易额、销售去向、品质占比 | 仅统计 **Y** 年内满足 **§2.6** 的**已完成**交易订单 |
54
+| **滚动最近 12 月** | 牦牛交易数额趋势(按月销量/销售额)、商城订单趋势 | **§2.3**;**不**随 **Y** 切换 |
42 55
 | **滚动窗口(行情)** | 近 7 日均价/最低价/最高价、行情走势 | 以**统计日**为终点向前连续 **7** 个自然日;**与 Y 无关** |
43 56
 | **主数据实时快照** | 入驻商铺数(供应商数) | **不随 Y** 变化;为当前有效主数据条数 |
44 57
 
@@ -139,7 +152,7 @@
139 152
 | 区块 | 与 **Y** / 统计日关系 | 口径摘要 |
140 153
 | --- | --- | --- |
141 154
 | 农资品类销售、热销 Top5 | **Y**(统计年;当年已完成单按 `finish_time` 归属 **Y**,一级品类销量) | 饼图占比 + Top5 排行 |
142
-| 商城订单趋势 | **Y**;按月 1~12 | 非删除订单按 `create_time` 计数 |
155
+| 商城订单趋势 | **滚动 12 月**;按月计数 | 非删除订单按 `create_time` 归属月;跨年时合并两年 Open API 数据 |
143 156
 | 店铺入驻 | **Y**;按月占比饼图 | 按店铺 `create_time` 归属月 |
144 157
 | 消费区域 Top5 | **Y**;已完成单实付按收货城市 | 金额万元,Top5 |
145 158
 | 消费者评价词云 | **与 Y 无关**(全量评价 Top50) | 词频降序 |
@@ -287,13 +300,14 @@ flowchart TB
287 300
 | 项 | 规则 |
288 301
 | --- | --- |
289 302
 | 图表类型 | **柱状图 + 折线图**组合,或双轴图(以原型为准) |
290
-| 横轴 | **§2.3** 1~12 月 |
303
+| 数据范围 | **§2.3** 滚动最近 **12** 个自然月 |
304
+| 横轴 | 12 刻度,**仅显示月份**;悬停显 **YYYY年M月** |
291 305
 | 系列一 | **销售量(头)**:该月 **§2.5** 已完成订单的 **交易总头数** 合计 |
292 306
 | 系列二 | **销售额(元)**:该月 **§2.5** 已完成订单的 **交易总金额** 合计 |
293
-| 缺月/未来月 | **§2.3** |
294
-| 交互 | 悬停展示月份 + 头数 + 金额 |
307
+| 缺月 | 窗口内无完成单的月份为 **0** |
308
+| 与 **Y** | **不**随 **Y** 切换 |
295 309
 
296
-**无数据:** **Y** 年无任何已完成订单时,图表空态或 12 个月均为 0(与 **§7.1** 协调)。
310
+**无数据:** 滚动窗口内无任何已完成订单时,图表空态或 12 槽位均为 0(与 **§7.1** 协调)。
297 311
 
298 312
 ---
299 313
 
@@ -334,7 +348,8 @@ flowchart TB
334 348
 | 项 | 规则 |
335 349
 | --- | --- |
336 350
 | 图表类型 | **折线图**(面积图可选) |
337
-| 横轴 | **§2.3** 1~12 月 |
351
+| 数据范围 | **§2.3** 滚动最近 **12** 个自然月(商城 Open API 按年返回时服务端合并并补 `statYear`) |
352
+| 横轴 | 12 刻度,**仅显示月份**;悬停显 **YYYY年M月** |
338 353
 | 系列 | 每月商城订单数(单) |
339 354
 | 与 **Y** | 切换年份同步更新 |
340 355
 
@@ -415,14 +430,14 @@ flowchart TB
415 430
 | SY-JY-02 | 切换年份 | 切换 **Y** 后交易类区块同步更新;近 7 日行情仍按统计日 |
416 431
 | SY-JY-03 | 交易总览 | 订单数/量/额与手工按 **§2.5** 核算一致;入驻商铺数不随 **Y** 变 |
417 432
 | SY-JY-04 | 产地行情 | 7 日指标与走势图与 **§2.7** 一致;与 **Y** 无关 |
418
-| SY-JY-05 | 数额趋势 | 12 月双系列;缺月/未来月为 0;与 **§2.5** 按月核算一致 |
433
+| SY-JY-05 | 数额趋势 | 滚动 12 月双系列;含 `statYear`+`month`;缺月 0;横轴仅月、悬停显年月;**不**随 **Y** |
419 434
 | SY-JY-06 | 销售去向 | 三档头数之和 = 当年已完成总头数;占比合理 |
420 435
 | SY-JY-07 | 品质占比 | 各等级占比之和为 100%(有明细时);仅统计已完成订单明细 |
421 436
 | SY-JY-08 | 农资区块 | 右栏六区块有数据或规范空态;与商城 Open API 口径一致 |
422 437
 | SY-JY-09 | 后台补录后刷新 | 完成支付或登记行情后刷新可见;商城侧订单/评价变更后刷新可见农资区块 |
423 438
 | SY-JY-10 | 只读 | 无业务维护按钮 |
424 439
 | SY-JY-11 | 商城降级 | 商城 API 关闭或失败时牦牛区块正常、农资空态 |
425
-| SY-JY-12 | 农资订单量 | 总览「农资订单量」= 当年订单趋势各月之和(与商城 orderTrend 一致) |
440
+| SY-JY-12 | 农资订单量 | 总览「农资订单量」= **滚动 12 月**商城订单趋势各月之和 |
426 441
 
427 442
 ---
428 443
 
@@ -433,6 +448,7 @@ flowchart TB
433 448
 | 1.0 | 2026-05-26 | 由草稿优化:补全流程、边界、五区块需求;农资商城整块标为范围外 |
434 449
 | **1.1** | **2026-05-20** | **纳入农资商城 §8~13**:Open API 对接;总览增农资订单量;六区块右栏;**§2.12** 口径;农资年度销售额待商城 API |
435 450
 | **1.2** | **2026-05-20** | 对齐商城 Open API **v1.2**:品类/热销/区域改为**统计年**口径;大屏请求 overview 仅传 `statYear`;右栏标题展示统计年 |
451
+| **1.3** | **2026-07-04** | 牦牛交易数额趋势、商城订单趋势改为**滚动最近 12 月**;接口增 `statYear`+`month`;农资订单量与滚动趋势合计一致 |
436 452
 
437 453
 ---
438 454
 

+ 11 - 8
doc/大屏/交易销售/大屏交易销售技术方案.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 交易销售统计 — 技术方案
2 2
 
3
-> 依据:同目录 `大屏交易销售功能需求.md` **v1.2**。  
3
+> 依据:同目录 `大屏交易销售功能需求.md` **v1.3**。  
4 4
 > **牦牛交易**:交易市场平台**既有表**(订单、明细、供应商、承销商、日度行情、等级重量配置等),本服务 MyBatis 只读聚合。  
5 5
 > **农资商城**:**不直连**商城库表;经 **`MallStatsOpenApiClient`** 调用农资商城 Open API `GET /api/open/stats/overview`(口径见商城项目 `doc/平台后台/外部接口/商城数据统计技术方案.md`)。  
6 6
 > 本模块为**大屏只读看板**;看板主接口仍为**单接口** `GET /bigScreen/tradeSales/dashboard`。
@@ -17,7 +17,7 @@
17 17
 | **代码包(牦牛)** | `com.ruoyi.web.modules.screen`(`TradeSalesScreenController` / `ITradeSalesScreenService` / `vo` / `support`) |
18 18
 | **代码包(商城)** | `com.ruoyi.web.modules.screen.mallstats`(`MallStatsOpenApiClient` / `MallStatsOpenProperties` / Token / HTTP) |
19 19
 
20
-**分层(牦牛)**:`Controller` → `ITradeSalesScreenService`(口径编排、`statDate` 计算)→ `TradeSalesScreenMapper`(只读 SQL)+ `TradeSalesScreenSupport`(行情 7 日聚合、12 月补 0、占比)。
20
+**分层(牦牛)**:`Controller` → `ITradeSalesScreenService`(口径编排、`statDate` 计算)→ `TradeSalesScreenMapper`(只读 SQL)+ `TradeSalesScreenSupport`(行情 7 日聚合、**滚动 12 月**趋势、占比)。
21 21
 
22 22
 **分层(商城)**:`TradeSalesScreenServiceImpl.mergeMallStats` → `MallStatsOpenApiClient.fetchOverview`(HTTP + 本地 Redis 缓存)→ 写入 `TradeSalesDashboardVo` 农资字段;失败**降级空态**,**不阻断**牦牛区块。
23 23
 
@@ -31,7 +31,7 @@
31 31
 | 年内订单上界 | `finish_time` ≤ `statDate 23:59:59`(当前年);历史年 ≤ `Y-12-31 23:59:59` |
32 32
 | 入驻商铺数 | `biz_supplier` **实时快照**,**不**随 `statYear` 变 |
33 33
 | 产地行情近 7 日 | 以 **`statDate`** 为终点 `[statDate−6, statDate]`,**与 Y 无关** |
34
-| 按月图表 | 横轴固定 **12** 月;缺月、当前年**晚于 statDate 的月份**均为 **0** |
34
+| 按月趋势图 | **滚动最近 12 月**(牦牛交易、商城订单);锚点 `HomeScreenSupport.currentYearMonth()`;**不**随 `statYear` 变 |
35 35
 | 性能 | 牦牛:默认实时聚合;可选 **§2.3** 缓存表;商城:overview + 本地 Redis |
36 36
 
37 37
 **依赖表(只读 — 牦牛侧)**
@@ -238,7 +238,7 @@ XML:`mapper/screen/TradeSalesScreenMapper.xml`。
238 238
 | `tradeHeads` | long | 牦牛交易量(头) |
239 239
 | `tradeAmount` | decimal | 牦牛交易总额(元) |
240 240
 | `supplierCount` | long | 入驻商铺数(家),**实时**(牦牛供应商快照) |
241
-| `agriOrderCount` | long | 农资订单量(单);当年 `mallOrderTrend` 各月 `orderCount` **求和**;未接入时为 `null` |
241
+| `agriOrderCount` | long | 农资订单量(单);**滚动 12 月** `mallOrderTrend` 各月 `orderCount` **求和**;未接入时为 `null` |
242 242
 | `agriSalesAmount` | decimal | 农资销售额(元);**商城 Open API v1 未提供年度总额**,未接入或未返回时为 `null`,前端显示 **—** |
243 243
 
244 244
 #### 3.1.2 `originQuote`
@@ -263,15 +263,16 @@ XML:`mapper/screen/TradeSalesScreenMapper.xml`。
263 263
 
264 264
 #### 3.1.3 `tradeMonthlyTrend[]`
265 265
 
266
-固定 **12** 条。
266
+固定 **12** 条;**滚动最近 12 自然月**(`buildRolling12MonthTradeTrend`)
267 267
 
268 268
 | 字段 | 说明 |
269 269
 | --- | --- |
270
+| `statYear` | 自然年 |
270 271
 | `month` | 1~12 |
271 272
 | `tradeHeads` | 该月已完成订单总头数 |
272 273
 | `tradeAmount` | 该月已完成订单总金额(元) |
273 274
 
274
-`month > statDate.getMonth()` 且 `Y` 为当前年时两项为 **0**
275
+查询窗口:`finish_time` ∈ `[anchor−11 月 1 日, rollingWindowEnd]`;按月 `YEAR`+`MONTH` 聚合
275 276
 
276 277
 #### 3.1.4 `salesDestination[]`
277 278
 
@@ -320,8 +321,10 @@ XML:`mapper/screen/TradeSalesScreenMapper.xml`。
320 321
 
321 322
 | 字段 | 说明 |
322 323
 | --- | --- |
323
-| `statYear` | 统计年 |
324
-| `items[]` | 固定 12 条:`month` 1~12、`orderCount`(按商城 `create_time` 归属 **Y**) |
324
+| `statYear` | 锚点年(回显) |
325
+| `items[]` | 固定 **12** 条:**滚动最近 12 月**;每项含 `statYear`、`month`、`orderCount` |
326
+
327
+跨年时分别拉取商城 Open API 两年 `orderTrend` 并合并,再 `buildRolling12MonthMallOrderTrend`。
325 328
 
326 329
 #### 3.1.9 `shopEntry`
327 330
 

+ 6 - 6
doc/大屏/交易销售/大屏交易销售测试用例.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 交易销售统计 — 测试用例
2 2
 
3
-> 依据:`大屏交易销售功能需求.md`(**v1.2**)、`大屏交易销售技术方案.md`(**v1.2**)  
3
+> 依据:`大屏交易销售功能需求.md`(**v1.3**)、`大屏交易销售技术方案.md`(**v1.3**)  
4 4
 > **接口 Base Path**:`/bigScreen/tradeSales`(含 `context-path`、网关前缀须补齐)。鉴权:若依 Cookie / `Authorization` Token;权限 `bigScreen:tradeSales:query`。  
5 5
 > **农资商城**:经 `MallStatsOpenApiClient` 调用商城 `GET /api/open/stats/overview`;配置 `bigscreen.mall-stats.*`。
6 6
 
@@ -14,7 +14,7 @@
14 14
 | 统计日 | `Y`=当前年→今日;历史年→`Y-12-31` |
15 15
 | 已完成订单 | `order_status=1`、`del_flag=0`;`finish_time` 在 **Y** 年内且 ≤ `statDate 23:59:59` |
16 16
 | 待支付 | **不参与**任何统计 |
17
-| 按月图表 | 固定 12 月;缺月、当前年未来月=**0** |
17
+| 按月图表 | **滚动最近 12 月**(牦牛数额趋势、商城订单);含 `statYear`+`month`;**不**随 **Y** |
18 18
 | 入驻商铺 | `biz_supplier` 有效条数;**不随 Y** |
19 19
 | 产地行情 | `[statDate−6, statDate]` 共 7 日;默认市场「巴青牦牛交易市场」;**与 Y 无关** |
20 20
 | 销售去向 | 承销商 `sales_destination` 1/2/3;汇总**头数** |
@@ -60,7 +60,7 @@
60 60
 | DP-JY-UT-004 | 统计日 | 历史年 statDate | 单元测试 | JUnit5 | §2.2 | 无 | `resolveStatDate(2024)` | 返回 `2024-12-31` |
61 61
 | DP-JY-UT-005 | 订单口径 | 排除待支付 | 单元测试 | JUnit5 | §2.5 | `ORD-Y`+`ORD-PEND` | `sumCompletedOrders(2026)` | 仅 `ORD-Y` 笔数/头数/金额 |
62 62
 | DP-JY-UT-006 | 订单口径 | 当前年上界 | 单元测试 | JUnit5 | 技术§1 | 2026-05-20 完成 1 笔;05-21 完成 1 笔 | `loadTradeOverview(2026)` | 仅含 05-20 及之前完成单 |
63
-| DP-JY-UT-007 | 按月趋势 | 12 条补零 | 单元测试 | JUnit5 | §2.3、SY-JY-05 | `ORD-Y` 仅 3、8 月 | `buildTradeMonthlyTrend(2026, statDate)` | `length=12`;非 3/8 月 `tradeHeads=tradeAmount=0` |
63
+| DP-JY-UT-007 | 按月趋势 | 滚动 12 条补零 | 单元测试 | JUnit5 | §2.3、SY-JY-05 | `ORD-Y` 仅 2026-3、8 月 | `buildRolling12MonthTradeTrend(..., 2026-08)` | `length=12`;末条 `statYear=2026,month=8`;首槽 0 |
64 64
 | DP-JY-UT-008 | 按月趋势 | 未来月为 0 | 单元测试 | JUnit5 | §2.3 | 当前年 statDate=5 月 | 检查 `month=6..12` | 均为 0 |
65 65
 | DP-JY-UT-009 | 入驻商铺 | 切年不变 | 单元测试 | JUnit5 | §2.10、SY-JY-03 | 固定 `SUP-SNAP` | `loadDashboard(2025)` 与 `2026` | `supplierCount` 相同 |
66 66
 | DP-JY-UT-010 | 销售去向 | 三档固定桶 | 单元测试 | JUnit5 | §2.8、SY-JY-06 | `DIST-MIX` | `buildSalesDestination` | 3 项;`sum(tradeHeads)`=当年总头数 |
@@ -93,7 +93,7 @@
93 93
 | DP-JY-API-003 | 看板 | 入驻商铺切年不变 | 接口测试 | Postman | §2.10 | `SUP-SNAP` 固定 | `statYear=2025` 与 `2026` | `supplierCount` 相同 |
94 94
 | DP-JY-API-004 | 看板 | 排除待支付 | 接口测试 | Postman | §2.5 | `ORD-Y`+`ORD-PEND` | `GET dashboard` 2026 | 总览不含待支付笔数/头数/金额 |
95 95
 | DP-JY-API-005 | 看板 | 历史年 statDate | 接口测试 | Postman | §2.2 | `ORD-HIST` | `statYear=2024` | `statDate=2024-12-31`;总览仅 2024 完成单 |
96
-| DP-JY-API-006 | 看板 | 按月趋势 12 条 | 接口测试 | Postman | SY-JY-05 | `ORD-Y` | `GET dashboard` | `tradeMonthlyTrend.length=12`;3、8 月有值;未来月为 0 |
96
+| DP-JY-API-006 | 看板 | 按月趋势滚动 12 条 | 接口测试 | Postman | SY-JY-05 | `ORD-Y` | `GET dashboard` | `tradeMonthlyTrend.length=12`;含 `statYear`、`month`;3、8 月有值 |
97 97
 | DP-JY-API-007 | 看板 | 销售去向三档 | 接口测试 | Postman | SY-JY-06 | `DIST-MIX` | `GET dashboard` | `salesDestination.length=3`;`sum(tradeHeads)`=总览 `tradeHeads` |
98 98
 | DP-JY-API-008 | 看板 | 品质占比 | 接口测试 | Postman | SY-JY-07 | `GRADE-MIX` | `GET dashboard` | `hasGradeData=true`;`sum(ratio)≈100`;含 `gradeName` |
99 99
 | DP-JY-API-009 | 看板 | 产地行情 7 日 | 接口测试 | Postman | SY-JY-04 | `QUOTE-7D`+`MKT-DEF` | `GET dashboard` | `hasQuoteData=true`;`dailyTrend.length=7`;含三价字段 |
@@ -132,7 +132,7 @@
132 132
 | DP-JY-UI-005 | 交易总览 | 入驻商铺切年不变 | UI 测试 | Playwright+Chrome | §2.10 | `SUP-SNAP` 固定 | 2025→2026 | 第四卡数值不变(未改主数据前提下) |
133 133
 | DP-JY-UI-006 | 产地行情 | 7 日指标卡 | UI 测试 | Playwright+Chrome | SY-JY-04 | `QUOTE-7D` | 查看行情指标区 | 7 日均价/最低/最高、最近行情日期;标注元/头或元/斤 |
134 134
 | DP-JY-UI-007 | 产地行情 | 三曲线 7 日 | UI 测试 | Playwright+Chrome | SY-JY-04 | `QUOTE-7D` | 查看走势图+悬停 | 7 个横轴刻度;最低/最高/均价三图例;悬停显示三价 |
135
-| DP-JY-UI-008 | 图表 | 数额趋势双系列 12 月 | UI 测试 | Playwright+Chrome | SY-JY-05 | `ORD-Y` | 查看趋势图+悬停 | 12 月;销售量(头)+销售额(元);3、8 月有值 |
135
+| DP-JY-UI-008 | 图表 | 数额趋势双系列滚动 12 月 | UI 测试 | Playwright+Chrome | SY-JY-05 | `ORD-Y` | 查看趋势图+悬停 | 12 刻度**仅月份**;悬停显年月;销售量+销售额 |
136 136
 | DP-JY-UI-009 | 图表 | 销售去向饼图 | UI 测试 | Playwright+Chrome | SY-JY-06 | `DIST-MIX` | 查看销售去向 | 本市/本省/外省三档;头数与占比 |
137 137
 | DP-JY-UI-010 | 图表 | 品质等级饼图 | UI 测试 | Playwright+Chrome | SY-JY-07 | `GRADE-MIX` | 查看品质占比 | 一级/二级等中文标签;占比之和 100% |
138 138
 | DP-JY-UI-011 | 空态 | 无订单 | UI 测试 | Playwright+Chrome | §7.1 | `ORD-EMPTY` 年 | 切换该年 | 总览前三项 0;趋势空态或全 0;去向/品质空态 |
@@ -202,7 +202,7 @@ await page.route('**/bigScreen/tradeSales/dashboard**', route =>
202 202
 | SY-JY-02 | 切年;行情不按 Y | UT-018;API-010、018;UI-002 |
203 203
 | SY-JY-03 | 交易总览+商铺不随 Y | UT-009;API-002~003;UI-004~005 |
204 204
 | SY-JY-04 | 产地行情 7 日 | UT-014~017;API-009;UI-006~007 |
205
-| SY-JY-05 | 按月双系列 12 月 | UT-007~008;API-006;UI-008 |
205
+| SY-JY-05 | 滚动 12 月双系列 | UT-007~008;API-006;UI-008 |
206 206
 | SY-JY-06 | 销售去向三档 | UT-010~011;API-007;UI-009 |
207 207
 | SY-JY-07 | 品质占比 | UT-012~013;API-008;UI-010 |
208 208
 | SY-JY-08 | 农资区块 | UT-023、021;API-028;UI-014 |

+ 6 - 6
doc/大屏/共同富裕/大屏共同富裕功能需求-草稿.md

@@ -4,17 +4,17 @@
4 4
 
5 5
 2. 共富成果:集体经济收入(万元),就业人数(人),就业岗位数(个),环境治理项目数(个),绿化面积(亩),文化传承人数(人),民族团结活动数(个),区域公共品牌数(个)、品牌产品溢价率(%)、数字平台使用率(%)。
6 6
 
7
-3. 集体经济收入:按月统计集体经济收入,横向柱状图
7
+3. 集体经济收入:按**距当前时间最近 12 个**统计集体经济收入,横向柱状图;横轴仅显示月份,悬停显示某年某月。
8 8
 
9
-4. 就业带动:按月统计 分2个维度 就业人数(人)、就业岗位(个),折线图
9
+4. 就业带动:按**距当前时间最近 12 个月**统计,分 2 个维度(就业人数、就业岗位),折线图;横轴仅显示月份,悬停显示某年某月。
10 10
 
11
-5. 环境治理:按月统计 环境治理项目数, 柱状图。
11
+5. 环境治理:按**距当前时间最近 12 个**统计环境治理项目数,柱状图。
12 12
 
13
-6. 绿化建设:按月统计 新增绿化面积, 折线图。
13
+6. 绿化建设:按**距当前时间最近 12 个**统计新增绿化面积,折线图。
14 14
 
15
-7. 文化传承:按月统计 文化传承人数,柱状图。
15
+7. 文化传承:按**距当前时间最近 12 个**统计文化传承人数,柱状图。
16 16
 
17
-8. 民族团结:按月统计 分2个维度 民族融合案例 、民族团结活动, 堆叠柱状图。
17
+8. 民族团结:按**距当前时间最近 12 个月**统计,分 2 个维度(民族融合案例、民族团结活动),堆叠柱状图。
18 18
 
19 19
 9. 共富项目分类:统计共富项目(合作共赢)、农文旅项目(农文旅融合)、认养项目(认养农业)类别项目各自占比,饼状图。
20 20
 

+ 14 - 7
doc/大屏/共同富裕/大屏共同富裕功能需求.md

@@ -21,12 +21,18 @@
21 21
 
22 22
 - 大屏顶部(或全局筛选区)提供**统计年份**选择,格式为自然年 **YYYY**(如 `2026`)。
23 23
 - 进入大屏时默认选中**当前自然年**。
24
-- 变更统计年份后,本页**全部区块**(总览、图表、项目分类、项目列表)须**同步**按新年份重新计算与展示,不得出现区块之间年份不一致
24
+- 变更统计年份后,**总览卡片、项目分类、项目列表**等标注「与 **Y** 相关」的区块须**同步**按新年份重算;**§5.3~5.9 按月图表**为滚动最近 12 月,**不**随 **Y** 切换(见 **§2.2**)
25 25
 
26 26
 ### 2.2 统计月份(图表横轴)
27 27
 
28
-- 凡「按月统计」的图表,横轴固定为 **1 月~12 月** 共 12 个刻度。
29
-- **缺月规则:** 某月无对应「共同富裕成果」台账记录时,该指标在该月按 **0** 参与展示(柱状高度为 0、折线落点为 0);**不**省略该月刻度、**不**断线留空、**不**用相邻月插值。
28
+**滚动最近 12 个月**(适用于 **§5.3~5.9** 全部按月图表)
29
+
30
+- 以服务器当前年月为锚点,取**含当月在内向前连续 12 个自然月**;**不**随页面「统计年份 **Y**」切换。
31
+- 接口 `achievement.monthly[]` 每条含 **`statYear`**、**`month`(1~12)**、**`statPeriod`(yyyy-MM)**;按时间升序固定 **12** 条。
32
+- **缺月规则:** 窗口槽位内无对应成果台账时,各指标按 **0** 展示;**不**省略刻度、**不**断线留空。
33
+- **前端横轴**仅展示月份(如 `8月`);**鼠标悬停**展示 **YYYY年M月** 及数值。
34
+
35
+**年度总览**(**§2.4**)仍按选定 **Y** 全年 1~12 月台账汇总,与滚动图表窗口**独立**。
30 36
 
31 37
 ### 2.3 共富成果指标(与后台台账一致)
32 38
 
@@ -278,10 +284,10 @@ flowchart TD
278 284
 | 项 | 规则 |
279 285
 | --- | --- |
280 286
 | 标题 | 各图表有明确中文标题(可与原型一致) |
281
-| 横轴 | 1~12 月;标签格式全站统一(如 `1月`…`12月`) |
287
+| 横轴 | **滚动 12 月**;12 个刻度,**仅显示月份**;悬停显 **YYYY年M月** |
282 288
 | 纵轴 | 标注单位或通过图例说明 |
283
-| 单点数据 | 仅 1 个月有台账时,图表仍须正常渲染 |
284
-| 跨年 | 仅使用选定年份内月份数据,**不得**混入其他年份台账 |
289
+| 单点数据 | 滚动窗口内仅 1 个月有台账时,图表仍须正常渲染 |
290
+| 跨年 | 滚动窗口可跨自然年;按 `statPeriod` 归属槽位 |
285 291
 | 同月唯一 | 依赖后台「同一统计范围不可重复」;若后台允许多条,须约定取**最新登记**一条并修订本文档 |
286 292
 
287 293
 ---
@@ -333,7 +339,7 @@ flowchart TD
333 339
 | --- | --- | --- |
334 340
 | DP-01 | 默认年份 | 进入大屏默认当前年,总览与图表年份一致 |
335 341
 | DP-02 | 切换年份 | 切换后全页数据同属一年;无旧年残留 |
336
-| DP-03 | 缺月 | 仅 3、8 月有台账时,其余月份图表为 0,横轴仍为 12 月 |
342
+| DP-03 | 缺月 | 滚动 12 月窗口内仅 3、8 月有台账时,其余槽位为 0;横轴仍为 12 刻度;悬停显年月 |
337 343
 | DP-04 | 全年无成果 | 总览与图表空态,非全 0 假数据 |
338 344
 | DP-05 | 比率展示 | 溢价率、使用率与后台逻辑一致(12 个月平均后按 % 展示) |
339 345
 | DP-06 | 就业/民族团结双系列 | 图例、Tooltip 可区分两个维度 |
@@ -349,6 +355,7 @@ flowchart TD
349 355
 | 版本 | 日期 | 说明 |
350 356
 | --- | --- | --- |
351 357
 | 1.0 | 2026-05-25 | 由草稿优化:补全流程、口径、十区块需求;对齐成果/项目/年度报告;明确列表行内详情;不涉及库表与接口 |
358
+| 1.1 | 2026-07-04 | **§5.3~5.9** 按月图表改为**滚动最近 12 月**;`monthly` 增 `statYear`;总览仍按 **Y** 汇总 |
352 359
 
353 360
 ---
354 361
 

+ 7 - 6
doc/大屏/共同富裕/大屏共同富裕技术方案.md

@@ -136,7 +136,7 @@
136 136
 | --- | --- |
137 137
 | `hasData` | 即 `hasAchievementData`;全年无成果台账为 `false` |
138 138
 | `summary` | 年度总览;`hasData=false` 时为 **`null`** |
139
-| `monthly` | 固定 **12** 条,`month` 1~12;缺月指标为 **0** |
139
+| `monthly` | 固定 **12** 条;**滚动最近 12 自然月**;每项含 `statYear`、`month`、`statPeriod`;缺月指标为 **0** |
140 140
 
141 141
 **图表字段映射**(与功能需求 §5、年度报告一致)
142 142
 
@@ -181,11 +181,12 @@
181 181
 
182 182
 ```
183 183
 1. year = parseStatYear(statYear)
184
-2. achievement = achievementReportService.getAnnualReport(String.valueOf(year))
185
-3. projects = mapper.selectPublishedForScreen(year)
186
-4. projectTypeStats = groupByType(projects); hasProjectData = total > 0
187
-5. availableYears = union(achievementMapper.selectDistinctStatYears(), projectYears)
188
-6. return AjaxResult.success(vo)
184
+2. achievement = achievementReportService.getAnnualReport(String.valueOf(year));`summary`/`hasData` 仍按 **Y**
185
+3. achievement.monthly = AchievementReportAggregator.buildRollingMonthly(anchor, selectByStatPeriodBetween(...)) — **滚动 12 月**,**不**随 **Y**
186
+4. projects = mapper.selectPublishedForScreen(year)
187
+5. projectTypeStats = groupByType(projects); hasProjectData = total > 0
188
+6. availableYears = union(achievementMapper.selectDistinctStatYears(), projectYears)
189
+7. return AjaxResult.success(vo)
189 190
 ```
190 191
 
191 192
 ---

+ 5 - 5
doc/大屏/共同富裕/大屏共同富裕测试用例.md

@@ -1,9 +1,9 @@
1 1
 # 大屏 — 共同富裕统计 — 测试用例
2 2
 
3
-> 依据:`大屏共同富裕功能需求.md`、`大屏共同富裕技术方案.md`  
3
+> 依据:`大屏共同富裕功能需求.md`(v1.1)、`大屏共同富裕技术方案.md`  
4 4
 > **接口 Base Path**:`/bigScreen/commonProsperity`(含 `context-path`、网关前缀须补齐)。鉴权:若依 Cookie / `Authorization` Token;权限 `bigScreen:commonProsperity:query`。
5 5
 
6
-**通用前置(无特殊说明)**:已执行 `sql/biz_common_prosperity_achievement.sql`、`sql/biz_common_prosperity_project.sql`;测试账号具备大屏查询权限。**成果口径**:缺月指标 **0**;全年无成果 `achievement.hasData=false`、`summary=null`;加总类 **SUM(12 月)**;比率类 **(SUM 12 月)/12**。**项目口径**:`publish_status=1`;实施周期与统计年 **Y** 交集(`impl_start_date ≤ Y-12-31` 且 `impl_end_date ≥ Y-01-01`)
6
+**成果口径(图表)**:`achievement.monthly` 为**滚动最近 12 月**;含 `statYear`+`month`;**不**随 **Y**;缺月 **0**。**总览** `summary` 仍按 **Y** 全年汇总
7 7
 
8 8
 **UI 测试**:**Playwright** + **Chromium**,`playwright.config` 中 `use: { channel: 'chrome' }` 调用本机 **Google Chrome**。
9 9
 
@@ -54,7 +54,7 @@
54 54
 | 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
55 55
 | --- | --- | --- | --- | --- | --- | --- | --- | --- |
56 56
 | DP-GTFY-API-001 | 看板 | 满年成果+项目 | 接口测试 | Postman/curl | 正常流程 DP-01 | 已登录;2026 成果多月+已发布项目 | `GET .../dashboard?statYear=2026` | `code` 成功;`achievement.hasData=true`;`monthly.length=12`;`hasProjectData=true`;`projectTypeStats` 有数据 |
57
-| DP-GTFY-API-002 | 看板 | 缺月补零 | 接口测试 | Postman | DP-03 | ACH-2026 仅 3、8 月 | `statYear=2026` | 缺月 `monthly` 指标为 0;横轴逻辑由前端;汇总符合 §2.4 |
57
+| DP-GTFY-API-002 | 看板 | 滚动 12 月缺月补零 | 接口测试 | Postman | DP-03 | ACH-2026 仅 3、8 月 | `statYear=2026` | `monthly` 含 `statYear`、`month`;缺槽 0;**不**随 **Y** 变窗口 |
58 58
 | DP-GTFY-API-003 | 看板 | 全年无成果 | 接口测试 | Postman | DP-04 | 2026 ACH-EMPTY | `GET dashboard` | `achievement.hasData=false`;`summary=null`;`monthly` 仍 12 条全 0 |
59 59
 | DP-GTFY-API-004 | 看板 | 仅项目无成果 | 接口测试 | Postman | §7.2 | 2026 无成果;有 PRJ-PUB-B | `GET dashboard` | `achievement.hasData=false`;`hasProjectData=true`;饼图 stats 正常 |
60 60
 | DP-GTFY-API-005 | 看板 | 仅成果无项目 | 接口测试 | Postman | §7.2 | 2026 有 ACH;无符合交集项目 | `GET dashboard` | `achievement.hasData=true`;`hasProjectData=false`;`projectTypeStats` 三项 count=0 |
@@ -94,7 +94,7 @@
94 94
 | DP-GTFY-UI-004 | 空态 | 全年无成果 | UI 测试 | Playwright+Chrome | DP-04、§7.1 | 选 ACH-EMPTY 年 | 进入或切换该年 | 总览/图表/数字赋能空态文案;**不**显示全 0 汇总卡片 |
95 95
 | DP-GTFY-UI-005 | 空态 | 无项目有成果 | UI 测试 | Playwright+Chrome | §7.2 | 2026 有成果无项目 | 打开 2026 | 图表正常;饼图空态;列表「本年度暂无共富项目」 |
96 96
 | DP-GTFY-UI-006 | 总览 | 指标与单位 | UI 测试 | Playwright+Chrome | §5.2 | 2026 有成果 | 查看共富成果卡片区 | 名称/数值/单位正确(万元、人、个、亩);比率显示 **%** |
97
-| DP-GTFY-UI-007 | 图表 | 集体经济横向柱 12 月 | UI 测试 | Playwright+Chrome | §5.3、DP-03 | ACH-2026 缺月 | 查看该图+悬停 | 12 刻度;缺月高度 0;Tooltip 含月份+万元 |
97
+| DP-GTFY-UI-007 | 图表 | 集体经济横向柱滚动 12 月 | UI 测试 | Playwright+Chrome | §5.3、DP-03 | ACH-2026 缺月 | 查看该图+悬停 | 12 刻度**仅月份**;悬停显 **YYYY年M月**+万元 |
98 98
 | DP-GTFY-UI-008 | 图表 | 就业双系列 | UI 测试 | Playwright+Chrome | DP-06、§5.4 | 2026 有数据 | 查看就业带动图 | 两图例/两色系;Tooltip 区分人数与岗位 |
99 99
 | DP-GTFY-UI-009 | 图表 | 环境治理/文化传承柱图 | UI 测试 | Playwright+Chrome | §5.5、§5.8 | 2026 有数据 | 查看两图 | 12 月;缺月为 0 |
100 100
 | DP-GTFY-UI-010 | 图表 | 绿化折线 | UI 测试 | Playwright+Chrome | §5.6 | 2026 有数据 | 查看绿化建设 | 12 落点;缺月 0 不断线 |
@@ -157,7 +157,7 @@ await expect(page.locator('[data-chart]')).toHaveCount(6); // 集体经济/就
157 157
 | --- | --- | --- |
158 158
 | DP-01 | 默认当前年 | UI-001;API-001 |
159 159
 | DP-02 | 切年一致 | API-028;UI-002~003 |
160
-| DP-03 | 缺月=0、12 月 | UT-003;API-002;UI-007~011 |
160
+| DP-03 | 滚动 12 月缺月=0 | UT-003;API-002;UI-007~011 |
161 161
 | DP-04 | 无成果空态 | UT-004;API-003;UI-004、013 |
162 162
 | DP-05 | 比率 % | UT-005;API-006;UI-006、012 |
163 163
 | DP-06 | 双系列图 | UI-008、011 |

+ 1 - 1
doc/大屏/畜牧资源/大屏畜牧资源功能需求-草稿.md

@@ -7,7 +7,7 @@
7 7
 5. 用户结构分析:统计biz_diagnosis_user表中的新用户人数、老用户人数;新用户:last_use_time-first_use_time <=半年;老用户:last_use_time-first_use_time > 半年;
8 8
 6. 提问分类占比:查询biz_consult_message表中sender_role=3、sender_user_id=0截至到当前时间的通过ai_category进行分类统计各个类型占问题总数的比例;饼状图展示。
9 9
 7. 模型调用分析:查询biz_consult_message表中sender_role=3、sender_user_id=0截至到当前时间的通过ai_category进行分类统计提问次数。
10
-8. 分时使用热度: 分会话数(次)、提问量(次)两个维度统当天24小时内每小时的会话数、提问量的趋势变化;会话数:biz_consult_session表中当天24小时内某个小时内创建的会话数;提问量:统计biz_consult_message表中sender_role=3、sender_user_id=0、create_time为当天24小时内某个小时的记录行数
10
+8. 分时使用热度: 分会话数(次)、提问量(次)两个维度统计**距当前时间最近 24 小时**内每整点小时的会话数、提问量趋势;会话数:`biz_consult_session` 表该小时内创建的会话数;提问量:`biz_consult_message` 表 `sender_role=3`、`sender_user_id=0` 且 `create_time` 落在该整点小时的记录行数。横轴 `HH:mm`,悬停显 `yyyy-MM-dd HH:mm`
11 11
 9. 单次会话提问数量分布:通过会话提问次数(1-2条|3-4条|5-10条|10条以上)分类统计对对应类型的会话与总会话数的占比;通过biz_consult_session表和biz_consult_message关联,统计每个会话的提问数量(sender_role=3、sender_user_id=0的记录条数);
12 12
 10. 会话状态分布:分正常应答、调用失败2个维度统计提问次数;正常应答:cost_time不为空;调用失败:cost_time为空;查询biz_consult_message表中sender_role=3、sender_user_id=0截至到当前时间的按维度统计记录的条数。
13 13
 11. 热点问题榜单:查询biz_consult_message表中sender_role=3、sender_user_id=0截至到当前时间的通过ai_category进行分类统计各个类型占问题总数的比例;占比多的即为热点问题;按时间倒序取前5条。

+ 14 - 12
doc/大屏/畜牧资源/大屏畜牧资源功能需求.md

@@ -9,7 +9,7 @@
9 9
 | 目标 | 按**统计年份**与**统计日**,集中展示 **AI 诊断(兽医、机构)** 及 **移动端 AI 助手** 的使用规模、活跃趋势、用户结构、提问分类与模型应答质量,形成「畜牧资源 / 智能问诊」成效一屏总览 |
10 10
 | 数据来源 | **牧业疫病诊疗服务 — AI 诊断**:AI 问诊会话、问答消息、AI 诊断使用用户台账;数据由兽医/机构后台、移动端用户日常使用 AI 助手产生,大屏**不录入、不修改** |
11 11
 | 修订依据 | 同目录 `大屏畜牧资源功能需求-草稿.md`;大屏页面布局见 `ruoyi-screen` 畜牧资源专题页;指标口径与《AI 诊断(兽医、机构)功能需求》v1.1 对齐 |
12
-| **文档版本** | **1.2**(对齐草稿修订;产品确认见 **§2.18**) |
12
+| **文档版本** | **1.3**(分时热度改为距当前最近 24 小时;对齐实现) |
13 13
 | 关联维护 | 会话、提问、AI 回复须在业务端(管理端 AI 诊断、移动端 AI 助手)产生;大屏通过刷新或重新进入获取最新结果 |
14 14
 
15 15
 **命名说明:** 本专题在大屏导航中称为「畜牧资源」,**本期统计对象为 AI 智能问诊使用数据**,与移动端「畜牧资源」资讯列表(专家团队、技术成果等)**不是同一业务**,二者勿混用。
@@ -25,7 +25,7 @@
25 25
 - 大屏顶部(或全局筛选区)提供**统计年份**选择,格式为自然年 **YYYY**(如 `2026`)。
26 26
 - 进入大屏时默认选中**当前自然年**。
27 27
 - 变更统计年份后,凡标注「与 **Y** 相关」的区块须**同步**按新年份重算;**不得**出现区块之间年份不一致。
28
-- **近 7 日活跃度**、**统计日分时热度**按 **§2.2 统计日** 计算,**不随 Y 切换**(见 **§2.4**)。
28
+- **近 7 日活跃度**、**分时使用热度(最近 24 小时)**按 **§2.2 统计日 / §2.3 统计时刻** 计算,**不随 Y 切换**(见 **§2.4**)。
29 29
 
30 30
 ### 2.2 统计日
31 31
 
@@ -42,7 +42,7 @@
42 42
 | **Y 年内累计** | 累计使用用户、累计会话数、累计提问量、平均响应时长、分类占比、模型调用次数、会话提问分布、会话状态分布、高频关键词 | 仅统计 **Y** 年内纳入 **§2.5** 的数据 |
43 43
 | **统计日当天** | 今日活跃用户、日新增用户、今日会话数、今日提问量 | 以**统计日**为自然日边界;当 **Y** 不等于当前自然年时,上述四项按 **0** 展示(或展示 **—** 并标注「仅当前年有效」,产品择一,全文统一) |
44 44
 | **滚动窗口** | 近 7 日会话数/提问量趋势 | 以**统计日**为终点向前 7 日;**与 Y 无关** |
45
-| **统计日分时** | 分时使用热度(24 整点小时) | 以**统计日**自然日为区间;**与 Y 无关** |
45
+| **最近 24 小时分时** | 分时使用热度(24 整点小时) | 以**统计时刻**为锚点向前 **24** 个整点小时;**与 Y 无关** |
46 46
 
47 47
 ### 2.5 AI 问诊数据纳入规则
48 48
 
@@ -119,12 +119,12 @@
119 119
 - **提问量**:该日 **`create_time`** 落在当日的 AI 助手回复条数(**§2.6**)。
120 120
 - 缺日无数据时该日按 **0** 展示;**不**省略刻度。
121 121
 
122
-### 2.12 统计日分时热度窗口(对齐草稿
122
+### 2.12 分时使用热度窗口(最近 24 小时
123 123
 
124
-- 区间:**统计日**自然日 **00:00:00~23:59:59**(**当天 24 小时**,**不**使用滑动 24 小时窗口)
125
-- 分桶:按自然小时 **0~23** 共 **24** 桶;横轴标签建议 `HH:00`(如 `00:00` … `23:00`)
126
-- **会话数**:该小时内**创建**的有效 AI 问诊会话数。
127
-- **提问量**:该小时内 **`create_time`** 落在该小时的 AI 助手回复条数(**§2.6**)。
124
+- 区间:以打开或刷新大屏时的**统计时刻**(**§2.3**)所在整点为右端点,向前连续 **24** 个整点小时(含右端点小时);**不**使用「统计日 0~23 时」自然日窗口
125
+- 分桶:共 **24** 桶;横轴标签 `HH:mm`(如 `15:00`);**鼠标悬停**展示完整时刻 `yyyy-MM-dd HH:mm` 及会话数、提问量
126
+- **会话数**:该整点小时内**创建**的有效 AI 问诊会话数。
127
+- **提问量**:该整点小时内 **`create_time`** 落在该小时的 AI 助手回复条数(**§2.6**)。
128 128
 
129 129
 ### 2.13 单次会话 AI 应答数量分布
130 130
 
@@ -180,7 +180,7 @@
180 180
 | 1 | 总览/趋势中的「提问量」名称 | 界面**统一**使用「提问量」;统计对象为 **AI 助手回复条数** |
181 181
 | 2 | 已隐藏会话 | **纳入**统计 |
182 182
 | 3 | 提问分类占比分母 | **Y 年内全部 AI 回复条数**(含未分类);有数据时占比之和 **100%** |
183
-| 4 | 分时热度窗口 | **统计日自然日** 24 个整点小时桶(**§2.12**),非滑动 24 小时 |
183
+| 4 | 分时热度窗口 | **距当前最近 24 小时**整点桶(**§2.12**),非统计日 0~23 自然小时 |
184 184
 | 7 | 今日活跃 / 日新增 | 今日活跃按会话 **`update_time`**;日新增须 **`create_time` 与 `update_time` 均在统计日** 且此前无会话(**§2.8**) |
185 185
 | 8 | 分类 / 模型调用 / 热点 | 统计 **AI 回复条数** 及分类归因(**§2.10**);占比分母为年内全部 AI 回复 |
186 186
 | 5 | 平均响应时长 | 已记录耗时的应答**含 0** 参与平均;**不排除 0** |
@@ -347,7 +347,8 @@ flowchart TB
347 347
 | --- | --- |
348 348
 | 位置 | 右栏顶部 |
349 349
 | 维度 | 会话数、提问量(**§2.12**) |
350
-| 统计窗口 | **过去 24 小时**滑动窗口(**§2.12**) |
350
+| 统计窗口 | **距当前最近 24 小时**整点窗口(**§2.12**) |
351
+| 横轴 / 悬停 | 横轴 `HH:mm`;悬停 `yyyy-MM-dd HH:mm` + 会话数、提问量 |
351 352
 | 图表类型 | 折线图/柱状图(以原型为准) |
352 353
 | 与 **Y** | **无关**;随刷新更新统计时刻 |
353 354
 
@@ -447,7 +448,7 @@ flowchart TB
447 448
 | SY-XM-04 | 活跃度趋势 | 7 日双维度与 **§2.11** 一致 |
448 449
 | SY-XM-05 | 用户结构 | 新老划分符合 **§2.9**(180 天);不随 **Y** 误变 |
449 450
 | SY-XM-06 | 分类占比与模型分析 | 分类名称与《AI 诊断》一致;占比之和为 100%(有数据时) |
450
-| SY-XM-07 | 24 小时热度 | **过去 24 小时**滑动窗口、24 时段分桶与 **§2.12** 一致 |
451
+| SY-XM-07 | 24 小时热度 | **最近 24 小时**整点窗口、24 桶与 **§2.12** 一致;悬停显完整时刻 |
451 452
 | SY-XM-08 | 会话分档与状态 | 分档、正常/失败与 **§2.13、§2.14** 一致 |
452 453
 | SY-XM-09 | 热点榜单 | Top5 为分类维度,非单条消息时间序 |
453 454
 | SY-XM-10 | 高频词 | Top30;语料为 **Y** 年内文本提问 |
@@ -464,6 +465,7 @@ flowchart TB
464 465
 | 1.0 | 2026-05-20 | 由草稿优化:补术语、流程、十区块需求与验收;对齐 AI 诊断业务;不涉及库表与接口;草稿文件不修改 |
465 466
 | 1.1 | 2026-05-20 | **§2.18** 产品确认:提问量名称、隐藏会话计入、分类占比 100% 分母、过去 24 小时窗口、耗时含 0、关键词仅文本 |
466 467
 | 1.2 | 2026-05-20 | 对齐草稿修订:**§2.8** `update_time` 今日活跃、日新增双时间+历史未出现;**§2.10~2.15** AI 回复分类统计;**§2.12** 统计日 24 自然小时桶;消息时间以 `create_time` 为主 |
468
+| 1.3 | 2026-07-04 | **§2.12** 分时使用热度改为距**统计时刻**最近 **24** 整点小时;前端悬停显 `yyyy-MM-dd HH:mm` |
467 469
 
468 470
 ---
469 471
 
@@ -475,7 +477,7 @@ flowchart TB
475 477
 | 「统计当前年份」与「截至当前时间」混用 | 统一 **§2.1、§2.4**:年内指标随 **Y**;今日类随统计日;7 日/24 小时滚动 |
476 478
 | 「提问量」统计 AI 回复行 | **§2.6** 展示名固定「提问量」,对象为 AI 回复条数 |
477 479
 | 分类占比分母 | **§2.10** 全部 AI 回复,占比之和 100% |
478
-| 24 小时窗口 | **§2.12** 统计日 **0~23** 自然小时(v1.2 对齐草稿) |
480
+| 24 小时窗口 | **§2.12** 距统计时刻最近 **24** 整点小时(v1.3) |
479 481
 | 平均耗时排除 0 | **§2.7** 含 0 参与平均 |
480 482
 | 隐藏会话 | **§2.5** 明确纳入 |
481 483
 | 关键词语料 | **§2.16** 仅文本提问 |

+ 11 - 11
doc/大屏/畜牧资源/大屏畜牧资源技术方案.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 畜牧资源统计 — 技术方案
2 2
 
3
-> 依据:同目录 `大屏畜牧资源功能需求.md` v1.2。数据源为 **AI 诊断** 既有表(会话、消息、使用用户台账)。本模块为**大屏只读看板**;**不**统计移动端「畜牧资源」资讯视图 `v_livestock_resource`。
3
+> 依据:同目录 `大屏畜牧资源功能需求.md` v1.3。数据源为 **AI 诊断** 既有表(会话、消息、使用用户台账)。本模块为**大屏只读看板**;**不**统计移动端「畜牧资源」资讯视图 `v_livestock_resource`。
4 4
 
5 5
 ---
6 6
 
@@ -24,7 +24,7 @@
24 24
 | 年内上界 | 会话 `create_time`;AI 消息 **`create_time`** ≤ `statDate 23:59:59`(当前年) |
25 25
 | 「今日」四项 | 仅当 `Y` = 当前自然年时按 `statDate` 自然日统计;否则固定 **0** |
26 26
 | 用户结构 | `biz_consult_user` **全表快照**,**不**随 `Y` 变 |
27
-| 7 日 / 分时 | 7 日以 `statDate` 滚动;分时为 **统计日 0~23 时**,**与 Y 无关** |
27
+| 7 日 / 分时 | 7 日以 `statDate` 滚动;分时为 **距 statDateTime 最近 24 整点小时**,**与 Y 无关** |
28 28
 | 已隐藏会话 | **不**过滤 `vet_visible`(对齐功能需求 **§2.18#2**) |
29 29
 | 性能 | 默认实时聚合;可选 **§2.3** 缓存表 |
30 30
 
@@ -66,7 +66,7 @@
66 66
 | 年区间止(会话 `create_time`、AI 消息 `create_time`) | `statDate 23:59:59` |
67 67
 | 统计日区间 | `statDate 00:00:00` ~ `statDate 23:59:59` |
68 68
 | 近 7 日 | `[statDate − 6 日 00:00:00, statDate 23:59:59]` |
69
-| 统计日分时 | 统计日自然日;`HOUR(create_time)` / `HOUR(m.create_time)` 分 **24** 桶(0~23) |
69
+| 最近 24 小时 | `[floor(statDateTime 到整点) − 23 小时, floor(statDateTime 到整点) + 59 分 59 秒]`;SQL 按 `DATE_FORMAT(create_time,'%Y%m%d%H')` 分组 |
70 70
 
71 71
 **会话别名(下文)**:`s` = `biz_consult_session`,条件 `s.consult_type = 2`。  
72 72
 **AI 消息别名**:`m_ai` = `biz_consult_message`,`m_ai.sender_role = 3 AND m_ai.sender_user_id = 0`,且 `EXISTS` 关联 `s.id = m_ai.session_id`。  
@@ -129,14 +129,14 @@
129 129
 | 占比 | 分类 AI 回复条数 / **当年全部 AI 回复** × 100 |
130 130
 | 热点 Top5 | 条数降序;同分按 `lastEventTime` 降序;取 **5** |
131 131
 
132
-#### 2.4.5 统计日分时热度
132
+#### 2.4.5 分时使用热度(最近 24 小时)
133 133
 
134 134
 | 维度 | SQL 要点 |
135 135
 | --- | --- |
136
-| 会话 | `s.create_time` ∈ 统计日,`GROUP BY HOUR(create_time)` |
137
-| 提问量 | `m_ai.create_time` ∈ 统计日,`GROUP BY HOUR(m_ai.create_time)` |
136
+| 会话 | `s.create_time` ∈ 24h 窗口,`GROUP BY DATE_FORMAT(create_time,'%Y%m%d%H')` |
137
+| 提问量 | `m_ai.create_time` ∈ 24h 窗口,同上分组 |
138 138
 
139
-应用层:固定 **24** 桶 `00:00`~`23:00`;`hourlyHeat.windowEnd` = `statDate`(`yyyy-MM-dd`)
139
+应用层:固定 **24** 桶(锚点整点向前 23 小时);`bucketStart`=`HH:mm`;`bucketDateTime`=`yyyy-MM-dd HH:mm`;`hourlyHeat.windowEnd` = 锚点整点 `yyyy-MM-dd HH:mm`
140 140
 
141 141
 #### 2.4.6 单次会话提问数量分布
142 142
 
@@ -184,8 +184,8 @@
184 184
 | | `selectUserStructure()` | 新老用户 |
185 185
 | | `selectAskerCategoryCounts(yearStart, yearEnd)` | AI 回复按分类键聚合 |
186 186
 | | `selectAiReplyTotal(yearStart, yearEnd)` | 分类占比分母(年内 AI 回复总数) |
187
-| | `selectHourlySessionCounts(dayStart, dayEnd)` | 统计日 24 小时会话 |
188
-| | `selectHourlyAiReplyCounts(dayStart, dayEnd)` | 统计日 24 小时提问量 |
187
+| | `selectHourlySessionCounts(windowStart, windowEnd)` | 最近 24h 会话 |
188
+| | `selectHourlyAiReplyCounts(windowStart, windowEnd)` | 最近 24h 提问量 |
189 189
 | | `selectSessionReplyBuckets(yearStart, yearEnd)` | 四档会话数 |
190 190
 | | `selectYearSessionTotal(yearStart, yearEnd)` | 年内会话总数 |
191 191
 | | `selectAiReplyStatusCounts(yearStart, yearEnd)` | 正常/失败 |
@@ -293,10 +293,10 @@ XML:`mapper/screen/LivestockResourceScreenMapper.xml`。
293 293
 
294 294
 | 字段 | 类型 | 说明 |
295 295
 | --- | --- | --- |
296
-| `windowEnd` | string | 回显 `statDateTime` |
296
+| `windowEnd` | string | 锚点整点 `yyyy-MM-dd HH:mm` |
297 297
 | `hourlySeries` | array | 固定 **24** 条 |
298 298
 
299
-`hourlySeries[]`:`bucketStart`(`HH:mm`)、`sessionCount`、`questionCount`。
299
+`hourlySeries[]`:`bucketStart`(`HH:mm`)、`bucketDateTime`(`yyyy-MM-dd HH:mm`,悬停)、`sessionCount`、`questionCount`。
300 300
 
301 301
 #### 3.1.7 `sessionReplyDistribution[]`
302 302
 

+ 7 - 7
doc/大屏/畜牧资源/大屏畜牧资源测试用例.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 畜牧资源统计 — 测试用例
2 2
 
3
-> 依据:`大屏畜牧资源功能需求.md`(v1.2)、`大屏畜牧资源技术方案.md`(v1.2
3
+> 依据:`大屏畜牧资源功能需求.md`(v1.3)、`大屏畜牧资源技术方案.md`(v1.3
4 4
 > **接口 Base Path**:`/bigScreen/livestockResource`(含 `context-path`、网关前缀须补齐)。鉴权:若依 Cookie / `Authorization` Token;权限 `bigScreen:livestockResource:query`。
5 5
 
6 6
 **通用前置(无特殊说明)**:已执行 `sql/biz_consult_session.sql`、`sql/biz_consult_message.sql`、`sql/biz_consult_user.sql`;测试账号具备大屏畜牧资源查询权限;时区 `Asia/Shanghai`。
@@ -19,7 +19,7 @@
19 19
 | 平均耗时 | `cost_time` 非空(**含 0**)参与平均;空值不参与;展示**秒** |
20 20
 | 用户结构 | `biz_consult_user` 全表;新≤180 天、老>180 天;**不随 Y** |
21 21
 | 近 7 日 | `[statDate−6, statDate]` 共 **7** 日;缺日 **0** |
22
-| 分时热度 | **统计日**自然日 **0~23** 整点小时桶;**与 Y 无关** |
22
+| 分时热度 | **距 statDateTime 最近 24** 整点小时桶;**与 Y 无关** |
23 23
 | 今日活跃 | 会话 **`update_time`** 在统计日 |
24 24
 | 日新增 | **`create_time` 与 `update_time` 均在统计日**,且此前无 AI 会话 |
25 25
 | 分类/模型/热点 | **AI 回复条数** + 提问人 `ai_category` 归因;占比分母=年内 AI 回复总数 |
@@ -69,7 +69,7 @@
69 69
 | DP-XM-UT-009 | 今日指标 | 当前年今日 | 单元测试 | JUnit5 | §2.8 | `AI-TODAY`;statDate=今日 | `buildOverview(2026)` | 今日四项与样本一致 |
70 70
 | DP-XM-UT-010 | 平均耗时 | 含 0 不排除 | 单元测试 | JUnit5 | §2.18#5 | `AI-COST`:0ms、3000ms、NULL | `avgResponseSeconds` | 平均=(0+3)/2 秒;NULL 不入分母 |
71 71
 | DP-XM-UT-011 | 7 日序列 | 补零 7 点 | 单元测试 | JUnit5 | §2.11 | 仅首尾 2 日有数据 | `buildDailySeries(statDate)` | `length=7`;中间日 `sessionCount=questionCount=0` |
72
-| DP-XM-UT-012 | 分时 | 统计日 24 自然小时桶 | 单元测试 | JUnit5 | §2.12、SY-XM-07 | `statDate=2026-05-20` | `buildHourlyHeat` | `hourlySeries.length=24`;`windowEnd=2026-05-20`;`10:00` 有数据 |
72
+| DP-XM-UT-012 | 分时 | 最近 24 整点小时桶 | 单元测试 | JUnit5 | §2.12、SY-XM-07 | `anchor=2026-05-20 10:30` | `buildHourlyHeat` | `hourlySeries.length=24`;`windowEnd=2026-05-20 10:00`;末桶 `10:00` 有数据;含 `bucketDateTime` |
73 73
 | DP-XM-UT-013 | 用户结构 | 180 天分界 | 单元测试 | JUnit5 | §2.9 | `DU-MIX` | `buildUserStructure` | 新/老人数与 `DATEDIFF` 规则一致 |
74 74
 | DP-XM-UT-014 | 用户结构 | 不随 Y 变 | 单元测试 | JUnit5 | SY-XM-05 | 固定 `DU-MIX` | `loadDashboard(2025)` 与 `2026` | `userStructure` 相同 |
75 75
 | DP-XM-UT-015 | 分类占比 | 分母全量 | 单元测试 | JUnit5 | §2.18#3 | 5 类 AI 回复已知 | `buildCategoryShare` | 各 `ratio` 之和≈100(1 位小数);分母=年内 AI 回复总数 |
@@ -101,7 +101,7 @@
101 101
 | DP-XM-API-010 | 看板 | 用户结构切年不变 | 接口测试 | Postman | §2.9 | `DU-MIX` 固定 | `statYear=2025` 与 `2026` | `userStructure` 相同 |
102 102
 | DP-XM-API-011 | 看板 | 分类占比 100% | 接口测试 | Postman | SY-XM-06 | `AI-Y` 多分类 | `categoryShare.items` | `sum(ratio)≈100`;分母=年内 **AI 回复** 总数(`totalAskerMessages` 字段名沿用) |
103 103
 | DP-XM-API-012 | 看板 | 模型调用同源 | 接口测试 | Postman | §5.6 | `AI-Y` | 对比 `modelCallAnalysis` 与 `categoryShare` | 分类条数一致 |
104
-| DP-XM-API-013 | 看板 | 统计日分时热度 | 接口测试 | Postman | SY-XM-07 | 统计日有跨小时数据 | `GET dashboard` | `hourlyHeat.hourlySeries.length=24`;`windowEnd`=`statDate`(yyyy-MM-dd) |
104
+| DP-XM-API-013 | 看板 | 分时使用热度 | 接口测试 | Postman | SY-XM-07 | 24h 窗口有跨小时数据 | `GET dashboard` | `hourlyHeat.hourlySeries.length=24`;`windowEnd` 为整点 `yyyy-MM-dd HH:mm`;点含 `bucketDateTime` |
105 105
 | DP-XM-API-014 | 看板 | 会话分档四档 | 接口测试 | Postman | SY-XM-08 | `AI-BAND` | `sessionReplyDistribution` | 4 条;`sum(ratio)≈100` |
106 106
 | DP-XM-API-015 | 看板 | 应答状态 | 接口测试 | Postman | SY-XM-08 | `AI-COST` | `replyStatusDistribution` | OK+FAIL=`totalAiReplies` |
107 107
 | DP-XM-API-016 | 看板 | 热点 Top5 | 接口测试 | Postman | SY-XM-09 | `AI-Y` | `hotTopics` | ≤5;为分类非单条消息 |
@@ -137,7 +137,7 @@
137 137
 | DP-XM-UI-007 | 图表 | 用户结构 | UI 测试 | Playwright+Chrome | SY-XM-05 | `DU-MIX` | 查看「用户结构分析」 | 新/老用户人数与占比;切年不变 |
138 138
 | DP-XM-UI-008 | 图表 | 提问分类占比 | UI 测试 | Playwright+Chrome | SY-XM-06 | `AI-Y` | 查看饼图 | 含 1~4 类及未分类;占比之和 100% |
139 139
 | DP-XM-UI-009 | 图表 | 模型调用分析 | UI 测试 | Playwright+Chrome | §5.6 | `AI-Y` | 查看柱状/条形区 | 各分类条数与占比区一致 |
140
-| DP-XM-UI-010 | 图表 | 统计日分时热度 | UI 测试 | Playwright+Chrome | SY-XM-07 | 统计日有数据 | 查看「分时使用热度」 | 24 整点(00:00~23:00);会话数/提问量维度 |
140
+| DP-XM-UI-010 | 图表 | 分时使用热度 | UI 测试 | Playwright+Chrome | SY-XM-07 | 24h 有数据 | 查看「分时使用热度」 | 24 整点;横轴 `HH:mm`;悬停显完整时刻+会话/提问量 |
141 141
 | DP-XM-UI-011 | 图表 | 会话提问分布 | UI 测试 | Playwright+Chrome | SY-XM-08 | `AI-BAND` | 查看「会话提问数量分布」 | 四档轻度~深度;占比展示 |
142 142
 | DP-XM-UI-012 | 图表 | 会话状态分布 | UI 测试 | Playwright+Chrome | SY-XM-08 | `AI-COST` | 查看「会话状态分布」 | 正常应答/调用失败两档 |
143 143
 | DP-XM-UI-013 | 榜单 | 热点问题 Top5 | UI 测试 | Playwright+Chrome | SY-XM-09 | `AI-Y` | 查看「热点问题榜单」 | ≤5 条分类排行 |
@@ -198,7 +198,7 @@ await page.route('**/bigScreen/livestockResource/dashboard**', route =>
198 198
 | SY-XM-04 | 活跃度 7 日 | UT-011;API-007;UI-006 |
199 199
 | SY-XM-05 | 用户结构 | UT-013~014;API-009~010;UI-007 |
200 200
 | SY-XM-06 | 分类 100% | UT-015;API-011~012;UI-008~009 |
201
-| SY-XM-07 | 统计日 24 自然小时 | UT-012;API-013;UI-010 |
201
+| SY-XM-07 | 最近 24h 整点热度 | UT-012;API-013;UI-010 |
202 202
 | SY-XM-08 | 分档与状态 | UT-017~018;API-014~015;UI-011~012 |
203 203
 | SY-XM-09 | 热点 Top5 | UT-019;API-016;UI-013 |
204 204
 | SY-XM-10 | 关键词 | UT-020;API-017;UI-014 |
@@ -217,4 +217,4 @@ await page.route('**/bigScreen/livestockResource/dashboard**', route =>
217 217
 | --- | --- |
218 218
 | 1.0 | 初版:单元 24、接口 32、UI 22;覆盖 SY-XM-01~13 与正常/异常/约束;Playwright+Chrome;Base `/bigScreen/livestockResource` |
219 219
 | 1.1 | 对齐功能需求 v1.1(提问量、滑动 24h 等) |
220
-| 1.2 | 对齐草稿 v1.2:`update_time` 今日活跃、日新增双时间、AI 回复分类、统计日分时、`create_time` 归属 |
220
+| 1.3 | 2026-07-04 | 分时热度改为最近 24 整点小时;VO 增 `bucketDateTime`;悬停显完整时刻 |

+ 1 - 1
doc/大屏/疫病风险/大屏疫病风险功能需求-草稿.md

@@ -3,7 +3,7 @@
3 3
 1. 参考 疾病检测与上报 模块
4 4
 2. 气象数据:由前端调用网上免费接口实现,后端不用关注
5 5
 3. 样本来源检测:计算当前年份的所有实验室检测记录的检测量,根据样本来源分类统计当前年份不同类别的实验室检测记录的检测量。
6
-4. 实验室检测:计算当前年份的所有实验室检测记录的检测量及阳性检出数,阳性检出率=阳性检出数/检测量;按月统计当前年份每个月的实验室检测记录的检测量及阳性检出数,分检测量和阳性数两个维度以曲线图展示检测量和阳性检出数的趋势变化
6
+4. 实验室检测:计算**距当前时间最近 12 个月**内实验室检测记录的检测量及阳性检出数,阳性检出率=阳性检出数/检测量;按月统计各月检测量及阳性检出数,分检测量和阳性数两个维度以曲线图展示。横轴仅显示月份,悬停显示某年某月。样本来源检测仍按当前统计年份汇总
7 7
 5. 疫病风险:根据风险等级(高危/中危/低危)统计当前年份各个等级疫情上报记录跟全年上报记录的占比,饼状体展示。
8 8
 6. 疫病态势:可用检疫点(个)、停用检疫点(个)、防控中地区(处)、已解除地区(处);可用检疫点数、停用检疫点数根据检疫站的运营状态进行统计;防控中地区数、已解除地区数根据当前年份的疫情上报信息的不同地区的数量统计。
9 9
 7. 疫情上报情况:分页查询当前年份的 疫情上报情况列表。

+ 29 - 15
doc/大屏/疫病风险/大屏疫病风险功能需求.md

@@ -25,16 +25,29 @@
25 25
 
26 26
 ### 2.2 统计月份(按月图表)
27 27
 
28
-- 凡「按月统计」的图表,横轴固定为 **1 月~12 月** 共 12 个刻度。
29
-- **缺月规则:** 该月无任何纳入统计的实验室检测记录时,该月检测量、阳性检出数按 **0** 参与展示;**不**省略该月刻度、**不**断线留空、**不**用相邻月插值。
28
+大屏存在两类按月图表,横轴规则**不同**:
30 29
 
31
-### 2.3 实验室检测纳入统计年份的规则
30
+| 类型 | 适用区块 | 横轴规则 |
31
+| --- | --- | --- |
32
+| **统计年 Y 内 1~12 月** | (本期无;样本来源等为年度汇总非按月趋势) | — |
33
+| **滚动最近 12 个月** | **实验室检测 · 按月趋势** | 以服务器当前年月为锚点,取**含当月在内向前连续 12 个自然月**;**不**随页面「统计年份 **Y**」切换 |
34
+
35
+**滚动最近 12 个月(实验室检测趋势)**
36
+
37
+- 接口每条记录含 **`statYear`(自然年)**、**`month`(1~12)**;按时间升序固定返回 **12** 条。
38
+- 缺月:`testQuantity`、`positiveCount` 为 **0**;**不**省略刻度。
39
+- **前端横轴**仅展示月份(如 `8月`);**鼠标悬停**展示完整年月(如 `2025年8月`)及检测量、阳性数。
40
+- 切换统计年份 **Y** 时,该趋势图**仍展示同一滚动窗口**(与 **Y** 无关);**样本来源检测**等仍按 **Y** 汇总(**§2.3**)。
41
+
42
+### 2.2.1 缺月规则(滚动 12 月窗口内)
43
+
44
+- 某自然月窗口槽位内无任何纳入 **§2.3** 检测日期的记录时,该月检测量、阳性检出数按 **0** 参与展示;**不**断线留空、**不**插值。
32 45
 
33
-选定统计年份 **Y** 后,纳入大屏实验室检测相关统计的记录须满足:
46
+### 2.3 实验室检测纳入统计的规则
34 47
 
35
-- **检测日期**落在 **Y** 年内(`Y-01-01`~`Y-12-31`,含起止日)。
48
+**样本来源检测(年度汇总)** — 选定统计年份 **Y** 后,纳入记录须满足 **检测日期**落在 **Y** 年内(`Y-01-01`~`Y-12-31`)。
36 49
 
37
-检测量、阳性检出数、检出率、样本来源分类等,均仅汇总上述记录。
50
+**实验室检测 · 按月趋势及趋势区年度三指标(检测量/阳性数/检出率)** — 纳入 **距当前时间最近 12 个自然月**窗口内、`test_date` 落在窗口内的全部检测记录;**不**随 **Y** 切换
38 51
 
39 52
 ### 2.4 疫情上报纳入统计年份的规则
40 53
 
@@ -188,7 +201,7 @@ flowchart TD
188 201
 
189 202
 | 项 | 规则 |
190 203
 | --- | --- |
191
-| 统计对象 | **§2.3** 当年全部实验室检测记录 |
204
+| 统计对象 | **§2.3** 统计年 **Y** 内全部实验室检测记录 |
192 205
 | 统计维度 | 按 **§2.6** 样本来源分类,汇总各来源 **检测量(份)** |
193 206
 | 展示内容 | 各来源检测量及占当年检测量合计的**占比**;可用饼图、环形图或条形图(以原型为准) |
194 207
 | 展示形式 | 须能区分四类来源;图例与标签一致 |
@@ -198,13 +211,13 @@ flowchart TD
198 211
 
199 212
 ### 5.3 区块二:实验室检测(年度 + 按月趋势)
200 213
 
201
-#### 5.3.1 年度汇总
214
+#### 5.3.1 趋势区汇总(滚动 12 月)
202 215
 
203 216
 | 项 | 规则 |
204 217
 | --- | --- |
205
-| 检测量 | 当年 **检测量** 合计(份) |
206
-| 阳性检出数 | 当年 **阳性检出数** 合计(份) |
207
-| 阳性检出率 | **§2.7** 年度阳性检出率;建议以 **%** 展示 |
218
+| 检测量 | 最近 12 月窗口内 **检测量** 合计(份) |
219
+| 阳性检出数 | 同上 **阳性检出数** 合计 |
220
+| 阳性检出率 | **§2.7**;建议以 **%** 展示 |
208 221
 
209 222
 #### 5.3.2 按月趋势
210 223
 
@@ -212,10 +225,10 @@ flowchart TD
212 225
 | --- | --- |
213 226
 | 图表类型 | **折线图**(或面积图,以产品定稿为准) |
214 227
 | 数据系列 | ① 检测量(份);② 阳性检出数(份) |
215
-| 横轴 | **§2.2** 1~12 月 |
228
+| 数据范围 | **§2.2** 滚动最近 **12** 个自然月 |
229
+| 横轴 | 12 个刻度,**仅显示月份**;悬停显 **YYYY年M月** |
216 230
 | 图例 | 两系列须有明确图例与颜色区分 |
217
-| 交互 | 至少支持悬停查看「月份 + 检测量 + 阳性检出数」 |
218
-| 缺月 | 按 **§2.2** 为 0 |
231
+| 缺月 | 按 **§2.2.1** 为 0 |
219 232
 
220 233
 ---
221 234
 
@@ -362,7 +375,7 @@ flowchart TD
362 375
 | --- | --- | --- |
363 376
 | DYFX-01 | 默认年份 | 进入大屏默认当前年,各区块年份口径一致 |
364 377
 | DYFX-02 | 切换年份 | 切换后检测/疫情类区块同步更新,无旧年残留 |
365
-| DYFX-03 | 缺月 | 仅部分月份有检测时,趋势图仍为 12 月,缺月为 0 |
378
+| DYFX-03 | 缺月 | 滚动 12 月窗口内仅部分月份有检测时,趋势图仍为 12 槽位,缺月为 0;横轴仅月、悬停显年月 |
366 379
 | DYFX-04 | 样本来源 | 四类来源占比之和为 100%(有检测时) |
367 380
 | DYFX-05 | 年度检出率 | 与手工按当年合计计算一致 |
368 381
 | DYFX-06 | 风险等级饼图 | 仅统计当年上报日记录;占比之和为 100%(有数据时) |
@@ -382,6 +395,7 @@ flowchart TD
382 395
 | --- | --- | --- |
383 396
 | 1.0 | 2026-05-25 | 由草稿优化:补全流程、口径、十区块需求;对齐疾病检测与上报体系;不涉及库表与接口 |
384 397
 | 1.1 | 2026-05-25 | 解除时效由加总改为按疫病类型的**平均天数**(§2.7、§5.8、DYFX-10) |
398
+| 1.2 | 2026-07-04 | 实验室检测按月趋势改为**滚动最近 12 月**;接口增 `statYear`+`month`;样本来源仍按 **Y** |
385 399
 
386 400
 ---
387 401
 

+ 9 - 8
doc/大屏/疫病风险/大屏疫病风险技术方案.md

@@ -20,7 +20,7 @@
20 20
 | 进入 / 切换 `statYear` | 调用 **§3.1**(检测汇总、疫情统计、检疫态势、风险因子等) |
21 21
 | 疫情列表翻页 | 仅调用 **§3.2** |
22 22
 | 数据权限 | 全县数据,**不按**部门/用户过滤 |
23
-| 汇总口径 | 与功能需求 **§2** 一致;检测缺月补 0;解除时效为按疫病类型**算术平均天数** |
23
+| 汇总口径 | 与功能需求 **§2** 一致;**样本来源**按 **Y**;**实验室检测趋势**为滚动 12 月、缺月补 0;解除时效为按疫病类型**算术平均天数** |
24 24
 | 检疫点 | **实时**主数据快照(与统计年份无关) |
25 25
 | 性能 | 默认实时聚合;可选 **§2.3** 缓存表 |
26 26
 
@@ -47,10 +47,11 @@
47 47
 
48 48
 | 项 | 条件 / 说明 |
49 49
 | --- | --- |
50
-| 按年 | `test_date >= CONCAT(Y,'-01-01')` AND `test_date <= CONCAT(Y,'-12-31')` |
51
-| 样本来源汇总 | `GROUP BY sample_source`,`SUM(test_quantity)` |
52
-| 年度合计 | `SUM(test_quantity)`、`SUM(positive_count)`,检出率服务端计算 |
53
-| 按月 | `MONTH(test_date)` 分组;应用层补全 1~12 月,缺月指标为 **0** |
50
+| 按年(样本来源) | `selectByTestYear(Y)`;`test_date` 在 **Y** 年内 |
51
+| 滚动 12 月(趋势区) | `selectByTestDateBetween(rangeStart, rangeEnd)`;锚点 = `HomeScreenSupport.currentYearMonth()`;窗口 `[anchor−11 月 1 日, rollingWindowEnd]` |
52
+| 样本来源汇总 | 基于 **Y** 年记录 `GROUP BY sample_source`,`SUM(test_quantity)` |
53
+| 趋势区合计 | 滚动窗口内 `SUM(test_quantity)`、`SUM(positive_count)` |
54
+| 按月趋势 | 按 `YEAR(test_date)`+`MONTH(test_date)` 聚合;`EpidemicRiskScreenSupport.buildLabDetection(rows, anchor)` 补全 **12** 槽位,含 `statYear`、`month` |
54 55
 
55 56
 **`sample_source`**:`1` 场地抽检 / `2` 疫情上报送检 / `3` 调运检疫 / `4` 日常检测。
56 57
 
@@ -175,10 +176,10 @@
175 176
 
176 177
 | 字段 | 说明 |
177 178
 | --- | --- |
178
-| `testQuantityTotal` | 当年检测量合计 |
179
-| `positiveCountTotal` | 当年阳性合计 |
179
+| `testQuantityTotal` | 滚动 12 月窗口内检测量合计 |
180
+| `positiveCountTotal` | 滚动 12 月窗口内阳性合计 |
180 181
 | `positiveRate` | 检出率 0~1;`testQuantityTotal=0` 时为 `null` 或 `0`(与产品约定) |
181
-| `monthly` | 长度 **12**;`month` 1~12;`testQuantity`、`positiveCount`;缺月为 **0** |
182
+| `monthly` | 长度 **12**;**滚动最近 12 月**;每项含 `statYear`、`month`、`testQuantity`、`positiveCount`;缺月为 **0** |
182 183
 
183 184
 #### 3.1.2 `sampleSourceStats[]`
184 185
 

+ 6 - 5
doc/大屏/疫病风险/大屏疫病风险测试用例.md

@@ -1,6 +1,6 @@
1 1
 # 大屏 — 疫病风险统计 — 测试用例
2 2
 
3
-> 依据:`大屏疫病风险功能需求.md`(v1.1)、`大屏疫病风险技术方案.md`  
3
+> 依据:`大屏疫病风险功能需求.md`(v1.2)、`大屏疫病风险技术方案.md`  
4 4
 > **接口 Base Path**:`/bigScreen/epidemicRisk`(含 `context-path`、网关前缀须补齐)。鉴权:若依 Cookie / `Authorization` Token;权限 `bigScreen:epidemicRisk:query`。
5 5
 
6 6
 **通用前置(无特殊说明)**:已执行 `sql/biz_lab_detection.sql`、`sql/biz_epidemic_report.sql`、`sql/biz_quarantine_station.sql`、`sql/biz_risk_factor_weight.sql`;测试账号具备大屏查询权限。
@@ -9,7 +9,8 @@
9 9
 
10 10
 | 域 | 规则 |
11 11
 | --- | --- |
12
-| 实验室检测 | `test_date` 落在统计年 **Y**;按月 12 刻度,缺月 **0** |
12
+| 实验室检测 · 趋势 | 滚动 12 月;含 `statYear`+`month`;**不**随 **Y**;缺月 **0** |
13
+| 实验室检测 · 样本来源 | `test_date` 落在统计年 **Y** |
13 14
 | 疫情(饼图/列表/类型/途径) | `report_date` 在 **Y** 年内 |
14 15
 | 防控中地区 | `report_date` 在 **Y** 且 `release_date IS NULL`;`affected_location_track` **去重** |
15 16
 | 已解除地区 / 解除时效 | `release_date` 在 **Y** 年内;时效 = **AVG**(解除日−上报日) 按 `epidemic_type` |
@@ -47,7 +48,7 @@
47 48
 | --- | --- | --- | --- | --- | --- | --- | --- | --- |
48 49
 | DP-DYFX-UT-001 | 参数校验 | statYear 合法 | 单元测试 | JUnit5 | 年份解析 | 无 | 传入 `2026`、`2000` | 解析为整数通过 |
49 50
 | DP-DYFX-UT-002 | 参数校验 | statYear 非法 | 单元测试 | JUnit5 | 异常入参 | 无 | 空、`26`、`abcd`、`1899` | 抛 `ServiceException` 或等价失败 |
50
-| DP-DYFX-UT-003 | 检测聚合 | 按月缺月补 0 | 单元测试 | JUnit5 | §2.2、DYFX-03 | Mock `LAB-2026` 仅 3、8 月 | `buildLabMonthly(2026, rows)` | `monthly.length=12`;非 3/8 月 `testQuantity=0`、`positiveCount=0` |
51
+| DP-DYFX-UT-003 | 检测聚合 | 滚动 12 月缺月补 0 | 单元测试 | JUnit5 | §2.2、DYFX-03 | Mock 仅 2026-3、2026-8 月 | `buildLabDetection(rows, 2026-08)` | `monthly.length=12`;末条 `statYear=2026,month=8`;首条 `2025-09` 为 0 |
51 52
 | DP-DYFX-UT-004 | 检测聚合 | 年度检出率 | 单元测试 | JUnit5 | §2.7、DYFX-05 | 检测量 100、阳性 12 | `calcPositiveRate` | `positiveRate=0.12` |
52 53
 | DP-DYFX-UT-005 | 检测聚合 | 检测量 0 检出率 | 单元测试 | JUnit5 | §2.7 | 有记录但 `testQuantity` 合计 0 | `calcPositiveRate` | `positiveRate=0` 或 `null`(与实现约定一致) |
53 54
 | DP-DYFX-UT-006 | 样本来源 | 四类占比 | 单元测试 | JUnit5 | §5.2、DYFX-04 | `LAB-SRC` 四类量 10/20/30/40 | `buildSampleSourceStats` | 四项 `ratio` 为 0.1/0.2/0.3/0.4;`sum(ratio)≈1` |
@@ -125,7 +126,7 @@
125 126
 | DP-DYFX-UI-006 | 空态 | 全年无疫情 | UI 测试 | Playwright+Chrome | §7.1 | `RPT-EMPTY` 年 | 切换该年 | 风险等级/类型/途径/列表空态;**无**单级 100% 假象 |
126 127
 | DP-DYFX-UI-007 | 空态 | 无已解除 | UI 测试 | Playwright+Chrome | §7.1 | 有上报无解除 | 查看解除时效图 | 空态文案;防控中区块仍可有数 |
127 128
 | DP-DYFX-UI-008 | 检测 | 年度三指标 | UI 测试 | Playwright+Chrome | §5.3 | 2026 有检测 | 查看实验室检测区 | 检测量、阳性数、检出率 **%** 与 API 一致 |
128
-| DP-DYFX-UI-009 | 图表 | 按月趋势 12 月 | UI 测试 | Playwright+Chrome | DYFX-03 | `LAB-2026` 缺月 | 查看折线/面积图+悬停 | 12 刻度;缺月为 0;Tooltip 含月份+两份数 |
129
+| DP-DYFX-UI-009 | 图表 | 按月趋势滚动 12 月 | UI 测试 | Playwright+Chrome | DYFX-03 | `LAB-2026` 缺月 | 查看折线/面积图+悬停 | 12 刻度**仅月份**;悬停显 **YYYY年M月**+检测量+阳性数 |
129 130
 | DP-DYFX-UI-010 | 图表 | 样本来源 | UI 测试 | Playwright+Chrome | DYFX-04 | `LAB-SRC` | 查看样本来源图 | 四类图例;占比之和 100%(有检测时) |
130 131
 | DP-DYFX-UI-011 | 图表 | 风险等级饼图 | UI 测试 | Playwright+Chrome | DYFX-06 | `RPT-Y` | 查看疫病风险饼图 | 高/中/低危图例;占比之和 100% |
131 132
 | DP-DYFX-UI-012 | 卡片 | 检疫点与地区 | UI 测试 | Playwright+Chrome | DYFX-07、DYFX-08 | `QN-MIX`+地区样本 | 查看疫病态势卡片 | 文案区分「检疫点」与「地区」;数字与 API 一致 |
@@ -192,7 +193,7 @@ await page.route('**/weather/**', route => route.fulfill({ status: 500 }));
192 193
 | --- | --- | --- |
193 194
 | DYFX-01 | 默认当前年 | UI-001;API-001 |
194 195
 | DYFX-02 | 切年一致 | API-020;UI-002~003 |
195
-| DYFX-03 | 缺月=0、12 月 | UT-003;API-002;UI-009 |
196
+| DYFX-03 | 滚动 12 月缺月=0 | UT-003;API-002;UI-009 |
196 197
 | DYFX-04 | 样本来源占比 | UT-006;API-004;UI-010 |
197 198
 | DYFX-05 | 年度检出率 | UT-004~005;API-003;UI-008 |
198 199
 | DYFX-06 | 风险等级饼图 | UT-008;API-005;UI-011 |