wwh 1 tydzień temu
rodzic
commit
36864b9617

+ 9 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/prosperity/mapper/BizCommonProsperityProjectMapper.java

@@ -3,6 +3,7 @@ package com.ruoyi.web.modules.prosperity.mapper;
3 3
 import java.util.List;
4 4
 import org.apache.ibatis.annotations.Param;
5 5
 import com.ruoyi.web.modules.prosperity.domain.BizCommonProsperityProject;
6
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
6 7
 
7 8
 /**
8 9
  * 共同富裕项目 Mapper
@@ -28,4 +29,12 @@ public interface BizCommonProsperityProjectMapper
28 29
      * 大屏:已发布项目的实施年限并集(可选年份下拉)。
29 30
      */
30 31
     List<String> selectDistinctStatYearsFromPublished();
32
+
33
+    /**
34
+     * 大屏:共富项目分类情况明细(按实施年限聚合类型数量;年份倒序)。
35
+     *
36
+     * @param statYear 所属年份(实施年限),必填
37
+     */
38
+    List<CommonProsperityProjectTypeDetailVo> selectPublishedTypeDetailsByYear(
39
+            @Param("statYear") int statYear);
31 40
 }

+ 24 - 3
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/controller/CommonProsperityScreenController.java

@@ -9,13 +9,15 @@ import org.springframework.web.bind.annotation.RestController;
9 9
 import com.ruoyi.common.core.controller.BaseController;
10 10
 import com.ruoyi.common.core.domain.AjaxResult;
11 11
 import com.ruoyi.common.core.page.TableDataInfo;
12
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
12 13
 import com.ruoyi.web.modules.screen.domain.vo.ScreenProjectListItemVo;
13 14
 import com.ruoyi.web.modules.screen.service.ICommonProsperityScreenService;
14 15
 
15 16
 /**
16 17
  * 大屏 — 共同富裕统计(只读)。
17 18
  * <p>
18
- * 提供看板聚合与共富项目分页列表。看板含:成果总览 / 数字赋能、按月趋势图、项目分类饼图。
19
+ * 提供看板聚合、共富项目分页列表,以及共富项目分类情况明细分页。
20
+ * 看板含:成果总览 / 数字赋能、按月趋势图、项目分类饼图。
19 21
  * </p>
20 22
  * <p>
21 23
  * 数据来源:{@code biz_common_prosperity_achievement}(成果台账)、
@@ -38,7 +40,7 @@ public class CommonProsperityScreenController extends BaseController
38 40
      * <p>
39 41
      * 成果:总览 / 数字赋能取所选年<strong>最大统计月</strong>单月值;
40 42
      * {@code monthly} 为该年 1~最大月(缺月补 0)。
41
-     * 项目:仅 {@code publish_status=1} 且实施周期与统计年 Y 有交集
43
+     * 项目:仅 {@code publish_status=1} 且实施年限等于统计年 Y
42 44
      * </p>
43 45
      *
44 46
      * @param statYear 统计年份,如 {@code 2026}
@@ -52,7 +54,7 @@ public class CommonProsperityScreenController extends BaseController
52 54
 
53 55
     /**
54 56
      * 共富项目分页列表(行内含运营图,无单独详情接口)。
55
-     * <p>筛选口径同看板项目:已发布且实施周期与 {@code statYear} 有交集;配合 PageHelper。</p>
57
+     * <p>筛选口径同看板项目:已发布且实施年限等于 {@code statYear};配合 PageHelper。</p>
56 58
      *
57 59
      * @param statYear 统计年份,如 {@code 2026}
58 60
      */
@@ -63,4 +65,23 @@ public class CommonProsperityScreenController extends BaseController
63 65
         List<ScreenProjectListItemVo> list = commonProsperityScreenService.listPublishedProjects(statYear);
64 66
         return getDataTable(list);
65 67
     }
