Procházet zdrojové kódy

交易市场平台(供应商)

wwh před 6 dny
rodič
revize
0d4e4f48fc

+ 0 - 12
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/domain/BizYakDiseaseWarning.java

@@ -15,8 +15,6 @@ public class BizYakDiseaseWarning extends BaseEntity
15 15
 
16 16
     private Long id;
17 17
 
18
-    private String externalAlertId;
19
-
20 18
     private String yakNo;
21 19
 
22 20
     private Long pastureId;
@@ -75,16 +73,6 @@ public class BizYakDiseaseWarning extends BaseEntity
75 73
         this.id = id;
76 74
     }
77 75
 
78
-    public String getExternalAlertId()
79
-    {
80
-        return externalAlertId;
81
-    }
82
-
83
-    public void setExternalAlertId(String externalAlertId)
84
-    {
85
-        this.externalAlertId = externalAlertId;
86
-    }
87
-
88 76
     public String getYakNo()
89 77
     {
90 78
         return yakNo;

+ 1 - 13
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/domain/dto/YakDiseaseWarningDto.java

@@ -4,12 +4,10 @@ import java.util.Date;
4 4
 import com.fasterxml.jackson.annotation.JsonFormat;
5 5
 
6 6
 /**
7
- * 第三方牦牛疾病预警 DTO。
7
+ * 本地规则分析生成的疾病预警 DTO。
8 8
  */
9 9
 public class YakDiseaseWarningDto
10 10
 {
11
-    private String externalAlertId;
12
-
13 11
     private String yakNo;
14 12
 
15 13
     private String pastureName;
@@ -32,16 +30,6 @@ public class YakDiseaseWarningDto
32 30
 
33 31
     private String yakAvatarUrl;
34 32
 
35
-    public String getExternalAlertId()
36
-    {
37
-        return externalAlertId;
38
-    }
39
-
40
-    public void setExternalAlertId(String externalAlertId)
41
-    {
42
-        this.externalAlertId = externalAlertId;
43
-    }
44
-
45 33
     public String getYakNo()
46 34
     {
47 35
         return yakNo;

+ 0 - 4
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/mapper/BizYakDiseaseWarningMapper.java

@@ -7,11 +7,7 @@ public interface BizYakDiseaseWarningMapper
7 7
 {
8 8
     BizYakDiseaseWarning selectBizYakDiseaseWarningById(Long id);
9 9
 
10
-    BizYakDiseaseWarning selectByExternalAlertId(String externalAlertId);
11
-
12 10
     List<BizYakDiseaseWarning> selectBizYakDiseaseWarningList(BizYakDiseaseWarning query);
13 11
 
14 12
     int insertBizYakDiseaseWarning(BizYakDiseaseWarning row);
15
-
16
-    int updateBizYakDiseaseWarning(BizYakDiseaseWarning row);
17 13
 }

+ 0 - 1
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/service/YakDiseaseWarningAnalyzer.java

@@ -121,7 +121,6 @@ public class YakDiseaseWarningAnalyzer
121 121
         String region = StringUtils.isNotEmpty(anchor.getRegionKey()) ? anchor.getRegionKey() : "未知地区";
122 122
         String day = dayKey(anchor.getRecordTime());
123 123
         YakDiseaseWarningDto dto = new YakDiseaseWarningDto();
124
-        dto.setExternalAlertId((quarantineMode ? "WARN-Q:" : "WARN-D:") + region + ":" + day);
125 124
         dto.setYakNo(StringUtils.isNotEmpty(anchor.getYakNo()) ? anchor.getYakNo() : "未知");
126 125
         dto.setPastureName(anchor.getFarmName());
127 126
         dto.setAlertTime(latestTime(hits, syncTime));

+ 5 - 14
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/service/YakDiseaseWarningSyncTxService.java

@@ -27,7 +27,7 @@ public class YakDiseaseWarningSyncTxService
27 27
     @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
28 28
     public boolean persistAlert(YakDiseaseWarningDto dto, Date syncTime)
29 29
     {
30
-        if (dto == null || StringUtils.isEmpty(dto.getExternalAlertId()))
30
+        if (dto == null)
31 31
         {
32 32
             throw new ServiceException("预警数据无效");
33 33
         }
@@ -44,7 +44,6 @@ public class YakDiseaseWarningSyncTxService
44 44
             throw new ServiceException("预警类型无效");
45 45
         }
46 46
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
47
-        row.setExternalAlertId(dto.getExternalAlertId().trim());
48 47
         row.setYakNo(dto.getYakNo().trim());
49 48
         row.setAlertTime(dto.getAlertTime());
50 49
         row.setWarningType(dto.getWarningType());
@@ -55,23 +54,15 @@ public class YakDiseaseWarningSyncTxService
55 54
         row.setYakAvatarUrl(StringUtils.trim(dto.getYakAvatarUrl()));
56 55
         row.setAlertMessage(YakDiseaseWarningValidation.buildAlertMessage(dto.getWarningType(), row.getMeasuredValue(),
57 56
                 row.getReferenceRange(), dto.getAlertMessage()));
58
-        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_THIRD_PARTY);
57
+        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_LOCAL);
59 58
         row.setLastSyncTime(syncTime);
60 59
         resolvePasture(row, dto.getPastureName());
61 60
 
62
-        BizYakDiseaseWarning existing = warningMapper.selectByExternalAlertId(row.getExternalAlertId());
63 61
         Date now = syncTime != null ? syncTime : new Date();
64
-        if (existing == null)
65
-        {
66
-            row.setCreateTime(now);
67
-            row.setUpdateTime(now);
68
-            warningMapper.insertBizYakDiseaseWarning(row);
69
-            return true;
70
-        }
71
-        row.setId(existing.getId());
62
+        row.setCreateTime(now);
72 63
         row.setUpdateTime(now);
73
-        warningMapper.updateBizYakDiseaseWarning(row);
74
-        return false;
64
+        warningMapper.insertBizYakDiseaseWarning(row);
65
+        return true;
75 66
     }
