소스 검색

外部接口

wwh 2 주 전
부모
커밋
1b56a84eea

+ 22 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/research/controller/ResearchOpenApiController.java

@@ -15,6 +15,7 @@ import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
15
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenRequest;
15
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenRequest;
16
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
16
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
18
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
18
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
20
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
20
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
21
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -222,4 +223,25 @@ public class ResearchOpenApiController
222
             return ResearchOpenApiSupport.error(code, ex.getMessage());
223
             return ResearchOpenApiSupport.error(code, ex.getMessage());
223
         }
224
         }
224
     }
225
     }
226
+
227
+    /**
228
+     * 可支配收入数据列表(县级年度汇总)。
229
+     */
230
+    @GetMapping("/disposable-incomes")
231
+    public OpenApiResponse<OpenApiPageResult<ResearchDisposableIncomeVo>> listDisposableIncomes(
232
+            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
233
+            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
234
+            @RequestParam(value = "statYear", required = false) Integer statYear)
235
+    {
236
+        try
237
+        {
238
+            return ResearchOpenApiSupport.success(
239
+                    researchOpenApiService.listDisposableIncomes(pageNum, pageSize, statYear));
240
+        }
241
+        catch (ServiceException ex)
242
+        {
243
+            int code = ex.getCode() != null ? ex.getCode() : 500;
244
+            return ResearchOpenApiSupport.error(code, ex.getMessage());
245
+        }
246
+    }
225
 }
247
 }

+ 87 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/research/domain/vo/ResearchDisposableIncomeVo.java

@@ -0,0 +1,87 @@
1
+package com.ruoyi.web.modules.industryservice.research.domain.vo;
2
+
3
+import java.math.BigDecimal;
4
+
5
+/**
6
+ * 科研开放接口 — 可支配收入数据填报(县级年度汇总;不含操作人 / 备注)。
7
+ */
8
+public class ResearchDisposableIncomeVo
9
+{
10
+    /** 可支配收入记录 ID */
11
+    private Long incomeId;
12
+
13
+    /** 所属年份 */
14
+    private Integer statYear;
15
+
16
+    /** 农村居民人均可支配收入(元) */
17
+    private BigDecimal ruralDisposableIncome;
18
+
19
+    /** 脱贫人口人均纯收入(元) */
20
+    private BigDecimal povertyNetIncome;
21
+
22
+    /** 增幅(元);公式=本年可支配收入-上年可支配收入 */
23
+    private BigDecimal incomeIncrease;
24
+
25
+    /** 增速(%);公式=(增幅/上年可支配收入)×100,保留2位小数 */
26
+    private BigDecimal incomeGrowthRate;
27
+
28
+    public Long getIncomeId()
29
+    {
30
+        return incomeId;
31
+    }
32
+
33
+    public void setIncomeId(Long incomeId)
34
+    {
35
+        this.incomeId = incomeId;
36
+    }
37
+
38
+    public Integer getStatYear()
39
+    {
40
+        return statYear;
41
+    }
42
+
43
+    public void setStatYear(Integer statYear)
44
+    {
45
+        this.statYear = statYear;
46
+    }
47
+
48
+    public BigDecimal getRuralDisposableIncome()
49
+    {
50
+        return ruralDisposableIncome;
51
+    }
52
+
53
+    public void setRuralDisposableIncome(BigDecimal ruralDisposableIncome)
54
+    {
55
+        this.ruralDisposableIncome = ruralDisposableIncome;
56
+    }
57
+
58
+    public BigDecimal getPovertyNetIncome()
59
+    {
60
+        return povertyNetIncome;
61
+    }
62
+
63
+    public void setPovertyNetIncome(BigDecimal povertyNetIncome)
64
+    {
65
+        this.povertyNetIncome = povertyNetIncome;
66
+    }
67
+
68
+    public BigDecimal getIncomeIncrease()
69
+    {
70
+        return incomeIncrease;
71
+    }
72
+
73
+    public void setIncomeIncrease(BigDecimal incomeIncrease)
74
+    {
75
+        this.incomeIncrease = incomeIncrease;
76
+    }
77
+
78
+    public BigDecimal getIncomeGrowthRate()
79
+    {
80
+        return incomeGrowthRate;
81
+    }
82
+
83
+    public void setIncomeGrowthRate(BigDecimal incomeGrowthRate)
84
+    {
85
+        this.incomeGrowthRate = incomeGrowthRate;
86
+    }
87
+}

+ 8 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/research/service/IResearchOpenApiService.java

