From 93de43267e1663031fe5dc2f5ae40d128a182a76 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 18 六月 2026 17:24:51 +0800
Subject: [PATCH] 新增智能电表、空调管理
---
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerDeviceAutoBindServiceImpl.java | 281 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 237 insertions(+), 44 deletions(-)
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerDeviceAutoBindServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerDeviceAutoBindServiceImpl.java
index 07a3d71..3fdaadc 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerDeviceAutoBindServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerDeviceAutoBindServiceImpl.java
@@ -2,10 +2,10 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.Utils;
import com.doumee.dao.business.*;
import com.doumee.dao.business.dto.YwCustomerGsConfigDTO;
import com.doumee.dao.business.model.*;
@@ -13,6 +13,7 @@
import com.doumee.service.business.YwCustomerRechargeBizService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -40,6 +41,7 @@
@Autowired
private YwConditionerMapper ywConditionerMapper;
@Autowired
+ @Lazy
private YwCustomerRechargeBizService ywCustomerRechargeBizService;
@Override
@@ -49,38 +51,52 @@
return;
}
YwContract contract = ywContractMapper.selectById(contractId);
- if (contract == null || Objects.equals(contract.getIsdeleted(), Constants.ONE)) {
+ if (contract == null || Objects.equals(contract.getIsdeleted(), Constants.ONE) || contract.getRenterId() == null) {
return;
}
- if (contract.getRenterId() == null) {
- return;
- }
- if (!isActiveContract(contract)) {
- return;
- }
- List<Integer> roomIds = listContractRoomIds(contractId);
- if (roomIds.isEmpty()) {
- return;
- }
- bindElectricals(contract, roomIds, user);
- bindConditioners(contract, roomIds, user);
+ refreshCustomerDevices(contract.getRenterId(), user);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncByCustomerId(Integer customerId, LoginUserInfo user) {
+ refreshCustomerDevices(customerId, user);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void refreshCustomerDevices(Integer customerId, LoginUserInfo user) {
if (customerId == null) {
return;
}
+ LoginUserInfo opUser = user != null ? user : systemUser();
List<YwContract> contracts = ywContractMapper.selectList(new QueryWrapper<YwContract>().lambda()
.eq(YwContract::getRenterId, customerId)
- .eq(YwContract::getIsdeleted, Constants.ZERO)
- .in(YwContract::getStatus, Arrays.asList(Constants.ZERO, Constants.ONE, Constants.THREE)));
- for (YwContract c : contracts) {
- if (isActiveContract(c)) {
- syncByContractId(c.getId(), user);
+ .eq(YwContract::getIsdeleted, Constants.ZERO));
+ List<YwContract> activeContracts = contracts.stream().filter(this::isActiveContract).collect(Collectors.toList());
+ Set<Integer> activeContractIds = activeContracts.stream().map(YwContract::getId).collect(Collectors.toSet());
+
+ for (YwContract contract : contracts) {
+ if (!activeContractIds.contains(contract.getId())) {
+ unbindByContractId(contract.getId(), opUser);
}
}
+
+ Set<Integer> roomIds = new LinkedHashSet<>();
+ for (YwContract contract : activeContracts) {
+ roomIds.addAll(listContractRoomIds(contract.getId()));
+ }
+ if (roomIds.isEmpty()) {
+ clearContractElectricalBindings(customerId, opUser);
+ softDeleteAllConditionerRels(customerId, opUser);
+ return;
+ }
+
+ List<Integer> roomIdList = new ArrayList<>(roomIds);
+ for (YwContract contract : activeContracts) {
+ bindElectricals(contract, listContractRoomIds(contract.getId()), opUser);
+ }
+ bindConditionersMerged(customerId, roomIdList, opUser);
}
@Override
@@ -100,14 +116,153 @@
.eq(YwCustomerElectrical::getIsdeleted, Constants.ZERO));
}
+ @Override
+ public List<Integer> listActiveContractRoomIds(Integer customerId) {
+ if (customerId == null) {
+ return Collections.emptyList();
+ }
+ List<YwContract> active = listActiveContracts(customerId);
+ Set<Integer> roomIds = new LinkedHashSet<>();
+ for (YwContract contract : active) {
+ roomIds.addAll(listContractRoomIds(contract.getId()));
+ }
+ return new ArrayList<>(roomIds);
+ }
+
+ @Override
+ public List<Integer> listElectricalIdsByActiveContracts(Integer customerId) {
+ List<Integer> roomIds = listActiveContractRoomIds(customerId);
+ if (roomIds.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return new ArrayList<>(resolveElectricalIdsFromRooms(roomIds));
+ }
+
+ @Override
+ public List<Integer> listConditionerIdsByActiveContracts(Integer customerId) {
+ List<Integer> roomIds = listActiveContractRoomIds(customerId);
+ if (roomIds.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return new ArrayList<>(resolveConditionerIdsFromRooms(roomIds));
+ }
+
+ @Override
+ public Map<Integer, List<Integer>> batchListElectricalIdsByActiveContracts(List<Integer> customerIds) {
+ return batchResolveDeviceIds(customerIds, Constants.ZERO);
+ }
+
+ @Override
+ public Map<Integer, List<Integer>> batchListConditionerIdsByActiveContracts(List<Integer> customerIds) {
+ return batchResolveDeviceIds(customerIds, Constants.ONE);
+ }
+
+ private Map<Integer, List<Integer>> batchResolveDeviceIds(List<Integer> customerIds, int deviceType) {
+ if (CollectionUtils.isEmpty(customerIds)) {
+ return Collections.emptyMap();
+ }
+ Map<Integer, Set<Integer>> roomsByCustomer = batchActiveContractRoomIds(customerIds);
+ Set<Integer> allRoomIds = roomsByCustomer.values().stream()
+ .flatMap(Set::stream).collect(Collectors.toCollection(LinkedHashSet::new));
+ Map<Integer, Set<Integer>> devicesByRoom = mapDevicesByRoom(allRoomIds, deviceType);
+
+ Map<Integer, List<Integer>> result = new LinkedHashMap<>();
+ for (Integer customerId : customerIds) {
+ Set<Integer> roomIds = roomsByCustomer.getOrDefault(customerId, Collections.emptySet());
+ Set<Integer> deviceIds = new LinkedHashSet<>();
+ for (Integer roomId : roomIds) {
+ deviceIds.addAll(devicesByRoom.getOrDefault(roomId, Collections.emptySet()));
+ }
+ result.put(customerId, new ArrayList<>(deviceIds));
+ }
+ return result;
+ }
+
+ private Map<Integer, Set<Integer>> batchActiveContractRoomIds(List<Integer> customerIds) {
+ List<YwContract> contracts = ywContractMapper.selectList(new QueryWrapper<YwContract>().lambda()
+ .in(YwContract::getRenterId, customerIds)
+ .eq(YwContract::getIsdeleted, Constants.ZERO));
+ Map<Integer, List<YwContract>> activeByCustomer = contracts.stream()
+ .filter(this::isActiveContract)
+ .collect(Collectors.groupingBy(YwContract::getRenterId));
+
+ List<Integer> contractIds = activeByCustomer.values().stream()
+ .flatMap(List::stream).map(YwContract::getId).distinct().collect(Collectors.toList());
+ Map<Integer, List<Integer>> roomsByContract = loadContractRoomMap(contractIds);
+
+ Map<Integer, Set<Integer>> roomsByCustomer = new LinkedHashMap<>();
+ for (Integer customerId : customerIds) {
+ Set<Integer> roomIds = new LinkedHashSet<>();
+ for (YwContract contract : activeByCustomer.getOrDefault(customerId, Collections.emptyList())) {
+ roomIds.addAll(roomsByContract.getOrDefault(contract.getId(), Collections.emptyList()));
+ }
+ roomsByCustomer.put(customerId, roomIds);
+ }
+ return roomsByCustomer;
+ }
+
+ private Map<Integer, List<Integer>> loadContractRoomMap(List<Integer> contractIds) {
+ if (CollectionUtils.isEmpty(contractIds)) {
+ return Collections.emptyMap();
+ }
+ return ywContractRoomMapper.selectList(new QueryWrapper<YwContractRoom>().lambda()
+ .in(YwContractRoom::getContractId, contractIds)
+ .eq(YwContractRoom::getType, Constants.ZERO)
+ .eq(YwContractRoom::getIsdeleted, Constants.ZERO))
+ .stream()
+ .collect(Collectors.groupingBy(YwContractRoom::getContractId,
+ Collectors.mapping(YwContractRoom::getRoomId,
+ Collectors.collectingAndThen(Collectors.toList(),
+ list -> list.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList())))));
+ }
+
+ private Map<Integer, Set<Integer>> mapDevicesByRoom(Set<Integer> roomIds, int deviceType) {
+ if (CollectionUtils.isEmpty(roomIds)) {
+ return Collections.emptyMap();
+ }
+ List<Integer> roomIdList = new ArrayList<>(roomIds);
+ Map<Integer, Set<Integer>> result = new HashMap<>();
+ List<YwElectricalRoom> relRooms = ywElectricalRoomMapper.selectList(new QueryWrapper<YwElectricalRoom>().lambda()
+ .in(YwElectricalRoom::getRoomId, roomIdList)
+ .eq(YwElectricalRoom::getType, deviceType)
+ .eq(YwElectricalRoom::getIsdeleted, Constants.ZERO));
+ for (YwElectricalRoom rel : relRooms) {
+ if (rel.getRoomId() == null || rel.getObjId() == null) {
+ continue;
+ }
+ result.computeIfAbsent(rel.getRoomId(), k -> new LinkedHashSet<>()).add(rel.getObjId());
+ }
+ if (deviceType == Constants.ONE) {
+ List<YwConditioner> byRoom = ywConditionerMapper.selectList(new QueryWrapper<YwConditioner>().lambda()
+ .in(YwConditioner::getRoomId, roomIdList)
+ .eq(YwConditioner::getIsdeleted, Constants.ZERO));
+ for (YwConditioner conditioner : byRoom) {
+ if (conditioner.getRoomId() == null || conditioner.getId() == null) {
+ continue;
+ }
+ result.computeIfAbsent(conditioner.getRoomId(), k -> new LinkedHashSet<>()).add(conditioner.getId());
+ }
+ }
+ return result;
+ }
+
+ private List<YwContract> listActiveContracts(Integer customerId) {
+ return ywContractMapper.selectList(new QueryWrapper<YwContract>().lambda()
+ .eq(YwContract::getRenterId, customerId)
+ .eq(YwContract::getIsdeleted, Constants.ZERO))
+ .stream().filter(this::isActiveContract).collect(Collectors.toList());
+ }
+
private boolean isActiveContract(YwContract contract) {
- if (contract.getStartDate() == null || contract.getEndDate() == null) {
+ if (contract == null || contract.getStartDate() == null || contract.getEndDate() == null) {
+ return false;
+ }
+ if (Objects.equals(contract.getStatus(), Constants.FOUR)) {
return false;
}
long now = System.currentTimeMillis();
return contract.getStartDate().getTime() <= now
- && contract.getEndDate().getTime() >= now
- && !Objects.equals(contract.getStatus(), Constants.FOUR);
+ && Utils.Date.getEnd(contract.getEndDate()).getTime() >= now;
}
private List<Integer> listContractRoomIds(Integer contractId) {
@@ -119,13 +274,39 @@
.collect(Collectors.toList());
}
- private void bindElectricals(YwContract contract, List<Integer> roomIds, LoginUserInfo user) {
- List<YwElectricalRoom> relRooms = ywElectricalRoomMapper.selectList(new QueryWrapper<YwElectricalRoom>().lambda()
+ private Set<Integer> resolveElectricalIdsFromRooms(List<Integer> roomIds) {
+ if (CollectionUtils.isEmpty(roomIds)) {
+ return Collections.emptySet();
+ }
+ return ywElectricalRoomMapper.selectList(new QueryWrapper<YwElectricalRoom>().lambda()
+ .in(YwElectricalRoom::getRoomId, roomIds)
+ .eq(YwElectricalRoom::getType, Constants.ZERO)
+ .eq(YwElectricalRoom::getIsdeleted, Constants.ZERO))
+ .stream().map(YwElectricalRoom::getObjId).filter(Objects::nonNull)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
+ private Set<Integer> resolveConditionerIdsFromRooms(List<Integer> roomIds) {
+ if (CollectionUtils.isEmpty(roomIds)) {
+ return Collections.emptySet();
+ }
+ Set<Integer> conditionerIds = new LinkedHashSet<>();
+ List<YwElectricalRoom> acRooms = ywElectricalRoomMapper.selectList(new QueryWrapper<YwElectricalRoom>().lambda()
.in(YwElectricalRoom::getRoomId, roomIds)
- .eq(YwElectricalRoom::getType, Constants.ZERO)
+ .eq(YwElectricalRoom::getType, Constants.ONE)
.eq(YwElectricalRoom::getIsdeleted, Constants.ZERO));
- Set<Integer> electricalIds = relRooms.stream().map(YwElectricalRoom::getObjId)
- .filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));
+ acRooms.stream().map(YwElectricalRoom::getObjId).filter(Objects::nonNull).forEach(conditionerIds::add);
+ if (conditionerIds.isEmpty()) {
+ ywConditionerMapper.selectList(new QueryWrapper<YwConditioner>().lambda()
+ .in(YwConditioner::getRoomId, roomIds)
+ .eq(YwConditioner::getIsdeleted, Constants.ZERO))
+ .stream().map(YwConditioner::getId).filter(Objects::nonNull).forEach(conditionerIds::add);
+ }
+ return conditionerIds;
+ }
+
+ private void bindElectricals(YwContract contract, List<Integer> roomIds, LoginUserInfo user) {
+ Set<Integer> electricalIds = resolveElectricalIdsFromRooms(roomIds);
if (electricalIds.isEmpty()) {
return;
}
@@ -142,7 +323,8 @@
.eq(YwCustomerElectrical::getIsdeleted, Constants.ZERO)
.last("limit 1"));
if (exist != null) {
- if (exist.getContractId() == null) {
+ if (!Objects.equals(exist.getContractId(), contract.getId())
+ || !Objects.equals(exist.getBindSource(), BIND_SOURCE_CONTRACT)) {
exist.setContractId(contract.getId());
exist.setBindSource(BIND_SOURCE_CONTRACT);
exist.setEditDate(now);
@@ -165,24 +347,14 @@
}
}
- private void bindConditioners(YwContract contract, List<Integer> roomIds, LoginUserInfo user) {
- Set<Integer> conditionerIds = new LinkedHashSet<>();
- List<YwElectricalRoom> acRooms = ywElectricalRoomMapper.selectList(new QueryWrapper<YwElectricalRoom>().lambda()
- .in(YwElectricalRoom::getRoomId, roomIds)
- .eq(YwElectricalRoom::getType, Constants.ONE)
- .eq(YwElectricalRoom::getIsdeleted, Constants.ZERO));
- acRooms.stream().map(YwElectricalRoom::getObjId).filter(Objects::nonNull).forEach(conditionerIds::add);
+ private void bindConditionersMerged(Integer customerId, List<Integer> roomIds, LoginUserInfo user) {
+ Set<Integer> conditionerIds = resolveConditionerIdsFromRooms(roomIds);
if (conditionerIds.isEmpty()) {
- List<YwConditioner> byRoom = ywConditionerMapper.selectList(new QueryWrapper<YwConditioner>().lambda()
- .in(YwConditioner::getRoomId, roomIds)
- .eq(YwConditioner::getIsdeleted, Constants.ZERO));
- byRoom.stream().map(YwConditioner::getId).forEach(conditionerIds::add);
- }
- if (conditionerIds.isEmpty()) {
+ softDeleteAllConditionerRels(customerId, user);
return;
}
YwCustomerGsConfigDTO dto = new YwCustomerGsConfigDTO();
- dto.setCustomerId(contract.getRenterId());
+ dto.setCustomerId(customerId);
dto.setIsPwr(Constants.ONE);
dto.setIsRestStop(Constants.ZERO);
dto.setGsBz("鍚堝悓鑷姩鍏宠仈");
@@ -196,12 +368,33 @@
}
dto.setConditioners(items);
try {
- ywCustomerRechargeBizService.saveCustomerGsConfig(dto, user != null ? user : systemUser());
+ ywCustomerRechargeBizService.saveCustomerGsConfig(dto, user);
} catch (BusinessException e) {
- log.warn("auto bind conditioner GS failed contractId={}: {}", contract.getId(), e.getMessage());
+ log.warn("auto bind conditioner GS failed customerId={}: {}", customerId, e.getMessage());
}
}
+ private void clearContractElectricalBindings(Integer customerId, LoginUserInfo user) {
+ Date now = new Date();
+ ywCustomerElectricalMapper.update(null, new UpdateWrapper<YwCustomerElectrical>().lambda()
+ .set(YwCustomerElectrical::getIsdeleted, Constants.ONE)
+ .set(YwCustomerElectrical::getEditDate, now)
+ .set(YwCustomerElectrical::getEditor, user != null ? user.getId() : null)
+ .eq(YwCustomerElectrical::getCustomerId, customerId)
+ .eq(YwCustomerElectrical::getBindSource, BIND_SOURCE_CONTRACT)
+ .eq(YwCustomerElectrical::getIsdeleted, Constants.ZERO));
+ }
+
+ private void softDeleteAllConditionerRels(Integer customerId, LoginUserInfo user) {
+ Date now = new Date();
+ ywCustomerConditionerMapper.update(null, new UpdateWrapper<YwCustomerConditioner>().lambda()
+ .set(YwCustomerConditioner::getIsdeleted, Constants.ONE)
+ .set(YwCustomerConditioner::getEditDate, now)
+ .set(YwCustomerConditioner::getEditor, user != null ? user.getId() : null)
+ .eq(YwCustomerConditioner::getCustomerId, customerId)
+ .eq(YwCustomerConditioner::getIsdeleted, Constants.ZERO));
+ }
+
private Set<Integer> listBoundElectricalIdsExcept(Integer customerId) {
List<YwCustomerElectrical> list = ywCustomerElectricalMapper.selectList(new QueryWrapper<YwCustomerElectrical>().lambda()
.eq(YwCustomerElectrical::getIsdeleted, Constants.ZERO)
--
Gitblit v1.9.3