wwh 1 nedēļu atpakaļ
vecāks
revīzija
7375c82d75

+ 24 - 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.ResearchCommonProsperityProjectVo;
18 19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
19 20
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
20 21
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
@@ -269,4 +270,27 @@ public class ResearchOpenApiController
269 270
             return ResearchOpenApiSupport.error(code, ex.getMessage());
270 271
         }
271 272
     }
273
+
274
+    /**
275
+     * 共同富裕项目列表。
276
+     */
277
+    @GetMapping("/common-prosperity-projects")
278
+    public OpenApiResponse<OpenApiPageResult<ResearchCommonProsperityProjectVo>> listCommonProsperityProjects(
279
+            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
280
+            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
281
+            @RequestParam(value = "projectName", required = false) String projectName,
282
+            @RequestParam(value = "projectType", required = false) Integer projectType,
283
+            @RequestParam(value = "implYear", required = false) Integer implYear)
284
+    {
285
+        try
286
+        {
287
+            return ResearchOpenApiSupport.success(researchOpenApiService.listCommonProsperityProjects(
288
+                    pageNum, pageSize, projectName, projectType, implYear));
289
+        }
290
+        catch (ServiceException ex)
291
+        {
292
+            int code = ex.getCode() != null ? ex.getCode() : 500;
293
+            return ResearchOpenApiSupport.error(code, ex.getMessage());
294
+        }
295
+    }
272 296
 }

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

@@ -0,0 +1,181 @@
1
+package com.ruoyi.web.modules.industryservice.research.domain.vo;
2
+
3
+import java.math.BigDecimal;
4
+import java.util.Date;
5
+import com.fasterxml.jackson.annotation.JsonFormat;
6
+
7
+/**
8
+ * 科研开放接口 — 共同富裕项目(不含本地文件路径 / 操作人 / 备注)。
9
+ */
10
+public class ResearchCommonProsperityProjectVo
11
+{
12
+    /** 项目 ID */
13
+    private Long projectId;
14
+
15
+    /** 项目名称 */
16
+    private String projectName;
17
+
18
+    /** 项目类型(1和美乡村建设 2人居环境整治提升 3其他项目投入) */
19
+    private Integer projectType;
20
+
21
+    /** 项目简介 */
22
+    private String introduction;
23
+
24
+    /** 建设规模及内容 */
25
+    private String projectContent;
26
+
27
+    /** 投资金额(万元) */
28
+    private BigDecimal investmentAmount;
29
+
30
+    /** 实施年限 */
31
+    private Integer implYear;
32
+
33
+    /** 实施情况 */
34
+    private String implStatus;
35
+
36
+    /** 宣传视频 URL */
37
+    private String videoFileUrl;
38
+
39
+    /** 封面图 URL */
40
+    private String coverFileUrl;
41
+
42
+    /** 发布状态(0未发布 1已发布) */
43
+    private Integer publishStatus;
44
+
45
+    /** 发布时间 */
46
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
47
+    private Date publishTime;
48
+
49
+    /** 运营图片数量 */
50
+    private Integer opImageCount;
51
+
52
+    public Long getProjectId()
53
+    {
54
+        return projectId;
55
+    }
56
+
57
+    public void setProjectId(Long projectId)
58
+    {
59
+        this.projectId = projectId;
60
+    }
61
+
62
+    public String getProjectName()
63
+    {
64
+        return projectName;
65
+    }
66
+
67
+    public void setProjectName(String projectName)
68
+    {
69
+        this.projectName = projectName;
70
+    }
71
+
72
+    public Integer getProjectType()
73
+    {
74
+        return projectType;
75
+    }
76
+
77
+    public void setProjectType(Integer projectType)
78
+    {
79
+        this.projectType = projectType;
80
+    }
81
+
82
+    public String getIntroduction()
83
+    {
84
+        return introduction;
85
+    }
86
+
87
+    public void setIntroduction(String introduction)
88
+    {
89
+        this.introduction = introduction;
90
+    }
91
+
92
+    public String getProjectContent()
93
+    {
94
+        return projectContent;
95
+    }
96
+
97
+    public void setProjectContent(String projectContent)
98
+    {
99
+        this.projectContent = projectContent;
100
+    }
101
+
102
+    public BigDecimal getInvestmentAmount()
103
+    {
104
+        return investmentAmount;
105
+    }
106
+
107
+    public void setInvestmentAmount(BigDecimal investmentAmount)
108
+    {
109
+        this.investmentAmount = investmentAmount;
110
+    }
111
+
112
+    public Integer getImplYear()
113
+    {
114
+        return implYear;
115
+    }
116
+
117
+    public void setImplYear(Integer implYear)
118
+    {
119
+        this.implYear = implYear;
120
+    }
121
+
122
+    public String getImplStatus()
123
+    {
124
+        return implStatus;
125
+    }
126
+
127
+    public void setImplStatus(String implStatus)
128
+    {
129
+        this.implStatus = implStatus;
130
+    }
131
+
132
+    public String getVideoFileUrl()
133
+    {
134
+        return videoFileUrl;
135
+    }
136
+
137
+    public void setVideoFileUrl(String videoFileUrl)
138
+    {
139
+        this.videoFileUrl = videoFileUrl;
140
+    }
141
+
142
+    public String getCoverFileUrl()
143
+    {
144
+        return coverFileUrl;
145
+    }
146
+
147
+    public void setCoverFileUrl(String coverFileUrl)
148
+    {
149
+        this.coverFileUrl = coverFileUrl;
150
+    }
151
+
152
+    public Integer getPublishStatus()
153
+    {
154
+        return publishStatus;
155
+    }
156
+
157
+    public void setPublishStatus(Integer publishStatus)
158
+    {
159
+        this.publishStatus = publishStatus;
160
+    }
161
+
162
+    public Date getPublishTime()
163
+    {
164
+        return publishTime;
165
+    }
166
+
167
+    public void setPublishTime(Date publishTime)
168
+    {
169
+        this.publishTime = publishTime;
170
+    }
171
+
172
+    public Integer getOpImageCount()
173
+    {
174
+        return opImageCount;
175
+    }
176
+
177
+    public void setOpImageCount(Integer opImageCount)
178
+    {
179
+        this.opImageCount = opImageCount;
180
+    }
181
+}

