Bladeren bron

交易市场平台(供应商)

wwh 6 dagen geleden
bovenliggende
commit
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
     private Long id;
16
     private Long id;
17
 
17
 
18
-    private String externalAlertId;
19
-
20
     private String yakNo;
18
     private String yakNo;
21
 
19
 
22
     private Long pastureId;
20
     private Long pastureId;
@@ -75,16 +73,6 @@ public class BizYakDiseaseWarning extends BaseEntity
75
         this.id = id;
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
     public String getYakNo()
76
     public String getYakNo()
89
     {
77
     {
90
         return yakNo;
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
 import com.fasterxml.jackson.annotation.JsonFormat;
4
 import com.fasterxml.jackson.annotation.JsonFormat;
5
 
5
 
6
 /**
6
 /**
7
- * 第三方牦牛疾病预警 DTO。
7
+ * 本地规则分析生成的疾病预警 DTO。
8
  */
8
  */
9
 public class YakDiseaseWarningDto
9
 public class YakDiseaseWarningDto
10
 {
10
 {
11
-    private String externalAlertId;
12
-
13
     private String yakNo;
11
     private String yakNo;
14
 
12
 
15
     private String pastureName;
13
     private String pastureName;
@@ -32,16 +30,6 @@ public class YakDiseaseWarningDto
32
 
30
 
33
     private String yakAvatarUrl;
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
     public String getYakNo()
33
     public String getYakNo()
46
     {
34
     {
47
         return yakNo;
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
     BizYakDiseaseWarning selectBizYakDiseaseWarningById(Long id);
8
     BizYakDiseaseWarning selectBizYakDiseaseWarningById(Long id);
9
 
9
 
10
-    BizYakDiseaseWarning selectByExternalAlertId(String externalAlertId);
11
-
12
     List<BizYakDiseaseWarning> selectBizYakDiseaseWarningList(BizYakDiseaseWarning query);
10
     List<BizYakDiseaseWarning> selectBizYakDiseaseWarningList(BizYakDiseaseWarning query);
13
 
11
 
14
     int insertBizYakDiseaseWarning(BizYakDiseaseWarning row);
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
         String region = StringUtils.isNotEmpty(anchor.getRegionKey()) ? anchor.getRegionKey() : "未知地区";
121
         String region = StringUtils.isNotEmpty(anchor.getRegionKey()) ? anchor.getRegionKey() : "未知地区";
122
         String day = dayKey(anchor.getRecordTime());
122
         String day = dayKey(anchor.getRecordTime());
123
         YakDiseaseWarningDto dto = new YakDiseaseWarningDto();
123
         YakDiseaseWarningDto dto = new YakDiseaseWarningDto();
124
-        dto.setExternalAlertId((quarantineMode ? "WARN-Q:" : "WARN-D:") + region + ":" + day);
125
         dto.setYakNo(StringUtils.isNotEmpty(anchor.getYakNo()) ? anchor.getYakNo() : "未知");
124
         dto.setYakNo(StringUtils.isNotEmpty(anchor.getYakNo()) ? anchor.getYakNo() : "未知");
126
         dto.setPastureName(anchor.getFarmName());
125
         dto.setPastureName(anchor.getFarmName());
127
         dto.setAlertTime(latestTime(hits, syncTime));
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
     @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
27
     @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
28
     public boolean persistAlert(YakDiseaseWarningDto dto, Date syncTime)
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
             throw new ServiceException("预警数据无效");
32
             throw new ServiceException("预警数据无效");
33
         }
33
         }
@@ -44,7 +44,6 @@ public class YakDiseaseWarningSyncTxService
44
             throw new ServiceException("预警类型无效");
44
             throw new ServiceException("预警类型无效");
45
         }
45
         }
46
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
46
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
47
-        row.setExternalAlertId(dto.getExternalAlertId().trim());
48
         row.setYakNo(dto.getYakNo().trim());
47
         row.setYakNo(dto.getYakNo().trim());
49
         row.setAlertTime(dto.getAlertTime());
48
         row.setAlertTime(dto.getAlertTime());
50
         row.setWarningType(dto.getWarningType());
49
         row.setWarningType(dto.getWarningType());
@@ -55,23 +54,15 @@ public class YakDiseaseWarningSyncTxService
55
         row.setYakAvatarUrl(StringUtils.trim(dto.getYakAvatarUrl()));
54
         row.setYakAvatarUrl(StringUtils.trim(dto.getYakAvatarUrl()));
56
         row.setAlertMessage(YakDiseaseWarningValidation.buildAlertMessage(dto.getWarningType(), row.getMeasuredValue(),
55
         row.setAlertMessage(YakDiseaseWarningValidation.buildAlertMessage(dto.getWarningType(), row.getMeasuredValue(),
57
                 row.getReferenceRange(), dto.getAlertMessage()));
56
                 row.getReferenceRange(), dto.getAlertMessage()));
58
-        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_THIRD_PARTY);
57
+        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_LOCAL);
59
         row.setLastSyncTime(syncTime);
