From fce70f98fcc93fbfd76ead2db0bafe127cb5aee6 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Sat, 30 May 2026 16:42:12 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=86=E6=B6=A6=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E7=BB=9F=E4=B8=80=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/BasicProfitSharingRecord.java | 19 ++ .../core/basic/mapper/AquPayOrderMapper.java | 2 + .../basic/service/IAquPayOrderService.java | 5 + .../service/impl/AquPayOrderServiceImpl.java | 5 + .../BasicProfitSharingRecordServiceImpl.java | 52 +++- .../core/basic/vo/SharingRecordSearchVo.java | 6 + .../resources/mapper/AquPayOrderMapper.xml | 15 +- .../mapper/BasicProfitSharingRecordMapper.xml | 17 +- .../mapper/BasicUserBindInfoMapper.xml | 2 +- .../com/limap/quartz/task/ProfitTask.java | 257 +++++++++++++++--- 10 files changed, 330 insertions(+), 50 deletions(-) diff --git a/fishery-core/src/main/java/com/limap/core/basic/domain/BasicProfitSharingRecord.java b/fishery-core/src/main/java/com/limap/core/basic/domain/BasicProfitSharingRecord.java index 4f1bae0..ddf894a 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/domain/BasicProfitSharingRecord.java +++ b/fishery-core/src/main/java/com/limap/core/basic/domain/BasicProfitSharingRecord.java @@ -2,7 +2,10 @@ package com.limap.core.basic.domain; import java.math.BigDecimal; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.baomidou.mybatisplus.annotation.IdType; @@ -109,4 +112,20 @@ public class BasicProfitSharingRecord { @ApiModelProperty("查询结束时间") @TableField(exist = false) private Date endTime; + + /** 请求参数 */ + @TableField(exist = false) + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + public Map getParams() { + if (params == null) { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) { + this.params = params; + } } diff --git a/fishery-core/src/main/java/com/limap/core/basic/mapper/AquPayOrderMapper.java b/fishery-core/src/main/java/com/limap/core/basic/mapper/AquPayOrderMapper.java index 09e8e7b..48a91cf 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/mapper/AquPayOrderMapper.java +++ b/fishery-core/src/main/java/com/limap/core/basic/mapper/AquPayOrderMapper.java @@ -20,6 +20,8 @@ public interface AquPayOrderMapper extends BaseMapper { List selectInfoByHour(Integer hour); + List selectInfoForBackfill(Integer hour); + void updatePayDeviceStatus(@Param("list") List list); void dealRechargeWarnCode(); diff --git a/fishery-core/src/main/java/com/limap/core/basic/service/IAquPayOrderService.java b/fishery-core/src/main/java/com/limap/core/basic/service/IAquPayOrderService.java index ca8836d..c9cf23c 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/service/IAquPayOrderService.java +++ b/fishery-core/src/main/java/com/limap/core/basic/service/IAquPayOrderService.java @@ -24,6 +24,11 @@ public interface IAquPayOrderService extends IService { List selectInfoByHour(Integer hour); + /** + * 补录用: 查询指定时间范围内所有订单(忽略profit_status) + */ + List selectInfoForBackfill(Integer hour); + void updatePayDeviceStatus(List list); void dealRechargeWarnCode(); diff --git a/fishery-core/src/main/java/com/limap/core/basic/service/impl/AquPayOrderServiceImpl.java b/fishery-core/src/main/java/com/limap/core/basic/service/impl/AquPayOrderServiceImpl.java index 2ce85d3..06d3bc9 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/service/impl/AquPayOrderServiceImpl.java +++ b/fishery-core/src/main/java/com/limap/core/basic/service/impl/AquPayOrderServiceImpl.java @@ -46,6 +46,11 @@ public class AquPayOrderServiceImpl extends ServiceImpl selectInfoForBackfill(Integer hour) { + return aquPayOrderMapper.selectInfoForBackfill(hour); + } + @Override public void updatePayDeviceStatus(List list) { aquPayOrderMapper.updatePayDeviceStatus(list); diff --git a/fishery-core/src/main/java/com/limap/core/basic/service/impl/BasicProfitSharingRecordServiceImpl.java b/fishery-core/src/main/java/com/limap/core/basic/service/impl/BasicProfitSharingRecordServiceImpl.java index f7df464..5817374 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/service/impl/BasicProfitSharingRecordServiceImpl.java +++ b/fishery-core/src/main/java/com/limap/core/basic/service/impl/BasicProfitSharingRecordServiceImpl.java @@ -3,9 +3,12 @@ package com.limap.core.basic.service.impl; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; +import java.util.Date; import java.util.List; import java.util.Map; +import com.limap.common.utils.DateUtils; + import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -18,6 +21,7 @@ import com.limap.core.basic.service.IBasicUserWithdrawService; import com.limap.core.basic.vo.BasicUserWithdrawVo; import com.limap.core.basic.vo.SharingRecordSearchVo; import com.limap.core.basic.vo.SharingUserTaskVo; +import com.baomidou.dynamic.datasource.annotation.DS; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,6 +33,8 @@ import com.limap.core.basic.mapper.BasicProfitSharingRecordMapper; import com.limap.core.basic.domain.BasicProfitSharingRecord; import com.limap.core.basic.service.IBasicProfitSharingRecordService; +import java.util.Collection; + /** * 分润记录Service业务层处理 * @@ -37,6 +43,7 @@ import com.limap.core.basic.service.IBasicProfitSharingRecordService; */ @Service @Slf4j +@DS("master") public class BasicProfitSharingRecordServiceImpl extends ServiceImpl implements IBasicProfitSharingRecordService { @Autowired private BasicProfitSharingRecordMapper basicProfitSharingRecordMapper; @@ -82,16 +89,59 @@ public class BasicProfitSharingRecordServiceImpl extends ServiceImpl params = basicProfitSharingRecord.getParams(); + String beginTime = (String) params.get("beginTime"); + String endTime = (String) params.get("endTime"); + if (StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)) { + queryWrapper.ge(BasicProfitSharingRecord::getGenerateTime, beginTime + " 00:00:00"); + queryWrapper.le(BasicProfitSharingRecord::getGenerateTime, endTime + " 23:59:59"); + } else if (StringUtils.isNotNull(basicProfitSharingRecord.getStartTime())) { queryWrapper.between(BasicProfitSharingRecord::getGenerateTime, basicProfitSharingRecord.getStartTime(), basicProfitSharingRecord.getEndTime()); } if (StringUtils.isNotNull(basicProfitSharingRecord.getTel())) { queryWrapper.like(BasicProfitSharingRecord::getTel, basicProfitSharingRecord.getTel()); } + if (StringUtils.isNotEmpty(basicProfitSharingRecord.getUserName())) { + queryWrapper.like(BasicProfitSharingRecord::getUserName, basicProfitSharingRecord.getUserName()); + } + if (StringUtils.isNotEmpty(basicProfitSharingRecord.getOrderNo())) { + queryWrapper.like(BasicProfitSharingRecord::getOrderNo, basicProfitSharingRecord.getOrderNo()); + } queryWrapper.orderByDesc(BasicProfitSharingRecord::getGenerateTime); return basicProfitSharingRecordMapper.selectList(queryWrapper); } + /** + * 重写saveBatch,解决dynamic-datasource下批量插入事务不提交的问题 + * 1. saveBatch内部BATCH模式绕过@DS + * 2. @Transactional与@DS冲突导致事务不提交 + * 去掉@Transactional,依赖连接池autoCommit=true逐条提交 + */ + @DS("master") + @Override + public boolean saveBatch(Collection entityList, int batchSize) { + if (entityList == null || entityList.isEmpty()) { + return false; + } + log.info("saveBatch开始, 待插入{}条记录", entityList.size()); + int count = 0; + for (BasicProfitSharingRecord record : entityList) { + try { + int rows = basicProfitSharingRecordMapper.insert(record); + if (rows > 0) { + count++; + } else { + log.warn("insert返回0行, record.orderNo={}, record.userId={}", record.getOrderNo(), record.getUserId()); + } + } catch (Exception e) { + log.error("insert单条异常, record.orderNo={}, error={}", record.getOrderNo(), e.getMessage()); + } + } + log.info("saveBatch完成, 预期插入{}条, 实际影响行数{}条", entityList.size(), count); + return count > 0; + } + /** * 处理分润计算 * diff --git a/fishery-core/src/main/java/com/limap/core/basic/vo/SharingRecordSearchVo.java b/fishery-core/src/main/java/com/limap/core/basic/vo/SharingRecordSearchVo.java index cc5103c..83ce861 100644 --- a/fishery-core/src/main/java/com/limap/core/basic/vo/SharingRecordSearchVo.java +++ b/fishery-core/src/main/java/com/limap/core/basic/vo/SharingRecordSearchVo.java @@ -2,6 +2,9 @@ package com.limap.core.basic.vo; import lombok.Data; +import java.util.HashMap; +import java.util.Map; + @Data public class SharingRecordSearchVo { @@ -10,4 +13,7 @@ public class SharingRecordSearchVo { private Long userId; private Long deptId; + + /** 请求参数(前端传 params[startDate] 等) */ + private Map params = new HashMap<>(); } diff --git a/fishery-core/src/main/resources/mapper/AquPayOrderMapper.xml b/fishery-core/src/main/resources/mapper/AquPayOrderMapper.xml index 80d27bd..361bdda 100644 --- a/fishery-core/src/main/resources/mapper/AquPayOrderMapper.xml +++ b/fishery-core/src/main/resources/mapper/AquPayOrderMapper.xml @@ -21,9 +21,22 @@ + + + diff --git a/fishery-core/src/main/resources/mapper/BasicProfitSharingRecordMapper.xml b/fishery-core/src/main/resources/mapper/BasicProfitSharingRecordMapper.xml index 0281e6e..7fc7939 100644 --- a/fishery-core/src/main/resources/mapper/BasicProfitSharingRecordMapper.xml +++ b/fishery-core/src/main/resources/mapper/BasicProfitSharingRecordMapper.xml @@ -12,19 +12,24 @@ SUM(CASE WHEN withdrawal_status = 1 THEN amount ELSE 0 END) AS tx FROM basic_profit_sharing_record - - AND created_time >= #{startDate} + + AND generate_time >= #{params.startDate} - - AND created_time <= #{endDate} + + AND generate_time <= #{params.endDate} + + + AND generate_time >= #{startDate} + + + AND generate_time <= #{endDate} AND user_id = #{userId} - and dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = #{deptId} or find_in_set( #{deptId} , ancestors )) + and dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = #{deptId} or find_in_set( #{deptId} , ancestors )) - diff --git a/fishery-core/src/main/resources/mapper/BasicUserBindInfoMapper.xml b/fishery-core/src/main/resources/mapper/BasicUserBindInfoMapper.xml index 2ae5d28..ee3d9ca 100644 --- a/fishery-core/src/main/resources/mapper/BasicUserBindInfoMapper.xml +++ b/fishery-core/src/main/resources/mapper/BasicUserBindInfoMapper.xml @@ -34,6 +34,6 @@ and app_user_tel = #{appUserTel} and user_name like CONCAT('%',#{userName},'%') - + order by create_time desc diff --git a/fishery-quartz/src/main/java/com/limap/quartz/task/ProfitTask.java b/fishery-quartz/src/main/java/com/limap/quartz/task/ProfitTask.java index 214c95d..b9b273c 100644 --- a/fishery-quartz/src/main/java/com/limap/quartz/task/ProfitTask.java +++ b/fishery-quartz/src/main/java/com/limap/quartz/task/ProfitTask.java @@ -37,14 +37,27 @@ public class ProfitTask { private IBasicUserBindInfoService basicUserBindInfoService; public void execute(Integer hour) { - log.info("分润计算定时任务开始"); - // TODO: 抽取支付订单,计算分润,更新分润表 + log.info("=== 分润计算定时任务开始, hour={} ===", hour); + // 步骤1: 查询待处理订单 List list = aquPayOrderService.selectInfoByHour(hour); + log.info("[步骤1] 查询到待处理订单数量: {}", list == null ? 0 : list.size()); if (list != null && list.size() > 0) { + // 打印前5条订单的设备序列号,方便核对 + list.stream().limit(5).forEach(o -> log.info("[步骤1-样本] 订单id={}, serialNum={}, payAmount={}, deviceType={}, profitStatus={}", + o.getId(), o.getSerialNum(), o.getPayAmount(), o.getDeviceType(), o.getProfitStatus())); + + // 步骤2: 查询分润用户 List sharingUserTaskVos = sharingUserService.selectBasicInfoList(); + log.info("[步骤2] 查询到分润用户数量: {}", sharingUserTaskVos == null ? 0 : sharingUserTaskVos.size()); + if (sharingUserTaskVos != null && sharingUserTaskVos.size() > 0) { + sharingUserTaskVos.stream().limit(5).forEach(u -> log.info("[步骤2-样本] userId={}, deviceName={}, omRatio={}, controlRatio={}, type={}", + u.getUserId(), u.getDeviceName(), u.getOmRatio(), u.getControlRatio(), u.getType())); + } + boolean b = list.stream().anyMatch(e -> e.getDeviceType() == 2); if (b) { BasicProfitSharingUser byId = sharingUserService.getById(101); + log.info("[步骤2-控制柜] 存在deviceType=2的订单, id=101的分润用户: {}", byId != null ? "存在" : "不存在"); if (byId != null) { list.stream().filter(e -> e.getDeviceType() == 2).forEach(e -> { SharingUserTaskVo sharingUserTaskVo = new SharingUserTaskVo(); @@ -58,67 +71,229 @@ public class ProfitTask { } } if (sharingUserTaskVos == null || sharingUserTaskVos.size() == 0) { - log.info("没有需要计算的用户"); + log.info("[步骤2] 没有需要计算的用户,退出"); return; } + + // 步骤3: 按设备名分组 Map> collect = dealProfitUser(sharingUserTaskVos); + log.info("[步骤3] dealProfitUser后设备分组数量: {}, 设备名keys(前10): {}", + collect.size(), collect.keySet().stream().limit(10).collect(Collectors.joining(", "))); + + // 步骤4: 匹配订单与分润用户 List basicProfitSharingRecords = new ArrayList<>(); List aquPayOrders = new ArrayList<>(); - list.forEach(aquPayOrder -> { - try{ + int matchCount = 0; + int noMatchCount = 0; + List noMatchDevices = new ArrayList<>(); + for (AquPayDevice aquPayOrder : list) { + try { String deviceName = aquPayOrder.getSerialNum(); if (collect.containsKey(deviceName)) { + matchCount++; List sharingUserTaskVos1 = collect.get(deviceName); - sharingUserTaskVos1.forEach(sharingUserTaskVo -> { - // 计算分润 - try{ + for (SharingUserTaskVo sharingUserTaskVo : sharingUserTaskVos1) { + try { BasicProfitSharingRecord basicProfitSharingRecord = basicProfitSharingRecordService.calculateProfit(aquPayOrder, sharingUserTaskVo); basicProfitSharingRecords.add(basicProfitSharingRecord); aquPayOrder.setProfitStatus(1); aquPayOrders.add(aquPayOrder); - }catch (Exception e){ - log.error("订单号:{},分润计算异常",aquPayOrder.getId(),e); + } catch (Exception e) { + log.error("[步骤4] 订单id={},serialNum={},分润计算异常: {}", aquPayOrder.getId(), aquPayOrder.getSerialNum(), e.getMessage(), e); } - }); + } + } else { + noMatchCount++; + if (noMatchDevices.size() < 10) { + noMatchDevices.add(deviceName); + } } - }catch (Exception e){ - log.error("订单号:{},jsonDeviceSerialNum解析异常",aquPayOrder.getId(),e); + } catch (Exception e) { + log.error("[步骤4] 订单id={},处理异常: {}", aquPayOrder.getId(), e.getMessage(), e); } - }); - // 批量更新订单状态和分润表 - if (basicProfitSharingRecords.size() > 0) { - basicProfitSharingRecordService.saveBatch(basicProfitSharingRecords); - aquPayOrderService.updatePayDeviceStatus(aquPayOrders); } - }else{ - log.info("没有需要计算的订单"); + log.info("[步骤4] 匹配成功: {}条, 未匹配: {}条, 生成分润记录: {}条", matchCount, noMatchCount, basicProfitSharingRecords.size()); + if (noMatchDevices.size() > 0) { + log.info("[步骤4] 未匹配的设备名(前10): {}", String.join(", ", noMatchDevices)); + } + + // 步骤5: 批量保存 + if (basicProfitSharingRecords.size() > 0) { + log.info("[步骤5] 准备批量保存分润记录: {}条, 更新订单状态: {}条", basicProfitSharingRecords.size(), aquPayOrders.size()); + try { + // 保存前查询记录数 + long beforeCount = basicProfitSharingRecordService.count(); + log.info("[步骤5] 保存前表中记录数: {}", beforeCount); + + basicProfitSharingRecordService.saveBatch(basicProfitSharingRecords); + + // 保存后立即查询验证 + long afterCount = basicProfitSharingRecordService.count(); + log.info("[步骤5] 保存后表中记录数: {}, 新增: {}", afterCount, afterCount - beforeCount); + + if (afterCount > beforeCount) { + aquPayOrderService.updatePayDeviceStatus(aquPayOrders); + log.info("[步骤5] 批量保存成功, 实际新增{}条", afterCount - beforeCount); + } else { + log.error("[步骤5] 严重问题: saveBatch执行完毕但表中无新增数据! 可能是数据源路由问题"); + } + } catch (Exception e) { + log.error("[步骤5] 批量保存异常: {}", e.getMessage(), e); + } + } else { + log.info("[步骤5] 没有生成任何分润记录,跳过保存"); + } + } else { + log.info("[步骤1] 没有需要计算的订单(hour={})", hour); } - log.info("分润计算定时任务结束"); + log.info("=== 分润计算定时任务结束 ==="); + } + + /** + * 补录历史分润数据 + * 从4月8日至今约1300小时,调用方式: profitTask.backfill() + * 或指定小时数: profitTask.backfillByHours(1300) + * 注意: 此方法会忽略profit_status,查询所有订单,并通过order_no去重避免重复写入 + */ + public void backfill() { + backfillByHours(1500); + } + + public void backfillByHours(Integer hours) { + log.info("===== 开始补录历史分润数据, 回溯{}小时 =====", hours); + // 使用backfill专用查询,忽略profit_status + List list = aquPayOrderService.selectInfoForBackfill(hours); + log.info("[补录] 查询到订单数量: {}", list == null ? 0 : list.size()); + if (list == null || list.isEmpty()) { + log.info("[补录] 没有需要补录的订单"); + return; + } + + // 查询已存在的分润记录order_no,用于去重 + List existingRecords = basicProfitSharingRecordService.list(); + Set existingOrderNos = existingRecords.stream() + .map(BasicProfitSharingRecord::getOrderNo) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + log.info("[补录] 已存在分润记录数: {}", existingOrderNos.size()); + + // 过滤掉已有记录的订单 + List needProcessList = list.stream() + .filter(o -> !existingOrderNos.contains(String.valueOf(o.getOrderId()))) + .collect(Collectors.toList()); + log.info("[补录] 去重后需要处理的订单数: {}", needProcessList.size()); + + if (needProcessList.isEmpty()) { + log.info("[补录] 所有订单均已有分润记录,无需补录"); + return; + } + + // 查询分润用户 + List sharingUserTaskVos = sharingUserService.selectBasicInfoList(); + log.info("[补录] 分润用户数量: {}", sharingUserTaskVos == null ? 0 : sharingUserTaskVos.size()); + + // 处理deviceType=2的控制柜订单 + boolean hasControlDevice = needProcessList.stream().anyMatch(e -> e.getDeviceType() == 2); + if (hasControlDevice) { + BasicProfitSharingUser byId = sharingUserService.getById(101); + if (byId != null) { + needProcessList.stream().filter(e -> e.getDeviceType() == 2).forEach(e -> { + SharingUserTaskVo vo = new SharingUserTaskVo(); + vo.setDeviceName(e.getSerialNum()); + vo.setUserId(byId.getUserId()); + vo.setControlRatio(byId.getControlRatio()); + vo.setOmRatio(byId.getOmRatio()); + vo.setType("2"); + sharingUserTaskVos.add(vo); + }); + } + } + + if (sharingUserTaskVos == null || sharingUserTaskVos.isEmpty()) { + log.info("[补录] 没有分润用户,退出"); + return; + } + + Map> collect = dealProfitUser(sharingUserTaskVos); + List records = new ArrayList<>(); + + for (AquPayDevice order : needProcessList) { + try { + String deviceName = order.getSerialNum(); + if (collect.containsKey(deviceName)) { + for (SharingUserTaskVo vo : collect.get(deviceName)) { + try { + BasicProfitSharingRecord record = basicProfitSharingRecordService.calculateProfit(order, vo); + records.add(record); + } catch (Exception e) { + log.error("[补录] 订单id={}, 计算异常: {}", order.getId(), e.getMessage()); + } + } + } + } catch (Exception e) { + log.error("[补录] 订单id={}, 处理异常: {}", order.getId(), e.getMessage()); + } + } + + log.info("[补录] 生成分润记录: {}条", records.size()); + if (!records.isEmpty()) { + try { + basicProfitSharingRecordService.saveBatch(records); + log.info("[补录] 保存成功, 共{}条记录", records.size()); + } catch (Exception e) { + log.error("[补录] 保存异常: {}", e.getMessage(), e); + } + } + log.info("===== 补录历史分润数据完成 ====="); } public void executeEquipmentBind() { - List deviceId = basicUserBindInfoService.list( - new LambdaQueryWrapper().isNull(BasicUserBindInfo::getDeviceId) + // 查询需要补全的记录:device_id为空 或 app_user为空(小程序用户后绑定的情况) + List needUpdateList = basicUserBindInfoService.list( + new LambdaQueryWrapper() + .and(w -> w.isNull(BasicUserBindInfo::getDeviceId) + .or().isNull(BasicUserBindInfo::getAppUser)) ); - if (!CollectionUtils.isEmpty(deviceId)) { - List appUserInfo = basicUserBindInfoService.selectAppUserInfo(); - if(!CollectionUtils.isEmpty(appUserInfo)){ - Map> collect = appUserInfo.stream().collect(Collectors.groupingBy(BasicUserBindInfo::getDeviceName)); - List updateList = new ArrayList<>(); - deviceId.forEach(e -> { - if (collect.containsKey(e.getDeviceName())) { - List list = collect.get(e.getDeviceName()); - BasicUserBindInfo e1 = list.get(0); - e1.setId(e.getId()); - updateList.add(e1); - } - }); - if (updateList.size() > 0) { - basicUserBindInfoService.updateBatchById(updateList); - } + if (CollectionUtils.isEmpty(needUpdateList)) { + log.info("没有需要补全的设备绑定记录"); + return; + } + log.info("[设备绑定补全] 待处理记录数: {}", needUpdateList.size()); + + // 从aqu_device + aqu_user获取最新设备和用户信息 + List appUserInfo = basicUserBindInfoService.selectAppUserInfo(); + if (CollectionUtils.isEmpty(appUserInfo)) { + log.info("[设备绑定补全] aqu_device中无设备数据"); + return; + } + + Map> collect = appUserInfo.stream() + .filter(e -> e != null && e.getDeviceName() != null) + .collect(Collectors.groupingBy(BasicUserBindInfo::getDeviceName)); + + List updateList = new ArrayList<>(); + for (BasicUserBindInfo record : needUpdateList) { + if (collect.containsKey(record.getDeviceName())) { + BasicUserBindInfo source = collect.get(record.getDeviceName()).get(0); + // 创建新对象避免对象引用问题 + BasicUserBindInfo updateItem = new BasicUserBindInfo(); + updateItem.setId(record.getId()); + updateItem.setDeviceId(source.getDeviceId()); + updateItem.setIotId(source.getIotId()); + updateItem.setType(source.getType()); + updateItem.setBindTime(source.getBindTime()); + updateItem.setAppUser(source.getAppUser()); + updateItem.setAppUserName(source.getAppUserName()); + updateItem.setAppUserTel(source.getAppUserTel()); + updateList.add(updateItem); } - }else{ - log.info("没有需要绑定的设备"); + } + + if (updateList.size() > 0) { + basicUserBindInfoService.updateBatchById(updateList); + log.info("[设备绑定补全] 成功更新{}条记录", updateList.size()); + } else { + log.info("[设备绑定补全] 没有匹配到aqu_device中的设备"); } }