Pu Zhibing
2025-04-22 d138293736414a314467a2641e6116ff263ead48
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package com.ruoyi.bussiness.service.impl;
 
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import com.ruoyi.bussiness.object.request.report.ReportRequest;
import com.ruoyi.bussiness.object.response.screen.*;
import com.ruoyi.bussiness.service.PlacementApplyRecordService;
import com.ruoyi.bussiness.service.PlacementBatchHouseholdService;
import com.ruoyi.bussiness.service.PlacementBatchService;
import com.ruoyi.bussiness.service.ScreenService;
import com.ruoyi.bussiness.utils.PaymentCycleHelper;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.system.service.ISysDictTypeService;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
@Service
public class ScreenServiceImpl implements ScreenService {
 
    @Autowired
    private PlacementApplyRecordService placementApplyRecordService;
    @Autowired
    private PlacementBatchService placementBatchService;
    @Autowired
    private ISysDictTypeService dictTypeService;
 
    @Override
    public ScreenResponse data(ReportRequest request) {
        String month = DateUtil.format(new Date(), "yyyy-MM");
        //获取当前季度
        String quarter = PaymentCycleHelper.getQuarterByOffset(new Date(),0);
        //上一个季度
        String lastQuarter = PaymentCycleHelper.getQuarterByOffset(new Date(),-1);
        String nextQuarter = PaymentCycleHelper.getQuarterByOffset(new Date(),1);
        List<String> quarters = PaymentCycleHelper.getQuarterlyPaymentCyclesFour(new Date());
        //统计
        ScreenResponse screenResponse = queryMainData(quarter,lastQuarter,nextQuarter);
        //多线程查询信息
        ExecutorService executorService = Executors.newFixedThreadPool(8);
        try {
            //已安置情况
            Callable<SelfBuyResponse> selfBuyResponseCallable = this::selfBuyResponse;
            //镇街道参与户数
            Callable<List<StreetResponse>> streetResponseCallable = this::streetResponse;
            //导入异常数据
            Callable<List<ImportErrorResponse>> importErrorResponseCallable = this::getImportErrorResponse;
            //地图
            Callable<List<MapResponse>> mapResponseCallable = this::getMapResponse;
            //季度款支付进度数据
            Callable<List<QuarterProcessResponse>> quarterProcessResponseCallable = ()-> getQuarterProcessResponse(request);
            //安置房型占比
            Callable<List<PlacementTypeResponse>> placementTypeResponseCallable = this::getPlacementTypeResponse;
            //本月应补偿占比
            Callable<List<MonthCompensationResponse>> monthCompensationResponseCallable = ()-> getMonthCompensationResponses(month);
            //各季度应补偿金额
            Callable<List<Map<String,Object>> > quarterPayResponseCallable = ()-> getQuarterPayResponse(quarters);
 
            FutureTask<SelfBuyResponse> selfBuyResponseFutureTask = new FutureTask<>(selfBuyResponseCallable);
            FutureTask<List<StreetResponse>> streetResponseFutureTask = new FutureTask<>(streetResponseCallable);
            FutureTask<List<ImportErrorResponse>> importErrorResponseFutureTask = new FutureTask<>(importErrorResponseCallable);
            FutureTask<List<MapResponse>> mapResponseFutureTask = new FutureTask<>(mapResponseCallable);
            FutureTask<List<QuarterProcessResponse>> quarterProcessResponseFutureTask = new FutureTask<>(quarterProcessResponseCallable);
            FutureTask<List<PlacementTypeResponse>> placementTypeResponseFutureTask = new FutureTask<>(placementTypeResponseCallable);
            FutureTask<List<MonthCompensationResponse>> monthCompensationResponseFutureTask = new FutureTask<>(monthCompensationResponseCallable);
            FutureTask<List<Map<String,Object>> > quarterPayResponseFutureTask = new FutureTask<>(quarterPayResponseCallable);
 
            executorService.submit(selfBuyResponseFutureTask);
            executorService.submit(streetResponseFutureTask);
            executorService.submit(importErrorResponseFutureTask);
            executorService.submit(mapResponseFutureTask);
            executorService.submit(quarterProcessResponseFutureTask);
            executorService.submit(placementTypeResponseFutureTask);
            executorService.submit(monthCompensationResponseFutureTask);
            executorService.submit(quarterPayResponseFutureTask);
 
            screenResponse.setSelfBuyResponse(selfBuyResponseFutureTask.get());
            screenResponse.setStreetResponses(streetResponseFutureTask.get());
            screenResponse.setImportErrorResponses(importErrorResponseFutureTask.get());
            screenResponse.setMapResponses(mapResponseFutureTask.get());
            screenResponse.setQuarterProcessResponses(quarterProcessResponseFutureTask.get());
            screenResponse.setPlacementTypeResponses(placementTypeResponseFutureTask.get());
            screenResponse.setMonthCompensationResponses(monthCompensationResponseFutureTask.get());
            screenResponse.setQuarterPayResponses(quarterPayResponseFutureTask.get());
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException("获取数据失败");
        } finally {
            executorService.shutdown();
        }
        return screenResponse;
    }
 