+ 11 - 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.ResearchCommonProsperityProjectVo;
6 7
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
7 8
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
8 9
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
@@ -86,4 +87,14 @@ public interface IResearchOpenApiService
86 87
      */
87 88
     OpenApiPageResult<ResearchFarmerHouseholdVo> listFarmerHouseholds(int pageNum, int pageSize,
88 89
             Integer statYear, Integer statMonth, String townName, String villageName);
90
+
91
+    /**
92
+     * 共同富裕项目列表。
93
+     *
94
+     * @param projectName 项目名称模糊匹配
95
+     * @param projectType 项目类型精确匹配
96
+     * @param implYear 实施年限精确匹配
97
+     */
98
+    OpenApiPageResult<ResearchCommonProsperityProjectVo> listCommonProsperityProjects(int pageNum, int pageSize,
99
+            String projectName, Integer projectType, Integer implYear);
89 100
 }

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

@@ -28,6 +28,7 @@ import com.ruoyi.web.modules.industryservice.mapper.BizYakOutboundReportMapper;
28 28
 import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
29 29
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
30 30
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
31
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCommonProsperityProjectVo;
31 32
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
32 33
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
33 34
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
@@ -41,6 +42,8 @@ import com.ruoyi.web.modules.industryservice.research.support.ResearchOpenApiSup
41 42
 import com.ruoyi.web.modules.industryservice.research.support.ResearchOpenApiTokenService;
42 43
 import com.ruoyi.web.modules.industryservice.service.IBizPastureService;
