无关风月
2025-04-10 099ea14bba367fd86f0dde37d908f07cc04c3d39
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
package com.ruoyi.system.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.model.TBill;
import com.ruoyi.system.model.TContract;
import com.ruoyi.system.model.THouse;
import com.ruoyi.system.service.TBillService;
import com.ruoyi.system.service.TContractService;
import com.ruoyi.system.service.THouseService;
import com.ruoyi.system.vo.ScreenRentIncomeTrendVO;
import com.ruoyi.system.vo.ScreenRentRankVO;
import com.ruoyi.system.vo.ScreenTopStaticsDataVO;
import com.ruoyi.system.vo.TenantCountTrendVO;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
 
/**
 * @author mitao
 * @date 2025/3/19
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ScreenService {
    private final THouseService tHouseService;
    private final TContractService tContractService;
    private final TBillService tBillService;
    private final TContractService contractService;
    /**
     * 获取顶部统计数据
     * @return
     */
    public ScreenTopStaticsDataVO getTopStaticsData() {
        String businessDeptId = SecurityUtils.getBusinessDeptId();
        Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date());
        Date first = quarterDate.get("first");
        Date last = quarterDate.get("last");
        ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO();
        //房屋总面积
        List<THouse> houseList = tHouseService.lambdaQuery()
                .eq(!businessDeptId.equals("0"), THouse::getBusinessDeptId, businessDeptId)
                .list();
        Double totalArea = houseList.stream()
                .map(item -> Double.parseDouble(item.getHouseArea()))
                .reduce(0D, Double::sum);
        vo.setHouseTotalArea(totalArea);
        //已出租面积
        Double totalRentedArea =  tHouseService.getRentedArea(businessDeptId);
        vo.setHouseRentedArea(totalRentedArea);
        //总计应收租金
        List<TBill> billList = tBillService.getJiFuBillList(businessDeptId);
        BigDecimal totalReceivableRent = billList.stream()
                .filter(item -> !item.getPayFeesStatus().equals("5"))
                .map(TBill::getPayableFeesMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
        vo.setTotalReceivableRent(totalReceivableRent);
        //总计已收租金
        BigDecimal totalReceivedRent = billList.stream()
                .map(TBill::getPayFeesMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
        vo.setTotalReceivedRent(totalReceivedRent);
        //本月新增租户数
        Integer newTenantCount = tContractService.getCurrentMonthRentCount(businessDeptId);
        vo.setNewTenantCount(newTenantCount);
        //总计租户数 系统租户列表里有生效合同绑定的租户总数。
        List<TContract> tContracts = tContractService.lambdaQuery()
                .eq(TContract::getPayType,2) //季付
                .in(TContract::getStatus, "4", "5", "6", "7", "8", "9")
                .eq(!businessDeptId.equals("0"), TContract::getBusinessDeptId, businessDeptId)
                .list();
        long count = tContracts.stream()
                .map(TContract::getTenantId)
                .distinct()
                .count();
        vo.setTotalTenantCount((int) count);
        List<TBill> currentQuarterBillList = tBillService.getJiFuBillListByTime(businessDeptId, first, last);
        //本季度已交租金
        BigDecimal totalRentPaid = currentQuarterBillList.stream()
                .map(TBill::getPayFeesMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
        vo.setTotalRentPaid(totalRentPaid);
        //本季度应交租金
        BigDecimal totalRentShould = currentQuarterBillList.stream()
                .filter(item -> !item.getPayFeesStatus().equals("5"))
                .map(TBill::getPayableFeesMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal("10000"),2, RoundingMode.DOWN);
        vo.setTotalRentShould(totalRentShould);
        //本季度欠费
        BigDecimal totalRentOwe = currentQuarterBillList.stream()
                .map(TBill::getOutstandingMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
        vo.setTotalRentOwe(totalRentOwe);
        //总计欠费
        BigDecimal totalRentOweAll = billList.stream()
                .map(TBill::getOutstandingMoney)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
        vo.setTotalRentOweAll(totalRentOweAll);
        return vo;
    }
 
    /**
     * 区域租金排名
     * @return
     */
    public List<ScreenRentRankVO> streetRentRank() {
        String businessDeptId = SecurityUtils.getBusinessDeptId();
        return  tBillService.getStreetRentRank(businessDeptId);
    }
 
    /**
     * 租金收入趋势
     * @return
     */
    public ScreenRentIncomeTrendVO rentIncomeTrend() {
        ScreenRentIncomeTrendVO vo = new ScreenRentIncomeTrendVO();
        String businessDeptId = SecurityUtils.getBusinessDeptId();
        // 获取当前日期
        Date currentDate = new Date();
        List<String> quarterLabels = new ArrayList<>(); // 季度标签列表
        List<BigDecimal> incomeData = new ArrayList<>(); //收入数据列表
        List<BigDecimal> outstandingData = new ArrayList<>();  // 欠费数据列表
        
        // 获取最近7个季度的数据
        for (int i = 6; i >= 0; i--) {
            // 计算对应季度的起止时间
            Date targetDate = DateUtils.addMonths(currentDate, -3 * i);
            Map<String, Date> quarterDate = DateUtils.getQuarterDate(targetDate);
            Date quarterStart = quarterDate.get("first");
            Date quarterEnd = quarterDate.get("last");
 
            // 获取该季度的账单数据
            List<TBill> quarterBills = tBillService.getJiFuBillListByTime(businessDeptId, quarterStart, quarterEnd);
 
            // 计算季度租金收入总和
            BigDecimal quarterIncome = quarterBills.stream()
                    .map(TBill::getPayFeesMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
 
            // 计算季度欠费总和
            BigDecimal quarterOutstanding = quarterBills.stream()
                    .map(TBill::getOutstandingMoney)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(10000L), 2, RoundingMode.DOWN);
 
            // 生成季度标签 (格式: YY-MM月)
            Calendar cal = Calendar.getInstance();
            cal.setTime(quarterEnd);
            String label = String.format("%02d-%d月",
                    cal.get(Calendar.YEAR) % 100,
                    cal.get(Calendar.MONTH) + 1);
 
            quarterLabels.add(label);
            incomeData.add(quarterIncome);
            outstandingData.add(quarterOutstanding);  // 添加欠费数据
        }
        
        vo.setQuarters(quarterLabels);
        vo.setIncomeData(incomeData);
        vo.setOutstandingData(outstandingData);  // 设置欠费数据到VO
        return vo;
    }
 
    public R<List<TenantCountTrendVO>> getTenantCountTrend() {
 
        // 获取当前日期
        Date currentDate = new Date();
        String businessDeptId = SecurityUtils.getBusinessDeptId();
        List<TenantCountTrendVO> list = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            Date targetDate = DateUtils.addMonths(currentDate, -3 * i);
            Map<String, Date> quarterDate = DateUtils.getQuarterDate(targetDate);
            Date quarterStart = quarterDate.get("first");
            Date quarterEnd = quarterDate.get("last");
            System.out.println("第" + (i + 1) + "季度的起止时间:" + quarterStart + " - " + quarterEnd);
 
            List<TContract> contracts = contractService.list(new LambdaQueryWrapper<TContract>()
                    .eq(!"0".equals(businessDeptId), TContract::getBusinessDeptId, businessDeptId)
                    .eq(TContract::getPayType, 2)
                    .isNotNull(TContract::getSignTime)
                    .between(TContract::getSignTime, quarterStart, quarterEnd)
                    .orderByAsc(TContract::getSignTime));
 
 
            TenantCountTrendVO vo = new TenantCountTrendVO();
            // 生成季度标签 (格式: YY-MM月)
            Calendar cal = Calendar.getInstance();
            cal.setTime(quarterEnd);
            String label = String.format("%02d-%d月",
                    cal.get(Calendar.YEAR) % 100,
                    cal.get(Calendar.MONTH) + 1);
            vo.setDate(label);
            long count = contracts.stream().map(TContract::getTenantId).distinct().count();
            vo.setCount(count);
            list.add(vo);
        }
        return R.ok(list);
    }
//
//
//
//
//
//
//
//        DateTimeFormatter quarterFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
//
//        List<TenantCountTrendVO> trendData = contracts.stream()
//                .collect(Collectors.groupingBy(contract -> {
//                    LocalDate date = contract.getSignTime().toLocalDate();
//                    int quarter = (date.getMonthValue() - 1) / 3 + 1;
//                    return YearQuarter.from(date.withMonth(quarter * 3 - 2));
//                }, TreeMap::new, Collectors.counting()))
//                .entrySet().stream()
//                .map(entry -> new TenantCountTrendVO(
//                        entry.getKey().format(quarterFormatter),
//                        entry.getValue()))
//                .collect(Collectors.toList());
//
//        return R.ok(trendData);
//    }
 
 
 
}