package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.core.domain.R; 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.model.TStreet; 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.service.impl.ScreenService; import com.ruoyi.system.vo.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; /** * @author mitao * @date 2025/3/19 */ @Api(tags = {"大屏相关接口"}) @RestController @RequestMapping("/screen") @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class ScreenController { private final ScreenService screenService; private final TContractService contractService; private final THouseService houseService; private final ITStreetService streetService; private final TBillService billService; @GetMapping("/statics-data") @ApiOperation(value = "获取顶部统计数据") public R getTopStaticsData() { return R.ok(screenService.getTopStaticsData()); } @GetMapping("/rent-rank") @ApiOperation("区域租金排名") public R> rentRank() { return R.ok(screenService.streetRentRank()); } @GetMapping("/rent-income-trend") @ApiOperation("租金收入趋势") public R rentIncomeTrend() { return R.ok(screenService.rentIncomeTrend()); } @GetMapping("/getTenantCountTrend") @ApiModelProperty(value = "租户数量趋势统计") public R> getTenantCountTrend() { Date currentDate = new Date(); Date targetDate = DateUtils.addMonths(currentDate, -3 * 6); Map startQuarterDate = DateUtils.getQuarterDate(targetDate); Date targetDate2 = DateUtils.addMonths(currentDate, 0); Map endQuarterDate = DateUtils.getQuarterDate(targetDate2); List contracts = contractService.list(new LambdaQueryWrapper() .isNotNull(TContract::getSignTime) .between(TContract::getSignTime, startQuarterDate.get("first"), endQuarterDate.get("last")) .orderByAsc(TContract::getSignTime)); // 创建季度格式化工具(示例:2025-Q1) DateTimeFormatter quarterFormatter = DateTimeFormatter.ofPattern("yyyy-'Q'Q"); List 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); } /** * 实时租赁数据 */ @GetMapping("/getRealTimeRentData") public R> getRealTimeRentData() { // 随机获取十条房源 List houses = houseService.list(new LambdaQueryWrapper() .last("ORDER BY RAND() LIMIT 10")); // 提取streetIds List streetIds = houses.stream() .map(THouse::getStreetId) .collect(Collectors.toList()); // 获取街道信息 Map streetMap = streetService.listByIds(streetIds).stream() .collect(Collectors.toMap(TStreet::getId, TStreet::getStreetName)); // 转换为返回格式 List result = houses.stream().map(house -> { RealTimeRentDataVO vo = new RealTimeRentDataVO(); vo.setStreetName(streetMap.getOrDefault(house.getStreetId(), "未知")); vo.setRoomName(house.getRoomNumber()); vo.setLeaseStatus(house.getLeaseStatus()); return vo; }).collect(Collectors.toList()); return R.ok(result); } /** * 获取房屋地图分布 */ @GetMapping("/getHouseMapDistribution") public R> getHouseMapDistribution() { // 获取所有房屋信息 List houses = houseService.list(); List result = new ArrayList<>(); for (THouse house : houses) { HouseMapDistributionVO houseMapDistributionVO = new HouseMapDistributionVO(); houseMapDistributionVO.setHouseName(house.getHouseName()); houseMapDistributionVO.setHouseAddress(house.getHouseAddress()); houseMapDistributionVO.setHouseStatus(house.getLeaseStatus()); TContract contract = contractService.getOne(new LambdaQueryWrapper() .eq(TContract::getHouseId, house.getId())); TBill bill = billService.getOne(new LambdaQueryWrapper() .eq(TBill::getContractId, contract.getId()) .eq(TBill::getBillType, 1)); houseMapDistributionVO.setTenant(contract.getPartyTwoName()); LocalDateTime startTime = contract.getStartTime(); LocalDateTime endTime = contract.getEndTime(); BigDecimal monthRent = contract.getMonthRent(); // 计算相差月份 long monthsBetween = ChronoUnit.MONTHS.between(startTime, endTime); BigDecimal payableFeesMoney = monthRent.multiply(new BigDecimal(monthsBetween)); BigDecimal remainingPayment = bill.getPayableFeesMoney(); BigDecimal paidAlready = payableFeesMoney.subtract(remainingPayment); String rentStatus = String.format("%.2f/%.2f", paidAlready, payableFeesMoney); houseMapDistributionVO.setRentStatus(rentStatus); String payType = contract.getPayType(); String rent = ""; LocalDateTime payFeesTime = bill.getPayFeesTime(); switch (payType) { case "1": if (isCurrentMonth(payFeesTime)) { rent = String.format("%.2f/%.2f", monthRent, monthRent); } else { rent = String.format("%.2f/%.2f", new BigDecimal("0"), monthRent); } break; case "2": // 季付价格 BigDecimal quarterRent = monthRent.multiply(new BigDecimal(3)); if (isCurrentQuarter(payFeesTime)) { rent = String.format("%.2f/%.2f", quarterRent, quarterRent); } else { rent = String.format("%.2f/%.2f", new BigDecimal("0"), quarterRent); } break; case "3": // 年付价格 BigDecimal yearRent = monthRent.multiply(new BigDecimal(12)); if (isCurrentYear(payFeesTime)) { rent = String.format("%.2f/%.2f", yearRent, yearRent); } else { rent = String.format("%.2f/%.2f", new BigDecimal("0"), yearRent); } break; } houseMapDistributionVO.setRent(rent); houseMapDistributionVO.setLongitude(house.getLongitude()); houseMapDistributionVO.setLatitude(house.getLatitude()); result.add(houseMapDistributionVO); } return R.ok(result); } /** * 判断是否是当前月份 * @param dateTime 日期时间 * @return boolean */ public static boolean isCurrentMonth(LocalDateTime dateTime) { YearMonth currentYearMonth = YearMonth.now(); YearMonth targetYearMonth = YearMonth.from(dateTime); return currentYearMonth.equals(targetYearMonth); } public static boolean isCurrentQuarter(LocalDateTime dateTime) { int currentMonth = LocalDateTime.now().getMonthValue(); int targetMonth = dateTime.getMonthValue(); // 计算当前季度和目标时间所属季度 int currentQuarter = (currentMonth - 1) / 3 + 1; int targetQuarter = (targetMonth - 1) / 3 + 1; return LocalDateTime.now().getYear() == dateTime.getYear() && currentQuarter == targetQuarter; } public static boolean isCurrentYear(LocalDateTime dateTime) { return LocalDateTime.now().getYear() == dateTime.getYear(); } }