76 67
 
77 68
     private void resolvePasture(BizYakDiseaseWarning row, String pastureName)

+ 1 - 1
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/support/YakDiseaseWarningRules.java

@@ -15,7 +15,7 @@ public final class YakDiseaseWarningRules
15 15
 
16 16
     public static final int WARNING_TYPE_OTHER = 9;
17 17
 
18
-    public static final String DATA_SOURCE_THIRD_PARTY = "third_party";
18
+    public static final String DATA_SOURCE_LOCAL = "local_analysis";
19 19
 
20 20
     public static final String MSG_DATE_RANGE_INVALID = "开始日期不能晚于结束日期";
21 21
 

+ 3 - 28
baqing-admin/src/main/resources/mapper/industryservice/BizYakDiseaseWarningMapper.xml

@@ -4,7 +4,6 @@
4 4
 
5 5
     <resultMap type="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning" id="BizYakDiseaseWarningResult">
6 6
         <id     property="id"               column="id"/>
7
-        <result property="externalAlertId"  column="external_alert_id"/>
8 7
         <result property="yakNo"            column="yak_no"/>
9 8
         <result property="pastureId"        column="pasture_id"/>
10 9
         <result property="pastureName"      column="pasture_name"/>
@@ -23,7 +22,7 @@
23 22
     </resultMap>
24 23
 
25 24
     <sql id="selectVo">
26
-        select id, external_alert_id, yak_no, pasture_id, pasture_name, alert_time, alert_message,
25
+        select id, yak_no, pasture_id, pasture_name, alert_time, alert_message,
27 26
                warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
28 27
                data_source, last_sync_time, create_time, update_time
29 28
         from biz_yak_disease_warning
@@ -34,11 +33,6 @@
34 33
         where id = #{id}
35 34
     </select>
36 35
 
37
-    <select id="selectByExternalAlertId" parameterType="string" resultMap="BizYakDiseaseWarningResult">
38
-        <include refid="selectVo"/>
39
-        where external_alert_id = #{externalAlertId}
40
-    </select>
41
-
42 36
     <select id="selectBizYakDiseaseWarningList" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
43 37
             resultMap="BizYakDiseaseWarningResult">
44 38
         <include refid="selectVo"/>
@@ -65,32 +59,13 @@
65 59
     <insert id="insertBizYakDiseaseWarning" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
66 60
             useGeneratedKeys="true" keyProperty="id">
67 61
         insert into biz_yak_disease_warning (
68
-            external_alert_id, yak_no, pasture_id, pasture_name, alert_time, alert_message,
62
+            yak_no, pasture_id, pasture_name, alert_time, alert_message,
69 63
             warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
70 64
             data_source, last_sync_time, create_time, update_time
71 65
         ) values (
72
-            #{externalAlertId}, #{yakNo}, #{pastureId}, #{pastureName}, #{alertTime}, #{alertMessage},
66
+            #{yakNo}, #{pastureId}, #{pastureName}, #{alertTime}, #{alertMessage},
73 67
             #{warningType}, #{measuredValue}, #{referenceRange}, #{deviceNo}, #{collectTime}, #{yakAvatarUrl},
74 68
             #{dataSource}, #{lastSyncTime}, #{createTime}, #{updateTime}
75 69
         )
