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<YwH5Banner> listBanners() {
|
return ywH5BannerService.listEnabledForCustomerWorkbench();
|
}
|
|
@Override
|
public Map<String, Object> home(Integer customerId, Integer memberId) {
|
YwCustomer customer = requireCustomer(customerId);
|
LoginUserInfo loginUser = ywCustomerH5AuthService.buildLoginUserInfo(customerId, memberId);
|
YwCustomerRechargeDetailVO detail = ywCustomerRechargeBizService.getDetail(customerId);
|
Map<String, Object> 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<CustomerDeviceH5VO> devicePage(PageWrap<CustomerDeviceQueryDTO> pageWrap, Integer customerId) {
|
requireCustomer(customerId);
|
ywCustomerDeviceAutoBindService.refreshCustomerDevices(customerId, systemUser());
|
CustomerDeviceQueryDTO q = pageWrap.getModel() != null ? pageWrap.getModel() : new CustomerDeviceQueryDTO();
|
List<CustomerDeviceH5VO> 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<CustomerDeviceH5VO> 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<CustomerDeviceQueryDTO> 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<YwCustomerRechargeRecordVO> rechargeRecordPage(PageWrap<CustomerRechargeRecordH5QueryDTO> pageWrap, Integer customerId) {
|
PageWrap<YwCustomerRechargeRecordQueryDTO> 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<YwContract> contractPage(PageWrap<CustomerContractQueryDTO> pageWrap, Integer customerId) {
|
requireCustomer(customerId);
|
IPage<YwContract> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
|
CustomerContractQueryDTO q = pageWrap.getModel();
|
QueryWrapper<YwContract> 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<YwContract> result = ywContractMapper.selectPage(page, qw);
|
enrichContractListForH5(result.getRecords());
|
return PageData.from(result);
|
}
|
|
@Override
|
public Map<String, Object> contractDetail(Integer contractId, Integer customerId, Integer billType) {
|
YwContract contract = requireCustomerContract(contractId, customerId);
|
enrichContractForH5(contract, true);
|
int type = billType != null ? billType : Constants.ZERO;
|
Map<String, Object> map = new LinkedHashMap<>();
|
map.put("contract", contract);
|
map.put("bills", listContractBillsForH5(contractId, type));
|
map.put("billType", type);
|
return map;
|
}
|
|
@Override
|
public PageData<YwContractBill> billPage(PageWrap<CustomerBillQueryDTO> pageWrap, Integer customerId) {
|
List<Integer> contractIds = listCustomerContractIds(customerId);
|
if (contractIds.isEmpty()) {
|
return emptyBillPage(pageWrap);
|
}
|
IPage<YwContractBill> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
|
CustomerBillQueryDTO q = pageWrap.getModel();
|
MPJLambdaWrapper<YwContractBill> wrapper = new MPJLambdaWrapper<YwContractBill>()
|
.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<YwContractBill> result = ywContractBillMapper.selectJoinPage(page, YwContractBill.class, wrapper);
|
enrichBillsWithContract(result.getRecords());
|
return PageData.from(result);
|
}
|
|
@Override
|
public Map<String, Object> 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<YwContractRevenue> 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<String, Object> 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<Integer> 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<YwCustomer>().lambda()
|
.set(YwCustomer::getFirstRechargeDone, Constants.ONE)
|
.set(YwCustomer::getEditDate, new Date())
|
.eq(YwCustomer::getId, customerId));
|
}
|
|
private List<CustomerDeviceH5VO> buildElectricalDevices(Integer customerId) {
|
List<Integer> ids = ywCustomerDeviceAutoBindService.listElectricalIdsByActiveContracts(customerId);
|
if (ids.isEmpty()) {
|
return Collections.emptyList();
|
}
|
List<YwElectrical> list = ywElectricalMapper.selectBatchIds(ids);
|
ywElectricalBizService.enrichList(list);
|
List<CustomerDeviceH5VO> 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<String> 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<CustomerDeviceH5VO> buildConditionerDevices(Integer customerId) {
|
List<YwConditioner> list = ywCustomerRechargeBizService.listCustomerConditioner(new PageWrap<>(), customerId).getRecords();
|
if (CollectionUtils.isEmpty(list)) {
|
return Collections.emptyList();
|
}
|
YwCustomerGs gs = ywCustomerRechargeBizService.getCustomerGsConfig(customerId);
|
List<CustomerDeviceH5VO> 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<Integer> listCustomerContractIds(Integer customerId) {
|
return ywContractMapper.selectList(new QueryWrapper<YwContract>().lambda()
|
.eq(YwContract::getRenterId, customerId)
|
.eq(YwContract::getIsdeleted, Constants.ZERO))
|
.stream().map(YwContract::getId).collect(Collectors.toList());
|
}
|
|
private void enrichContractListForH5(List<YwContract> contracts) {
|
if (CollectionUtils.isEmpty(contracts)) {
|
return;
|
}
|
List<Integer> contractIds = contracts.stream().map(YwContract::getId).collect(Collectors.toList());
|
Map<Integer, List<YwRoom>> roomMap = loadContractRoomMap(contractIds);
|
Map<Integer, List<YwContractBill>> billMap = loadContractBillMap(contractIds);
|
for (YwContract contract : contracts) {
|
List<YwRoom> 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<Integer, List<YwRoom>> 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<Integer, List<YwRoom>> loadContractRoomMap(List<Integer> contractIds) {
|
if (CollectionUtils.isEmpty(contractIds)) {
|
return Collections.emptyMap();
|
}
|
List<YwContractRoom> contractRooms = ywContractRoomMapper.selectList(new QueryWrapper<YwContractRoom>().lambda()
|
.in(YwContractRoom::getContractId, contractIds)
|
.eq(YwContractRoom::getType, Constants.ZERO)
|
.eq(YwContractRoom::getIsdeleted, Constants.ZERO));
|
if (contractRooms.isEmpty()) {
|
return Collections.emptyMap();
|
}
|
List<Integer> roomIds = contractRooms.stream().map(YwContractRoom::getRoomId).distinct().collect(Collectors.toList());
|
Map<Integer, YwRoom> roomById = loadRoomsWithNames(roomIds).stream()
|
.collect(Collectors.toMap(YwRoom::getId, r -> r, (a, b) -> a));
|
Map<Integer, List<YwRoom>> 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<YwRoom> loadRoomsWithNames(List<Integer> roomIds) {
|
if (CollectionUtils.isEmpty(roomIds)) {
|
return Collections.emptyList();
|
}
|
MPJLambdaWrapper<YwRoom> wrapper = new MPJLambdaWrapper<YwRoom>()
|
.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<YwRoom> 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<YwRoom> 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<Integer, List<YwContractBill>> loadContractBillMap(List<Integer> contractIds) {
|
if (CollectionUtils.isEmpty(contractIds)) {
|
return Collections.emptyMap();
|
}
|
List<YwContractBill> bills = ywContractBillMapper.selectList(new QueryWrapper<YwContractBill>().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<YwContractBill> 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<YwContractDetail>()
|
.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<YwContractDetail>()
|
.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<Multifile> multifiles = multifileMapper.selectJoinList(Multifile.class, new MPJLambdaWrapper<Multifile>()
|
.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<Multifile> 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<YwContractBill> bills) {
|
if (CollectionUtils.isEmpty(bills)) {
|
return;
|
}
|
List<Integer> contractIds = bills.stream()
|
.map(YwContractBill::getContractId)
|
.filter(Objects::nonNull)
|
.distinct()
|
.collect(Collectors.toList());
|
if (contractIds.isEmpty()) {
|
return;
|
}
|
Map<Integer, YwContract> 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<YwRoom> 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<YwContractBill> listContractBillsForH5(Integer contractId, Integer billType) {
|
List<YwContractBill> bills = ywContractBillMapper.selectJoinList(YwContractBill.class,
|
new MPJLambdaWrapper<YwContractBill>()
|
.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<YwContractBill> 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<YwContractRevenue> listBillRevenues(Integer billId, YwContractBill bill) {
|
List<YwContractRevenue> revenues = ywContractRevenueMapper.selectJoinList(YwContractRevenue.class, new MPJLambdaWrapper<YwContractRevenue>()
|
.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<YwContractRevenue> 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<YwContractRevenue> 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<YwContractBill> emptyBillPage(PageWrap<?> pageWrap) {
|
PageData<YwContractBill> data = new PageData<>();
|
data.setRecords(Collections.emptyList());
|
data.setTotal(0);
|
data.setPage(pageWrap.getPage());
|
data.setCapacity(pageWrap.getCapacity());
|
return data;
|
}
|
}
|