package com.doumee.service.business.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.model.PageData; import com.doumee.core.model.PageWrap; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.utils.Constants; import com.doumee.core.utils.Utils; import com.doumee.dao.business.YwContractBillMapper; import com.doumee.dao.business.YwContractDetailMapper; import com.doumee.dao.business.YwContractMapper; import com.doumee.dao.business.YwContractRevenueMapper; import com.doumee.dao.business.YwContractRoomMapper; import com.doumee.dao.business.YwCustomerElectricalMapper; import com.doumee.dao.business.YwCustomerMapper; import com.doumee.dao.business.YwElectricalMapper; import com.doumee.dao.business.YwRoomMapper; import com.doumee.dao.business.dto.YwCustomerRechargeElectricalDTO; import com.doumee.dao.business.dto.YwCustomerRechargeDetailVO; import com.doumee.dao.business.dto.YwCustomerRechargeRecordQueryDTO; import com.doumee.dao.business.dto.YwCustomerRechargeRecordVO; import com.doumee.dao.business.dto.h5.*; import com.doumee.dao.business.model.*; import com.doumee.dao.system.MultifileMapper; import com.doumee.dao.system.model.Multifile; import com.doumee.service.business.YwCustomerDeviceAutoBindService; import com.doumee.service.business.YwCustomerH5AuthService; import com.doumee.service.business.YwCustomerH5BizService; import com.doumee.service.business.YwCustomerRechargeBizService; import com.doumee.service.business.YwElectricalBizService; import com.doumee.service.business.YwH5BannerService; import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @Service public class YwCustomerH5BizServiceImpl implements YwCustomerH5BizService { private static final int BILL_DUE_SOON_DAYS = 7; @Autowired private YwH5BannerService ywH5BannerService; @Autowired private YwCustomerMapper ywCustomerMapper; @Autowired private YwCustomerRechargeBizService ywCustomerRechargeBizService; @Autowired private YwCustomerDeviceAutoBindService ywCustomerDeviceAutoBindService; @Autowired private YwCustomerElectricalMapper ywCustomerElectricalMapper; @Autowired private YwElectricalMapper ywElectricalMapper; @Autowired private YwElectricalBizService ywElectricalBizService; @Autowired private YwContractMapper ywContractMapper; @Autowired private YwContractDetailMapper ywContractDetailMapper; @Autowired private YwContractBillMapper ywContractBillMapper; @Autowired private YwContractRevenueMapper ywContractRevenueMapper; @Autowired private YwContractRoomMapper ywContractRoomMapper; @Autowired private YwRoomMapper ywRoomMapper; @Autowired private MultifileMapper multifileMapper; @Autowired private SystemDictDataBiz systemDictDataBiz; @Autowired private YwCustomerH5AuthService ywCustomerH5AuthService; @Override public List listBanners() { return ywH5BannerService.listEnabledForCustomerWorkbench(); } @Override public Map home(Integer customerId, Integer memberId) { YwCustomer customer = requireCustomer(customerId); LoginUserInfo loginUser = ywCustomerH5AuthService.buildLoginUserInfo(customerId, memberId); YwCustomerRechargeDetailVO detail = ywCustomerRechargeBizService.getDetail(customerId); Map map = new LinkedHashMap<>(); map.put("customerName", loginUser.getCustomerName() != null ? loginUser.getCustomerName() : customer.getName()); map.put("memberName", loginUser.getMemberName()); map.put("displayName", loginUser.getDisplayName()); map.put("electricalCount", detail.getElectricalList() != null ? detail.getElectricalList().size() : 0); map.put("conditionerCount", detail.getConditionerList() != null ? detail.getConditionerList().size() : 0); map.put("gsConfig", detail.getGsConfig()); map.put("electricalList", detail.getElectricalList()); return map; } @Override public PageData devicePage(PageWrap pageWrap, Integer customerId) { requireCustomer(customerId); ywCustomerDeviceAutoBindService.refreshCustomerDevices(customerId, systemUser()); CustomerDeviceQueryDTO q = pageWrap.getModel() != null ? pageWrap.getModel() : new CustomerDeviceQueryDTO(); List all = new ArrayList<>(); if (q.getDeviceType() == null || q.getDeviceType() == 0) { all.addAll(buildElectricalDevices(customerId)); } if (q.getDeviceType() == null || q.getDeviceType() == 1) { all.addAll(buildConditionerDevices(customerId)); } if (q.getStatusFilter() != null) { all = all.stream().filter(d -> matchDeviceStatus(d, q.getStatusFilter())).collect(Collectors.toList()); } int p = (int) Math.max(pageWrap.getPage(), 1); int size = (int) Math.max(pageWrap.getCapacity(), 10); int from = (p - 1) * size; int to = Math.min(from + size, all.size()); PageData data = new PageData<>(); data.setTotal(all.size()); data.setPage(p); data.setCapacity(size); data.setRecords(from >= all.size() ? Collections.emptyList() : all.subList(from, to)); return data; } @Override public CustomerDeviceH5VO deviceDetail(Integer deviceType, Integer deviceId, Integer customerId) { PageWrap pw = new PageWrap<>(); pw.setPage(1); pw.setCapacity(1000); CustomerDeviceQueryDTO q = new CustomerDeviceQueryDTO(); q.setDeviceType(deviceType); pw.setModel(q); return devicePage(pw, customerId).getRecords().stream() .filter(d -> Objects.equals(d.getDeviceType(), deviceType) && Objects.equals(d.getDeviceId(), deviceId)) .findFirst() .orElseThrow(() -> new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "设备不存在")); } @Override public PageData rechargeRecordPage(PageWrap pageWrap, Integer customerId) { PageWrap wrap = new PageWrap<>(); wrap.setPage(pageWrap.getPage()); wrap.setCapacity(pageWrap.getCapacity()); YwCustomerRechargeRecordQueryDTO model = new YwCustomerRechargeRecordQueryDTO(); model.setCustomerId(customerId); CustomerRechargeRecordH5QueryDTO q = pageWrap.getModel(); if (q != null) { model.setStatus(q.getStatus()); model.setCreateTimeBegin(q.getCreateTimeBegin()); model.setCreateTimeEnd(q.getCreateTimeEnd()); if (StringUtils.isNotBlank(q.getMonth())) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); Date start = sdf.parse(q.getMonth()); Calendar cal = Calendar.getInstance(); cal.setTime(start); cal.add(Calendar.MONTH, 1); model.setCreateTimeBegin(start); model.setCreateTimeEnd(cal.getTime()); } catch (Exception ignored) { } } } wrap.setModel(model); return ywCustomerRechargeBizService.findRechargeRecordPage(wrap); } @Override public PageData contractPage(PageWrap pageWrap, Integer customerId) { requireCustomer(customerId); IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); CustomerContractQueryDTO q = pageWrap.getModel(); QueryWrapper qw = new QueryWrapper<>(); qw.lambda() .eq(YwContract::getRenterId, customerId) .eq(YwContract::getIsdeleted, Constants.ZERO) .eq(q != null && q.getStatus() != null, YwContract::getStatus, q != null ? q.getStatus() : null) .orderByDesc(YwContract::getCreateDate); IPage result = ywContractMapper.selectPage(page, qw); enrichContractListForH5(result.getRecords()); return PageData.from(result); } @Override public Map contractDetail(Integer contractId, Integer customerId, Integer billType) { YwContract contract = requireCustomerContract(contractId, customerId); enrichContractForH5(contract, true); int type = billType != null ? billType : Constants.ZERO; Map map = new LinkedHashMap<>(); map.put("contract", contract); map.put("bills", listContractBillsForH5(contractId, type)); map.put("billType", type); return map; } @Override public PageData billPage(PageWrap pageWrap, Integer customerId) { List contractIds = listCustomerContractIds(customerId); if (contractIds.isEmpty()) { return emptyBillPage(pageWrap); } IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); CustomerBillQueryDTO q = pageWrap.getModel(); MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .selectAll(YwContractBill.class) .select(" ( select ifnull( sum( CASE WHEN t.bill_type = 0 and yw.REVENUE_TYPE = 0 THEN yw.ACT_RECEIVABLE_FEE when t.bill_type = 0 and yw.REVENUE_TYPE = 1 then -yw.ACT_RECEIVABLE_FEE when t.bill_type = 1 and yw.REVENUE_TYPE = 0 then -yw.ACT_RECEIVABLE_FEE else yw.ACT_RECEIVABLE_FEE END),0) from yw_contract_revenue yw where yw.bill_id = t.id and yw.status = 0 and yw.isdeleted = 0 ) as actReceivableFee ") .in(YwContractBill::getContractId, contractIds) .eq(YwContractBill::getIsdeleted, Constants.ZERO) .eq(YwContractBill::getBillType, Constants.ZERO); if (q != null && q.getPayTab() != null) { if (q.getPayTab() == 0) { wrapper.in(YwContractBill::getPayStatus, Arrays.asList(Constants.ZERO, Constants.TWO, Constants.THREE)); } else if (q.getPayTab() == 1) { wrapper.eq(YwContractBill::getPayStatus, Constants.ONE); } } if (q != null && q.getCostType() != null) { wrapper.eq(YwContractBill::getCostType, q.getCostType()); } wrapper.orderByDesc(YwContractBill::getPlanPayDate); IPage result = ywContractBillMapper.selectJoinPage(page, YwContractBill.class, wrapper); enrichBillsWithContract(result.getRecords()); return PageData.from(result); } @Override public Map billDetail(Integer billId, Integer customerId) { YwContractBill bill = ywContractBillMapper.selectById(billId); if (bill == null || Objects.equals(bill.getIsdeleted(), Constants.ONE)) { throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "账单不存在"); } requireCustomerContract(bill.getContractId(), customerId); enrichBillWithContract(bill); enrichBillWithRooms(bill); List revenues = listBillRevenues(billId, bill); BigDecimal paid = sumPaid(revenues, bill.getBillType()); BigDecimal needPay = bill.getReceivableFee() != null ? bill.getReceivableFee().subtract(paid) : BigDecimal.ZERO; bill.setActReceivableFee(paid); bill.setNeedReceivableFee(needPay); bill.setYwContractRevenueList(revenues); Map map = new LinkedHashMap<>(); map.put("bill", bill); map.put("revenues", revenues); map.put("paidAmount", paid); map.put("needPayAmount", needPay); return map; } @Override @Transactional(rollbackFor = Exception.class) public void applyFirstRechargeIfNeeded(Integer customerId, LoginUserInfo user) { YwCustomer customer = requireCustomer(customerId); if (Objects.equals(customer.getFirstRechargeDone(), Constants.ONE)) { return; } ywCustomerDeviceAutoBindService.refreshCustomerDevices(customerId, user != null ? user : systemUser()); List electricalIds = ywCustomerDeviceAutoBindService.listElectricalIdsByActiveContracts(customerId); for (Integer eid : electricalIds) { YwCustomerRechargeElectricalDTO dto = new YwCustomerRechargeElectricalDTO(); dto.setCustomerId(customerId); dto.setElectricalId(eid); dto.setResetAction("resetPrepay"); try { ywCustomerRechargeBizService.resetElectricalAccount(dto, user); } catch (Exception e) { // 已开户则跳过 } } try { ywCustomerRechargeBizService.cleanConditionerAccount(customerId, user); } catch (Exception ignored) { } ywCustomerMapper.update(null, new UpdateWrapper().lambda() .set(YwCustomer::getFirstRechargeDone, Constants.ONE) .set(YwCustomer::getEditDate, new Date()) .eq(YwCustomer::getId, customerId)); } private List buildElectricalDevices(Integer customerId) { List ids = ywCustomerDeviceAutoBindService.listElectricalIdsByActiveContracts(customerId); if (ids.isEmpty()) { return Collections.emptyList(); } List list = ywElectricalMapper.selectBatchIds(ids); ywElectricalBizService.enrichList(list); List vos = new ArrayList<>(); for (YwElectrical e : list) { if (e == null || Objects.equals(e.getIsdeleted(), Constants.ONE)) continue; CustomerDeviceH5VO vo = new CustomerDeviceH5VO(); vo.setDeviceType(0); vo.setDeviceId(e.getId()); vo.setDeviceName(e.getName()); vo.setMeterAccountNo(e.getParamId()); vo.setMeterAddress(e.getAddress()); vo.setRoomInfo(e.getRoomNames()); vo.setBalance(e.getBalance()); vo.setBalanceLow(e.getBalance() != null && e.getBalance().compareTo(new BigDecimal("50")) < 0); vo.setUpdateTime(e.getEditDate()); boolean online = Objects.equals(e.getOnline(), Constants.ONE); vo.setStatusCode(online ? 1 : 2); vo.setStatusText(online ? "正常" : "断电"); List alarms = new ArrayList<>(); if (!online) alarms.add("断电报警"); if (Boolean.TRUE.equals(vo.getBalanceLow())) alarms.add("余额不足二级报警"); vo.setAlarmTags(alarms); vos.add(vo); } return vos; } private List buildConditionerDevices(Integer customerId) { List list = ywCustomerRechargeBizService.listCustomerConditioner(new PageWrap<>(), customerId).getRecords(); if (CollectionUtils.isEmpty(list)) { return Collections.emptyList(); } YwCustomerGs gs = ywCustomerRechargeBizService.getCustomerGsConfig(customerId); List vos = new ArrayList<>(); for (YwConditioner c : list) { CustomerDeviceH5VO vo = new CustomerDeviceH5VO(); vo.setDeviceType(1); vo.setDeviceId(c.getId()); vo.setDeviceName(StringUtils.defaultIfBlank(c.getName(), c.getCode())); vo.setRoomInfo(c.getRoomName()); if (StringUtils.isNotBlank(c.getRoomName())) { vo.setRoomList(Collections.singletonList(c.getRoomName())); } vo.setBalance(gs != null ? gs.getLeftMoney() : null); boolean online = "在线".equals(c.getOnline()); vo.setStatusCode(online ? 1 : 2); vo.setStatusText(online ? "正常" : "离线"); vo.setUpdateTime(c.getLastSyncDate()); vos.add(vo); } return vos; } private boolean matchDeviceStatus(CustomerDeviceH5VO d, Integer filter) { if (filter == 1) return Objects.equals(d.getStatusCode(), 1); if (filter == 2) return Objects.equals(d.getStatusCode(), 2); return true; } private LoginUserInfo systemUser() { LoginUserInfo user = new LoginUserInfo(); user.setId(1); user.setRealname("system"); return user; } private YwCustomer requireCustomer(Integer customerId) { YwCustomer c = ywCustomerMapper.selectById(customerId); if (c == null || Objects.equals(c.getIsdeleted(), Constants.ONE)) { throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "商户不存在"); } return c; } private YwContract requireCustomerContract(Integer contractId, Integer customerId) { YwContract c = ywContractMapper.selectById(contractId); if (c == null || !Objects.equals(c.getRenterId(), customerId)) { throw new BusinessException(ResponseStatus.NOT_ALLOWED); } return c; } private List listCustomerContractIds(Integer customerId) { return ywContractMapper.selectList(new QueryWrapper().lambda() .eq(YwContract::getRenterId, customerId) .eq(YwContract::getIsdeleted, Constants.ZERO)) .stream().map(YwContract::getId).collect(Collectors.toList()); } private void enrichContractListForH5(List contracts) { if (CollectionUtils.isEmpty(contracts)) { return; } List contractIds = contracts.stream().map(YwContract::getId).collect(Collectors.toList()); Map> roomMap = loadContractRoomMap(contractIds); Map> billMap = loadContractBillMap(contractIds); for (YwContract contract : contracts) { List rooms = roomMap.getOrDefault(contract.getId(), Collections.emptyList()); applyRoomSummary(contract, rooms); contract.setPayTypeText(resolvePayTypeText(contract)); fillBillStatusTip(contract, billMap.getOrDefault(contract.getId(), Collections.emptyList())); } } private void enrichContractForH5(YwContract contract, boolean withFiles) { if (contract == null) { return; } Map> roomMap = loadContractRoomMap(Collections.singletonList(contract.getId())); applyRoomSummary(contract, roomMap.getOrDefault(contract.getId(), Collections.emptyList())); contract.setPayTypeText(resolvePayTypeText(contract)); contract.setFreeRentPeriod(resolveFreeRentPeriod(contract)); initContractDetails(contract); fillBillStatusTip(contract, loadContractBillMap(Collections.singletonList(contract.getId())) .getOrDefault(contract.getId(), Collections.emptyList())); if (withFiles) { initContractFiles(contract); } } private Map> loadContractRoomMap(List contractIds) { if (CollectionUtils.isEmpty(contractIds)) { return Collections.emptyMap(); } List contractRooms = ywContractRoomMapper.selectList(new QueryWrapper().lambda() .in(YwContractRoom::getContractId, contractIds) .eq(YwContractRoom::getType, Constants.ZERO) .eq(YwContractRoom::getIsdeleted, Constants.ZERO)); if (contractRooms.isEmpty()) { return Collections.emptyMap(); } List roomIds = contractRooms.stream().map(YwContractRoom::getRoomId).distinct().collect(Collectors.toList()); Map roomById = loadRoomsWithNames(roomIds).stream() .collect(Collectors.toMap(YwRoom::getId, r -> r, (a, b) -> a)); Map> result = new HashMap<>(); for (YwContractRoom cr : contractRooms) { YwRoom room = roomById.get(cr.getRoomId()); if (room != null) { result.computeIfAbsent(cr.getContractId(), k -> new ArrayList<>()).add(room); } } return result; } private List loadRoomsWithNames(List roomIds) { if (CollectionUtils.isEmpty(roomIds)) { return Collections.emptyList(); } MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .selectAll(YwRoom.class) .selectAs(YwProject::getName, YwRoom::getProjectName) .selectAs(YwFloor::getName, YwRoom::getFloorName) .selectAs(YwBuilding::getName, YwRoom::getBuildingName) .leftJoin(YwProject.class, YwProject::getId, YwRoom::getProjectId) .leftJoin(YwBuilding.class, YwBuilding::getId, YwRoom::getBuildingId) .leftJoin(YwFloor.class, YwFloor::getId, YwRoom::getFloor) .in(YwRoom::getId, roomIds) .eq(YwRoom::getIsdeleted, Constants.ZERO); return ywRoomMapper.selectJoinList(YwRoom.class, wrapper); } private void applyRoomSummary(YwContract contract, List rooms) { contract.setRoomList(rooms); contract.setRoomInfo(buildRoomInfo(rooms)); BigDecimal totalArea = BigDecimal.ZERO; if (!CollectionUtils.isEmpty(rooms)) { for (YwRoom room : rooms) { totalArea = totalArea.add(Constants.formatBigdecimal(room.getRentArea())); } } contract.setTotalArea(totalArea); } private String buildRoomInfo(List rooms) { if (CollectionUtils.isEmpty(rooms)) { return ""; } return rooms.stream().map(this::formatRoomLine).filter(StringUtils::isNotBlank).collect(Collectors.joining("、")); } private String formatRoomLine(YwRoom room) { if (room == null) { return ""; } StringBuilder sb = new StringBuilder(); if (StringUtils.isNotBlank(room.getProjectName())) { sb.append(room.getProjectName()); } if (StringUtils.isNotBlank(room.getBuildingName())) { if (sb.length() > 0) { sb.append("/"); } sb.append(room.getBuildingName()); } if (StringUtils.isNotBlank(room.getFloorName()) || StringUtils.isNotBlank(room.getRoomNum())) { if (sb.length() > 0) { sb.append("/"); } sb.append(StringUtils.defaultString(room.getFloorName())).append("/").append(StringUtils.defaultString(room.getRoomNum())); } return sb.toString(); } private String resolvePayTypeText(YwContract contract) { Integer type = contract.getType() == null ? Constants.ZERO : contract.getType(); if (Objects.equals(type, Constants.ONE)) { return formatPayType(contract.getWyPayType()); } if (Objects.equals(type, Constants.TWO)) { return formatPayType(contract.getZlPayType()); } String zl = formatPayType(contract.getZlPayType()); String wy = formatPayType(contract.getWyPayType()); if (StringUtils.isBlank(wy) || StringUtils.equals(zl, wy)) { return zl; } return "租赁" + zl + ";物业" + wy; } private String formatPayType(Integer payType) { if (payType == null) { return "-"; } if (Objects.equals(payType, Constants.ONE)) { return "每三个月一付"; } if (Objects.equals(payType, Constants.TWO)) { return "六个月一付"; } if (Objects.equals(payType, Constants.THREE)) { return "一年一付"; } return "一次性付款"; } private String resolveFreeRentPeriod(YwContract contract) { Date start; Date end; if (Objects.equals(contract.getType(), Constants.ONE)) { start = contract.getWyFreeStartDate(); end = contract.getWyFreeEndDate(); } else { start = contract.getZlFreeStartDate(); end = contract.getZlFreeEndDate(); } if (start == null && end == null) { return "-"; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String startText = start != null ? sdf.format(start) : "-"; String endText = end != null ? sdf.format(end) : "-"; return startText + " ~ " + endText; } private Map> loadContractBillMap(List contractIds) { if (CollectionUtils.isEmpty(contractIds)) { return Collections.emptyMap(); } List bills = ywContractBillMapper.selectList(new QueryWrapper().lambda() .in(YwContractBill::getContractId, contractIds) .eq(YwContractBill::getIsdeleted, Constants.ZERO) .orderByDesc(YwContractBill::getPlanPayDate)); return bills.stream().collect(Collectors.groupingBy(YwContractBill::getContractId)); } private void fillBillStatusTip(YwContract contract, List bills) { int overdue = 0; int dueSoon = 0; long now = System.currentTimeMillis(); Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, BILL_DUE_SOON_DAYS); long dueSoonLimit = Utils.Date.getDayEnd(cal.getTime()).getTime(); for (YwContractBill bill : bills) { if (!isBillCountable(bill) || !isBillUnpaid(bill) || bill.getPlanPayDate() == null) { continue; } long planEnd = Utils.Date.getEnd(bill.getPlanPayDate()).getTime(); if (planEnd < now) { overdue++; } else if (planEnd <= dueSoonLimit) { dueSoon++; } } if (overdue > 0) { contract.setBillStatusTip(overdue + "个账单已逾期,请尽快支付"); contract.setBillStatusType("danger"); } else if (dueSoon > 0) { contract.setBillStatusTip(dueSoon + "个账单即将到期,请及时支付"); contract.setBillStatusType("warn"); } else { contract.setBillStatusTip("账单都按时缴费了,很棒!"); contract.setBillStatusType("ok"); } } private boolean isBillCountable(YwContractBill bill) { if (bill == null || Objects.equals(bill.getIsdeleted(), Constants.ONE)) { return false; } if (!Constants.equalsInteger(bill.getStatus(), Constants.ZERO)) { return false; } return bill.getReceivableFee() != null && bill.getReceivableFee().compareTo(BigDecimal.ZERO) > 0; } private boolean isBillUnpaid(YwContractBill bill) { Integer payStatus = bill.getPayStatus(); if (Constants.equalsInteger(payStatus, Constants.ONE) || Constants.equalsInteger(payStatus, Constants.FIVE)) { return false; } return Constants.equalsInteger(payStatus, Constants.ZERO) || Constants.equalsInteger(payStatus, Constants.TWO) || Constants.equalsInteger(payStatus, Constants.THREE) || Constants.equalsInteger(payStatus, Constants.FOUR); } private void initContractDetails(YwContract contract) { if (contract == null || contract.getId() == null) { return; } contract.setZlDetailList(ywContractDetailMapper.selectJoinList(YwContractDetail.class, new MPJLambdaWrapper() .selectAll(YwContractDetail.class) .eq(YwContractDetail::getIsdeleted, Constants.ZERO) .eq(YwContractDetail::getContractId, contract.getId()) .in(YwContractDetail::getType, Constants.ZERO, Constants.TWO) .orderByAsc(YwContractDetail::getSortnum))); contract.setWyDetailList(ywContractDetailMapper.selectJoinList(YwContractDetail.class, new MPJLambdaWrapper() .selectAll(YwContractDetail.class) .eq(YwContractDetail::getIsdeleted, Constants.ZERO) .eq(YwContractDetail::getContractId, contract.getId()) .in(YwContractDetail::getType, Constants.ONE, Constants.THREE) .orderByAsc(YwContractDetail::getSortnum))); } private void initContractFiles(YwContract contract) { List multifiles = multifileMapper.selectJoinList(Multifile.class, new MPJLambdaWrapper() .selectAll(Multifile.class) .eq(Multifile::getObjId, contract.getId()) .eq(Multifile::getObjType, Constants.MultiFile.YW_CONTRACT_FILE.getKey()) .eq(Multifile::getIsdeleted, Constants.ZERO) .orderByAsc(Multifile::getSortnum)); if (CollectionUtils.isEmpty(multifiles)) { contract.setFileList(Collections.emptyList()); return; } String path = systemDictDataBiz.queryByCode(Constants.FTP, Constants.FTP_RESOURCE_PATH).getCode() + systemDictDataBiz.queryByCode(Constants.FTP, Constants.YW_CONTRACT_FILE).getCode(); List fileList = new ArrayList<>(); for (Multifile file : multifiles) { if (StringUtils.isBlank(file.getFileurl())) { continue; } file.setFileurlFull(path + file.getFileurl()); fileList.add(file); } contract.setFileList(fileList); } private void enrichBillsWithContract(List bills) { if (CollectionUtils.isEmpty(bills)) { return; } List contractIds = bills.stream() .map(YwContractBill::getContractId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); if (contractIds.isEmpty()) { return; } Map contractMap = ywContractMapper.selectBatchIds(contractIds).stream() .filter(Objects::nonNull) .collect(Collectors.toMap(YwContract::getId, c -> c, (a, b) -> a)); for (YwContractBill bill : bills) { applyContractToBill(bill, contractMap.get(bill.getContractId())); } } private void enrichBillWithContract(YwContractBill bill) { if (bill == null || bill.getContractId() == null) { return; } YwContract contract = ywContractMapper.selectById(bill.getContractId()); applyContractToBill(bill, contract); if (contract != null && contract.getRenterId() != null) { YwCustomer customer = ywCustomerMapper.selectById(contract.getRenterId()); if (customer != null) { bill.setCustomerName(customer.getName()); } } } private void enrichBillWithRooms(YwContractBill bill) { if (bill == null || bill.getContractId() == null) { return; } List rooms = loadContractRoomMap(Collections.singletonList(bill.getContractId())) .getOrDefault(bill.getContractId(), Collections.emptyList()); bill.setRoomList(rooms); bill.setRoomInfo(buildRoomInfo(rooms)); } private void applyContractToBill(YwContractBill bill, YwContract contract) { if (bill == null || contract == null) { return; } bill.setContractCode(contract.getCode()); bill.setContractStartDate(contract.getStartDate()); bill.setContractEndDate(contract.getEndDate()); } private List listContractBillsForH5(Integer contractId, Integer billType) { List bills = ywContractBillMapper.selectJoinList(YwContractBill.class, new MPJLambdaWrapper() .selectAll(YwContractBill.class) .select(" ( select ifnull( sum( CASE WHEN t.bill_type = 0 and yw.REVENUE_TYPE = 0 THEN yw.ACT_RECEIVABLE_FEE when t.bill_type = 0 and yw.REVENUE_TYPE = 1 then -yw.ACT_RECEIVABLE_FEE when t.bill_type = 1 and yw.REVENUE_TYPE = 0 then -yw.ACT_RECEIVABLE_FEE else yw.ACT_RECEIVABLE_FEE END),0) from yw_contract_revenue yw where yw.bill_id = t.id and yw.status = 0 and yw.isdeleted = 0 ) as actReceivableFee ") .eq(YwContractBill::getIsdeleted, Constants.ZERO) .eq(YwContractBill::getStatus, Constants.ZERO) .eq(YwContractBill::getContractId, contractId) .eq(YwContractBill::getBillType, billType != null ? billType : Constants.ZERO) .orderByDesc(YwContractBill::getPlanPayDate) .orderByDesc(YwContractBill::getId)); enrichContractBillsForH5(bills); return bills; } private void enrichContractBillsForH5(List bills) { if (CollectionUtils.isEmpty(bills)) { return; } for (YwContractBill bill : bills) { if (bill.getReceivableFee() != null && bill.getActReceivableFee() != null) { bill.setNeedReceivableFee(bill.getReceivableFee().subtract(bill.getActReceivableFee())); } if (Constants.equalsInteger(bill.getStatus(), Constants.ZERO) && (Constants.equalsInteger(bill.getPayStatus(), Constants.ZERO) || Constants.equalsInteger(bill.getPayStatus(), Constants.TWO) || Constants.equalsInteger(bill.getPayStatus(), Constants.THREE) || Constants.equalsInteger(bill.getPayStatus(), Constants.FOUR)) && bill.getPlanPayDate() != null && Utils.Date.getEnd(bill.getPlanPayDate()).getTime() < System.currentTimeMillis()) { bill.setIsOverdue(Constants.ONE); } else { bill.setIsOverdue(Constants.ZERO); } } } /** * 与 PC 端收支流水一致:经账单关联合同承租人,填充对方单位名称 */ private List listBillRevenues(Integer billId, YwContractBill bill) { List revenues = ywContractRevenueMapper.selectJoinList(YwContractRevenue.class, new MPJLambdaWrapper() .selectAll(YwContractRevenue.class) .selectAs(YwCustomer::getName, YwContractRevenue::getCustomerName) .leftJoin(YwContractBill.class, YwContractBill::getId, YwContractRevenue::getBillId) .leftJoin(YwContract.class, YwContract::getId, YwContractBill::getContractId) .leftJoin(YwCustomer.class, YwCustomer::getId, YwContract::getRenterId) .eq(YwContractRevenue::getStatus, Constants.ZERO) .eq(YwContractRevenue::getBillId, billId) .orderByDesc(YwContractRevenue::getId)); fillRevenueCustomerNames(revenues, bill); return revenues; } private void fillRevenueCustomerNames(List revenues, YwContractBill bill) { if (CollectionUtils.isEmpty(revenues) || bill == null || StringUtils.isBlank(bill.getCustomerName())) { return; } for (YwContractRevenue revenue : revenues) { if (StringUtils.isBlank(revenue.getCustomerName())) { revenue.setCustomerName(bill.getCustomerName()); } } } private BigDecimal sumPaid(List revenues, Integer billType) { if (CollectionUtils.isEmpty(revenues)) return BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; for (YwContractRevenue r : revenues) { if (r.getActReceivableFee() == null) continue; int sign = Constants.equalsInteger(r.getRevenueType(), Constants.ZERO) ? 1 : -1; if (Constants.equalsInteger(billType, Constants.ONE)) sign = -sign; total = total.add(r.getActReceivableFee().multiply(BigDecimal.valueOf(sign))); } return total; } private PageData emptyBillPage(PageWrap pageWrap) { PageData data = new PageData<>(); data.setRecords(Collections.emptyList()); data.setTotal(0); data.setPage(pageWrap.getPage()); data.setCapacity(pageWrap.getCapacity()); return data; } }