ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java
@@ -2,6 +2,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.system.service.impl.ScreenService; import com.ruoyi.system.vo.ScreenRentIncomeTrendVO; import com.ruoyi.system.vo.ScreenRentRankVO; import com.ruoyi.system.vo.ScreenTopStaticsDataVO; import io.swagger.annotations.Api; @@ -29,9 +30,14 @@ public R<ScreenTopStaticsDataVO> getTopStaticsData() { return R.ok(screenService.getTopStaticsData()); } @ApiOperation("区域租金排名") @GetMapping("/rent-rank") @ApiOperation("区域租金排名") public R<List<ScreenRentRankVO>> rentRank() { return R.ok(screenService.rentRank()); return R.ok(screenService.streetRentRank()); } @GetMapping("/rent-income-trend") @ApiOperation("租金收入趋势") public R<ScreenRentIncomeTrendVO> rentIncomeTrend() { return R.ok(screenService.rentIncomeTrend()); } } ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -1,16 +1,21 @@ package com.ruoyi.common.utils; import org.apache.commons.lang3.time.DateFormatUtils; import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.time.DateFormatUtils; /** * 时间工具类 @@ -267,7 +272,7 @@ cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, startMonth); cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(Calendar.HOUR, 0); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); Date first = cal.getTime(); @@ -279,9 +284,9 @@ cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, lastMonth); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); cal.set(Calendar.SECOND, 59); Date last = cal.getTime(); map.put("last", last); ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java
@@ -5,9 +5,9 @@ import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.vo.ScreenRentRankVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.math.BigDecimal; import java.util.List; @@ -46,4 +46,9 @@ BigDecimal statisticsOverdue(); Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds); /** * 街道租金排行 * @return */ List<ScreenRentRankVO> getStreetRentRank(); } ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java
@@ -28,4 +28,9 @@ List<BillVO> contractBillList(@Param("query") TContractBillQuery query, @Param("pageInfo") PageInfo<BillVO> pageInfo); List<TContract> contractExportList(@Param("query")TContractQuery query); /** * 本月新增租户数 * @return */ Integer getCurrentMonthRentCount(); } ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java
@@ -24,4 +24,5 @@ List<HouseVO> userHistoryList(@Param("req")TUserHistoryQuery query, @Param("pageInfo")PageInfo<HouseVO> pageInfo); Double getHouseRentedArea(); } ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
@@ -2,18 +2,21 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.dto.*; import com.ruoyi.system.dto.BillStatisticsDto; import com.ruoyi.system.dto.CachPayDto; import com.ruoyi.system.dto.OfflinePayCheckDto; import com.ruoyi.system.dto.SmsByBillDto; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.vo.ScreenRentRankVO; import com.taxi591.bankapi.dto.ChargeBillRequest; import javax.validation.constraints.NotEmpty; import java.math.BigDecimal; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; import java.util.List; /** * <p> @@ -87,4 +90,10 @@ BillStatisticsDto statistics(); Integer batchBillCount(String userId, List<String> billIds); /** * 查询街道租金排行 * @return */ List<ScreenRentRankVO> getStreetRentRank(); } ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
@@ -43,4 +43,9 @@ Boolean updateContractAuditStatus(String projectId, Integer submitStatus); /** * 本月新增租户数 * @return */ Integer getCurrentMonthRentCount(); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java
@@ -1,12 +1,26 @@ package com.ruoyi.system.service.impl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.THouse; import com.ruoyi.system.service.ITStreetService; 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 lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Calendar; import java.util.ArrayList; /** * @author mitao @@ -15,19 +29,97 @@ @Service @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class ScreenService { private final THouseService tHouseService; private final TContractService tContractService; private final TBillService tBillService; private final ITStreetService tStreetService; /** * 获取顶部统计数据 * @return */ public ScreenTopStaticsDataVO getTopStaticsData() { return null; ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO(); //房屋总面积 List<THouse> houseList = tHouseService.list(); Double totalArea = houseList.stream().map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum); vo.setHouseTotalArea(totalArea); //已出租面积 Double totalRentedArea = houseList.stream().filter(item -> !item.getLeaseStatus().equals("1")) .map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum); vo.setHouseRentedArea(totalRentedArea); //总计应收租金 List<TBill> billList = tBillService.list(); BigDecimal totalReceivableRent = billList.stream().filter(item -> !item.getPayFeesStatus().equals("5")) .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); vo.setTotalReceivableRent(totalReceivableRent); //总计已收租金 BigDecimal totalReceivedRent = billList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); vo.setTotalReceivedRent(totalReceivedRent); //本月新增租户数 Integer newTenantCount = tContractService.getCurrentMonthRentCount(); vo.setNewTenantCount(newTenantCount); //总计租户数 系统租户列表里有生效合同绑定的租户总数。 Long count = tContractService.lambdaQuery().in(TContract::getStatus, "4", "5", "6", "7", "8", "9").groupBy(TContract::getTenantId).count(); vo.setTotalTenantCount(count.intValue()); Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date()); Date first = quarterDate.get("first"); Date last = quarterDate.get("last"); List<TBill> currentQuarterBillList = tBillService.lambdaQuery().between(TBill::getPayableFeesTime, first, last).list(); //本季度已交租金 BigDecimal totalRentPaid = currentQuarterBillList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); vo.setTotalRentPaid(totalRentPaid); //本季度应交租金 BigDecimal totalRentShould = currentQuarterBillList.stream().filter(item -> !item.getPayFeesStatus().equals("5")) .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); vo.setTotalRentShould(totalRentShould); return vo; } /** * 区域租金排名 * @return */ public List<ScreenRentRankVO> rentRank() { return null; public List<ScreenRentRankVO> streetRentRank() { return tBillService.getStreetRentRank(); } public ScreenRentIncomeTrendVO rentIncomeTrend() { ScreenRentIncomeTrendVO vo = new ScreenRentIncomeTrendVO(); // 获取当前日期 Date currentDate = new Date(); List<String> quarterLabels = new ArrayList<>(); List<BigDecimal> incomeData = 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"); // 获取该季度的账单数据并计算总和 BigDecimal quarterIncome = tBillService.lambdaQuery() .between(TBill::getPayableFeesTime, quarterStart, quarterEnd) .list() .stream() .map(TBill::getPayFeesMoney) .reduce(BigDecimal.ZERO, BigDecimal::add); // 生成季度标签 (格式: 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); } vo.setQuarters(quarterLabels); vo.setIncomeData(incomeData); return vo; } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
@@ -1,21 +1,42 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.config.SmsProperties; import com.ruoyi.common.constant.AmountConstant; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.*; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.OrderNos; import com.ruoyi.common.utils.SmsUtil; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.TencentMailUtil; import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.system.dto.*; import com.ruoyi.system.dto.BillStatisticsDto; import com.ruoyi.system.dto.CachPayDto; import com.ruoyi.system.dto.OfflinePayCheckDto; import com.ruoyi.system.dto.SmsByBillDto; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.mapper.TBillMapper; import com.ruoyi.system.model.*; import com.ruoyi.system.model.TBankFlow; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillDetail; import com.ruoyi.system.model.TFlowManagement; import com.ruoyi.system.model.TInvoiceToBill; import com.ruoyi.system.model.TOrderBill; import com.ruoyi.system.model.TPayOrder; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.query.TInvoiceToBillQuery; import com.ruoyi.system.service.*; import com.ruoyi.system.service.TBankFlowService; import com.ruoyi.system.service.TBillConfirmService; import com.ruoyi.system.service.TBillDetailService; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TFlowManagementService; import com.ruoyi.system.service.TInvoiceToBillService; import com.ruoyi.system.service.TOrderBillService; import com.ruoyi.system.service.TPayOrderService; import com.ruoyi.system.vo.ScreenRentRankVO; import com.taxi591.bankapi.dto.ChargeBillRequest; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; @@ -28,7 +49,6 @@ import javax.validation.constraints.NotEmpty; import java.math.BigDecimal; import java.text.ParseException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; @@ -552,5 +572,12 @@ return this.baseMapper.batchBillCount(userId,billIds); } /** * 街道租金排行 * @return */ @Override public List<ScreenRentRankVO> getStreetRentRank() { return baseMapper.getStreetRentRank(); } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -4,6 +4,7 @@ import com.aizuda.bpm.mybatisplus.mapper.FlwHisTaskMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; @@ -17,7 +18,9 @@ import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; import com.ruoyi.system.mapper.TContractMapper; import com.ruoyi.system.mapper.THouseMapper; import com.ruoyi.system.model.*; import com.ruoyi.system.model.TCheckAcceptRecord; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.THouse; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; @@ -25,21 +28,16 @@ import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TContractRentTypeService; import com.ruoyi.system.service.TContractService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.BillVO; import com.ruoyi.system.vo.CheckAcceptRecordVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.stream.Collectors; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; /** * <p> @@ -198,4 +196,13 @@ contractLambdaUpdateWrapper.eq(TContract::getId, projectId).set(TContract::getStatus, status); return this.update(contractLambdaUpdateWrapper); } /** * 本月新增租户数 * @return */ @Override public Integer getCurrentMonthRentCount() { return baseMapper.getCurrentMonthRentCount(); } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.utils.DictUtils; @@ -12,7 +13,6 @@ import com.ruoyi.system.query.THouseQuery; import com.ruoyi.system.query.TUserHistoryQuery; import com.ruoyi.system.service.THouseService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.HouseVO; import org.springframework.stereotype.Service; ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java
New file @@ -0,0 +1,23 @@ package com.ruoyi.system.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.util.List; /** * @author mitao * @date 2025/3/20 */ @Data @ApiModel("租金收入区域视图对象") public class ScreenRentIncomeTrendVO { @ApiModelProperty("x轴 时间列表") private List<String> quarters; @ApiModelProperty("y轴 收入列表") private List<BigDecimal> incomeData; } ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -186,4 +186,15 @@ AND b.bill_type = 3 </where> </select> <select id="getStreetRentRank" resultType="com.ruoyi.system.vo.ScreenRentRankVO"> SELECT ts.street_name,ROUND(COALESCE(SUM(tb.pay_fees_money),0) /10000,2) AS rentAmount FROM t_street ts LEFT JOIN t_house th ON ts.id = th.street_id LEFT JOIN t_contract tc ON tc.house_id = th.id LEFT JOIN t_bill tb ON tc.id = tb.contract_id GROUP BY ts.id ORDER BY rentAmount DESC </select> </mapper> ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
@@ -124,5 +124,19 @@ </where> </select> <select id="getCurrentMonthRentCount" resultType="java.lang.Integer"> SELECT COUNT(DISTINCT tc.tenant_id) AS new_tenant_count FROM t_contract tc WHERE -- 筛选本月签订的合同 DATE_FORMAT(tc.sign_time, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m') AND tc.status IN ("4", "5", "6", "7", "8", "9") -- 且租户在本月前从未签订过任何合同 AND NOT EXISTS ( SELECT 1 FROM t_contract tc_hist WHERE tc_hist.tenant_id = tc.tenant_id AND tc_hist.sign_time <![CDATA[ < ]]> DATE_FORMAT(CURDATE(), '%Y-%m-01') AND tc_hist.status IN ("4", "5", "6", "7", "8", "9") ) </select> </mapper>