58
         row.setLastSyncTime(syncTime);
60
         resolvePasture(row, dto.getPastureName());
59
         resolvePasture(row, dto.getPastureName());
61
 
60
 
62
-        BizYakDiseaseWarning existing = warningMapper.selectByExternalAlertId(row.getExternalAlertId());
63
         Date now = syncTime != null ? syncTime : new Date();
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
         row.setUpdateTime(now);
63
         row.setUpdateTime(now);
73
-        warningMapper.updateBizYakDiseaseWarning(row);
74
-        return false;
64
+        warningMapper.insertBizYakDiseaseWarning(row);
65
+        return true;
75
     }
66
     }
76
 
67
 
77
     private void resolvePasture(BizYakDiseaseWarning row, String pastureName)
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
     public static final int WARNING_TYPE_OTHER = 9;
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
     public static final String MSG_DATE_RANGE_INVALID = "开始日期不能晚于结束日期";
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
     <resultMap type="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning" id="BizYakDiseaseWarningResult">
5
     <resultMap type="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning" id="BizYakDiseaseWarningResult">
6
         <id     property="id"               column="id"/>
6
         <id     property="id"               column="id"/>
7
-        <result property="externalAlertId"  column="external_alert_id"/>
8
         <result property="yakNo"            column="yak_no"/>
7
         <result property="yakNo"            column="yak_no"/>
9
         <result property="pastureId"        column="pasture_id"/>
8
         <result property="pastureId"        column="pasture_id"/>
10
         <result property="pastureName"      column="pasture_name"/>
9
         <result property="pastureName"      column="pasture_name"/>
@@ -23,7 +22,7 @@
23
     </resultMap>
22
     </resultMap>
24
 
23
 
25
     <sql id="selectVo">
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
                warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
26
                warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
28
                data_source, last_sync_time, create_time, update_time
27
                data_source, last_sync_time, create_time, update_time
29
         from biz_yak_disease_warning
28
         from biz_yak_disease_warning
@@ -34,11 +33,6 @@
34
         where id = #{id}
33
         where id = #{id}
35
     </select>
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
     <select id="selectBizYakDiseaseWarningList" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
36
     <select id="selectBizYakDiseaseWarningList" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
43
             resultMap="BizYakDiseaseWarningResult">
37
             resultMap="BizYakDiseaseWarningResult">
44
         <include refid="selectVo"/>
38
         <include refid="selectVo"/>
@@ -65,32 +59,13 @@
65
     <insert id="insertBizYakDiseaseWarning" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
59
     <insert id="insertBizYakDiseaseWarning" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakDiseaseWarning"
66
             useGeneratedKeys="true" keyProperty="id">
60
             useGeneratedKeys="true" keyProperty="id">
67
         insert into biz_yak_disease_warning (
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
             warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
63
             warning_type, measured_value, reference_range, device_no, collect_time, yak_avatar_url,
70
             data_source, last_sync_time, create_time, update_time
64
             data_source, last_sync_time, create_time, update_time
71
         ) values (
65
         ) values (
72
-            #{externalAlertId}, #{yakNo}, #{pastureId}, #{pastureName}, #{alertTime}, #{alertMessage},
66
+            #{yakNo}, #{pastureId}, #{pastureName}, #{alertTime}, #{alertMessage},
73
             #{warningType}, #{measuredValue}, #{referenceRange}, #{deviceNo}, #{collectTime}, #{yakAvatarUrl},
67
             #{warningType}, #{measuredValue}, #{referenceRange}, #{deviceNo}, #{collectTime}, #{yakAvatarUrl},
74
             #{dataSource}, #{lastSyncTime}, #{createTime}, #{updateTime}
68
             #{dataSource}, #{lastSyncTime}, #{createTime}, #{updateTime}
75
         )
69
         )
76
     </insert>
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
 </mapper>
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
     public static final Long OTHER_WARNING_ID = 8999L;