76 70
     </insert>
77
-
78
-    <update id="updateBizYakDiseaseWarning" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning">
79
-        update biz_yak_disease_warning
80
-        set yak_no = #{yakNo},
81
-            pasture_id = #{pastureId},
82
-            pasture_name = #{pastureName},
83
-            alert_time = #{alertTime},
84
-            alert_message = #{alertMessage},
85
-            warning_type = #{warningType},
86
-            measured_value = #{measuredValue},
87
-            reference_range = #{referenceRange},
88
-            device_no = #{deviceNo},
89
-            collect_time = #{collectTime},
90
-            yak_avatar_url = #{yakAvatarUrl},
91
-            data_source = #{dataSource},
92
-            last_sync_time = #{lastSyncTime},
93
-            update_time = #{updateTime}
94
-        where id = #{id}
95
-    </update>
96 71
 </mapper>

+ 1 - 5
baqing-admin/src/test/java/com/ruoyi/web/modules/industryservice/YakDiseaseWarningTestSamples.java

@@ -18,8 +18,6 @@ public final class YakDiseaseWarningTestSamples
18 18
 
19 19
     public static final Long OTHER_WARNING_ID = 8999L;
20 20
 
21
-    public static final String EXTERNAL_ID = "TP-ALERT-001";
22
-
23 21
     private YakDiseaseWarningTestSamples()
24 22
     {
25 23
     }
@@ -28,7 +26,6 @@ public final class YakDiseaseWarningTestSamples
28 26
     {
29 27
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
30 28
         row.setId(WARNING_ID);
31
-        row.setExternalAlertId(EXTERNAL_ID);
32 29
         row.setYakNo("YAK-W-001");
33 30
         row.setPastureId(PASTURE_P1);
34 31
         row.setPastureName("牧场甲");
@@ -37,7 +34,7 @@ public final class YakDiseaseWarningTestSamples
37 34
         row.setWarningType(YakDiseaseWarningRules.WARNING_TYPE_TEMP);
38 35
         row.setMeasuredValue("39.8℃");
39 36
         row.setReferenceRange("正常体温参考范围");
40
-        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_THIRD_PARTY);
37
+        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_LOCAL);
41 38
         return row;
42 39
     }
43 40
 
@@ -47,7 +44,6 @@ public final class YakDiseaseWarningTestSamples
47 44
         row.setId(OTHER_WARNING_ID);
48 45
         row.setPastureId(PASTURE_P2);
49 46
         row.setPastureName("牧场乙");
50
-        row.setExternalAlertId("TP-ALERT-OTHER");
51 47
         return row;
52 48
     }
53 49
 

+ 1 - 1
doc/产业数据模型及服务/牦牛疾病预警/牦牛疾病预警功能需求.md

@@ -200,7 +200,7 @@ flowchart LR
200 200
 | 拉取范围 | 分页拉取三类 OpenAPI:**检疫记录**、**诊疗记录**、**养殖过程记录**(与 Apifox 文档一致);按 `external_id` 合并写入本地健康源表 |
201 201
 | 分析生成 | 同步完成后,对 `analyzed_flag=0` 的源记录执行集中判断:**检疫**同地区同日异常/阳性 ≥3 条 → 健康预警;**诊疗**同地区同日 ≥3 条 → 健康预警;**养殖过程**本期仅标记已分析、不产预警 |
202 202
 | 已分析标记 | 参与判断的源记录在分析后置 **已分析**,下次同步不再重复判断 |
203
-| 预警去重 | 集中预警以「类型 + 地区 + 自然日」生成唯一 `external_alert_id`;重复同步时**更新**预警文案而非重复插多条 |
203
+| 预警去重 | 源记录分析后置 **已分析**,同一条健康源不再重复触发;预警表无第三方 ID,按分析批次插入 |
204 204
 | 成功反馈 | 提示完成及摘要(源记录新增/更新条数、预警生成计入新增摘要);列表宜可刷新 |
205 205
 | 失败反馈 | 明确原因(超时、鉴权失败等);**不删除**已有本地数据 |
206 206
 | 部分成功 | 宜区分成功/失败条数(单条源记录映射失败记 `failCount`) |

+ 2 - 6
doc/产业数据模型及服务/牦牛疾病预警/牦牛疾病预警技术方案.md

@@ -22,7 +22,7 @@
22 22
 | --- | --- |
23 23
 | 健康源同步 | 分页拉取检疫/诊疗/养殖过程 OpenAPI;以 `external_id`(`Q:`/`D:`/`B:` + 第三方 ID)**唯一** upsert 至 `biz_yak_health_source_record` |