@@ -3,6 +3,7 @@ package com.ruoyi.web.modules.industryservice.research.service;
3
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
3
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
4
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
4
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
5
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
5
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
6
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
6
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
7
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
7
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
8
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
8
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
9
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -68,4 +69,11 @@ public interface IResearchOpenApiService
68
      */
69
      */
69
     OpenApiPageResult<ResearchFamilyRanchVo> listFamilyRanches(int pageNum, int pageSize,
70
     OpenApiPageResult<ResearchFamilyRanchVo> listFamilyRanches(int pageNum, int pageSize,
70
             Integer statYear, Integer statMonth, String townName, String villageName, String enterpriseName);
71
             Integer statYear, Integer statMonth, String townName, String villageName, String enterpriseName);
72
+
73
+    /**
74
+     * 可支配收入填报列表。
75
+     *
76
+     * @param statYear 所属年份精确匹配
77
+     */
78
+    OpenApiPageResult<ResearchDisposableIncomeVo> listDisposableIncomes(int pageNum, int pageSize, Integer statYear);
71
 }
79
 }

+ 22 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/research/service/impl/ResearchOpenApiServiceImpl.java

@@ -9,6 +9,7 @@ import com.github.pagehelper.PageInfo;
9
 import com.ruoyi.common.exception.ServiceException;
9
 import com.ruoyi.common.exception.ServiceException;
10
 import com.ruoyi.common.utils.StringUtils;
10
 import com.ruoyi.common.utils.StringUtils;
11
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
11
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
12
+import com.ruoyi.web.modules.industryservice.domain.BizDisposableIncome;
12
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
13
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
13
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
14
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
14
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
15
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
@@ -17,6 +18,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
17
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
18
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
18
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
19
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
19
 import com.ruoyi.web.modules.industryservice.mapper.BizCooperativeDevelopmentMapper;
20
 import com.ruoyi.web.modules.industryservice.mapper.BizCooperativeDevelopmentMapper;
21
+import com.ruoyi.web.modules.industryservice.mapper.BizDisposableIncomeMapper;
20
 import com.ruoyi.web.modules.industryservice.mapper.BizFamilyRanchMapper;
22
 import com.ruoyi.web.modules.industryservice.mapper.BizFamilyRanchMapper;
21
 import com.ruoyi.web.modules.industryservice.mapper.BizLivestockProductOutputMapper;
23
 import com.ruoyi.web.modules.industryservice.mapper.BizLivestockProductOutputMapper;
22
 import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
24
 import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
@@ -24,6 +26,7 @@ import com.ruoyi.web.modules.industryservice.mapper.BizYakOutboundReportMapper;
24
 import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
26
 import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
25
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
27
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
29
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
30
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
31
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
29
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
32
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -66,6 +69,9 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
66
     @Autowired
69
     @Autowired
67
     private BizFamilyRanchMapper bizFamilyRanchMapper;
70
     private BizFamilyRanchMapper bizFamilyRanchMapper;
68
 
71
 
72
+    @Autowired
73
+    private BizDisposableIncomeMapper bizDisposableIncomeMapper;
74
+
69
     @Override
75
     @Override
70
     public ResearchTokenVo authenticate(String appKey, String appSecret)
76
     public ResearchTokenVo authenticate(String appKey, String appSecret)
71
     {
77
     {
@@ -250,6 +256,22 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
250
                 rows.stream().map(ResearchOpenApiSupport::toFamilyRanchVo).collect(Collectors.toList()));
256
                 rows.stream().map(ResearchOpenApiSupport::toFamilyRanchVo).collect(Collectors.toList()));
251
     }
257
     }
252
 
258
 
259
+    @Override
260
+    public OpenApiPageResult<ResearchDisposableIncomeVo> listDisposableIncomes(int pageNum, int pageSize,
261
+            Integer statYear)
262
+    {
263
+        tokenService.assertEnabled();
264
+        int safePageNum = normalizePageNum(pageNum);
265
+        int safePageSize = normalizePageSize(pageSize);
266
+        BizDisposableIncome query = new BizDisposableIncome();
267
+        query.setStatYear(statYear);
268
+        PageHelper.startPage(safePageNum, safePageSize);
269
+        List<BizDisposableIncome> rows = bizDisposableIncomeMapper.selectBizDisposableIncomeList(query);
270
+        PageInfo<BizDisposableIncome> page = new PageInfo<>(rows);
271
+        return toPageResult(safePageNum, safePageSize, page.getTotal(),
272
+                rows.stream().map(ResearchOpenApiSupport::toDisposableIncomeVo).collect(Collectors.toList()));
273
+    }
274
+
253
     private int normalizePageNum(int pageNum)
