Ver código fonte

外部接口

wwh 1 semana atrás
pai
commit
122797e6eb

+ 26 - 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.ResearchFamilyRanchVo;
18 19
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
19 20
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
20 21
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakAssetVo;
@@ -196,4 +197,29 @@ public class ResearchOpenApiController
196 197
             return ResearchOpenApiSupport.error(code, ex.getMessage());
197 198
         }
198 199
     }
200
+
201
+    /**
202
+     * 家庭牧场数据列表。
203
+     */
204
+    @GetMapping("/family-ranches")
205
+    public OpenApiResponse<OpenApiPageResult<ResearchFamilyRanchVo>> listFamilyRanches(
206
+            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
207
+            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
208
+            @RequestParam(value = "statYear", required = false) Integer statYear,
209
+            @RequestParam(value = "statMonth", required = false) Integer statMonth,
210
+            @RequestParam(value = "townName", required = false) String townName,
211
+            @RequestParam(value = "villageName", required = false) String villageName,
212
+            @RequestParam(value = "enterpriseName", required = false) String enterpriseName)
213
+    {
214
+        try
215
+        {
216
+            return ResearchOpenApiSupport.success(researchOpenApiService.listFamilyRanches(
217
+                    pageNum, pageSize, statYear, statMonth, townName, villageName, enterpriseName));
218
+        }
219
+        catch (ServiceException ex)
220
+        {
221
+            int code = ex.getCode() != null ? ex.getCode() : 500;
222
+            return ResearchOpenApiSupport.error(code, ex.getMessage());
223
+        }
224
+    }
199 225
 }

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