68
+
69
+    /**
70
+     * 共富项目分类情况明细(分页);按所属年份(实施年限)倒序。
71
+     * <p>
72
+     * 数据源 {@code biz_common_prosperity_project};口径与看板分类一致:
73
+     * {@code publish_status=1},按 {@code impl_year}、{@code project_type} 聚合。
74
+     * </p>
75
+     *
76
+     * @param statYear 所属年份;未传默认当前自然年
77
+     */
78
+    @GetMapping("/projectTypeDetails")
79
+    public TableDataInfo projectTypeDetails(
80
+            @RequestParam(value = "statYear", required = false) Integer statYear)
81
+    {
82
+        startPage();
83
+        List<CommonProsperityProjectTypeDetailVo> list =
84
+                commonProsperityScreenService.listProjectTypeDetails(statYear);
85
+        return getDataTable(list);
86
+    }
66 87
 }

+ 80 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/domain/vo/CommonProsperityProjectTypeDetailVo.java

@@ -0,0 +1,80 @@
1
+package com.ruoyi.web.modules.screen.domain.vo;
2
+
3
+import java.io.Serializable;
4
+
5
+/**
6
+ * 大屏 — 共富项目分类情况明细行。
7
+ * <p>
8
+ * 对应 {@code GET /bigScreen/commonProsperity/projectTypeDetails} 的 {@code rows[]};
9
+ * 按 {@code impl_year} 聚合已发布项目的类型数量。
10
+ * </p>
11
+ */
12
+public class CommonProsperityProjectTypeDetailVo implements Serializable
13
+{
14
+    private static final long serialVersionUID = 1L;
15
+
16
+    /** 所属年份(实施年限 impl_year) */
17
+    private Integer statYear;
18
+
19
+    /** 项目总数(个) */
20
+    private Integer totalCount;
21
+
22
+    /** 和美乡村建设项目数(个),project_type=1 */
23
+    private Integer heMeiVillageCount;
24
+
25
+    /** 人居环境整治提升项目数(个),project_type=2 */
26
+    private Integer habitatImproveCount;
27
+
28
+    /** 其他项目投入数(个),project_type=3 */
29
+    private Integer otherProjectCount;
30
+
31
+    public Integer getStatYear()
32
+    {
33
+        return statYear;
34
+    }
35
+
36
+    public void setStatYear(Integer statYear)
37
+    {
38
+        this.statYear = statYear;
39
+    }
40
+
41
+    public Integer getTotalCount()
42
+    {
43
+        return totalCount;
44
+    }
45
+
46
+    public void setTotalCount(Integer totalCount)
47
+    {
48
+        this.totalCount = totalCount;
49
+    }
50
+
51
+    public Integer getHeMeiVillageCount()
52
+    {
53
+        return heMeiVillageCount;
54
+    }
55
+
56
+    public void setHeMeiVillageCount(Integer heMeiVillageCount)
57
+    {
58
+        this.heMeiVillageCount = heMeiVillageCount;
59
+    }
60
+
61
+    public Integer getHabitatImproveCount()
62
+    {
63
+        return habitatImproveCount;
64
+    }
65
+
66
+    public void setHabitatImproveCount(Integer habitatImproveCount)
67
+    {
68
+        this.habitatImproveCount = habitatImproveCount;
69
+    }
70
+
71
+    public Integer getOtherProjectCount()
72
+    {
73
+        return otherProjectCount;
74
+    }
75
+
76
+    public void setOtherProjectCount(Integer otherProjectCount)
77
+    {
78
+        this.otherProjectCount = otherProjectCount;
79
+    }
80
+}

+ 8 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/service/ICommonProsperityScreenService.java

@@ -1,6 +1,7 @@
1 1
 package com.ruoyi.web.modules.screen.service;
2 2
 
3 3
 import java.util.List;
4
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
4 5
 import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityScreenDashboardVo;
5 6
 import com.ruoyi.web.modules.screen.domain.vo.ScreenProjectListItemVo;
6 7
 
@@ -26,4 +27,11 @@ public interface ICommonProsperityScreenService
26 27
      * @param statYear 统计年份(四位)
27 28
      */
28 29
     List<ScreenProjectListItemVo> listPublishedProjects(String statYear);
30
+
31
+    /**
32
+     * 共富项目分类情况明细(按实施年限聚合各类型数量;分页由 Controller 启 PageHelper)。
33
+     *
34
+     * @param statYear 所属年份;{@code null} 时默认当前自然年
35
+     */
36
+    List<CommonProsperityProjectTypeDetailVo> listProjectTypeDetails(Integer statYear);
29 37
 }