    /**
     * //修改为统计季度款支付合计了
     * 首页 申请总户数 本季度支付款金额 下季度支付款金额 统计安置批次房产表
     * 1.总共申请的户数信息(审核通过的)
     * 2.统计本月需要补偿的金额合计包含(25%首付款。过渡费、季度款)环比是跟上一个月进行比较;
     * 3.统计下个月需要补偿的金额合计包含(25%首付款、过渡费、季度款)环比是跟上一个月进行比较;
     * @return
     */
    private ScreenResponse queryMainData(String month,String lastMonth,String nextMonth) {
        ScreenResponse screenResponse = placementApplyRecordService.queryMainData(month, lastMonth, nextMonth);
        // 计算环比
        String monthCompensationAmountRate = calculateRate(screenResponse.getMonthCompensationAmount(), screenResponse.getLastMonthCompensationAmount());
        String nextMonthCompensationAmountRate = calculateRate(screenResponse.getNextMonthCompensationAmount(), screenResponse.getMonthCompensationAmount());
        screenResponse.setMonthCompensationAmountRate(monthCompensationAmountRate);
        screenResponse.setNextMonthCompensationAmountRate(nextMonthCompensationAmountRate);
        // 输出结果
        return screenResponse;
    }
 
    /**
     * 审核通过-已参与自主购房安置统计(统计安置批次房产表)
     * 1. 统计安置批次审核过的总户数和总人数
     */
    private SelfBuyResponse selfBuyResponse(){
        return placementBatchService.getSelfBuyResponse();
    }
 
    /**
     * 审核通过-各镇/街参与户数排名(统计安置批次房产表)
     * 1.按镇/街维度统计安置批次审核过的总户数
     * 2.环比根据批次来比较,最新批次比上一批次按审核通过时间)
     * @return
     */
    private List<StreetResponse> streetResponse() {
        List<StreetResponse> streetResponses = placementBatchService.getStreetResponse();
        if (ObjUtil.isEmpty(streetResponses)) {
            streetResponses = new ArrayList<>();
        }
        //获取所有街道(填充无数据街道)
        List<SysDictData> street = dictTypeService.selectDictDataByType("street");
 
        List<StreetResponse> responses = new ArrayList<>();
        for(SysDictData sysDictData : street){
            StreetResponse streetResponse = new StreetResponse();
            streetResponse.setStreet(sysDictData.getDictLabel());
            for(StreetResponse itemData : streetResponses){
                if(itemData.getStreet().equals(streetResponse.getStreet())){
                    streetResponse.setHouseholdNum(itemData.getHouseholdNum());
                    streetResponse.setLatestBatchHouseholdCount(itemData.getLatestBatchHouseholdCount());
                    streetResponse.setSecondLatestBatchHouseholdCount(itemData.getSecondLatestBatchHouseholdCount());
                }
            }
            responses.add(streetResponse);
        }
 
        for (StreetResponse streetResponse : responses) {
            //计算环比
            String rate = calculateRate(new BigDecimal(streetResponse.getLatestBatchHouseholdCount()), new BigDecimal(streetResponse.getSecondLatestBatchHouseholdCount()));
            streetResponse.setHouseholdNumRate(rate);
        }
 
        //排序
        responses.sort(Comparator.comparing(StreetResponse::getHouseholdNum).reversed());
        return responses;
    }
 