@@ -0,0 +1,464 @@
1
+package com.ruoyi.web.modules.industryservice.research.domain.vo;
2
+
3
+import java.math.BigDecimal;
4
+
5
+/**
6
+ * 科研开放接口 — 家庭牧场填报记录(脱敏法人姓名;不含部门 ID / 备注)。
7
+ */
8
+public class ResearchFamilyRanchVo
9
+{
10
+    /** 家庭牧场记录 ID */
11
+    private Long ranchId;
12
+
13
+    /** 所属年份 */
14
+    private Integer statYear;
15
+
16
+    /** 所属月份(1~12) */
17
+    private Integer statMonth;
18
+
19
+    /** 所属乡镇名称 */
20
+    private String townName;
21
+
22
+    /** 所属村名称 */
23
+    private String villageName;
24
+
25
+    /** 企业名称 */
26
+    private String enterpriseName;
27
+
28
+    /** 法定代表人(脱敏) */
29
+    private String legalRepresentative;
30
+
31
+    /** 企业类型 */
32
+    private String enterpriseType;
33
+
34
+    /** 注册资本(万元) */
35
+    private BigDecimal registeredCapital;
36
+
37
+    /** 成立时间(yyyy-MM-dd) */
38
+    private String establishDate;
39
+
40
+    /** 从事畜牧业生产经营劳力人员 */
41
+    private Integer livestockLaborCount;
42
+
43
+    /** 年底牲畜存栏小计(牛+羊) */
44
+    private Integer stockSubtotal;
45
+
46
+    /** 牛年底存栏 */
47
+    private Integer cattleYearEndStock;
48
+
49
+    /** 牛能繁母畜 */
50
+    private Integer cattleBreedingFemaleStock;
51
+
52
+    /** 羊年底存栏 */
53
+    private Integer sheepYearEndStock;
54
+
55
+    /** 羊能繁母畜 */
56
+    private Integer sheepBreedingFemaleStock;
57
+
58
+    /** 牛出栏 */
59
+    private Integer cattleOutbound;
60
+
61
+    /** 羊出栏 */
62
+    private Integer sheepOutbound;
63
+
64
+    /** 草场面积小计(亩) */
65
+    private BigDecimal grasslandAreaSubtotal;
66
+
67
+    /** 草畜平衡面积(亩) */
68
+    private BigDecimal grassBalanceArea;
69
+
70
+    /** 流转经营草地面积(亩) */
71
+    private BigDecimal transferGrassArea;
72
+
73
+    /** 核定年末草畜平衡载畜量(绵羊单位) */
74
+    private BigDecimal approvedCarryingCapacity;
75
+
76
+    /** 年底牲畜存栏(绵羊单位) */
77
+    private BigDecimal yearEndStockSheepUnit;
78
+
79
+    /** 是否草畜平衡户(是/否) */
80
+    private String isGrassBalanced;
81
+
82
+    /** 年度经营总收入(万元) */
83
+    private BigDecimal income;
84
+
85
+    /** 年度经营总支出(万元) */
86
+    private BigDecimal expense;
87
+
88
+    /** 利润(万元)= 收入 - 支出 */
89
+    private BigDecimal profit;
90
+
91
+    /** 家庭牧场补助资金年份 */
92
+    private Integer subsidyYear;
93
+
94
+    /** 是否享受补助(是/否) */
95
+    private String hasSubsidy;
96
+
97
+    /** 补贴资金(万元) */
98
+    private BigDecimal subsidyAmount;
99
+
100
+    /** 是否有注册商标(是/否) */
101
+    private String hasTrademark;
102
+
103
+    /** 是否通过农产品质量认证(是/否) */
104
+    private String hasQualityCert;
105
+
106
+    /** 产品销售渠道 */
107
+    private String salesChannel;
108
+
109
+    /** 带动人数 */
110
+    private Integer drivenPopulation;
111
+
112
+    /** 发放工资(万元) */
113
+    private BigDecimal wagePaid;
114
+
115
+    public Long getRanchId()
116
+    {
117
+        return ranchId;
118
+    }
119
+
120
+    public void setRanchId(Long ranchId)
121
+    {
122
+        this.ranchId = ranchId;
123
+    }
124
+
125
+    public Integer getStatYear()
126
+    {
127
+        return statYear;
128
+    }
129
+
130
+    public void setStatYear(Integer statYear)
131
+    {
132
+        this.statYear = statYear;
133
+    }
134
+
135
+    public Integer getStatMonth()
136
+    {
137
+        return statMonth;
138
+    }
139
+
140
+    public void setStatMonth(Integer statMonth)
141
+    {
142
+        this.statMonth = statMonth;
143
+    }
144
+
145
+    public String getTownName()
146
+    {
147
+        return townName;
148
+    }
149
+
150
+    public void setTownName(String townName)
151
+    {
152
+        this.townName = townName;
153
+    }
154
+
155
+    public String getVillageName()
156
+    {
157
+        return villageName;
158
+    }
159
+
160
+    public void setVillageName(String villageName)
161
+    {
162
+        this.villageName = villageName;
163
+    }
164
+
165
+    public String getEnterpriseName()
166
+    {
167
+        return enterpriseName;
168
+    }
169
+
170
+    public void setEnterpriseName(String enterpriseName)
171
+    {
172
+        this.enterpriseName = enterpriseName;
173
+    }
174
+
175
+    public String getLegalRepresentative()
176
+    {
177
+        return legalRepresentative;
178
+    }
179
+
180
+    public void setLegalRepresentative(String legalRepresentative)
181
+    {
182
+        this.legalRepresentative = legalRepresentative;
183
+    }
184
+
185
+    public String getEnterpriseType()
186
+    {
187
+        return enterpriseType;
188
+    }
189
+
190
+    public void setEnterpriseType(String enterpriseType)
191
+    {
192
+        this.enterpriseType = enterpriseType;
193
+    }
194
+
195
+    public BigDecimal getRegisteredCapital()
196
+    {
197
+        return registeredCapital;
198
+    }
199
+
200
+    public void setRegisteredCapital(BigDecimal registeredCapital)
201
+    {
202
+        this.registeredCapital = registeredCapital;
203
+    }
204
+
205
+    public String getEstablishDate()
206
+    {
207
+        return establishDate;
208
+    }
209
+
210
+    public void setEstablishDate(String establishDate)
211
+    {
212
+        this.establishDate = establishDate;
213
+    }
214
+
215
+    public Integer getLivestockLaborCount()
216
+    {
217
+        return livestockLaborCount;
218
+    }
219
+
220
+    public void setLivestockLaborCount(Integer livestockLaborCount)
221
+    {
222
+        this.livestockLaborCount = livestockLaborCount;
223
+    }
224
+
225
+    public Integer getStockSubtotal()
226
+    {
227
+        return stockSubtotal;
228
+    }
229
+
230
+    public void setStockSubtotal(Integer stockSubtotal)
231
+    {
232
+        this.stockSubtotal = stockSubtotal;
233
+    }
234
+
235
+    public Integer getCattleYearEndStock()
236
+    {
237
+        return cattleYearEndStock;
238
+    }
239
+
240
+    public void setCattleYearEndStock(Integer cattleYearEndStock)
241
+    {
242
+        this.cattleYearEndStock = cattleYearEndStock;
243
+    }
244
+
245
+    public Integer getCattleBreedingFemaleStock()
246
+    {
247
+        return cattleBreedingFemaleStock;
248
+    }
249
+
250
+    public void setCattleBreedingFemaleStock(Integer cattleBreedingFemaleStock)
251
+    {
252
+        this.cattleBreedingFemaleStock = cattleBreedingFemaleStock;
253
+    }
254
+
255
+    public Integer getSheepYearEndStock()
256
+    {
257
+        return sheepYearEndStock;
258
+    }
259
+
260
+    public void setSheepYearEndStock(Integer sheepYearEndStock)
261
+    {
262
+        this.sheepYearEndStock = sheepYearEndStock;
263
+    }
264
+
265
+    public Integer getSheepBreedingFemaleStock()
266
+    {
267
+        return sheepBreedingFemaleStock;
268
+    }
269
+
270
+    public void setSheepBreedingFemaleStock(Integer sheepBreedingFemaleStock)
271
+    {
272
+        this.sheepBreedingFemaleStock = sheepBreedingFemaleStock;
273
+    }
274
+
275
+    public Integer getCattleOutbound()
276
+    {
277
+        return cattleOutbound;
278
+    }
279
+
280
+    public void setCattleOutbound(Integer cattleOutbound)
281
+    {
282
+        this.cattleOutbound = cattleOutbound;
283
+    }
284
+
285
+    public Integer getSheepOutbound()
286
+    {
287
+        return sheepOutbound;
288
+    }
289
+
290
+    public void setSheepOutbound(Integer sheepOutbound)
291
+    {
292
+        this.sheepOutbound = sheepOutbound;
293
+    }
294
+
295
+    public BigDecimal getGrasslandAreaSubtotal()
296
+    {
297
+        return grasslandAreaSubtotal;
298
+    }
299
+
300
+    public void setGrasslandAreaSubtotal(BigDecimal grasslandAreaSubtotal)
301
+    {
302
+        this.grasslandAreaSubtotal = grasslandAreaSubtotal;
303
+    }
304
+
305
+    public BigDecimal getGrassBalanceArea()
306
+    {
307
+        return grassBalanceArea;
308
+    }
309
+
310
+    public void setGrassBalanceArea(BigDecimal grassBalanceArea)
311
+    {
312
+        this.grassBalanceArea = grassBalanceArea;
313
+    }
314
+
315
+    public BigDecimal getTransferGrassArea()
316
+    {
317
+        return transferGrassArea;
318
+    }
319
+
320
+    public void setTransferGrassArea(BigDecimal transferGrassArea)
321
+    {
322
+        this.transferGrassArea = transferGrassArea;
323
+    }
324
+
325
+    public BigDecimal getApprovedCarryingCapacity()
326
+    {
327
+        return approvedCarryingCapacity;
328
+    }
329
+
330
+    public void setApprovedCarryingCapacity(BigDecimal approvedCarryingCapacity)
331
+    {
332
+        this.approvedCarryingCapacity = approvedCarryingCapacity;
333
+    }
334
+
335
+    public BigDecimal getYearEndStockSheepUnit()
336
+    {
337
+        return yearEndStockSheepUnit;
338
+    }
339
+
340
+    public void setYearEndStockSheepUnit(BigDecimal yearEndStockSheepUnit)
341
+    {
342
+        this.yearEndStockSheepUnit = yearEndStockSheepUnit;
343
+    }
344
+
345
+    public String getIsGrassBalanced()
346
+    {
347
+        return isGrassBalanced;
348
+    }
349
+
350
+    public void setIsGrassBalanced(String isGrassBalanced)
351
+    {
352
+        this.isGrassBalanced = isGrassBalanced;
353
+    }
354
+
355
+    public BigDecimal getIncome()
356
+    {
357
+        return income;
358
+    }
359
+
360
+    public void setIncome(BigDecimal income)
361
+    {
362
+        this.income = income;
363
+    }
364
+
365
+    public BigDecimal getExpense()
366
+    {
367
+        return expense;
368
+    }
369
+
370
+    public void setExpense(BigDecimal expense)
371
+    {
372
+        this.expense = expense;
373
+    }
374
+
375
+    public BigDecimal getProfit()
376
+    {
377
+        return profit;
378
+    }
379
+
380
+    public void setProfit(BigDecimal profit)
381
+    {
382
+        this.profit = profit;
383
+    }
384
+
385
+    public Integer getSubsidyYear()
386
+    {
387
+        return subsidyYear;
388
+    }
389
+
390
+    public void setSubsidyYear(Integer subsidyYear)
391
+    {
392
+        this.subsidyYear = subsidyYear;
393
+    }
394
+
395
+    public String getHasSubsidy()
396
+    {
397
+        return hasSubsidy;
398
+    }
399
+
400
+    public void setHasSubsidy(String hasSubsidy)
401
+    {
402
+        this.hasSubsidy = hasSubsidy;
403
+    }
404
+
405
+    public BigDecimal getSubsidyAmount()
406
+    {
407
+        return subsidyAmount;
408
+    }
409
+
410
+    public void setSubsidyAmount(BigDecimal subsidyAmount)
411
+    {
412
+        this.subsidyAmount = subsidyAmount;
413
+    }
414
+
415
+    public String getHasTrademark()
416
+    {
417
+        return hasTrademark;
418
+    }
419
+
420
+    public void setHasTrademark(String hasTrademark)
421
+    {
422
+        this.hasTrademark = hasTrademark;
423
+    }
424
+
425
+    public String getHasQualityCert()
426
+    {
427
+        return hasQualityCert;
428
+    }
429
+
430
+    public void setHasQualityCert(String hasQualityCert)
431
+    {
432
+        this.hasQualityCert = hasQualityCert;
433
+    }
434
+
435
+    public String getSalesChannel()
436
+    {
437
+        return salesChannel;
438
+    }
439
+
440
+    public void setSalesChannel(String salesChannel)
441
+    {
442
+        this.salesChannel = salesChannel;
443
+    }
444
+
445
+    public Integer getDrivenPopulation()
446
+    {
447
+        return drivenPopulation;
448
+    }
449
+
450
+    public void setDrivenPopulation(Integer drivenPopulation)
451
+    {
452
+        this.drivenPopulation = drivenPopulation;
453
+    }
454
+
455
+    public BigDecimal getWagePaid()
456
+    {
457
+        return wagePaid;
458
+    }
459
+
460
+    public void setWagePaid(BigDecimal wagePaid)
461
+    {
462
+        this.wagePaid = wagePaid;
463
+    }
464
+}