+ 15 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/service/impl/CommonProsperityScreenServiceImpl.java

@@ -15,10 +15,12 @@ import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityProjectMapper;
15 15
 import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityProjectOpImageMapper;
16 16
 import com.ruoyi.web.modules.prosperity.support.AchievementReportAggregator;
17 17
 import com.ruoyi.web.modules.prosperity.support.AchievementReportValidation;
18
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
18 19
 import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityScreenDashboardVo;
19 20
 import com.ruoyi.web.modules.screen.domain.vo.ScreenProjectListItemVo;
20 21
 import com.ruoyi.web.modules.screen.service.ICommonProsperityScreenService;
21 22
 import com.ruoyi.web.modules.screen.support.CommonProsperityScreenSupport;
23
+import com.ruoyi.web.modules.screen.support.HomeScreenSupport;
22 24
 
23 25
 /**
24 26
  * 大屏共同富裕统计服务实现。
@@ -87,6 +89,19 @@ public class CommonProsperityScreenServiceImpl implements ICommonProsperityScree
87 89
         return CommonProsperityScreenSupport.toListItems(projects, byProject);
88 90
     }
89 91
 
92
+    /**
93
+     * {@inheritDoc}
94
+     * <p>口径:{@code publish_status=1},按 {@code impl_year} 聚合;未传年份默认当前自然年。</p>
95
+     */
96
+    @Override
97
+    public List<CommonProsperityProjectTypeDetailVo> listProjectTypeDetails(Integer statYear)
98
+    {
99
+        int year = statYear != null ? statYear : HomeScreenSupport.currentYearMonth().getYear();
100
+        List<CommonProsperityProjectTypeDetailVo> list =
101
+                projectMapper.selectPublishedTypeDetailsByYear(year);
102
+        return list != null ? list : new ArrayList<>();
103
+    }
104
+
90 105
     /** 大屏已发布项目(实施周期与统计年交集);Mapper 返回 null 时转空列表 */
91 106
     private List<BizCommonProsperityProject> safePublishedForScreen(int statYear)
92 107
     {

+ 15 - 0
baqing-admin/src/main/resources/mapper/prosperity/BizCommonProsperityProjectMapper.xml

@@ -132,4 +132,19 @@
132 132
           and impl_year is not null
133 133
         order by y desc
134 134
     </select>
135
+
136
+    <!-- 共富项目分类情况明细:按实施年限聚合;与看板一致仅已发布 -->
137
+    <select id="selectPublishedTypeDetailsByYear"
138
+            resultType="com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo">
139
+        select p.impl_year as statYear,
140
+               count(*) as totalCount,
141
+               sum(case when p.project_type = 1 then 1 else 0 end) as heMeiVillageCount,
142
+               sum(case when p.project_type = 2 then 1 else 0 end) as habitatImproveCount,
143
+               sum(case when p.project_type = 3 then 1 else 0 end) as otherProjectCount
144
+        from biz_common_prosperity_project p
145
+        where p.publish_status = 1
146
+          and p.impl_year = #{statYear}
147
+        group by p.impl_year
148
+        order by p.impl_year desc
149
+    </select>
135 150
 </mapper>

+ 2 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/prosperity/mapper/BizCommonProsperityProjectMapperScreenXmlTest.java

@@ -24,6 +24,8 @@ class BizCommonProsperityProjectMapperScreenXmlTest
24 24
         assertTrue(xml.contains("screenPublishedWhere"));
25 25
         assertTrue(xml.contains("publish_status = 1"));
26 26
         assertTrue(xml.contains("selectDistinctStatYearsFromPublished"));
27
+        assertTrue(xml.contains("selectPublishedTypeDetailsByYear"));
28
+        assertTrue(xml.contains("heMeiVillageCount"));
27 29
     }
28 30
 
29 31
     private static String readMapperXml()

+ 34 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/screen/controller/CommonProsperityScreenControllerApiTest.java

@@ -30,6 +30,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
30 30
 import com.ruoyi.common.core.domain.model.LoginUser;
31 31
 import com.ruoyi.web.modules.prosperity.domain.vo.AchievementAnnualReportVo;
32 32
 import com.ruoyi.web.modules.prosperity.support.AchievementReportAggregator;