19
     public static final Long OTHER_WARNING_ID = 8999L;
20
 
20
 
21
-    public static final String EXTERNAL_ID = "TP-ALERT-001";
22
-
23
     private YakDiseaseWarningTestSamples()
21
     private YakDiseaseWarningTestSamples()
24
     {
22
     {
25
     }
23
     }
@@ -28,7 +26,6 @@ public final class YakDiseaseWarningTestSamples
28
     {
26
     {
29
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
27
         BizYakDiseaseWarning row = new BizYakDiseaseWarning();
30
         row.setId(WARNING_ID);
28
         row.setId(WARNING_ID);
31
-        row.setExternalAlertId(EXTERNAL_ID);
32
         row.setYakNo("YAK-W-001");
29
         row.setYakNo("YAK-W-001");
33
         row.setPastureId(PASTURE_P1);
30
         row.setPastureId(PASTURE_P1);
34
         row.setPastureName("牧场甲");
31
         row.setPastureName("牧场甲");
@@ -37,7 +34,7 @@ public final class YakDiseaseWarningTestSamples
37
         row.setWarningType(YakDiseaseWarningRules.WARNING_TYPE_TEMP);
34
         row.setWarningType(YakDiseaseWarningRules.WARNING_TYPE_TEMP);
38
         row.setMeasuredValue("39.8℃");
35
         row.setMeasuredValue("39.8℃");
39
         row.setReferenceRange("正常体温参考范围");
36
         row.setReferenceRange("正常体温参考范围");
40
-        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_THIRD_PARTY);
37
+        row.setDataSource(YakDiseaseWarningRules.DATA_SOURCE_LOCAL);
41
         return row;
38
         return row;
42
     }
39
     }
43
 
40
 
@@ -47,7 +44,6 @@ public final class YakDiseaseWarningTestSamples
47
         row.setId(OTHER_WARNING_ID);
44
         row.setId(OTHER_WARNING_ID);
48
         row.setPastureId(PASTURE_P2);
45
         row.setPastureId(PASTURE_P2);
49
         row.setPastureName("牧场乙");
46
         row.setPastureName("牧场乙");
50
-        row.setExternalAlertId("TP-ALERT-OTHER");
51
         return row;
47
         return row;
52
     }
48
     }
53
 
49
 

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

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

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

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

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

@@ -18,7 +18,6 @@
18
 | **AW1** | 近期预警 | `yak_no=YAK-W-001`,`pasture_id=P1`,`alert_time` 为 3 日内;`alert_message` 含「体温异常」 |
18
 | **AW1** | 近期预警 | `yak_no=YAK-W-001`,`pasture_id=P1`,`alert_time` 为 3 日内;`alert_message` 含「体温异常」 |
19
 | **AW2** | 超窗预警 | 同 P1,`alert_time` 为 4 个月前 |
19
 | **AW2** | 超窗预警 | 同 P1,`alert_time` 为 4 个月前 |
20
 | **AW3** | 越权样本 | 归属 P2;UA 列表/详情应不可见 |
20
 | **AW3** | 越权样本 | 归属 P2;UA 列表/详情应不可见 |
21
-| **AW-TP1** | 同步键 | `external_alert_id=TP-ALERT-001`;首次同步 insert,二次改 `alert_message` 为 update |
22
 
21
 
23
 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。菜单组件路径以 `dataModel/yakDiseaseWarning/index` 为准。
22
 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。菜单组件路径以 `dataModel/yakDiseaseWarning/index` 为准。
24
 
23
 
@@ -36,7 +35,7 @@
36
 | ZCZX-MYNBJY-UT-006 | 枚举 | warning_type 非法 | 单元测试 | JUnit5 | 枚举边界 | 无 | 入参 0、5、null(若业务禁止) | 映射失败或落 null(与实现一致并固定) |
35
 | ZCZX-MYNBJY-UT-006 | 枚举 | warning_type 非法 | 单元测试 | JUnit5 | 枚举边界 | 无 | 入参 0、5、null(若业务禁止) | 映射失败或落 null(与实现一致并固定) |
37
 | ZCZX-MYNBJY-UT-007 | 文案拼接 | 组装 alert_message | 单元测试 | JUnit5 | 技术方案 §4 | 无 | `measured=39.8℃`、`reference=正常体温`、`type=1` | 生成文案含实测值、参考范围、体温异常语义 |