275
     private int normalizePageNum(int pageNum)
254
     {
276
     {
255
         return pageNum > 0 ? pageNum : 1;
277
         return pageNum > 0 ? pageNum : 1;

+ 18 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/industryservice/research/support/ResearchOpenApiSupport.java

@@ -3,6 +3,7 @@ package com.ruoyi.web.modules.industryservice.research.support;
3
 import java.time.Instant;
3
 import java.time.Instant;
4
 import java.util.UUID;
4
 import java.util.UUID;
5
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
5
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
6
+import com.ruoyi.web.modules.industryservice.domain.BizDisposableIncome;
6
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
7
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
7
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
8
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
8
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
9
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
@@ -11,6 +12,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
11
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
12
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
12
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
13
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
13
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
14
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
15
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
14
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
16
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
15
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
16
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
18
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -272,4 +274,20 @@ public final class ResearchOpenApiSupport
272
         vo.setWagePaid(row.getWagePaid());
274
         vo.setWagePaid(row.getWagePaid());
273
         return vo;
275
         return vo;
274
     }
276
     }
277
+
278
+    public static ResearchDisposableIncomeVo toDisposableIncomeVo(BizDisposableIncome row)
279
+    {
280
+        if (row == null)
281
+        {
282
+            return null;
283
+        }
284
+        ResearchDisposableIncomeVo vo = new ResearchDisposableIncomeVo();
285
+        vo.setIncomeId(row.getId());
286
+        vo.setStatYear(row.getStatYear());
287
+        vo.setRuralDisposableIncome(row.getRuralDisposableIncome());
288
+        vo.setPovertyNetIncome(row.getPovertyNetIncome());
289
+        vo.setIncomeIncrease(row.getIncomeIncrease());
290
+        vo.setIncomeGrowthRate(row.getIncomeGrowthRate());
291
+        return vo;
292
+    }
275
 }
293
 }

+ 22 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/industryservice/research/controller/ResearchOpenApiControllerApiTest.java

@@ -22,6 +22,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
22
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
22
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
23
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
23
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
24
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
24
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
25
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
25
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -231,4 +232,25 @@ class ResearchOpenApiControllerApiTest
231
                 .andExpect(jsonPath("$.code").value(200))
232
                 .andExpect(jsonPath("$.code").value(200))
232
                 .andExpect(jsonPath("$.data.records[0].enterpriseName").value("测试牧场"));
233
                 .andExpect(jsonPath("$.data.records[0].enterpriseName").value("测试牧场"));
233
     }
234
     }
235
+
236
+    @Test
237
+    @DisplayName("GET /disposable-incomes 成功")
238
+    void listDisposableIncomes() throws Exception
239
+    {
240
+        ResearchDisposableIncomeVo row = new ResearchDisposableIncomeVo();
241
+        row.setIncomeId(1L);
242
+        row.setStatYear(2025);
243
+        OpenApiPageResult<ResearchDisposableIncomeVo> page = new OpenApiPageResult<>();
244
+        page.setPageNum(1);
245
+        page.setPageSize(20);
246
+        page.setTotal(1L);
247
+        page.setRecords(Collections.singletonList(row));
248
+        when(researchOpenApiService.listDisposableIncomes(anyInt(), anyInt(), any())).thenReturn(page);
249
+
250
+        mockMvc.perform(get("/open-api/v1/research/disposable-incomes")
251
+                .param("statYear", "2025"))
252
+                .andExpect(status().isOk())
253
+                .andExpect(jsonPath("$.code").value(200))
254
+                .andExpect(jsonPath("$.data.records[0].statYear").value(2025));
255
+    }
234
 }
256
 }

+ 17 - 0
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口功能需求.md

@@ -33,6 +33,7 @@
33
 | 合作社发展数据列表 | 分页返回合作社发展填报;法人姓名脱敏 |
33
 | 合作社发展数据列表 | 分页返回合作社发展填报;法人姓名脱敏 |
34
 | 畜牧产品产量登记列表 | 分页返回村级肉/奶产量 |
34
 | 畜牧产品产量登记列表 | 分页返回村级肉/奶产量 |
35
 | 家庭牧场数据列表 | 分页返回家庭牧场填报;法人姓名脱敏 |
35
 | 家庭牧场数据列表 | 分页返回家庭牧场填报;法人姓名脱敏 |
