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

@@ -37,14 +37,27 @@ public class ProfitTask {
private IBasicUserBindInfoService basicUserBindInfoService;
public void execute(Integer hour) {
log.info("分润计算定时任务开始");
// TODO: 抽取支付订单,计算分润,更新分润表
log.info("=== 分润计算定时任务开始, hour={} ===", hour);
// 步骤1: 查询待处理订单
List<AquPayDevice> 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<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);
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<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<AquPayDevice> aquPayOrders = new ArrayList<>();
list.forEach(aquPayOrder -> {
try{
int matchCount = 0;
int noMatchCount = 0;
List<String> noMatchDevices = new ArrayList<>();
for (AquPayDevice aquPayOrder : list) {
try {
String deviceName = aquPayOrder.getSerialNum();
if (collect.containsKey(deviceName)) {
matchCount++;
List<SharingUserTaskVo> 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<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() {
List<BasicUserBindInfo> deviceId = basicUserBindInfoService.list(
new LambdaQueryWrapper<BasicUserBindInfo>().isNull(BasicUserBindInfo::getDeviceId)
// 查询需要补全的记录device_id为空 或 app_user为空小程序用户后绑定的情况
List<BasicUserBindInfo> needUpdateList = basicUserBindInfoService.list(
new LambdaQueryWrapper<BasicUserBindInfo>()
.and(w -> w.isNull(BasicUserBindInfo::getDeviceId)
.or().isNull(BasicUserBindInfo::getAppUser))
);
if (!CollectionUtils.isEmpty(deviceId)) {
List<BasicUserBindInfo> appUserInfo = basicUserBindInfoService.selectAppUserInfo();
if(!CollectionUtils.isEmpty(appUserInfo)){
Map<String, List<BasicUserBindInfo>> collect = appUserInfo.stream().collect(Collectors.groupingBy(BasicUserBindInfo::getDeviceName));
List<BasicUserBindInfo> updateList = new ArrayList<>();
deviceId.forEach(e -> {
if (collect.containsKey(e.getDeviceName())) {
List<BasicUserBindInfo> 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<BasicUserBindInfo> appUserInfo = basicUserBindInfoService.selectAppUserInfo();
if (CollectionUtils.isEmpty(appUserInfo)) {
log.info("[设备绑定补全] aqu_device中无设备数据");
return;
}
Map<String, List<BasicUserBindInfo>> collect = appUserInfo.stream()
.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中的设备");
}
}