wwh пре 1 месец
родитељ
комит
ee4e91e86f

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

@@ -12,6 +12,7 @@ public class BizYakWeighingRecord extends BaseEntity
12
     private Long id;
12
     private Long id;
13
     private Long externalId;
13
     private Long externalId;
14
     private Long yakAssetId;
14
     private Long yakAssetId;
15
+    private String earTagNumber;
15
     private Long cattleExternalId;
16
     private Long cattleExternalId;
16
     private String yakNo;
17
     private String yakNo;
17
     private Long pastureId;
18
     private Long pastureId;
@@ -32,6 +33,8 @@ public class BizYakWeighingRecord extends BaseEntity
32
     public void setExternalId(Long externalId) { this.externalId = externalId; }
33
     public void setExternalId(Long externalId) { this.externalId = externalId; }
33
     public Long getYakAssetId() { return yakAssetId; }
34
     public Long getYakAssetId() { return yakAssetId; }
34
     public void setYakAssetId(Long yakAssetId) { this.yakAssetId = yakAssetId; }
35
     public void setYakAssetId(Long yakAssetId) { this.yakAssetId = yakAssetId; }
36
+    public String getEarTagNumber() { return earTagNumber; }
37
+    public void setEarTagNumber(String earTagNumber) { this.earTagNumber = earTagNumber; }
35
     public Long getCattleExternalId() { return cattleExternalId; }
38
     public Long getCattleExternalId() { return cattleExternalId; }
36
     public void setCattleExternalId(Long cattleExternalId) { this.cattleExternalId = cattleExternalId; }
39
     public void setCattleExternalId(Long cattleExternalId) { this.cattleExternalId = cattleExternalId; }
37
     public String getYakNo() { return yakNo; }
40
     public String getYakNo() { return yakNo; }

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

@@ -52,10 +52,12 @@ public class YakWeighingSyncTxService
52
             throw new ServiceException(FarmingSyncRules.MSG_EXTERNAL_ID_REQUIRED);
52
             throw new ServiceException(FarmingSyncRules.MSG_EXTERNAL_ID_REQUIRED);
53
         }
53
         }
54
         Date now = syncTime != null ? syncTime : new Date();
54
         Date now = syncTime != null ? syncTime : new Date();
55
+        String earTagNumber = StringUtils.isNotEmpty(dto.getEarTagNumber()) ? dto.getEarTagNumber().trim() : null;
55
         String yakNo = FarmingSyncSupport.firstNonBlank(dto.getEarTagNumber(), dto.getCattleNo());
56
         String yakNo = FarmingSyncSupport.firstNonBlank(dto.getEarTagNumber(), dto.getCattleNo());
56
 
57
 
57
         BizYakWeighingRecord row = new BizYakWeighingRecord();
58
         BizYakWeighingRecord row = new BizYakWeighingRecord();
58
         row.setExternalId(dto.getId());
59
         row.setExternalId(dto.getId());
60
+        row.setEarTagNumber(earTagNumber);
59
         row.setCattleExternalId(dto.getCattleId());
61
         row.setCattleExternalId(dto.getCattleId());
60
         row.setYakNo(yakNo);
62
         row.setYakNo(yakNo);
