wwh недель назад: 2
Родитель
Сommit
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 15
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenRequest;
16 16
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
17 17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
18
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
18 19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
19 20
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
20 21
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -222,4 +223,25 @@ public class ResearchOpenApiController
222 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 3
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
4 4
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
5 5
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
6
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
6 7
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
7 8
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
8 9
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -68,4 +69,11 @@ public interface IResearchOpenApiService
68 69
      */
69 70
     OpenApiPageResult<ResearchFamilyRanchVo> listFamilyRanches(int pageNum, int pageSize,
70 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 9
 import com.ruoyi.common.exception.ServiceException;
10 10
 import com.ruoyi.common.utils.StringUtils;
11 11
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
12
+import com.ruoyi.web.modules.industryservice.domain.BizDisposableIncome;
12 13
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
13 14
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
14 15
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
@@ -17,6 +18,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
17 18
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
18 19
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
19 20
 import com.ruoyi.web.modules.industryservice.mapper.BizCooperativeDevelopmentMapper;
21
+import com.ruoyi.web.modules.industryservice.mapper.BizDisposableIncomeMapper;
20 22
 import com.ruoyi.web.modules.industryservice.mapper.BizFamilyRanchMapper;
21 23
 import com.ruoyi.web.modules.industryservice.mapper.BizLivestockProductOutputMapper;
22 24
 import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
@@ -24,6 +26,7 @@ import com.ruoyi.web.modules.industryservice.mapper.BizYakOutboundReportMapper;
24 26
 import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
25 27
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
26 28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
29
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
27 30
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
28 31
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
29 32
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -66,6 +69,9 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
66 69
     @Autowired
67 70
     private BizFamilyRanchMapper bizFamilyRanchMapper;
68 71
 
72
+    @Autowired
73
+    private BizDisposableIncomeMapper bizDisposableIncomeMapper;
74
+
69 75
     @Override
70 76
     public ResearchTokenVo authenticate(String appKey, String appSecret)
71 77
     {
@@ -250,6 +256,22 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
250 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 275
     private int normalizePageNum(int pageNum)
254 276
     {
255 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 3
 import java.time.Instant;
4 4
 import java.util.UUID;
5 5
 import com.ruoyi.web.modules.industryservice.domain.BizCooperativeDevelopment;
6
+import com.ruoyi.web.modules.industryservice.domain.BizDisposableIncome;
6 7
 import com.ruoyi.web.modules.industryservice.domain.BizFamilyRanch;
7 8
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
8 9
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
@@ -11,6 +12,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
11 12
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
12 13
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
13 14
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
15
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
14 16
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
15 17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
16 18
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -272,4 +274,20 @@ public final class ResearchOpenApiSupport
272 274
         vo.setWagePaid(row.getWagePaid());
273 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 22
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
23 23
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
24 24
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
25
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
25 26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
26 27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
27 28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
@@ -231,4 +232,25 @@ class ResearchOpenApiControllerApiTest
231 232
                 .andExpect(jsonPath("$.code").value(200))
232 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 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 209
 ## 7. 脱敏规则摘要
@@ -231,6 +246,7 @@ sequenceDiagram
231 246
 | 合作社发展数据填报 | 数据源 `biz_cooperative_development` |
232 247
 | 畜牧产品产量登记 | 数据源 `biz_livestock_product_output` |
233 248
 | 家庭牧场数据填报 | 数据源 `biz_family_ranch` |
249
+| 可支配收入数据填报 | 数据源 `biz_disposable_income` |
234 250
 | 若依权限体系 | **无**关联;开放接口走独立 Token |
235 251
 
236 252
 ---
@@ -247,5 +263,6 @@ sequenceDiagram
247 263
 | 合作社发展列表 | §6.6 |
248 264
 | 畜牧产品产量列表 | §6.7 |
249 265
 | 家庭牧场列表 | §6.8 |
266
+| 可支配收入列表 | §6.9 |
250 267
 | 脱敏合规 | §7 |
251 268
 | 本期不实现 | §3 |

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

@@ -9,7 +9,7 @@
9 9
 | 项 | 说明 |
10 10
 | --- | --- |
11 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 13
 | **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
14 14
 | **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
15 15
 
@@ -195,6 +195,19 @@ Authorization: Bearer <accessToken>
195 195
 
196 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 213
 ## 4. 鉴权流程
@@ -221,8 +234,9 @@ Token 申请:`appKey`/`appSecret` 与配置项精确匹配后签发 JWT(HS51
221 234
 | 合作社列表 | `BizCooperativeDevelopmentMapper.selectBizCooperativeDevelopmentList` | `biz_cooperative_development` | 年/月精确;乡镇/村/合作社名模糊;清空 `params.dataScope` |
222 235
 | 产量列表 | `BizLivestockProductOutputMapper.selectBizLivestockProductOutputList` | `biz_livestock_product_output` | 年/月精确;乡镇/村名模糊;清空 `params.dataScope` |
223 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 301
 # 8. 家庭牧场
288 302
 curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSize=10&statYear=2026&enterpriseName=牧场" \
289 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 331
 | §6.6 合作社 | **§3.6**、**§5** BizCooperativeDevelopment |
314 332
 | §6.7 产量 | **§3.7**、**§5** BizLivestockProductOutput |
315 333
 | §6.8 家庭牧场 | **§3.8**、**§5** BizFamilyRanch |
334
+| §6.9 可支配收入 | **§3.9**、**§5** BizDisposableIncome |
316 335
 | §7 脱敏 | **§6** Masking |
317 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 345
 | 1.5 | 2026-07-22 | 新增家庭牧场开放列表(年/月/乡镇村/企业名模糊+分页;法人脱敏) |
326 346
 | 1.4 | 2026-07-22 | 新增畜牧产品产量登记开放列表(年/月/乡镇村模糊+分页) |
327 347
 | 1.3 | 2026-07-22 | 新增合作社发展开放列表(年/月/乡镇村/名称模糊+分页;法人脱敏) |

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

@@ -53,6 +53,8 @@
53 53
 | KYKF-API-020 | 产量 | 年/月/乡镇村筛选 | 接口测试 | curl | §6.7 | 已知年月与乡镇名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
54 54
 | KYKF-API-021 | 家庭牧场 | 分页列表 | 接口测试 | curl | §6.8 | 有效 Token;库有牧场数据 | GET `/family-ranches?pageNum=1&pageSize=10` | `code=200`;法人已脱敏;无部门 ID |
55 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 70
 | §6.6 合作社列表 | — | API-017~018 |
69 71
 | §6.7 产量列表 | — | API-019~020 |
70 72
 | §6.8 家庭牧场列表 | — | API-021~022 |
73
+| §6.9 可支配收入列表 | — | API-023~024 |
71 74
 | §7 脱敏 | UT-001~004 | API-012 |
72 75
 | §2 分页 | — | API-010 |
73 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 95
 curl -s "$BASE/cooperative-developments?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
93 96
 curl -s "$BASE/livestock-product-outputs?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
94 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 101
 (Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)