+ 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.ResearchFamilyRanchVo;
6 7
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
7 8
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
8 9
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakAssetVo;
@@ -57,4 +58,14 @@ public interface IResearchOpenApiService
57 58
      */
58 59
     OpenApiPageResult<ResearchLivestockProductOutputVo> listLivestockProductOutputs(int pageNum, int pageSize,
59 60
             Integer statYear, Integer statMonth, String townName, String villageName);
61
+
62
+    /**
63
+     * 家庭牧场填报列表。
64
+     *
65
+     * @param townName 所属乡镇名称模糊匹配
66
+     * @param villageName 所属村名称模糊匹配
67
+     * @param enterpriseName 企业名称模糊匹配
68
+     */
69
+    OpenApiPageResult<ResearchFamilyRanchVo> listFamilyRanches(int pageNum, int pageSize,
70
+            Integer statYear, Integer statMonth, String townName, String villageName, String enterpriseName);
60 71
 }

+ 37 - 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.BizFamilyRanch;
12 13
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
13 14
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
14 15
 import com.ruoyi.web.modules.industryservice.domain.BizYakAsset;
@@ -16,12 +17,14 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
16 17
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
17 18
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
18 19
 import com.ruoyi.web.modules.industryservice.mapper.BizCooperativeDevelopmentMapper;