24 24
 | 预警生成 | 对 `analyzed_flag=0` 记录集中分析;检疫异常/阳性、诊疗同区同日 ≥3 条写入 `biz_yak_disease_warning`;分析后标记源记录已分析 |
25
-| 预警合并 | 以 `external_alert_id`(如 `WARN-Q:{regionKey}:{yyyy-MM-dd}`)**唯一**;有则更新,无则插入 |
25
+| 预警生成 | 健康源分析后**插入**预警记录;源记录 `analyzed_flag=1` 后不再重复分析 |
26 26
 | 列表/详情 | 无 `del_flag` 删除需求;全量展示有效同步记录;排序 `alert_time DESC, id DESC` |
27 27
 | 日期筛选 | `startDate`/`endDate`(`yyyy-MM-dd`)转当日 00:00:00~23:59:59(`Asia/Shanghai`) |
28 28
 | 牧场权限 | 列表/详情/移动端按用户可见 `pasture_id` 过滤(`@DataScope` 或 Service 注入牧场 ID 集合) |
@@ -37,7 +37,6 @@
37 37
 | 字段 | 类型 | 非空 | 说明 |
38 38
 | --- | --- | --- | --- |
39 39
 | `id` | `bigint(20)` | Y | 主键 |
40
-| `external_alert_id` | `varchar(64)` | Y | 第三方预警唯一 ID,**去重键** |
41 40
 | `yak_no` | `varchar(64)` | Y | 牦牛编号 |
42 41
 | `pasture_id` | `bigint(20)` | N | 映射 `biz_pasture.id` 成功时写入 |
43 42
 | `pasture_name` | `varchar(128)` | N | 所属牧场名称(冗余展示) |
@@ -58,7 +57,6 @@
58 57
 | 索引 | 字段 | 用途 |
59 58
 | --- | --- | --- |
60 59
 | `PRIMARY` | `id` | 主键 |
61
-| `UNIQUE uk_external_alert` | `external_alert_id` | 同步幂等 |
62 60
 | `KEY idx_alert_time` | `alert_time` | 列表排序、日期范围 |
63 61
 | `KEY idx_pasture_time` | `pasture_id`, `alert_time` | 牧场 + 时间筛选 |
64 62
 | `KEY idx_yak_no` | `yak_no` | 关联档案、产业统计去重 |