33
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
33 34
 import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityScreenDashboardVo;
34 35
 import com.ruoyi.web.modules.screen.domain.vo.ProjectTypeStatVo;
35 36
 import com.ruoyi.web.modules.screen.domain.vo.ScreenProjectListItemVo;
@@ -172,6 +173,39 @@ class CommonProsperityScreenControllerApiTest
172 173
                 .andExpect(jsonPath("$.rows").isEmpty());
173 174
     }
174 175
 
176
+    @Test
177
+    @DisplayName("GET projectTypeDetails 分类明细")
178
+    void api_projectTypeDetails() throws Exception
179
+    {
180
+        CommonProsperityProjectTypeDetailVo row = new CommonProsperityProjectTypeDetailVo();
181
+        row.setStatYear(2026);
182
+        row.setTotalCount(10);
183
+        row.setHeMeiVillageCount(4);
184
+        row.setHabitatImproveCount(3);
185
+        row.setOtherProjectCount(3);
186
+        when(commonProsperityScreenService.listProjectTypeDetails(2026))
187
+                .thenReturn(Collections.singletonList(row));
188
+        mockMvc.perform(get("/bigScreen/commonProsperity/projectTypeDetails").param("statYear", "2026"))
189
+                .andExpect(status().isOk())
190
+                .andExpect(jsonPath("$.code").value(200))
191
+                .andExpect(jsonPath("$.rows[0].statYear").value(2026))
192
+                .andExpect(jsonPath("$.rows[0].totalCount").value(10))
193
+                .andExpect(jsonPath("$.rows[0].heMeiVillageCount").value(4))
194
+                .andExpect(jsonPath("$.rows[0].habitatImproveCount").value(3))
195
+                .andExpect(jsonPath("$.rows[0].otherProjectCount").value(3));
196
+    }
197
+
198
+    @Test
199
+    @DisplayName("GET projectTypeDetails 缺年份传 null 由服务默认当前年")
200
+    void api_projectTypeDetails_defaultYear() throws Exception
201
+    {
202
+        when(commonProsperityScreenService.listProjectTypeDetails(null)).thenReturn(Collections.emptyList());
203
+        mockMvc.perform(get("/bigScreen/commonProsperity/projectTypeDetails"))
204
+                .andExpect(status().isOk())
205
+                .andExpect(jsonPath("$.code").value(200))
206
+                .andExpect(jsonPath("$.rows").isEmpty());
207
+    }
208
+
175 209
     private static CommonProsperityScreenDashboardVo sampleDashboard(boolean hasAchievement, boolean hasProject)