36
 | ZCZX-MYNBJY-UT-007 | 文案拼接 | 组装 alert_message | 单元测试 | JUnit5 | 技术方案 §4 | 无 | `measured=39.8℃`、`reference=正常体温`、`type=1` | 生成文案含实测值、参考范围、体温异常语义 |
38
 | ZCZX-MYNBJY-UT-008 | 同步合并 | 源记录 external_id 新增 | 单元测试 | JUnit5+Mockito | 幂等 | DB 无 Q:2001 | `persistSourceRecord` | `insert`;`insertCount+1` |
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
 | ZCZX-MYNBJY-UT-021 | 分析规则 | 检疫集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条阳性/异常 | `analyzeAndGenerate` | 生成 1 条 `warning_type=3`;源记录已分析 |
39
 | ZCZX-MYNBJY-UT-021 | 分析规则 | 检疫集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条阳性/异常 | `analyzeAndGenerate` | 生成 1 条 `warning_type=3`;源记录已分析 |
41
 | ZCZX-MYNBJY-UT-022 | 分析规则 | 诊疗集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条诊疗 | `analyzeAndGenerate` | 生成 1 条 `warning_type=4` |
40
 | ZCZX-MYNBJY-UT-022 | 分析规则 | 诊疗集中阈值 | 单元测试 | JUnit5+Mockito | 功能需求 §5 | 同区同日 3 条诊疗 | `analyzeAndGenerate` | 生成 1 条 `warning_type=4` |
42
 | ZCZX-MYNBJY-UT-023 | 映射 | 检疫 OpenAPI → 源表 | 单元测试 | JUnit5 | 技术方案 §4 | 样例 DTO | `HealthRecordOpenApiMapper.fromQuarantine` | `external_id=Q:{id}`;`analyzed_flag=0` |
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
 CREATE TABLE IF NOT EXISTS `biz_yak_disease_warning` (
2
 CREATE TABLE IF NOT EXISTS `biz_yak_disease_warning` (
3
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
3
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
4
-  `external_alert_id` varchar(64) NOT NULL COMMENT '第三方预警ID',
5
   `yak_no` varchar(64) NOT NULL COMMENT '牦牛编号',
4
   `yak_no` varchar(64) NOT NULL COMMENT '牦牛编号',
6
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '牧场ID',
5
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '牧场ID',
7
   `pasture_name` varchar(128) DEFAULT NULL COMMENT '所属牧场名称',
6
   `pasture_name` varchar(128) DEFAULT NULL COMMENT '所属牧场名称',
8
   `alert_time` datetime NOT NULL COMMENT '预警时间',
7
   `alert_time` datetime NOT NULL COMMENT '预警时间',
9
   `alert_message` varchar(1024) NOT NULL COMMENT '预警信息',
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
   `measured_value` varchar(128) DEFAULT NULL COMMENT '实测值',
10
   `measured_value` varchar(128) DEFAULT NULL COMMENT '实测值',
12
   `reference_range` varchar(128) DEFAULT NULL COMMENT '参考范围',
11
   `reference_range` varchar(128) DEFAULT NULL COMMENT '参考范围',
13
   `device_no` varchar(64) DEFAULT NULL COMMENT '设备编号',
12
   `device_no` varchar(64) DEFAULT NULL COMMENT '设备编号',
14
   `collect_time` datetime DEFAULT NULL COMMENT '采集时间',
13
   `collect_time` datetime DEFAULT NULL COMMENT '采集时间',
15
   `yak_avatar_url` varchar(512) DEFAULT NULL COMMENT '头像URL',
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
   `last_sync_time` datetime DEFAULT NULL COMMENT '最近同步时间',
16
   `last_sync_time` datetime DEFAULT NULL COMMENT '最近同步时间',
18
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',
17
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',
19
   `update_time` datetime DEFAULT NULL COMMENT '更新时间',
18
   `update_time` datetime DEFAULT NULL COMMENT '更新时间',
20
   PRIMARY KEY (`id`),
19
   PRIMARY KEY (`id`),
21
-  UNIQUE KEY `uk_external_alert` (`external_alert_id`),
22
   KEY `idx_alert_time` (`alert_time`),
20
   KEY `idx_alert_time` (`alert_time`),
23
   KEY `idx_pasture_time` (`pasture_id`,`alert_time`),
21
   KEY `idx_pasture_time` (`pasture_id`,`alert_time`),
24
   KEY `idx_yak_no` (`yak_no`),
22
   KEY `idx_yak_no` (`yak_no`),