fix: 分润发现问题,统一修复。
This commit is contained in:
@@ -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中的设备");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user