43 44
 import com.ruoyi.web.modules.industryservice.service.IBizYakAssetService;
45
+import com.ruoyi.web.modules.prosperity.domain.BizCommonProsperityProject;
46
+import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityProjectMapper;
44 47
 
45 48
 @Service
46 49
 public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
@@ -78,6 +81,9 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
78 81
     @Autowired
79 82
     private BizFarmerHouseholdMapper bizFarmerHouseholdMapper;
80 83
 
84
+    @Autowired
85
+    private BizCommonProsperityProjectMapper bizCommonProsperityProjectMapper;
86
+
81 87
     @Override
82 88
     public ResearchTokenVo authenticate(String appKey, String appSecret)
83 89
     {
@@ -305,6 +311,28 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
305 311
                 rows.stream().map(ResearchOpenApiSupport::toFarmerHouseholdVo).collect(Collectors.toList()));
306 312
     }
307 313
 
314
+    @Override
315
+    public OpenApiPageResult<ResearchCommonProsperityProjectVo> listCommonProsperityProjects(int pageNum, int pageSize,
316
+            String projectName, Integer projectType, Integer implYear)
317
+    {
318
+        tokenService.assertEnabled();
319
+        int safePageNum = normalizePageNum(pageNum);
320
+        int safePageSize = normalizePageSize(pageSize);
321
+        BizCommonProsperityProject query = new BizCommonProsperityProject();
322
+        if (StringUtils.isNotEmpty(projectName))
323
+        {
324
+            query.setProjectName(projectName.trim());
325
+        }
326
+        query.setProjectType(projectType);
327
+        query.setImplYear(implYear);
328
+        PageHelper.startPage(safePageNum, safePageSize);
329
+        List<BizCommonProsperityProject> rows =
330
+                bizCommonProsperityProjectMapper.selectBizCommonProsperityProjectList(query);
331
+        PageInfo<BizCommonProsperityProject> page = new PageInfo<>(rows);
332
+        return toPageResult(safePageNum, safePageSize, page.getTotal(),
333
+                rows.stream().map(ResearchOpenApiSupport::toCommonProsperityProjectVo).collect(Collectors.toList()));
334
+    }
335
+
308 336
     private int normalizePageNum(int pageNum)