176 210
     {
177 211
         AchievementAnnualReportVo achievement = hasAchievement

+ 36 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/screen/service/impl/CommonProsperityScreenServiceImplTest.java

@@ -13,6 +13,7 @@ import static org.mockito.Mockito.when;
13 13
 import java.math.BigDecimal;
14 14
 import java.util.Arrays;
15 15
 import java.util.Collections;
16
+import java.util.List;
16 17
 import org.junit.jupiter.api.DisplayName;
17 18
 import org.junit.jupiter.api.Test;
18 19
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -24,7 +25,9 @@ import com.ruoyi.web.modules.prosperity.domain.BizCommonProsperityProject;
24 25
 import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityAchievementMapper;
25 26
 import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityProjectMapper;
26 27
 import com.ruoyi.web.modules.prosperity.mapper.BizCommonProsperityProjectOpImageMapper;
28
+import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityProjectTypeDetailVo;
27 29
 import com.ruoyi.web.modules.screen.domain.vo.CommonProsperityScreenDashboardVo;
30
+import com.ruoyi.web.modules.screen.support.HomeScreenSupport;
28 31
 
29 32
 /**
30 33
  * DP-GTFY-UT-014、015
@@ -140,6 +143,39 @@ class CommonProsperityScreenServiceImplTest
140 143
         verify(opImageMapper).selectByProjectIds(Arrays.asList(9L));
141 144
     }
142 145
 
146
+    @Test
147
+    @DisplayName("分类明细:指定年份调用聚合查询")
148
+    void listProjectTypeDetails_withYear()
149
+    {
150
+        CommonProsperityProjectTypeDetailVo row = new CommonProsperityProjectTypeDetailVo();
151
+        row.setStatYear(2025);
152
+        row.setTotalCount(5);
153
+        row.setHeMeiVillageCount(2);
154
+        row.setHabitatImproveCount(2);
155
+        row.setOtherProjectCount(1);
156
+        when(projectMapper.selectPublishedTypeDetailsByYear(2025)).thenReturn(Collections.singletonList(row));
157
+
158
+        List<CommonProsperityProjectTypeDetailVo> list = service.listProjectTypeDetails(2025);
159
+        assertEquals(1, list.size());
160
+        assertEquals(2025, list.get(0).getStatYear().intValue());
161
+        assertEquals(5, list.get(0).getTotalCount().intValue());
162
+        assertEquals(2, list.get(0).getHeMeiVillageCount().intValue());
163
+        verify(projectMapper).selectPublishedTypeDetailsByYear(2025);
164
+    }
165
+
166
+    @Test
167
+    @DisplayName("分类明细:未传年份默认当前自然年")
168
+    void listProjectTypeDetails_defaultCurrentYear()
169
+    {
170
+        int currentYear = HomeScreenSupport.currentYearMonth().getYear();
171
+        when(projectMapper.selectPublishedTypeDetailsByYear(currentYear)).thenReturn(Collections.emptyList());
172
+
173
+        List<CommonProsperityProjectTypeDetailVo> list = service.listProjectTypeDetails(null);
174
+        assertNotNull(list);
175
+        assertTrue(list.isEmpty());
176
+        verify(projectMapper).selectPublishedTypeDetailsByYear(currentYear);
177
+    }
178
+
143 179
     private static BizCommonProsperityAchievement sampleAchievementRow()
144 180
     {
145 181
         return sampleAchievementRowForYear(2026, 3);

+ 29 - 0
doc/大屏/共同富裕/大屏共同富裕技术方案.md

@@ -227,6 +227,34 @@
227 227
 
228 228
 ---
229 229
 
230
+### 3.3 共富项目分类情况明细
231
+
232
+#### Query
233
+
234
+| 参数 | 类型 | 必填 | 说明 |
235
+| --- | --- | --- | --- |
236
+| `statYear` | int | N | 所属年份(实施年限);**未传默认当前自然年** |
237
+| `pageNum` | int | N | 默认 `1` |
238
+| `pageSize` | int | N | 默认若依分页 |
239
+
240
+#### 响应
241
+
242
+`TableDataInfo`:按 `impl_year` 倒序;口径与看板分类一致(`publish_status=1`)。
243
+
244
+#### 3.3.1 `rows[]` 单条
245
+
246
+| 字段 | 类型 | 说明 |
247
+| --- | --- | --- |
248
+| `statYear` | int | 所属年份(`impl_year`) |
249
+| `totalCount` | int | 项目总数(个) |
250
+| `heMeiVillageCount` | int | 和美乡村建设项目数(`project_type=1`) |
251
+| `habitatImproveCount` | int | 人居环境整治提升项目数(`project_type=2`) |
252
+| `otherProjectCount` | int | 其他项目投入数(`project_type=3`) |
253
+
254
+`GET /bigScreen/commonProsperity/projectTypeDetails`
255
+
256
+---
257
+
230 258
 ## 4. 菜单与权限(示例)
231 259
 
232 260
 | 类型 | 名称 | 权限标识 | 说明 |
@@ -258,3 +286,4 @@ SQL 示例:`sql/big_screen_common_prosperity_perm.sql`(挂载「大屏」父
258 286
 | 1.1 | 2026-07-24 | 看板 `monthly` 改回所选年 1~12 月(与 `summary` 同源),不再覆盖为滚动 12 月 |
259 287
 | 1.2 | 2026-07-24 | 看板 `summary` 改为所选年**最大统计月**单月值;`monthly` 仍为该年 1~12 月 |
260 288
 | 1.3 | 2026-07-24 | `monthly` 改为所选年 1~最大月;与管理端年度报告共用 Aggregator 口径 |
289
+| 1.4 | 2026-07-24 | 新增共富项目分类情况明细 `GET /projectTypeDetails`(分页、按年聚合) |