package com.ruoyi.web.controller.api; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; 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.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.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; import static org.checkerframework.checker.units.qual.Prefix.one; /** * @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") @ApiOperation(value = "租户数量趋势统计") public R> getTenantCountTrend() { String businessDeptId = SecurityUtils.getBusinessDeptId(); 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() .eq(!"0".equals(businessDeptId),TContract::getBusinessDeptId, businessDeptId) .isNotNull(TContract::getSignTime) .between(TContract::getSignTime, startQuarterDate.get("first"), endQuarterDate.get("last")) .orderByAsc(TContract::getSignTime)); DateTimeFormatter quarterFormatter = DateTimeFormatter.ofPattern("yyyy-MM"); 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") @ApiOperation("获取实时租赁数据") public R> getRealTimeRentData() { // 随机获取十条房源 String businessDeptId = SecurityUtils.getBusinessDeptId(); List houses = houseService.list(new LambdaQueryWrapper() .eq(!"0".equals(businessDeptId),THouse::getBusinessDeptId, businessDeptId) .last("ORDER BY RAND() LIMIT 10")); if (CollectionUtil.isEmpty(houses)){ return R.ok(new ArrayList<>()); } // 提取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.getHouseName()); vo.setLeaseStatus(house.getLeaseStatus()); return vo; }).collect(Collectors.toList()); return R.ok(result); } /** * 获取房屋地图分布 */ @GetMapping("/getHouseMapDistribution") @ApiOperation("获取房屋地图分布") public R> getHouseMapDistribution() { String businessDeptId = SecurityUtils.getBusinessDeptId(); // 获取所有房屋信息 List houses = houseService.list(new LambdaQueryWrapper() .eq(!"0".equals(businessDeptId),THouse::getBusinessDeptId, businessDeptId)); List result = new ArrayList<>(); for (THouse house : houses) { HouseMapDistributionVO houseMapDistributionVO = new HouseMapDistributionVO(); houseMapDistributionVO.setHouseName(house.getHouseName()); houseMapDistributionVO.setHouseAddress(house.getHouseAddress()); houseMapDistributionVO.setHouseStatus(house.getLeaseStatus()); houseMapDistributionVO.setLongitude(house.getLongitude()); houseMapDistributionVO.setLatitude(house.getLatitude()); TContract contract = contractService.getOne(new LambdaQueryWrapper() .eq(!"0".equals(businessDeptId),TContract::getBusinessDeptId, businessDeptId) .gt(TContract::getEndTime, LocalDate.now()) .eq(TContract::getHouseId, house.getId()) .eq(TContract::getStatus, 4) .last("limit 1")); if (contract != null){ List tBills = billService.list(new LambdaQueryWrapper() .eq(!"0".equals(businessDeptId),TBill::getBusinessDeptId, businessDeptId) .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 paidAlready = tBills.stream() .map(TBill::getPayableFeesMoney) .reduce(BigDecimal::add) .orElse(BigDecimal.ZERO); String rentStatus = String.format("%.2f/%.2f", paidAlready, payableFeesMoney); houseMapDistributionVO.setRentStatus(rentStatus); // TBill one = billService.getOne(new LambdaQueryWrapper() // .le(TBill::getStartTime, LocalDate.now()) // .ge(TBill::getEndTime, LocalDate.now()) // .eq(TBill::getBillType, 1) // .eq(TBill::getContractId, contract.getId())); List ones = billService.list(new LambdaQueryWrapper() .eq(!"0".equals(businessDeptId),TBill::getBusinessDeptId, businessDeptId) .le(TBill::getStartTime, LocalDate.now()) .ge(TBill::getEndTime, LocalDate.now()) .eq(TBill::getBillType, 1) .eq(TBill::getContractId, contract.getId())); TBill one = null; if (!ones.isEmpty()){ one = ones.get(0); } if (one != null){ if ("4".equals(one.getPayFeesStatus())){ houseMapDistributionVO.setHouseStatus("4"); } BigDecimal payFeesMoney = one.getPayFeesMoney(); BigDecimal payableFeesMoney1 = one.getPayableFeesMoney(); String rent = String.format("%.2f/%.2f", payFeesMoney, payableFeesMoney1); houseMapDistributionVO.setRent(rent); }else { houseMapDistributionVO.setRent("暂无"); } }else { houseMapDistributionVO.setTenant("暂无"); houseMapDistributionVO.setRentStatus("暂无"); houseMapDistributionVO.setRent("暂无"); } result.add(houseMapDistributionVO); } return R.ok(result); } }