309 337
     {
310 338
         return pageNum > 0 ? pageNum : 1;

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

@@ -13,6 +13,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
13 13
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
14 14
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
15 15
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
16
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCommonProsperityProjectVo;
16 17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
17 18
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
18 19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
@@ -21,6 +22,7 @@ import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureV
21 22
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakAssetVo;
22 23
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakHerdInventoryVo;
23 24
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakOutboundReportVo;
25
+import com.ruoyi.web.modules.prosperity.domain.BizCommonProsperityProject;
24 26
 
25 27
 /**
26 28
  * 科研开放接口响应组装与实体脱敏转换。
@@ -326,4 +328,27 @@ public final class ResearchOpenApiSupport
326 328
         vo.setSubsidyTotal(row.getSubsidyTotal());
327 329
         return vo;
328 330
     }
331
+
332
+    public static ResearchCommonProsperityProjectVo toCommonProsperityProjectVo(BizCommonProsperityProject row)
333
+    {
334
+        if (row == null)
335
+        {
336
+            return null;
337
+        }
338
+        ResearchCommonProsperityProjectVo vo = new ResearchCommonProsperityProjectVo();
339
+        vo.setProjectId(row.getId());
340
+        vo.setProjectName(row.getProjectName());
341
+        vo.setProjectType(row.getProjectType());
342
+        vo.setIntroduction(row.getIntroduction());
343
+        vo.setProjectContent(row.getProjectContent());
344
+        vo.setInvestmentAmount(row.getInvestmentAmount());
345
+        vo.setImplYear(row.getImplYear());
346
+        vo.setImplStatus(row.getImplStatus());
347
+        vo.setVideoFileUrl(row.getVideoFileUrl());
348
+        vo.setCoverFileUrl(row.getCoverFileUrl());
349
+        vo.setPublishStatus(row.getPublishStatus());
350
+        vo.setPublishTime(row.getPublishTime());
351
+        vo.setOpImageCount(row.getOpImageCount());
352
+        return vo;
353
+    }
329 354
 }

+ 28 - 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.ResearchCommonProsperityProjectVo;
25 26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
26 27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
27 28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
@@ -283,4 +284,31 @@ class ResearchOpenApiControllerApiTest
283 284
                 .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
284 285
                 .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
285 286
     }
287
+
288
+    @Test
289
+    @DisplayName("GET /common-prosperity-projects 成功")
290
+    void listCommonProsperityProjects() throws Exception
291
+    {
292
+        ResearchCommonProsperityProjectVo row = new ResearchCommonProsperityProjectVo();
293
+        row.setProjectId(1L);
294
+        row.setProjectName("和美乡村示范项目");
295
+        row.setProjectType(1);
296
+        row.setImplYear(2025);
297
+        OpenApiPageResult<ResearchCommonProsperityProjectVo> page = new OpenApiPageResult<>();
298
+        page.setPageNum(1);
299
+        page.setPageSize(20);
300
+        page.setTotal(1L);
301
+        page.setRecords(Collections.singletonList(row));
302
+        when(researchOpenApiService.listCommonProsperityProjects(anyInt(), anyInt(), any(), any(), any()))
303
+                .thenReturn(page);
304
+
305
+        mockMvc.perform(get("/open-api/v1/research/common-prosperity-projects")
306
+                .param("projectName", "和美")
307
+                .param("projectType", "1")
308
+                .param("implYear", "2025"))
309
+                .andExpect(status().isOk())
310
+                .andExpect(jsonPath("$.code").value(200))
311
+                .andExpect(jsonPath("$.data.records[0].projectName").value("和美乡村示范项目"))
312
+                .andExpect(jsonPath("$.data.records[0].implYear").value(2025));
313
+    }
286 314
 }

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

@@ -35,6 +35,7 @@
35 35
 | 家庭牧场数据列表 | 分页返回家庭牧场填报;法人姓名脱敏 |
36 36
 | 可支配收入数据列表 | 分页返回县级年度可支配收入填报 |
37 37
 | 农牧户数据列表 | 分页返回村级农牧户填报 |
38
+| 共同富裕项目列表 | 分页返回共同富裕项目 |
38 39
 
39 40
 **本期不实现:**
40 41
 
@@ -219,6 +220,20 @@ sequenceDiagram
219 220
 
220 221
 **不返回**:部门 ID、创建人、备注等内部字段。
221 222
 
223
+### 6.11 共同富裕项目列表
224
+
225
+| 项 | 说明 |
226
+| --- | --- |
227
+| 方法 | GET |
228
+| 路径 | `/common-prosperity-projects` |
229
+| 鉴权 | Bearer Token |
230
+| 分页 | 同 §6.2 |
231
+| 筛选 | `projectName`(项目名称模糊)、`projectType`(项目类型精确,1~3)、`implYear`(实施年限精确) |
232
+
233
+**返回字段**:`projectId`、`projectName`、`projectType`、简介与内容、投资金额、实施年限与情况、媒体 URL、发布状态、运营图片数量等。
234
+
235
+**不返回**:本地文件路径、创建人、备注等内部字段。
236
+
222 237
 ---
223 238
 
224 239
 ## 7. 脱敏规则摘要
@@ -263,6 +278,7 @@ sequenceDiagram
263 278
 | 家庭牧场数据填报 | 数据源 `biz_family_ranch` |
264 279
 | 可支配收入数据填报 | 数据源 `biz_disposable_income` |
265 280
 | 农牧户数据填报 | 数据源 `biz_farmer_household` |
281
+| 共同富裕项目管理 | 数据源 `biz_common_prosperity_project` |
266 282
 | 若依权限体系 | **无**关联;开放接口走独立 Token |
267 283
 
268 284
 ---
@@ -281,5 +297,6 @@ sequenceDiagram
281 297
 | 家庭牧场列表 | §6.8 |
282 298
 | 可支配收入列表 | §6.9 |
283 299
 | 农牧户列表 | §6.10 |
300
+| 共同富裕项目列表 | §6.11 |
284 301
 | 脱敏合规 | §7 |
285 302
 | 本期不实现 | §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`、`biz_disposable_income`、`biz_farmer_household` |
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`、`biz_farmer_household`、`biz_common_prosperity_project` |
13 13
 | **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
14 14
 | **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
15 15
 
@@ -221,6 +221,19 @@ Authorization: Bearer <accessToken>
221 221
 
222 222
 实现说明:直接查 `BizFarmerHouseholdMapper`(清空 `params.dataScope`)。
223 223
 
224
+### 3.11 共同富裕项目列表
225
+
226
+```
227
+GET /open-api/v1/research/common-prosperity-projects?pageNum=1&pageSize=20&projectName=&projectType=1&implYear=2025
228
+Authorization: Bearer <accessToken>
229
+```
230
+
231
+**查询参数:** `projectName`(模糊);`projectType` / `implYear`(精确);分页同前。
232
+
233
+**`records[]` 元素(ResearchCommonProsperityProjectVo):** 项目业务字段与媒体 URL;**不含**本地文件路径、操作人、备注。
234
+
235
+实现说明:直接查 `BizCommonProsperityProjectMapper.selectBizCommonProsperityProjectList`。
236
+
224 237
 ---
225 238
 
226 239
 ## 4. 鉴权流程
@@ -249,8 +262,9 @@ Token 申请:`appKey`/`appSecret` 与配置项精确匹配后签发 JWT(HS51
249 262
 | 家庭牧场列表 | `BizFamilyRanchMapper.selectBizFamilyRanchList` | `biz_family_ranch` | 年/月精确;乡镇/村/企业名模糊;清空 `params.dataScope` |
250 263
 | 可支配收入列表 | `BizDisposableIncomeMapper.selectBizDisposableIncomeList` | `biz_disposable_income` | 年份精确 |
251 264
 | 农牧户列表 | `BizFarmerHouseholdMapper.selectBizFarmerHouseholdList` | `biz_farmer_household` | 年/月精确;乡镇/村名模糊;清空 `params.dataScope` |
265
+| 共同富裕项目列表 | `BizCommonProsperityProjectMapper.selectBizCommonProsperityProjectList` | `biz_common_prosperity_project` | 项目名模糊;类型/实施年限精确 |
252 266
 
253
-实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo` / `toFamilyRanchVo` / `toDisposableIncomeVo` / `toFarmerHouseholdVo`。
267
+实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo` / `toFamilyRanchVo` / `toDisposableIncomeVo` / `toFarmerHouseholdVo` / `toCommonProsperityProjectVo`
254 268
 
255 269
 ---
256 270
 
@@ -323,6 +337,10 @@ curl "http://localhost:8010/open-api/v1/research/disposable-incomes?pageNum=1&pa
323 337
 # 10. 农牧户
324 338
 curl "http://localhost:8010/open-api/v1/research/farmer-households?pageNum=1&pageSize=10&statYear=2026&townName=雅安" \
325 339
   -H "Authorization: Bearer <accessToken>"
340
+
341
+# 11. 共同富裕项目
342
+curl "http://localhost:8010/open-api/v1/research/common-prosperity-projects?pageNum=1&pageSize=10&projectName=和美&implYear=2025" \
343
+  -H "Authorization: Bearer <accessToken>"
326 344
 ```
327 345
 
328 346
 ---
@@ -351,6 +369,7 @@ curl "http://localhost:8010/open-api/v1/research/farmer-households?pageNum=1&pag
351 369
 | §6.8 家庭牧场 | **§3.8**、**§5** BizFamilyRanch |
352 370
 | §6.9 可支配收入 | **§3.9**、**§5** BizDisposableIncome |
353 371
 | §6.10 农牧户 | **§3.10**、**§5** BizFarmerHousehold |
372
+| §6.11 共同富裕项目 | **§3.11**、**§5** BizCommonProsperityProject |
354 373
 | §7 脱敏 | **§6** Masking |
355 374
 | §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
356 375
 
@@ -360,6 +379,7 @@ curl "http://localhost:8010/open-api/v1/research/farmer-households?pageNum=1&pag
360 379
 
361 380
 | 版本 | 日期 | 说明 |
362 381
 | --- | --- | --- |
382
+| 1.8 | 2026-07-22 | 新增共同富裕项目开放列表(项目名模糊/类型与实施年限精确+分页) |
363 383
 | 1.7 | 2026-07-22 | 新增农牧户开放列表(年/月/乡镇村模糊+分页) |
364 384
 | 1.6 | 2026-07-22 | 新增可支配收入开放列表(年份精确+分页) |
365 385
 | 1.5 | 2026-07-22 | 新增家庭牧场开放列表(年/月/乡镇村/企业名模糊+分页;法人脱敏) |

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

@@ -57,6 +57,8 @@
57 57
 | KYKF-API-024 | 可支配收入 | 年份筛选 | 接口测试 | curl | §6.9 | 已知年份 | GET 带 `statYear` | 仅返回该年记录 |
58 58
 | KYKF-API-025 | 农牧户 | 分页列表 | 接口测试 | curl | §6.10 | 有效 Token;库有农牧户数据 | GET `/farmer-households?pageNum=1&pageSize=10` | `code=200`;无部门 ID |
59 59
 | KYKF-API-026 | 农牧户 | 年/月/乡镇村筛选 | 接口测试 | curl | §6.10 | 已知年月与乡镇名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
60
+| KYKF-API-027 | 共同富裕项目 | 分页列表 | 接口测试 | curl | §6.11 | 有效 Token;库有项目数据 | GET `/common-prosperity-projects?pageNum=1&pageSize=10` | `code=200`;无本地路径/操作人 |
61
+| KYKF-API-028 | 共同富裕项目 | 名称/类型/年限筛选 | 接口测试 | curl | §6.11 | 已知项目名片段与类型 | GET 带筛选参数 | 条件生效;名称模糊、类型与年限精确 |
60 62
 
61 63
 ---
62 64
 
@@ -74,11 +76,12 @@
74 76
 | §6.8 家庭牧场列表 | — | API-021~022 |
75 77
 | §6.9 可支配收入列表 | — | API-023~024 |
76 78
 | §6.10 农牧户列表 | — | API-025~026 |
79
+| §6.11 共同富裕项目列表 | — | API-027~028 |
77 80
 | §7 脱敏 | UT-001~004 | API-012 |
78 81
 | §2 分页 | — | API-010 |
79 82
 | §3 无机构区分 | UT-005 | API-001(单一凭证) |
80 83
 
81
-**用例统计**:单元 **6**、接口 **26**,合计 **32** 条。
84
+**用例统计**:单元 **6**、接口 **28**,合计 **34** 条。
82 85
 
83 86
 ---
84 87
 
@@ -100,6 +103,7 @@ curl -s "$BASE/livestock-product-outputs?pageNum=1&pageSize=5&statYear=2026" -H
100 103
 curl -s "$BASE/family-ranches?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
101 104
 curl -s "$BASE/disposable-incomes?pageNum=1&pageSize=5&statYear=2025" -H "Authorization: Bearer $TOKEN"
102 105
 curl -s "$BASE/farmer-households?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
106
+curl -s "$BASE/common-prosperity-projects?pageNum=1&pageSize=5&implYear=2025" -H "Authorization: Bearer $TOKEN"
103 107
 ```
104 108
 
105 109
 (Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)