    /**
     * 审核通过-安置批次房产表
     * 1.补偿金额异常:统计过渡费异常数据、补偿标准金额异常数据;
     * 2.安置面积异常:统计面积异常数据
     * @return
     */
    public List<ImportErrorResponse> getImportErrorResponse(){
        return placementBatchService.getImportErrorResponse();
    }
 
 
    /**
     * 地图数据
     * 按照街道统计户数、安置人数
     * @return
     */
    public List<MapResponse> getMapResponse(){
        List<MapResponse> mapResponses = placementBatchService.getMapResponse();
        //获取所有街道(填充无数据街道)
        List<SysDictData> street = dictTypeService.selectDictDataByType("street");
        List<MapResponse> responses = new ArrayList<>();
        for(SysDictData sysDictData : street){
            MapResponse mapResponse = new MapResponse();
            mapResponse.setStreet(sysDictData.getDictLabel());
 
            for(MapResponse itemData : mapResponses){
                if(itemData.getStreet().equals(mapResponse.getStreet())){
                    mapResponse.setHouseholdCount(itemData.getHouseholdCount());
                    mapResponse.setPersonCount(itemData.getPersonCount());
                }
            }
            responses.add(mapResponse);
        }
 
        //渲染不出来崇庆街道的标点 把崇庆街道的数量统计到崇阳街道上
        Integer householdCount = 0;
        Integer personCount = 0;
        if(ObjUtil.isNotEmpty(responses)) {
            for (MapResponse mapResponse : responses) {
                if (mapResponse.getStreet().equals("崇庆街道")) {
                    householdCount = mapResponse.getHouseholdCount();
                    personCount = mapResponse.getPersonCount();
                }
            }
            boolean exists = true;
            for (MapResponse mapResponse : responses) {
                if (mapResponse.getStreet().equals("崇阳街道")) {
                    exists = false;
                    mapResponse.setHouseholdCount(mapResponse.getHouseholdCount() + householdCount);
                    mapResponse.setPersonCount(mapResponse.getPersonCount() + personCount);
                }
            }
 
//            //不存在崇阳街道
//            if (exists) {
//                MapResponse mapResponse = new MapResponse();
//                mapResponse.setHouseholdCount(householdCount);
//                mapResponse.setPersonCount(personCount);
//                mapResponse.setStreet("崇阳街道");
//                responses.add(mapResponse);
//            }
 
        }
        return responses;
    }
 
    /**
     * 季度款支付进度数据
     * @return
     */
    public List<QuarterProcessResponse> getQuarterProcessResponse(ReportRequest request) {
        List<QuarterProcessResponse> responses = placementBatchService.getQuarterProcessResponse(request);
        //计算季度
        if (ObjUtil.isEmpty(responses)) {
            return responses;
        }
        for (QuarterProcessResponse quarterProcessResponse : responses) {
            Integer period = PaymentCycleHelper.getPaymentPeriod(quarterProcessResponse.getCompensationPayTime());
            quarterProcessResponse.setProcess(period);
        }
        return responses;
    }
 
    /**
     * 安置房型占比
     * 根据数量算占比
     * @return
     */
    public List<PlacementTypeResponse> getPlacementTypeResponse(){
        return  placementBatchService.getPlacementTypeResponse();
    }
 
    /**
     * 本月应补偿占比
     * @return
     */
    public List<MonthCompensationResponse> getMonthCompensationResponses(String month){
        return placementBatchService.getMonthCompensationResponses(month);
    }
 
    /**
     * 各季度应补偿金额
     * @return
     */
    public List<Map<String,Object>> getQuarterPayResponse(List<String> quarters){
       return placementBatchService.getQuarterPayResponse(quarters);
    }
 
    /**
     * 计算环比增长率并返回百分比字符串
     *
     * @param currentMonth 本期金额
     * @param lastMonth 上期金额
     * @return 环比增长率(百分比形式,保留2位小数)
     */
    private static String calculateRate(BigDecimal currentMonth, BigDecimal lastMonth) {
        if (lastMonth == null || lastMonth.compareTo(BigDecimal.ZERO) == 0) {
            return "0%"; // 避免除以零
        }
        BigDecimal rate = currentMonth.subtract(lastMonth)
                .divide(lastMonth, 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
        return rate.setScale(2, RoundingMode.HALF_UP) + "%";
    }
 
 
}