@@ -81,7 +79,6 @@
81 79
 ```sql
82 80
 CREATE TABLE `biz_yak_disease_warning` (
83 81
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
84
-  `external_alert_id` varchar(64) NOT NULL COMMENT '第三方预警ID',
85 82
   `yak_no` varchar(64) NOT NULL COMMENT '牦牛编号',
86 83
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '牧场ID',
87 84
   `pasture_name` varchar(128) DEFAULT NULL COMMENT '所属牧场名称',
@@ -93,12 +90,11 @@ CREATE TABLE `biz_yak_disease_warning` (
93 90
   `device_no` varchar(64) DEFAULT NULL COMMENT '设备编号',
94 91
   `collect_time` datetime DEFAULT NULL COMMENT '采集时间',
95 92
   `yak_avatar_url` varchar(512) DEFAULT NULL COMMENT '头像URL',
96
-  `data_source` varchar(32) DEFAULT 'third_party' COMMENT '数据来源',
93
+  `data_source` varchar(32) DEFAULT 'local_analysis' COMMENT '数据来源',
97 94
   `last_sync_time` datetime DEFAULT NULL COMMENT '最近同步时间',
98 95
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',
99 96
   `update_time` datetime DEFAULT NULL COMMENT '更新时间',
100 97
   PRIMARY KEY (`id`),
101
-  UNIQUE KEY `uk_external_alert` (`external_alert_id`),
102 98
   KEY `idx_alert_time` (`alert_time`),
103 99
   KEY `idx_pasture_time` (`pasture_id`,`alert_time`),
104 100
   KEY `idx_yak_no` (`yak_no`),

+ 1 - 2
doc/产业数据模型及服务/牦牛疾病预警/牦牛疾病预警测试用例.md

@@ -18,7 +18,6 @@
18 18
 | **AW1** | 近期预警 | `yak_no=YAK-W-001`,`pasture_id=P1`,`alert_time` 为 3 日内;`alert_message` 含「体温异常」 |
19 19
 | **AW2** | 超窗预警 | 同 P1,`alert_time` 为 4 个月前 |
20 20
 | **AW3** | 越权样本 | 归属 P2;UA 列表/详情应不可见 |
21
-| **AW-TP1** | 同步键 | `external_alert_id=TP-ALERT-001`;首次同步 insert,二次改 `alert_message` 为 update |
22 21
 
23 22
 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。菜单组件路径以 `dataModel/yakDiseaseWarning/index` 为准。
24 23
 
@@ -36,7 +35,7 @@
36 35
 | ZCZX-MYNBJY-UT-006 | 枚举 | warning_type 非法 | 单元测试 | JUnit5 | 枚举边界 | 无 | 入参 0、5、null(若业务禁止) | 映射失败或落 null(与实现一致并固定) |
37 36
 | ZCZX-MYNBJY-UT-007 | 文案拼接 | 组装 alert_message | 单元测试 | JUnit5 | 技术方案 §4 | 无 | `measured=39.8℃`、`reference=正常体温`、`type=1` | 生成文案含实测值、参考范围、体温异常语义 |
38 37
 | ZCZX-MYNBJY-UT-008 | 同步合并 | 源记录 external_id 新增 | 单元测试 | JUnit5+Mockito | 幂等 | DB 无 Q:2001 | `persistSourceRecord` | `insert`;`insertCount+1` |
39
-| ZCZX-MYNBJY-UT-009 | 同步合并 | 预警 external_alert_id 更新 | 单元测试 | JUnit5+Mockito | 去重 | 已有 WARN-Q:… | 同键再分析 | `update`;列表仅 1 行 |
38
+| ZCZX-MYNBJY-UT-009 | 预警入库 | 分析生成 insert | 单元测试 | JUnit5+Mockito | 本地分析 | DB 无对应预警 | `persistAlert` | `insert`;返回 true |
40 39
 | ZCZX-MYNBJY-UT-021 | 分析规则 | 检疫集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条阳性/异常 | `analyzeAndGenerate` | 生成 1 条 `warning_type=3`;源记录已分析 |
41 40
 | ZCZX-MYNBJY-UT-022 | 分析规则 | 诊疗集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条诊疗 | `analyzeAndGenerate` | 生成 1 条 `warning_type=4` |
42 41
 | ZCZX-MYNBJY-UT-023 | 映射 | 检疫 OpenAPI → 源表 | 单元测试 | JUnit5 | 技术方案 §4 | 样例 DTO | `HealthRecordOpenApiMapper.fromQuarantine` | `external_id=Q:{id}`;`analyzed_flag=0` |

+ 2 - 4
sql/biz_yak_disease_warning.sql

@@ -1,24 +1,22 @@
1 1
 -- 牦牛疾病预警
2 2
 CREATE TABLE IF NOT EXISTS `biz_yak_disease_warning` (
3 3
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
4
-  `external_alert_id` varchar(64) NOT NULL COMMENT '第三方预警ID',
5 4
   `yak_no` varchar(64) NOT NULL COMMENT '牦牛编号',
6 5
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '牧场ID',
7 6
   `pasture_name` varchar(128) DEFAULT NULL COMMENT '所属牧场名称',
8 7
   `alert_time` datetime NOT NULL COMMENT '预警时间',
9 8
   `alert_message` varchar(1024) NOT NULL COMMENT '预警信息',
10
-  `warning_type` tinyint(4) DEFAULT NULL COMMENT '1体温 2运动量 9其他',
9
+  `warning_type` tinyint(4) DEFAULT NULL COMMENT '1体温 2运动量 3检疫集中 4诊疗集中 9其他',
11 10
   `measured_value` varchar(128) DEFAULT NULL COMMENT '实测值',
12 11
   `reference_range` varchar(128) DEFAULT NULL COMMENT '参考范围',
13 12
   `device_no` varchar(64) DEFAULT NULL COMMENT '设备编号',
14 13
   `collect_time` datetime DEFAULT NULL COMMENT '采集时间',
15 14
   `yak_avatar_url` varchar(512) DEFAULT NULL COMMENT '头像URL',
16
-  `data_source` varchar(32) DEFAULT 'third_party' COMMENT '数据来源',
15
+  `data_source` varchar(32) DEFAULT 'local_analysis' COMMENT '数据来源',
17 16
   `last_sync_time` datetime DEFAULT NULL COMMENT '最近同步时间',
18 17
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',
19 18
   `update_time` datetime DEFAULT NULL COMMENT '更新时间',
20 19
   PRIMARY KEY (`id`),
21
-  UNIQUE KEY `uk_external_alert` (`external_alert_id`),
22 20
   KEY `idx_alert_time` (`alert_time`),
23 21
   KEY `idx_pasture_time` (`pasture_id`,`alert_time`),
24 22
   KEY `idx_yak_no` (`yak_no`),