fix: 分润发现问题,统一修复。

This commit is contained in:
tianyongbao
2026-05-30 16:42:12 +08:00
parent 3b25ecc916
commit 771d46edbb
10 changed files with 330 additions and 50 deletions

View File

@@ -2,7 +2,10 @@ package com.limap.core.basic.domain;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; 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.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
@@ -109,4 +112,20 @@ public class BasicProfitSharingRecord {
@ApiModelProperty("查询结束时间") @ApiModelProperty("查询结束时间")
@TableField(exist = false) @TableField(exist = false)
private Date endTime; private Date endTime;
/** 请求参数 */
@TableField(exist = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
} }

View File

@@ -20,6 +20,8 @@ public interface AquPayOrderMapper extends BaseMapper<AquPayOrder> {
List<AquPayDevice> selectInfoByHour(Integer hour); List<AquPayDevice> selectInfoByHour(Integer hour);
List<AquPayDevice> selectInfoForBackfill(Integer hour);
void updatePayDeviceStatus(@Param("list") List<AquPayDevice> list); void updatePayDeviceStatus(@Param("list") List<AquPayDevice> list);
void dealRechargeWarnCode(); void dealRechargeWarnCode();

View File

@@ -24,6 +24,11 @@ public interface IAquPayOrderService extends IService<AquPayOrder> {
List<AquPayDevice> selectInfoByHour(Integer hour); List<AquPayDevice> selectInfoByHour(Integer hour);
/**
* 补录用: 查询指定时间范围内所有订单(忽略profit_status)
*/
List<AquPayDevice> selectInfoForBackfill(Integer hour);
void updatePayDeviceStatus(List<AquPayDevice> list); void updatePayDeviceStatus(List<AquPayDevice> list);
void dealRechargeWarnCode(); void dealRechargeWarnCode();

View File

@@ -46,6 +46,11 @@ public class AquPayOrderServiceImpl extends ServiceImpl<AquPayOrderMapper, AquPa
return aquPayOrderMapper.selectInfoByHour(hour); return aquPayOrderMapper.selectInfoByHour(hour);
} }
@Override
public List<AquPayDevice> selectInfoForBackfill(Integer hour) {
return aquPayOrderMapper.selectInfoForBackfill(hour);
}
@Override @Override
public void updatePayDeviceStatus(List<AquPayDevice> list) { public void updatePayDeviceStatus(List<AquPayDevice> list) {
aquPayOrderMapper.updatePayDeviceStatus(list); aquPayOrderMapper.updatePayDeviceStatus(list);

View File

@@ -3,9 +3,12 @@ package com.limap.core.basic.service.impl;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.limap.common.utils.DateUtils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 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.BasicUserWithdrawVo;
import com.limap.core.basic.vo.SharingRecordSearchVo; import com.limap.core.basic.vo.SharingRecordSearchVo;
import com.limap.core.basic.vo.SharingUserTaskVo; import com.limap.core.basic.vo.SharingUserTaskVo;
import com.baomidou.dynamic.datasource.annotation.DS;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; 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.domain.BasicProfitSharingRecord;
import com.limap.core.basic.service.IBasicProfitSharingRecordService; import com.limap.core.basic.service.IBasicProfitSharingRecordService;
import java.util.Collection;
/** /**
* 分润记录Service业务层处理 * 分润记录Service业务层处理
* *
@@ -37,6 +43,7 @@ import com.limap.core.basic.service.IBasicProfitSharingRecordService;
*/ */
@Service @Service
@Slf4j @Slf4j
@DS("master")
public class BasicProfitSharingRecordServiceImpl extends ServiceImpl<BasicProfitSharingRecordMapper, BasicProfitSharingRecord> implements IBasicProfitSharingRecordService { public class BasicProfitSharingRecordServiceImpl extends ServiceImpl<BasicProfitSharingRecordMapper, BasicProfitSharingRecord> implements IBasicProfitSharingRecordService {
@Autowired @Autowired
private BasicProfitSharingRecordMapper basicProfitSharingRecordMapper; private BasicProfitSharingRecordMapper basicProfitSharingRecordMapper;
@@ -82,16 +89,59 @@ public class BasicProfitSharingRecordServiceImpl extends ServiceImpl<BasicProfit
if (StringUtils.isNotNull(basicProfitSharingRecord.getDeviceName())) { if (StringUtils.isNotNull(basicProfitSharingRecord.getDeviceName())) {
queryWrapper.eq(BasicProfitSharingRecord::getDeviceName, basicProfitSharingRecord.getDeviceName()); queryWrapper.eq(BasicProfitSharingRecord::getDeviceName, basicProfitSharingRecord.getDeviceName());
} }
if (StringUtils.isNotNull(basicProfitSharingRecord.getStartTime())) { // 兼容前端params[beginTime]/params[endTime]传参方式
Map<String, Object> 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()); queryWrapper.between(BasicProfitSharingRecord::getGenerateTime, basicProfitSharingRecord.getStartTime(), basicProfitSharingRecord.getEndTime());
} }
if (StringUtils.isNotNull(basicProfitSharingRecord.getTel())) { if (StringUtils.isNotNull(basicProfitSharingRecord.getTel())) {
queryWrapper.like(BasicProfitSharingRecord::getTel, 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); queryWrapper.orderByDesc(BasicProfitSharingRecord::getGenerateTime);
return basicProfitSharingRecordMapper.selectList(queryWrapper); return basicProfitSharingRecordMapper.selectList(queryWrapper);
} }
/**
* 重写saveBatch解决dynamic-datasource下批量插入事务不提交的问题
* 1. saveBatch内部BATCH模式绕过@DS
* 2. @Transactional与@DS冲突导致事务不提交
* 去掉@Transactional依赖连接池autoCommit=true逐条提交
*/
@DS("master")
@Override
public boolean saveBatch(Collection<BasicProfitSharingRecord> 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;
}
/** /**
* 处理分润计算 * 处理分润计算
* *

View File

@@ -2,6 +2,9 @@ package com.limap.core.basic.vo;
import lombok.Data; import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data @Data
public class SharingRecordSearchVo { public class SharingRecordSearchVo {
@@ -10,4 +13,7 @@ public class SharingRecordSearchVo {
private Long userId; private Long userId;
private Long deptId; private Long deptId;
/** 请求参数(前端传 params[startDate] 等) */
private Map<String, Object> params = new HashMap<>();
} }