20
+import com.ruoyi.web.modules.industryservice.mapper.BizFamilyRanchMapper;
19 21
 import com.ruoyi.web.modules.industryservice.mapper.BizLivestockProductOutputMapper;
20 22
 import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
21 23
 import com.ruoyi.web.modules.industryservice.mapper.BizYakOutboundReportMapper;
22 24
 import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
23 25
 import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
24 26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
27
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
25 28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
26 29
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
27 30
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakAssetVo;
@@ -60,6 +63,9 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
60 63
     @Autowired
61 64
     private BizLivestockProductOutputMapper bizLivestockProductOutputMapper;
62 65
 
66
+    @Autowired
67
+    private BizFamilyRanchMapper bizFamilyRanchMapper;
68
+
63 69
     @Override
64 70
     public ResearchTokenVo authenticate(String appKey, String appSecret)
65 71
     {
@@ -213,6 +219,37 @@ public class ResearchOpenApiServiceImpl implements IResearchOpenApiService
213 219
                 rows.stream().map(ResearchOpenApiSupport::toLivestockProductOutputVo).collect(Collectors.toList()));
214 220
     }
215 221
 
222
+    @Override
223
+    public OpenApiPageResult<ResearchFamilyRanchVo> listFamilyRanches(int pageNum, int pageSize,
224
+            Integer statYear, Integer statMonth, String townName, String villageName, String enterpriseName)
225
+    {
226
+        tokenService.assertEnabled();
227
+        int safePageNum = normalizePageNum(pageNum);
228
+        int safePageSize = normalizePageSize(pageSize);
229
+        BizFamilyRanch query = new BizFamilyRanch();
230
+        query.setStatYear(statYear);
231
+        query.setStatMonth(statMonth);
232
+        if (StringUtils.isNotEmpty(townName))
233
+        {
234
+            query.setTownName(townName.trim());
235
+        }
236
+        if (StringUtils.isNotEmpty(villageName))
237
+        {
238
+            query.setVillageName(villageName.trim());
239
+        }
240
+        if (StringUtils.isNotEmpty(enterpriseName))
241
+        {
242
+            query.setEnterpriseName(enterpriseName.trim());
243
+        }
244
+        // 开放接口无登录上下文,清空 dataScope,避免走填报部门权限
245
+        query.getParams().put("dataScope", "");
246
+        PageHelper.startPage(safePageNum, safePageSize);
247
+        List<BizFamilyRanch> rows = bizFamilyRanchMapper.selectBizFamilyRanchList(query);
248
+        PageInfo<BizFamilyRanch> page = new PageInfo<>(rows);
249
+        return toPageResult(safePageNum, safePageSize, page.getTotal(),
250
+                rows.stream().map(ResearchOpenApiSupport::toFamilyRanchVo).collect(Collectors.toList()));
251
+    }
252
+
216 253
     private int normalizePageNum(int pageNum)