36
+| 可支配收入数据列表 | 分页返回县级年度可支配收入填报 |
36
 
37
 
37
 **本期不实现:**
38
 **本期不实现:**
38
 
39
 
@@ -189,6 +190,20 @@ sequenceDiagram
189
 
190
 
190
 **不返回**:部门 ID、创建人、备注等内部字段。
191
 **不返回**:部门 ID、创建人、备注等内部字段。
191
 
192
 
193
+### 6.9 可支配收入数据列表
194
+
195
+| 项 | 说明 |
196
+| --- | --- |
197
+| 方法 | GET |
198
+| 路径 | `/disposable-incomes` |
199
+| 鉴权 | Bearer Token |
200
+| 分页 | 同 §6.2 |
201
+| 筛选 | `statYear`(所属年份精确) |
202
+
203
+**返回字段**:`incomeId`、`statYear`、`ruralDisposableIncome`、`povertyNetIncome`、`incomeIncrease`、`incomeGrowthRate`。
204
+
205
+**不返回**:创建人、备注等内部字段。
206
+
192
 ---
207
 ---
193
 
208
 
194
 ## 7. 脱敏规则摘要
209
 ## 7. 脱敏规则摘要
@@ -231,6 +246,7 @@ sequenceDiagram
231
 | 合作社发展数据填报 | 数据源 `biz_cooperative_development` |
246
 | 合作社发展数据填报 | 数据源 `biz_cooperative_development` |
232
 | 畜牧产品产量登记 | 数据源 `biz_livestock_product_output` |
247
 | 畜牧产品产量登记 | 数据源 `biz_livestock_product_output` |
233
 | 家庭牧场数据填报 | 数据源 `biz_family_ranch` |
248
 | 家庭牧场数据填报 | 数据源 `biz_family_ranch` |
249
+| 可支配收入数据填报 | 数据源 `biz_disposable_income` |
234
 | 若依权限体系 | **无**关联;开放接口走独立 Token |
250
 | 若依权限体系 | **无**关联;开放接口走独立 Token |
235
 
251
 
236
 ---
252
 ---
@@ -247,5 +263,6 @@ sequenceDiagram
247
 | 合作社发展列表 | §6.6 |
263
 | 合作社发展列表 | §6.6 |
248
 | 畜牧产品产量列表 | §6.7 |
264
 | 畜牧产品产量列表 | §6.7 |
249
 | 家庭牧场列表 | §6.8 |
265
 | 家庭牧场列表 | §6.8 |
266
+| 可支配收入列表 | §6.9 |
250
 | 脱敏合规 | §7 |
267
 | 脱敏合规 | §7 |
251
 | 本期不实现 | §3 |
268
 | 本期不实现 | §3 |

+ 22 - 2
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口技术方案.md

@@ -9,7 +9,7 @@
9
 | 项 | 说明 |
9
 | 项 | 说明 |
10
 | --- | --- |
10
 | --- | --- |
11
 | **后端** | RuoYi **v3.9.2**(**springboot2** 分支):JDK 8、Spring MVC、MyBatis |
11
 | **后端** | RuoYi **v3.9.2**(**springboot2** 分支):JDK 8、Spring MVC、MyBatis |
12
-| **数据库** | 只读查询既有表 `biz_pasture`、`biz_yak_asset`、`biz_yak_herd_inventory`、`biz_yak_outbound_report`、`biz_cooperative_development`、`biz_livestock_product_output`、`biz_family_ranch` |
12
+| **数据库** | 只读查询既有表 `biz_pasture`、`biz_yak_asset`、`biz_yak_herd_inventory`、`biz_yak_outbound_report`、`biz_cooperative_development`、`biz_livestock_product_output`、`biz_family_ranch`、`biz_disposable_income` |
13
 | **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
13
 | **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
14
 | **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
14
 | **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
15
 
15
 
@@ -195,6 +195,19 @@ Authorization: Bearer <accessToken>
195
 
195
 
196
 实现说明:直接查 `BizFamilyRanchMapper`(清空 `params.dataScope`)。
196
 实现说明:直接查 `BizFamilyRanchMapper`(清空 `params.dataScope`)。
197
 
197
 
198
+### 3.9 可支配收入数据列表
199
+
200
+```
201
+GET /open-api/v1/research/disposable-incomes?pageNum=1&pageSize=20&statYear=2025
202
+Authorization: Bearer <accessToken>
203
+```
204
+
205
+**查询参数:** `statYear`(精确);分页同前。
206
+
207
+**`records[]` 元素(ResearchDisposableIncomeVo):** `incomeId`、`statYear`、`ruralDisposableIncome`、`povertyNetIncome`、`incomeIncrease`、`incomeGrowthRate`;**不含**操作人、备注。
208
+
209
+实现说明:直接查 `BizDisposableIncomeMapper.selectBizDisposableIncomeList`。
210
+
198
 ---