View File

@@ -21,9 +21,22 @@
<select id="selectInfoByHour" resultType="com.limap.core.basic.domain.AquPayDevice"> <select id="selectInfoByHour" resultType="com.limap.core.basic.domain.AquPayDevice">
select * from aqu_pay_device select id, user_id, pay_amount, pay_type, create_time as "createdTime",
device_type, serial_num, order_id, profit_status
from aqu_pay_device
where create_time &gt;= now() - interval '${hour} hour' where create_time &gt;= now() - interval '${hour} hour'
AND create_time &lt;= now() - interval '1 hour' AND create_time &lt;= now() - interval '1 hour'
AND (profit_status IS NULL OR profit_status = 0) AND (profit_status IS NULL OR profit_status = 0)
AND pay_type = 1
</select>
<!-- 补录用: 查询指定时间范围内所有订单(忽略profit_status) -->
<select id="selectInfoForBackfill" resultType="com.limap.core.basic.domain.AquPayDevice">
select id, user_id, pay_amount, pay_type, create_time as "createdTime",
device_type, serial_num, order_id, profit_status
from aqu_pay_device
where create_time &gt;= now() - interval '${hour} hour'
AND create_time &lt;= now() - interval '1 hour'
AND pay_type = 1
</select> </select>
</mapper> </mapper>

View File

@@ -12,19 +12,24 @@
SUM(CASE WHEN withdrawal_status = 1 THEN amount ELSE 0 END) AS tx SUM(CASE WHEN withdrawal_status = 1 THEN amount ELSE 0 END) AS tx
FROM basic_profit_sharing_record FROM basic_profit_sharing_record
<where> <where>
<if test="startDate != null"> <if test="params.startDate != null and params.startDate != ''">
AND created_time &gt;= #{startDate} AND generate_time &gt;= #{params.startDate}
</if> </if>
<if test="endDate != null"> <if test="params.endDate != null and params.endDate != ''">
AND created_time &lt;= #{endDate} AND generate_time &lt;= #{params.endDate}
</if>
<if test="startDate != null and startDate != ''">
AND generate_time &gt;= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND generate_time &lt;= #{endDate}
</if> </if>
<if test="userId != null"> <if test="userId != null">
AND user_id = #{userId} AND user_id = #{userId}
</if> </if>
<if test="deptId != null"> <if test="deptId != null">
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 ))
</if> </if>
</where> </where>
</select> </select>
</mapper> </mapper>

View File