217 254
     {
218 255
         return pageNum > 0 ? pageNum : 1;

+ 47 - 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.BizFamilyRanch;
6 7
 import com.ruoyi.web.modules.industryservice.domain.BizLivestockProductOutput;
7 8
 import com.ruoyi.web.modules.industryservice.domain.BizPasture;
8 9
 import com.ruoyi.web.modules.industryservice.domain.BizYakAsset;
@@ -10,6 +11,7 @@ import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
10 11
 import com.ruoyi.web.modules.industryservice.domain.BizYakOutboundReport;
11 12
 import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiResponse;
12 13
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
14
+import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
13 15
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
14 16
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
15 17
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakAssetVo;
@@ -225,4 +227,49 @@ public final class ResearchOpenApiSupport
225 227
         vo.setMilkOutput(row.getMilkOutput());
226 228
         return vo;
227 229
     }
230
+
231
+    public static ResearchFamilyRanchVo toFamilyRanchVo(BizFamilyRanch row)
232
+    {
233
+        if (row == null)
234
+        {
235
+            return null;
236
+        }
237
+        ResearchFamilyRanchVo vo = new ResearchFamilyRanchVo();
238
+        vo.setRanchId(row.getId());
239
+        vo.setStatYear(row.getStatYear());
240
+        vo.setStatMonth(row.getStatMonth());
241
+        vo.setTownName(row.getTownName());
242
+        vo.setVillageName(row.getVillageName());
243
+        vo.setEnterpriseName(row.getEnterpriseName());
244
+        vo.setLegalRepresentative(ResearchOpenApiMasking.maskPersonName(row.getLegalRepresentative()));
245
+        vo.setEnterpriseType(row.getEnterpriseType());
246
+        vo.setRegisteredCapital(row.getRegisteredCapital());
247
+        vo.setEstablishDate(row.getEstablishDate());
248
+        vo.setLivestockLaborCount(row.getLivestockLaborCount());
249
+        vo.setStockSubtotal(row.getStockSubtotal());
250
+        vo.setCattleYearEndStock(row.getCattleYearEndStock());
251
+        vo.setCattleBreedingFemaleStock(row.getCattleBreedingFemaleStock());
252
+        vo.setSheepYearEndStock(row.getSheepYearEndStock());
253
+        vo.setSheepBreedingFemaleStock(row.getSheepBreedingFemaleStock());
254
+        vo.setCattleOutbound(row.getCattleOutbound());
255
+        vo.setSheepOutbound(row.getSheepOutbound());
256
+        vo.setGrasslandAreaSubtotal(row.getGrasslandAreaSubtotal());
257
+        vo.setGrassBalanceArea(row.getGrassBalanceArea());
258
+        vo.setTransferGrassArea(row.getTransferGrassArea());
259
+        vo.setApprovedCarryingCapacity(row.getApprovedCarryingCapacity());
260
+        vo.setYearEndStockSheepUnit(row.getYearEndStockSheepUnit());
261
+        vo.setIsGrassBalanced(row.getIsGrassBalanced());
262
+        vo.setIncome(row.getIncome());
263
+        vo.setExpense(row.getExpense());
264
+        vo.setProfit(row.getProfit());
265
+        vo.setSubsidyYear(row.getSubsidyYear());
266
+        vo.setHasSubsidy(row.getHasSubsidy());
267
+        vo.setSubsidyAmount(row.getSubsidyAmount());
268
+        vo.setHasTrademark(row.getHasTrademark());
269
+        vo.setHasQualityCert(row.getHasQualityCert());
270
+        vo.setSalesChannel(row.getSalesChannel());
271
+        vo.setDrivenPopulation(row.getDrivenPopulation());
272
+        vo.setWagePaid(row.getWagePaid());
273
+        return vo;
274
+    }
228 275
 }