211
 ---
199
 
212
 
200
 ## 4. 鉴权流程
213
 ## 4. 鉴权流程
@@ -221,8 +234,9 @@ Token 申请:`appKey`/`appSecret` 与配置项精确匹配后签发 JWT(HS51
221
 | 合作社列表 | `BizCooperativeDevelopmentMapper.selectBizCooperativeDevelopmentList` | `biz_cooperative_development` | 年/月精确;乡镇/村/合作社名模糊;清空 `params.dataScope` |
234
 | 合作社列表 | `BizCooperativeDevelopmentMapper.selectBizCooperativeDevelopmentList` | `biz_cooperative_development` | 年/月精确;乡镇/村/合作社名模糊;清空 `params.dataScope` |
222
 | 产量列表 | `BizLivestockProductOutputMapper.selectBizLivestockProductOutputList` | `biz_livestock_product_output` | 年/月精确;乡镇/村名模糊;清空 `params.dataScope` |
235
 | 产量列表 | `BizLivestockProductOutputMapper.selectBizLivestockProductOutputList` | `biz_livestock_product_output` | 年/月精确;乡镇/村名模糊;清空 `params.dataScope` |
223
 | 家庭牧场列表 | `BizFamilyRanchMapper.selectBizFamilyRanchList` | `biz_family_ranch` | 年/月精确;乡镇/村/企业名模糊;清空 `params.dataScope` |
236
 | 家庭牧场列表 | `BizFamilyRanchMapper.selectBizFamilyRanchList` | `biz_family_ranch` | 年/月精确;乡镇/村/企业名模糊;清空 `params.dataScope` |
237
+| 可支配收入列表 | `BizDisposableIncomeMapper.selectBizDisposableIncomeList` | `biz_disposable_income` | 年份精确 |
224
 
238
 
225
-实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo` / `toFamilyRanchVo`。
239
+实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo` / `toFamilyRanchVo` / `toDisposableIncomeVo`
226
 
240
 
227
 ---
241
 ---
228
 
242
 
@@ -287,6 +301,10 @@ curl "http://localhost:8010/open-api/v1/research/livestock-product-outputs?pageN
287
 # 8. 家庭牧场
301
 # 8. 家庭牧场
288
 curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSize=10&statYear=2026&enterpriseName=牧场" \
302
 curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSize=10&statYear=2026&enterpriseName=牧场" \
289
   -H "Authorization: Bearer <accessToken>"
303
   -H "Authorization: Bearer <accessToken>"
304
+
305
+# 9. 可支配收入
306
+curl "http://localhost:8010/open-api/v1/research/disposable-incomes?pageNum=1&pageSize=10&statYear=2025" \
307
+  -H "Authorization: Bearer <accessToken>"
290
 ```
308
 ```
291
 
309
 
292
 ---
310
 ---
@@ -313,6 +331,7 @@ curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSi
313
 | §6.6 合作社 | **§3.6**、**§5** BizCooperativeDevelopment |
331
 | §6.6 合作社 | **§3.6**、**§5** BizCooperativeDevelopment |
314
 | §6.7 产量 | **§3.7**、**§5** BizLivestockProductOutput |
332
 | §6.7 产量 | **§3.7**、**§5** BizLivestockProductOutput |
315
 | §6.8 家庭牧场 | **§3.8**、**§5** BizFamilyRanch |
333
 | §6.8 家庭牧场 | **§3.8**、**§5** BizFamilyRanch |
334
+| §6.9 可支配收入 | **§3.9**、**§5** BizDisposableIncome |
316
 | §7 脱敏 | **§6** Masking |
335
 | §7 脱敏 | **§6** Masking |
317
 | §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
336
 | §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
318
 
337
 
@@ -322,6 +341,7 @@ curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSi
322
 
341
 
323
 | 版本 | 日期 | 说明 |
342
 | 版本 | 日期 | 说明 |
324
 | --- | --- | --- |
343
 | --- | --- | --- |
344
+| 1.6 | 2026-07-22 | 新增可支配收入开放列表(年份精确+分页) |
325
 | 1.5 | 2026-07-22 | 新增家庭牧场开放列表(年/月/乡镇村/企业名模糊+分页;法人脱敏) |
345
 | 1.5 | 2026-07-22 | 新增家庭牧场开放列表(年/月/乡镇村/企业名模糊+分页;法人脱敏) |
326
 | 1.4 | 2026-07-22 | 新增畜牧产品产量登记开放列表(年/月/乡镇村模糊+分页) |
346
 | 1.4 | 2026-07-22 | 新增畜牧产品产量登记开放列表(年/月/乡镇村模糊+分页) |
327
 | 1.3 | 2026-07-22 | 新增合作社发展开放列表(年/月/乡镇村/名称模糊+分页;法人脱敏) |
347
 | 1.3 | 2026-07-22 | 新增合作社发展开放列表(年/月/乡镇村/名称模糊+分页;法人脱敏) |

+ 5 - 1
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口测试用例.md

@@ -53,6 +53,8 @@
53
 | KYKF-API-020 | 产量 | 年/月/乡镇村筛选 | 接口测试 | curl | §6.7 | 已知年月与乡镇名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
53
 | KYKF-API-020 | 产量 | 年/月/乡镇村筛选 | 接口测试 | curl | §6.7 | 已知年月与乡镇名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
54
 | KYKF-API-021 | 家庭牧场 | 分页列表 | 接口测试 | curl | §6.8 | 有效 Token;库有牧场数据 | GET `/family-ranches?pageNum=1&pageSize=10` | `code=200`;法人已脱敏;无部门 ID |
54
 | KYKF-API-021 | 家庭牧场 | 分页列表 | 接口测试 | curl | §6.8 | 有效 Token;库有牧场数据 | GET `/family-ranches?pageNum=1&pageSize=10` | `code=200`;法人已脱敏;无部门 ID |
55
 | KYKF-API-022 | 家庭牧场 | 年/月/乡镇村/企业名筛选 | 接口测试 | curl | §6.8 | 已知企业名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
55
 | KYKF-API-022 | 家庭牧场 | 年/月/乡镇村/企业名筛选 | 接口测试 | curl | §6.8 | 已知企业名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
56
+| KYKF-API-023 | 可支配收入 | 分页列表 | 接口测试 | curl | §6.9 | 有效 Token;库有收入数据 | GET `/disposable-incomes?pageNum=1&pageSize=10` | `code=200`;无操作人/备注 |
57
+| KYKF-API-024 | 可支配收入 | 年份筛选 | 接口测试 | curl | §6.9 | 已知年份 | GET 带 `statYear` | 仅返回该年记录 |
56
 
58
 
57
 ---
59
 ---
58
 
60
 
@@ -68,11 +70,12 @@
68
 | §6.6 合作社列表 | — | API-017~018 |
70
 | §6.6 合作社列表 | — | API-017~018 |
69
 | §6.7 产量列表 | — | API-019~020 |
71
 | §6.7 产量列表 | — | API-019~020 |
70
 | §6.8 家庭牧场列表 | — | API-021~022 |
72
 | §6.8 家庭牧场列表 | — | API-021~022 |
73
+| §6.9 可支配收入列表 | — | API-023~024 |
71
 | §7 脱敏 | UT-001~004 | API-012 |
74
 | §7 脱敏 | UT-001~004 | API-012 |
72
 | §2 分页 | — | API-010 |
75
 | §2 分页 | — | API-010 |
73
 | §3 无机构区分 | UT-005 | API-001(单一凭证) |
76
 | §3 无机构区分 | UT-005 | API-001(单一凭证) |
74
 
77
 
75
-**用例统计**:单元 **6**、接口 **22**,合计 **28** 条。
78
+**用例统计**:单元 **6**、接口 **24**,合计 **30** 条。
76
 
79
 
77
 ---
80
 ---
78
 
81
 
@@ -92,6 +95,7 @@ curl -s "$BASE/yak-outbound-reports?pageNum=1&pageSize=5&statYear=2026" -H "Auth
92
 curl -s "$BASE/cooperative-developments?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
95
 curl -s "$BASE/cooperative-developments?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
93
 curl -s "$BASE/livestock-product-outputs?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
96
 curl -s "$BASE/livestock-product-outputs?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
94
 curl -s "$BASE/family-ranches?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
97
 curl -s "$BASE/family-ranches?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
98
+curl -s "$BASE/disposable-incomes?pageNum=1&pageSize=5&statYear=2025" -H "Authorization: Bearer $TOKEN"
95
 ```
99
 ```
96
 
100
 
97
 (Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)
101
 (Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)