@@ -34,6 +34,6 @@
<if test="appUserTel != null and appUserTel != ''"> and app_user_tel = #{appUserTel}</if> <if test="appUserTel != null and appUserTel != ''"> and app_user_tel = #{appUserTel}</if>
<if test="userName != null and userName != ''"> and user_name like CONCAT('%',#{userName},'%')</if> <if test="userName != null and userName != ''"> and user_name like CONCAT('%',#{userName},'%')</if>
</where> </where>
order by create_time desc
</select> </select>
</mapper> </mapper>

View File

@@ -37,14 +37,27 @@ public class ProfitTask {
private IBasicUserBindInfoService basicUserBindInfoService; private IBasicUserBindInfoService basicUserBindInfoService;
public void execute(Integer hour) { public void execute(Integer hour) {
log.info("分润计算定时任务开始"); log.info("=== 分润计算定时任务开始, hour={} ===", hour);
// TODO: 抽取支付订单,计算分润,更新分润表 // 步骤1: 查询待处理订单
List<AquPayDevice> list = aquPayOrderService.selectInfoByHour(hour); List<AquPayDevice> list = aquPayOrderService.selectInfoByHour(hour);
log.info("[步骤1] 查询到待处理订单数量: {}", list == null ? 0 : list.size());
if (list != null && list.size() > 0) { 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<SharingUserTaskVo> sharingUserTaskVos = sharingUserService.selectBasicInfoList(); List<SharingUserTaskVo> 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); boolean b = list.stream().anyMatch(e -> e.getDeviceType() == 2);
if (b) { if (b) {
BasicProfitSharingUser byId = sharingUserService.getById(101); BasicProfitSharingUser byId = sharingUserService.getById(101);
log.info("[步骤2-控制柜] 存在deviceType=2的订单, id=101的分润用户: {}", byId != null ? "存在" : "不存在");
if (byId != null) { if (byId != null) {
list.stream().filter(e -> e.getDeviceType() == 2).forEach(e -> { list.stream().filter(e -> e.getDeviceType() == 2).forEach(e -> {
SharingUserTaskVo sharingUserTaskVo = new SharingUserTaskVo(); SharingUserTaskVo sharingUserTaskVo = new SharingUserTaskVo();
@@ -58,67 +71,229 @@ public class ProfitTask {
} }
} }
if (sharingUserTaskVos == null || sharingUserTaskVos.size() == 0) { if (sharingUserTaskVos == null || sharingUserTaskVos.size() == 0) {
log.info("没有需要计算的用户"); log.info("[步骤2] 没有需要计算的用户,退出");
return; return;
} }
// 步骤3: 按设备名分组
Map<String,List<SharingUserTaskVo>> collect = dealProfitUser(sharingUserTaskVos); Map<String,List<SharingUserTaskVo>> collect = dealProfitUser(sharingUserTaskVos);
log.info("[步骤3] dealProfitUser后设备分组数量: {}, 设备名keys(前10): {}",
collect.size(), collect.keySet().stream().limit(10).collect(Collectors.joining(", ")));
// 步骤4: 匹配订单与分润用户
List<BasicProfitSharingRecord> basicProfitSharingRecords = new ArrayList<>(); List<BasicProfitSharingRecord> basicProfitSharingRecords = new ArrayList<>();
List<AquPayDevice> aquPayOrders = new ArrayList<>(); List<AquPayDevice> aquPayOrders = new ArrayList<>();
list.forEach(aquPayOrder -> { int matchCount = 0;
try{ int noMatchCount = 0;
List<String> noMatchDevices = new ArrayList<>();
for (AquPayDevice aquPayOrder : list) {
try {
String deviceName = aquPayOrder.getSerialNum(); String deviceName = aquPayOrder.getSerialNum();
if (collect.containsKey(deviceName)) { if (collect.containsKey(deviceName)) {
matchCount++;
List<SharingUserTaskVo> sharingUserTaskVos1 = collect.get(deviceName); List<SharingUserTaskVo> sharingUserTaskVos1 = collect.get(deviceName);
sharingUserTaskVos1.forEach(sharingUserTaskVo -> { for (SharingUserTaskVo sharingUserTaskVo : sharingUserTaskVos1) {
// 计算分润 try {
try{
BasicProfitSharingRecord basicProfitSharingRecord = basicProfitSharingRecordService.calculateProfit(aquPayOrder, sharingUserTaskVo); BasicProfitSharingRecord basicProfitSharingRecord = basicProfitSharingRecordService.calculateProfit(aquPayOrder, sharingUserTaskVo);
basicProfitSharingRecords.add(basicProfitSharingRecord); basicProfitSharingRecords.add(basicProfitSharingRecord);
aquPayOrder.setProfitStatus(1); aquPayOrder.setProfitStatus(1);
aquPayOrders.add(aquPayOrder); aquPayOrders.add(aquPayOrder);
}catch (Exception e){ } catch (Exception e) {
log.error("订单号:{},分润计算异常",aquPayOrder.getId(),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){ } catch (Exception e) {
log.error("订单号:{}jsonDeviceSerialNum解析异常",aquPayOrder.getId(),e); log.error("[步骤4] 订单id={},处理异常: {}", aquPayOrder.getId(), e.getMessage(), e);
} }
});
// 批量更新订单状态和分润表
if (basicProfitSharingRecords.size() > 0) {
basicProfitSharingRecordService.saveBatch(basicProfitSharingRecords);
aquPayOrderService.updatePayDeviceStatus(aquPayOrders);
} }
}else{ log.info("[步骤4] 匹配成功: {}条, 未匹配: {}条, 生成分润记录: {}条", matchCount, noMatchCount, basicProfitSharingRecords.size());
log.info("没有需要计算的订单"); 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<AquPayDevice> list = aquPayOrderService.selectInfoForBackfill(hours);
log.info("[补录] 查询到订单数量: {}", list == null ? 0 : list.size());
if (list == null || list.isEmpty()) {
log.info("[补录] 没有需要补录的订单");
return;
}
// 查询已存在的分润记录order_no用于去重
List<BasicProfitSharingRecord> existingRecords = basicProfitSharingRecordService.list();
Set<String> existingOrderNos = existingRecords.stream()
.map(BasicProfitSharingRecord::getOrderNo)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
log.info("[补录] 已存在分润记录数: {}", existingOrderNos.size());
// 过滤掉已有记录的订单
List<AquPayDevice> 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<SharingUserTaskVo> 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<String, List<SharingUserTaskVo>> collect = dealProfitUser(sharingUserTaskVos);
List<BasicProfitSharingRecord> 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() { public void executeEquipmentBind() {
List<BasicUserBindInfo> deviceId = basicUserBindInfoService.list( // 查询需要补全的记录device_id为空 或 app_user为空小程序用户后绑定的情况
new LambdaQueryWrapper<BasicUserBindInfo>().isNull(BasicUserBindInfo::getDeviceId) List<BasicUserBindInfo> needUpdateList = basicUserBindInfoService.list(
new LambdaQueryWrapper<BasicUserBindInfo>()
.and(w -> w.isNull(BasicUserBindInfo::getDeviceId)
.or().isNull(BasicUserBindInfo::getAppUser))
); );
if (!CollectionUtils.isEmpty(deviceId)) { if (CollectionUtils.isEmpty(needUpdateList)) {
List<BasicUserBindInfo> appUserInfo = basicUserBindInfoService.selectAppUserInfo(); log.info("没有需要补全的设备绑定记录");
if(!CollectionUtils.isEmpty(appUserInfo)){ return;
Map<String, List<BasicUserBindInfo>> collect = appUserInfo.stream().collect(Collectors.groupingBy(BasicUserBindInfo::getDeviceName)); }
List<BasicUserBindInfo> updateList = new ArrayList<>(); log.info("[设备绑定补全] 待处理记录数: {}", needUpdateList.size());
deviceId.forEach(e -> {
if (collect.containsKey(e.getDeviceName())) { // 从aqu_device + aqu_user获取最新设备和用户信息
List<BasicUserBindInfo> list = collect.get(e.getDeviceName()); List<BasicUserBindInfo> appUserInfo = basicUserBindInfoService.selectAppUserInfo();
BasicUserBindInfo e1 = list.get(0); if (CollectionUtils.isEmpty(appUserInfo)) {
e1.setId(e.getId()); log.info("[设备绑定补全] aqu_device中无设备数据");
updateList.add(e1); return;
} }
});
if (updateList.size() > 0) { Map<String, List<BasicUserBindInfo>> collect = appUserInfo.stream()
basicUserBindInfoService.updateBatchById(updateList); .filter(e -> e != null && e.getDeviceName() != null)
} .collect(Collectors.groupingBy(BasicUserBindInfo::getDeviceName));
List<BasicUserBindInfo> 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中的设备");
} }
} }