61
         row.setYakAssetId(FarmingSyncSupport.resolveYakAssetId(yakAssetMapper, dto.getCattleId(),
63
         row.setYakAssetId(FarmingSyncSupport.resolveYakAssetId(yakAssetMapper, dto.getCattleId(),

+ 5 - 4
baqing-admin/src/main/resources/mapper/industryservice/BizYakWeighingRecordMapper.xml

@@ -6,6 +6,7 @@
6
         <id property="id" column="id"/>
6
         <id property="id" column="id"/>
7
         <result property="externalId" column="external_id"/>
7
         <result property="externalId" column="external_id"/>
8
         <result property="yakAssetId" column="yak_asset_id"/>
8
         <result property="yakAssetId" column="yak_asset_id"/>
9
+        <result property="earTagNumber" column="ear_tag_number"/>
9
         <result property="cattleExternalId" column="cattle_external_id"/>
10
         <result property="cattleExternalId" column="cattle_external_id"/>
10
         <result property="yakNo" column="yak_no"/>
11
         <result property="yakNo" column="yak_no"/>
11
         <result property="pastureId" column="pasture_id"/>
12
         <result property="pastureId" column="pasture_id"/>
@@ -27,7 +28,7 @@
27
     </resultMap>
28
     </resultMap>
28
 
29
 
29
     <select id="selectByExternalId" resultMap="BizYakWeighingRecordResult">
30
     <select id="selectByExternalId" resultMap="BizYakWeighingRecordResult">
30
-        select id, external_id, yak_asset_id, cattle_external_id, yak_no, pasture_id, farm_external_id, farm_name,
31
+        select id, external_id, yak_asset_id, ear_tag_number, cattle_external_id, yak_no, pasture_id, farm_external_id, farm_name,
31
                enclosure_id, enclosure_external_id, enclosure_name, weight_kg, weighing_time,
32
                enclosure_id, enclosure_external_id, enclosure_name, weight_kg, weighing_time,
32
                data_source, last_sync_time, del_flag, create_by, create_time, update_by, update_time, remark
33
                data_source, last_sync_time, del_flag, create_by, create_time, update_by, update_time, remark
33
         from biz_yak_weighing_record where external_id = #{externalId} limit 1
34
         from biz_yak_weighing_record where external_id = #{externalId} limit 1
@@ -43,11 +44,11 @@
43
 
44
 
44
     <insert id="insertBizYakWeighingRecord" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakWeighingRecord" useGeneratedKeys="true" keyProperty="id">
45
     <insert id="insertBizYakWeighingRecord" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakWeighingRecord" useGeneratedKeys="true" keyProperty="id">
45
         insert into biz_yak_weighing_record (
46
         insert into biz_yak_weighing_record (
46
-            external_id, yak_asset_id, cattle_external_id, yak_no, pasture_id, farm_external_id, farm_name,
47
+            external_id, yak_asset_id, ear_tag_number, cattle_external_id, yak_no, pasture_id, farm_external_id, farm_name,
47
             enclosure_id, enclosure_external_id, enclosure_name, weight_kg, weighing_time,
48
             enclosure_id, enclosure_external_id, enclosure_name, weight_kg, weighing_time,
48
             data_source, last_sync_time, del_flag, create_by, create_time, remark
49
             data_source, last_sync_time, del_flag, create_by, create_time, remark
49
         ) values (
50
         ) values (
50
-            #{externalId}, #{yakAssetId}, #{cattleExternalId}, #{yakNo}, #{pastureId}, #{farmExternalId}, #{farmName},
51
+            #{externalId}, #{yakAssetId}, #{earTagNumber}, #{cattleExternalId}, #{yakNo}, #{pastureId}, #{farmExternalId}, #{farmName},
51
             #{enclosureId}, #{enclosureExternalId}, #{enclosureName}, #{weightKg}, #{weighingTime, jdbcType=TIMESTAMP},
52
             #{enclosureId}, #{enclosureExternalId}, #{enclosureName}, #{weightKg}, #{weighingTime, jdbcType=TIMESTAMP},
52
             #{dataSource}, #{lastSyncTime}, #{delFlag}, #{createBy}, #{createTime, jdbcType=TIMESTAMP}, #{remark}
53
             #{dataSource}, #{lastSyncTime}, #{delFlag}, #{createBy}, #{createTime, jdbcType=TIMESTAMP}, #{remark}
53
         )
54
         )
@@ -55,7 +56,7 @@
55
 
56
 
56
     <update id="updateBizYakWeighingRecordFromSync" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakWeighingRecord">
57
     <update id="updateBizYakWeighingRecordFromSync" parameterType="com.ruoyi.web.modules.industryservice.domain.BizYakWeighingRecord">
57
         update biz_yak_weighing_record set
58
         update biz_yak_weighing_record set
58
-            yak_asset_id = #{yakAssetId}, cattle_external_id = #{cattleExternalId}, yak_no = #{yakNo},
59
+            yak_asset_id = #{yakAssetId}, ear_tag_number = #{earTagNumber}, cattle_external_id = #{cattleExternalId}, yak_no = #{yakNo},
59
             pasture_id = #{pastureId}, farm_external_id = #{farmExternalId}, farm_name = #{farmName},
60
             pasture_id = #{pastureId}, farm_external_id = #{farmExternalId}, farm_name = #{farmName},
60
             enclosure_id = #{enclosureId}, enclosure_external_id = #{enclosureExternalId}, enclosure_name = #{enclosureName},
61
             enclosure_id = #{enclosureId}, enclosure_external_id = #{enclosureExternalId}, enclosure_name = #{enclosureName},
61
             weight_kg = #{weightKg}, weighing_time = #{weighingTime, jdbcType=TIMESTAMP},
62
             weight_kg = #{weightKg}, weighing_time = #{weighingTime, jdbcType=TIMESTAMP},

+ 98 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/industryservice/service/YakWeighingSyncTxServiceTest.java

@@ -0,0 +1,98 @@
1
+package com.ruoyi.web.modules.industryservice.service;
2
+
3
+import static org.junit.jupiter.api.Assertions.assertEquals;
4
+import static org.junit.jupiter.api.Assertions.assertFalse;
5
+import static org.junit.jupiter.api.Assertions.assertThrows;
6
+import static org.mockito.ArgumentMatchers.any;
7
+import static org.mockito.Mockito.verify;
8
+import static org.mockito.Mockito.when;
9
+
10
+import java.math.BigDecimal;
11
+import java.util.Date;
12
+import org.junit.jupiter.api.DisplayName;
13
+import org.junit.jupiter.api.Test;
14
+import org.junit.jupiter.api.extension.ExtendWith;
15
+import org.mockito.ArgumentCaptor;
16
+import org.mockito.InjectMocks;
17
+import org.mockito.Mock;
18
+import org.mockito.junit.jupiter.MockitoExtension;
19
+import com.ruoyi.common.exception.ServiceException;
20
+import com.ruoyi.web.modules.industryservice.domain.BizYakWeighingRecord;
21
+import com.ruoyi.web.modules.industryservice.domain.dto.OpenWeighingDto;
22
+import com.ruoyi.web.modules.industryservice.mapper.BizFarmEnclosureMapper;
23
+import com.ruoyi.web.modules.industryservice.mapper.BizPastureMapper;
24
+import com.ruoyi.web.modules.industryservice.mapper.BizYakAssetMapper;
25
+import com.ruoyi.web.modules.industryservice.mapper.BizYakWeighingRecordMapper;
26
+
27
+@ExtendWith(MockitoExtension.class)
28
+@DisplayName("YakWeighingSyncTxService")
29
+class YakWeighingSyncTxServiceTest
30
+{
31
+    @Mock
32
+    private BizYakWeighingRecordMapper weighingRecordMapper;
33
+
34
+    @Mock
35
+    private BizPastureMapper pastureMapper;
36
+
37
+    @Mock
38
+    private BizFarmEnclosureMapper enclosureMapper;
39
+
40
+    @Mock
41
+    private BizYakAssetMapper yakAssetMapper;
42
+
43
+    @InjectMocks
44
+    private YakWeighingSyncTxService service;
45
+
46
+    @Test
47
+    @DisplayName("新增称重记录")
48
+    void persistWeighing_insert()
49
+    {
50
+        when(weighingRecordMapper.selectByExternalId(3001L)).thenReturn(null);
51
+        when(weighingRecordMapper.insertBizYakWeighingRecord(any())).thenReturn(1);
52
+
53
+        OpenWeighingDto dto = sampleDto();
54
+        assertEquals(true, service.persistWeighing(dto, new Date()));
55
+
56
+        ArgumentCaptor<BizYakWeighingRecord> captor = ArgumentCaptor.forClass(BizYakWeighingRecord.class);
57
+        verify(weighingRecordMapper).insertBizYakWeighingRecord(captor.capture());
58
+        BizYakWeighingRecord row = captor.getValue();
59
+        assertEquals(3001L, row.getExternalId());
60
+        assertEquals("YAK20250001", row.getEarTagNumber());
61
+        assertEquals("YAK20250001", row.getYakNo());
62
+        assertEquals(0, row.getWeightKg().compareTo(new BigDecimal("385.50")));
63
+    }
64
+
65
+    @Test
66
+    @DisplayName("更新已有称重记录")
67
+    void persistWeighing_update()
68
+    {
69
+        BizYakWeighingRecord existing = new BizYakWeighingRecord();
70
+        existing.setId(10L);
71
+        existing.setCreateTime(new Date(1_000L));
72
+        when(weighingRecordMapper.selectByExternalId(3001L)).thenReturn(existing);
73
+
74
+        assertFalse(service.persistWeighing(sampleDto(), new Date()));
75
+        verify(weighingRecordMapper).updateBizYakWeighingRecordFromSync(any());
76
+    }
77
+
78
+    @Test
79
+    @DisplayName("缺少 external id 拒绝")
80
+    void persistWeighing_missingId()
81
+    {
82
+        OpenWeighingDto dto = sampleDto();
83
+        dto.setId(null);
84
+        assertThrows(ServiceException.class, () -> service.persistWeighing(dto, new Date()));
85
+    }
86
+
87
+    private static OpenWeighingDto sampleDto()
88
+    {
89
+        OpenWeighingDto dto = new OpenWeighingDto();
90
+        dto.setId(3001L);
91
+        dto.setCattleId(4001L);
92
+        dto.setCattleNo("YAK20250001");
93
+        dto.setEarTagNumber("YAK20250001");
94
+        dto.setWeight("385.50");
95
+        dto.setWeighingTime("2026-05-20 08:30:00");
96
+        return dto;
97
+    }
98
+}

+ 2 - 0
doc/产业数据模型及服务/牧业金融生物资产管理/牦牛资产档案管理技术方案.md

@@ -158,6 +158,8 @@
158
 | 表名 | 第三方接口 | 唯一键 | DDL |
158
 | 表名 | 第三方接口 | 唯一键 | DDL |
159
 | --- | --- | --- | --- |
159
 | --- | --- | --- | --- |
160
 | `biz_yak_weighing_record` | `GET /open-api/v1/iot/weighings` | `external_id` | `sql/biz_yak_weighing_record.sql` |
160
 | `biz_yak_weighing_record` | `GET /open-api/v1/iot/weighings` | `external_id` | `sql/biz_yak_weighing_record.sql` |
161
+
162
+`biz_yak_weighing_record` 字段映射:`earTagNumber`→`ear_tag_number`,`cattleNo` 参与 `yak_no` 与资产关联解析;`cattleId`→`cattle_external_id`,`farmId`/`enclosureId`/`weight`/`weighingTime` 等按接口落库。
161
 | `biz_yak_ear_tag_record` | `GET /open-api/v1/iot/ear-tags` | `external_id` | `sql/biz_yak_ear_tag_record.sql` |
163
 | `biz_yak_ear_tag_record` | `GET /open-api/v1/iot/ear-tags` | `external_id` | `sql/biz_yak_ear_tag_record.sql` |
162
 
164
 
163
 `biz_yak_ear_tag_record` 字段映射:`earTagNumber`→`ear_tag_number`,`cattleNo` 参与 `yak_no` 与资产关联解析;`actualTemperature`/`temperature`/`steps`/`reportTime` 同名落库。
165
 `biz_yak_ear_tag_record` 字段映射:`earTagNumber`→`ear_tag_number`,`cattleNo` 参与 `yak_no` 与资产关联解析;`actualTemperature`/`temperature`/`steps`/`reportTime` 同名落库。

+ 3 - 1
sql/biz_yak_weighing_record.sql

@@ -3,8 +3,9 @@ CREATE TABLE IF NOT EXISTS `biz_yak_weighing_record` (
3
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '本地主键',
3
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '本地主键',
4
   `external_id` bigint(20) NOT NULL COMMENT '第三方称重记录ID',
4
   `external_id` bigint(20) NOT NULL COMMENT '第三方称重记录ID',
5
   `yak_asset_id` bigint(20) DEFAULT NULL COMMENT '本地牦牛 biz_yak_asset.id',
5
   `yak_asset_id` bigint(20) DEFAULT NULL COMMENT '本地牦牛 biz_yak_asset.id',
6
+  `ear_tag_number` varchar(64) DEFAULT NULL COMMENT '耳标编号(接口 earTagNumber)',
6
   `cattle_external_id` bigint(20) DEFAULT NULL COMMENT '第三方牛只ID cattleId',
7
   `cattle_external_id` bigint(20) DEFAULT NULL COMMENT '第三方牛只ID cattleId',
7
-  `yak_no` varchar(64) DEFAULT NULL COMMENT '牦牛编号(耳标优先)',
8
+  `yak_no` varchar(64) DEFAULT NULL COMMENT '牦牛编号(关联资产,耳标优先于 cattleNo)',
8
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '本地养殖场ID',
9
   `pasture_id` bigint(20) DEFAULT NULL COMMENT '本地养殖场ID',
9
   `farm_external_id` bigint(20) DEFAULT NULL COMMENT '第三方养殖场ID',
10
   `farm_external_id` bigint(20) DEFAULT NULL COMMENT '第三方养殖场ID',
10
   `farm_name` varchar(128) DEFAULT NULL COMMENT '养殖场名称',
11
   `farm_name` varchar(128) DEFAULT NULL COMMENT '养殖场名称',
@@ -24,6 +25,7 @@ CREATE TABLE IF NOT EXISTS `biz_yak_weighing_record` (
24
   PRIMARY KEY (`id`),
25
   PRIMARY KEY (`id`),
25
   UNIQUE KEY `uk_external_id` (`external_id`),
26
   UNIQUE KEY `uk_external_id` (`external_id`),
26
   KEY `idx_yak_asset_id` (`yak_asset_id`),
27
   KEY `idx_yak_asset_id` (`yak_asset_id`),
28
+  KEY `idx_ear_tag_number` (`ear_tag_number`),
27
   KEY `idx_yak_no` (`yak_no`),
29
   KEY `idx_yak_no` (`yak_no`),
28
   KEY `idx_weighing_time` (`weighing_time`)
30
   KEY `idx_weighing_time` (`weighing_time`)
29
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牛只称重数据(第三方同步)';
31
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牛只称重数据(第三方同步)';