+ 2 - 0
baqing-admin/src/main/resources/mapper/industryservice/BizFamilyRanchMapper.xml

@@ -88,6 +88,8 @@
88 88
             <if test="statMonth != null">and r.stat_month = #{statMonth}</if>
89 89
             <if test="townDeptId != null">and r.town_dept_id = #{townDeptId}</if>
90 90
             <if test="villageDeptId != null">and r.village_dept_id = #{villageDeptId}</if>
91
+            <if test="townName != null and townName != ''">and r.town_name like concat('%', #{townName}, '%')</if>
92
+            <if test="villageName != null and villageName != ''">and r.village_name like concat('%', #{villageName}, '%')</if>
91 93
             <if test="enterpriseName != null and enterpriseName != ''">and r.enterprise_name like concat('%', #{enterpriseName}, '%')</if>
92 94
             ${params.dataScope}
93 95
         </where>

+ 31 - 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.ResearchFamilyRanchVo;
25 26
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
26 27
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
27 28
 import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakHerdInventoryVo;
@@ -200,4 +201,34 @@ class ResearchOpenApiControllerApiTest
200 201
                 .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
201 202
                 .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
202 203
     }
204
+
205
+    @Test
206
+    @DisplayName("GET /family-ranches 成功")
207
+    void listFamilyRanches() throws Exception
208
+    {
209
+        ResearchFamilyRanchVo row = new ResearchFamilyRanchVo();
210
+        row.setRanchId(1L);
211
+        row.setStatYear(2026);
212
+        row.setStatMonth(5);
213
+        row.setTownName("雅安镇");
214
+        row.setVillageName("荣嘎村");
215
+        row.setEnterpriseName("测试牧场");
216
+        OpenApiPageResult<ResearchFamilyRanchVo> page = new OpenApiPageResult<>();
217
+        page.setPageNum(1);
218
+        page.setPageSize(20);
219
+        page.setTotal(1L);
220
+        page.setRecords(Collections.singletonList(row));
221
+        when(researchOpenApiService.listFamilyRanches(
222
+                anyInt(), anyInt(), any(), any(), any(), any(), any())).thenReturn(page);
223
+
224
+        mockMvc.perform(get("/open-api/v1/research/family-ranches")
225
+                .param("statYear", "2026")
226
+                .param("statMonth", "5")
227
+                .param("townName", "雅安")
228
+                .param("villageName", "荣嘎")
229
+                .param("enterpriseName", "测试"))
230
+                .andExpect(status().isOk())
231
+                .andExpect(jsonPath("$.code").value(200))
232
+                .andExpect(jsonPath("$.data.records[0].enterpriseName").value("测试牧场"));
233
+    }
203 234
 }

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

@@ -32,6 +32,7 @@
32 32
 | 牦牛出栏数据列表 | 分页返回村级出栏填报汇总 |
33 33
 | 合作社发展数据列表 | 分页返回合作社发展填报;法人姓名脱敏 |
34 34
 | 畜牧产品产量登记列表 | 分页返回村级肉/奶产量 |
35
+| 家庭牧场数据列表 | 分页返回家庭牧场填报;法人姓名脱敏 |
35 36
 
36 37
 **本期不实现:**
37 38
 
@@ -174,6 +175,20 @@ sequenceDiagram
174 175
 
175 176
 **不返回**:部门 ID、创建人、备注等内部字段。
176 177
 
178
+### 6.8 家庭牧场数据列表
179
+
180
+| 项 | 说明 |
181
+| --- | --- |
182
+| 方法 | GET |
183
+| 路径 | `/family-ranches` |
184
+| 鉴权 | Bearer Token |
185
+| 分页 | 同 §6.2 |
186
+| 筛选 | `statYear`、`statMonth`、`townName`(乡镇模糊)、`villageName`(村模糊)、`enterpriseName`(企业名称模糊) |
187
+
188
+**返回字段**:`ranchId`、年月、乡镇村、企业信息、存出栏、草场、经营收支、补助与认证等;`legalRepresentative` 脱敏。
189
+
190
+**不返回**:部门 ID、创建人、备注等内部字段。
191
+
177 192
 ---
178 193
 
179 194
 ## 7. 脱敏规则摘要
@@ -215,6 +230,7 @@ sequenceDiagram
215 230
 | 牦牛出栏数据填报 | 数据源 `biz_yak_outbound_report` |
216 231
 | 合作社发展数据填报 | 数据源 `biz_cooperative_development` |
217 232
 | 畜牧产品产量登记 | 数据源 `biz_livestock_product_output` |
233
+| 家庭牧场数据填报 | 数据源 `biz_family_ranch` |
218 234
 | 若依权限体系 | **无**关联;开放接口走独立 Token |
219 235
 
220 236
 ---
@@ -230,5 +246,6 @@ sequenceDiagram
230 246
 | 牦牛出栏列表 | §6.5 |
231 247
 | 合作社发展列表 | §6.6 |
232 248
 | 畜牧产品产量列表 | §6.7 |
249
+| 家庭牧场列表 | §6.8 |
233 250
 | 脱敏合规 | §7 |
234 251
 | 本期不实现 | §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` |
12
+| **数据库** | 只读查询既有表 `biz_pasture`、`biz_yak_asset`、`biz_yak_herd_inventory`、`biz_yak_outbound_report`、`biz_cooperative_development`、`biz_livestock_product_output`、`biz_family_ranch` |
13 13
 | **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
14 14
 | **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
15 15
 
@@ -182,6 +182,19 @@ Authorization: Bearer <accessToken>
182 182
 
183 183
 实现说明:直接查 `BizLivestockProductOutputMapper`(清空 `params.dataScope`)。
184 184
 
185
+### 3.8 家庭牧场数据列表
186
+
187
+```
188
+GET /open-api/v1/research/family-ranches?pageNum=1&pageSize=20&statYear=2026&statMonth=5&townName=&villageName=&enterpriseName=
189
+Authorization: Bearer <accessToken>
190
+```
191
+
192
+**查询参数:** `statYear` / `statMonth`(精确);`townName` / `villageName` / `enterpriseName`(模糊);分页同前。
193
+
194
+**`records[]` 元素(ResearchFamilyRanchVo):** 家庭牧场业务字段;`legalRepresentative` 脱敏;**不含**部门 ID、操作人、备注。
195
+
196
+实现说明:直接查 `BizFamilyRanchMapper`(清空 `params.dataScope`)。
197
+
185 198
 ---
186 199
 
187 200
 ## 4. 鉴权流程
@@ -207,8 +220,9 @@ Token 申请:`appKey`/`appSecret` 与配置项精确匹配后签发 JWT(HS51
207 220
 | 出栏列表 | `BizYakOutboundReportMapper.selectBizYakOutboundReportList` | `biz_yak_outbound_report` | 同上 |
208 221
 | 合作社列表 | `BizCooperativeDevelopmentMapper.selectBizCooperativeDevelopmentList` | `biz_cooperative_development` | 年/月精确;乡镇/村/合作社名模糊;清空 `params.dataScope` |
209 222
 | 产量列表 | `BizLivestockProductOutputMapper.selectBizLivestockProductOutputList` | `biz_livestock_product_output` | 年/月精确;乡镇/村名模糊;清空 `params.dataScope` |
223
+| 家庭牧场列表 | `BizFamilyRanchMapper.selectBizFamilyRanchList` | `biz_family_ranch` | 年/月精确;乡镇/村/企业名模糊;清空 `params.dataScope` |
210 224
 
211
-实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo`。
225
+实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo` / `toYakHerdInventoryVo` / `toYakOutboundReportVo` / `toCooperativeDevelopmentVo` / `toLivestockProductOutputVo` / `toFamilyRanchVo`
212 226
 
213 227
 ---
214 228
 
@@ -269,6 +283,10 @@ curl "http://localhost:8010/open-api/v1/research/cooperative-developments?pageNu
269 283
 # 7. 畜牧产品产量
270 284
 curl "http://localhost:8010/open-api/v1/research/livestock-product-outputs?pageNum=1&pageSize=10&statYear=2026&townName=雅安" \
271 285
   -H "Authorization: Bearer <accessToken>"
286
+
287
+# 8. 家庭牧场
288
+curl "http://localhost:8010/open-api/v1/research/family-ranches?pageNum=1&pageSize=10&statYear=2026&enterpriseName=牧场" \
289
+  -H "Authorization: Bearer <accessToken>"
272 290
 ```
273 291
 
274 292
 ---
@@ -294,6 +312,7 @@ curl "http://localhost:8010/open-api/v1/research/livestock-product-outputs?pageN
294 312
 | §6.5 出栏 | **§3.5**、**§5** BizYakOutboundReport |
295 313
 | §6.6 合作社 | **§3.6**、**§5** BizCooperativeDevelopment |
296 314
 | §6.7 产量 | **§3.7**、**§5** BizLivestockProductOutput |
315
+| §6.8 家庭牧场 | **§3.8**、**§5** BizFamilyRanch |
297 316
 | §7 脱敏 | **§6** Masking |
298 317
 | §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
299 318
 
@@ -303,6 +322,7 @@ curl "http://localhost:8010/open-api/v1/research/livestock-product-outputs?pageN
303 322
 
304 323
 | 版本 | 日期 | 说明 |
305 324
 | --- | --- | --- |
325
+| 1.5 | 2026-07-22 | 新增家庭牧场开放列表(年/月/乡镇村/企业名模糊+分页;法人脱敏) |
306 326
 | 1.4 | 2026-07-22 | 新增畜牧产品产量登记开放列表(年/月/乡镇村模糊+分页) |
307 327
 | 1.3 | 2026-07-22 | 新增合作社发展开放列表(年/月/乡镇村/名称模糊+分页;法人脱敏) |
308 328
 | 1.2 | 2026-07-22 | 新增牦牛出栏开放列表(年/月/乡镇村模糊+分页) |

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

@@ -51,6 +51,8 @@
51 51
 | KYKF-API-018 | 合作社 | 年/月/乡镇村/名称筛选 | 接口测试 | curl | §6.6 | 已知合作社名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
52 52
 | KYKF-API-019 | 产量 | 分页列表 | 接口测试 | curl | §6.7 | 有效 Token;库有产量数据 | GET `/livestock-product-outputs?pageNum=1&pageSize=10` | `code=200`;含肉/奶产量;无部门 ID |
53 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 |
55
+| KYKF-API-022 | 家庭牧场 | 年/月/乡镇村/企业名筛选 | 接口测试 | curl | §6.8 | 已知企业名片段 | GET 带筛选参数 | 条件生效;名称模糊匹配 |
54 56
 
55 57
 ---
56 58
 
@@ -65,11 +67,12 @@
65 67
 | §6.5 出栏列表 | — | API-015~016 |
66 68
 | §6.6 合作社列表 | — | API-017~018 |
67 69
 | §6.7 产量列表 | — | API-019~020 |
70
+| §6.8 家庭牧场列表 | — | API-021~022 |
68 71
 | §7 脱敏 | UT-001~004 | API-012 |
69 72
 | §2 分页 | — | API-010 |
70 73
 | §3 无机构区分 | UT-005 | API-001(单一凭证) |
71 74
 
72
-**用例统计**:单元 **6**、接口 **20**,合计 **26** 条。
75
+**用例统计**:单元 **6**、接口 **22**,合计 **28** 条。
73 76
 
74 77
 ---
75 78
 
@@ -88,6 +91,7 @@ curl -s "$BASE/yak-herd-inventories?pageNum=1&pageSize=5&statYear=2026" -H "Auth
88 91
 curl -s "$BASE/yak-outbound-reports?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
89 92
 curl -s "$BASE/cooperative-developments?pageNum=1&pageSize=5&statYear=2026" -H "Authorization: Bearer $TOKEN"
90 93
 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"
91 95
 ```
92 96
 
93 97
 (Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)