854 lines
33 KiB
Java
854 lines
33 KiB
Java
package com.rj.service.impl;
|
||
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||
import com.rj.dto.hxr.HxrAdminOrderApiContext;
|
||
import com.rj.dto.hxr.HxrOrderRow;
|
||
import com.rj.dto.hxr.HxrOrderSelectResponse;
|
||
import com.rj.entity.LbDepartmentUser;
|
||
import com.rj.entity.LbOrderRow;
|
||
import com.rj.entity.LbUser;
|
||
import com.rj.mapper.LbOrderRowMapper;
|
||
import com.rj.service.*;
|
||
import com.rj.tenant.TenantContextHolder;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import java.math.BigDecimal;
|
||
import java.time.LocalDate;
|
||
import java.time.LocalDateTime;
|
||
import java.time.format.DateTimeFormatter;
|
||
import java.time.format.DateTimeParseException;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.HashSet;
|
||
import java.util.LinkedHashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Optional;
|
||
import java.util.Set;
|
||
import java.util.stream.Collectors;
|
||
|
||
@Slf4j
|
||
@Service
|
||
public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrderRow> implements ILbOrderRowService {
|
||
|
||
/** 从第三方同步的订单明细默认 data_type */
|
||
private static final String SYNC_DATA_TYPE_DETAIL = "detail_data";
|
||
|
||
private static final String SUM_DATA_TYPE = "sum_data";
|
||
|
||
private static final int DINGTALK_SELLER_CONFIRM_BATCH_SIZE = 15;
|
||
|
||
private static final String DINGTALK_SELLER_CONFIRM_PREFIX =
|
||
"提醒,请如下卖家确认,不要耽误 买方寄卖";
|
||
|
||
private static final long SUM_PLACEHOLDER_USER_ID = 10000L;
|
||
|
||
private static final String SUM_ORDER_SN = "order_sn_10000";
|
||
|
||
private static final DateTimeFormatter DAY_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||
|
||
private static final DateTimeFormatter DAY_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||
|
||
@Autowired
|
||
private HxrAdminOrderSelectService hxrAdminOrderSelectService;
|
||
|
||
@Autowired
|
||
private ILbThirdIntegrationConfigService lbThirdIntegrationConfigService;
|
||
|
||
@Autowired
|
||
private ILbDepartmentUserService lbDepartmentUserService;
|
||
|
||
@Autowired
|
||
private DingTalkRobotService dingTalkRobotService;
|
||
|
||
@Override
|
||
public Map<String, Object> add(LbOrderRow entity) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (entity.getId() == null) {
|
||
result.put("success", false);
|
||
result.put("message", "id(订单 id)不能为空");
|
||
return result;
|
||
}
|
||
if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
if (entity.getSellerId() == null) {
|
||
result.put("success", false);
|
||
result.put("message", "sellerId不能为空");
|
||
return result;
|
||
}
|
||
if (entity.getBuyerId() == null) {
|
||
result.put("success", false);
|
||
result.put("message", "buyerId不能为空");
|
||
return result;
|
||
}
|
||
if (entity.getOrderSn() == null || entity.getOrderSn().trim().isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "orderSn不能为空");
|
||
return result;
|
||
}
|
||
if (entity.getMerchandiseId() == null) {
|
||
result.put("success", false);
|
||
result.put("message", "merchandiseId不能为空");
|
||
return result;
|
||
}
|
||
entity.setTenantId(entity.getTenantId().trim());
|
||
if (getByTenantAndId(entity.getTenantId(), entity.getId()) != null) {
|
||
result.put("success", false);
|
||
result.put("message", "该租户下订单 id 已存在");
|
||
return result;
|
||
}
|
||
entity.setOrderSn(entity.getOrderSn().trim());
|
||
if (entity.getStatus() == null) {
|
||
entity.setStatus(0);
|
||
}
|
||
if (entity.getIsResell() == null) {
|
||
entity.setIsResell(0);
|
||
}
|
||
if (entity.getIsShow() == null) {
|
||
entity.setIsShow(0);
|
||
}
|
||
|
||
boolean ok = this.save(entity);
|
||
result.put("success", ok);
|
||
result.put("message", ok ? "新增成功" : "新增失败");
|
||
if (ok) {
|
||
result.put("data", getByTenantAndId(entity.getTenantId(), entity.getId()));
|
||
}
|
||
return result;
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "新增异常:" + e.getMessage());
|
||
return result;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> update(LbOrderRow entity) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (entity.getId() == null) {
|
||
result.put("success", false);
|
||
result.put("message", "id不能为空");
|
||
return result;
|
||
}
|
||
String tenantId = resolveTenantId(entity.getTenantId());
|
||
if (tenantId == null) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
entity.setTenantId(tenantId);
|
||
if (getByTenantAndId(tenantId, entity.getId()) == null) {
|
||
result.put("success", false);
|
||
result.put("message", "记录不存在");
|
||
return result;
|
||
}
|
||
boolean ok =
|
||
this.update(
|
||
entity,
|
||
new LambdaQueryWrapper<LbOrderRow>()
|
||
.eq(LbOrderRow::getTenantId, tenantId)
|
||
.eq(LbOrderRow::getId, entity.getId()));
|
||
result.put("success", ok);
|
||
result.put("message", ok ? "编辑成功" : "编辑失败");
|
||
if (ok) {
|
||
result.put("data", getByTenantAndId(tenantId, entity.getId()));
|
||
}
|
||
return result;
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "编辑异常:" + e.getMessage());
|
||
return result;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> deleteById(Long id, String tenantId) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (id == null) {
|
||
result.put("success", false);
|
||
result.put("message", "id不能为空");
|
||
return result;
|
||
}
|
||
String tid = resolveTenantId(tenantId);
|
||
if (tid == null) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
if (getByTenantAndId(tid, id) == null) {
|
||
result.put("success", false);
|
||
result.put("message", "记录不存在");
|
||
return result;
|
||
}
|
||
boolean ok =
|
||
this.remove(
|
||
new LambdaQueryWrapper<LbOrderRow>()
|
||
.eq(LbOrderRow::getTenantId, tid)
|
||
.eq(LbOrderRow::getId, id));
|
||
result.put("success", ok);
|
||
result.put("message", ok ? "删除成功" : "删除失败");
|
||
return result;
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "删除异常:" + e.getMessage());
|
||
return result;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> pageQuery(
|
||
Integer current,
|
||
Integer size,
|
||
String isResell,
|
||
String dataType,
|
||
String orderSn,
|
||
String phone,
|
||
Long buyerId,
|
||
Long sellerId,
|
||
Integer status,
|
||
Long merchandiseId) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (current == null || current < 1) {
|
||
current = 1;
|
||
}
|
||
if (size == null || size < 1) {
|
||
size = 10;
|
||
}
|
||
|
||
LambdaQueryWrapper<LbOrderRow> w = new LambdaQueryWrapper<>();
|
||
if (isResell != null && !isResell.trim().isEmpty()) {
|
||
w.eq(LbOrderRow::getIsResell, isResell.trim());
|
||
}
|
||
if (dataType != null && !dataType.trim().isEmpty()) {
|
||
w.eq(LbOrderRow::getDataType, dataType.trim());
|
||
}
|
||
if (orderSn != null && !orderSn.trim().isEmpty()) {
|
||
w.like(LbOrderRow::getOrderSn, orderSn.trim());
|
||
}
|
||
if (phone != null && !phone.trim().isEmpty()) {
|
||
w.like(LbOrderRow::getPhone, phone.trim());
|
||
}
|
||
if (buyerId != null) {
|
||
w.eq(LbOrderRow::getBuyerId, buyerId);
|
||
}
|
||
if (sellerId != null) {
|
||
w.eq(LbOrderRow::getSellerId, sellerId);
|
||
}
|
||
if (status != null) {
|
||
w.eq(LbOrderRow::getStatus, status);
|
||
}
|
||
if (merchandiseId != null) {
|
||
w.eq(LbOrderRow::getMerchandiseId, merchandiseId);
|
||
}
|
||
w.orderByDesc(LbOrderRow::getId);
|
||
|
||
Page<LbOrderRow> page = this.page(new Page<>(current, size), w);
|
||
result.put("success", true);
|
||
result.put("message", "查询成功");
|
||
result.put("data", page.getRecords());
|
||
result.put("total", page.getTotal());
|
||
result.put("current", page.getCurrent());
|
||
result.put("size", page.getSize());
|
||
result.put("pages", page.getPages());
|
||
return result;
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "查询异常:" + e.getMessage());
|
||
return result;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Map<String, Object> syncFromHxrAdmin(
|
||
String buyTimeStart, String buyTimeEnd, String tenantId, Integer isResell) {
|
||
return syncFromHxrAdmin(buyTimeStart, buyTimeEnd, tenantId, isResell, null);
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Map<String, Object> syncFromHxrAdmin(
|
||
String buyTimeStart, String buyTimeEnd, String tenantId, Integer isResell, Integer hxrOrderStatus) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
|
||
|
||
String tid = tenantId.trim();
|
||
Optional<HxrAdminOrderApiContext> apiContextOpt =
|
||
lbThirdIntegrationConfigService.resolveAdminOrderApiContext(tid);
|
||
if (apiContextOpt.isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message",
|
||
"未找到该租户的第三方集成配置,或配置未启用、URL/凭证不完整(请检查 lb_third_integration_config)");
|
||
result.put("synced", 0);
|
||
return result;
|
||
}
|
||
HxrAdminOrderApiContext apiContext = apiContextOpt.get();
|
||
int orderPageLimit = apiContext.pageLimit() > 0 ? apiContext.pageLimit() : 90;
|
||
|
||
String previousTenantId = TenantContextHolder.getTenantId();
|
||
TenantContextHolder.setTenantId(tid);
|
||
try {
|
||
HxrOrderSelectResponse firstBody = null;
|
||
int page = 1;
|
||
int totalSynced = 0;
|
||
while (true) {
|
||
Optional<HxrOrderSelectResponse> opt =
|
||
fetchHxrOrderPage(buyTimeStart, buyTimeEnd, isResell, hxrOrderStatus, page, apiContext);
|
||
if (opt.isEmpty()) {
|
||
if (page == 1) {
|
||
result.put("success", false);
|
||
result.put("message",
|
||
"未拉取到订单(请检查 lb_third_integration_config 中 cookie/phpsid、URL 或网络)");
|
||
result.put("synced", 0);
|
||
return result;
|
||
}
|
||
result.put("success", false);
|
||
result.put("message", "第 " + page + " 页拉取失败,已成功同步前 "
|
||
+ (page - 1) + " 页共 " + totalSynced + " 条");
|
||
result.put("synced", totalSynced);
|
||
if (firstBody != null) {
|
||
result.put("remoteCount", firstBody.count());
|
||
result.put("allMoney", firstBody.allMoney());
|
||
}
|
||
result.put("pages", page - 1);
|
||
return result;
|
||
}
|
||
|
||
HxrOrderSelectResponse body = opt.get();
|
||
if (firstBody == null) {
|
||
firstBody = body;
|
||
}
|
||
List<HxrOrderRow> rows = body.data();
|
||
if (rows == null || rows.isEmpty()) {
|
||
break;
|
||
}
|
||
|
||
List<LbOrderRow> entities = new ArrayList<>(rows.size());
|
||
for (HxrOrderRow row : rows) {
|
||
entities.add(toLbOrderRow(row, tid));
|
||
}
|
||
fillSellerInfoFromDepartmentUsers(entities, tid);
|
||
fillBuyerInfoFromLBtUsers(entities, tid);
|
||
int upserted = upsertBatch(entities);
|
||
if (upserted < 0) {
|
||
result.put("success", false);
|
||
result.put("message", "第 " + page + " 页保存失败,已成功同步前 "
|
||
+ (page - 1) + " 页共 " + totalSynced + " 条");
|
||
result.put("synced", totalSynced);
|
||
result.put("remoteCount", firstBody.count());
|
||
result.put("allMoney", firstBody.allMoney());
|
||
result.put("pages", page - 1);
|
||
return result;
|
||
}
|
||
totalSynced += upserted;
|
||
|
||
if (rows.size() < orderPageLimit) {
|
||
break;
|
||
}
|
||
page++;
|
||
}
|
||
|
||
if (totalSynced == 0) {
|
||
result.put("success", true);
|
||
result.put("message", "接口成功,时间范围内无订单数据");
|
||
result.put("synced", 0);
|
||
result.put("remoteCount", firstBody != null ? firstBody.count() : 0);
|
||
result.put("pages", page);
|
||
return result;
|
||
}
|
||
|
||
result.put("success", true);
|
||
result.put("message", "同步完成");
|
||
result.put("synced", totalSynced);
|
||
result.put("remoteCount", firstBody.count());
|
||
result.put("allMoney", firstBody.allMoney());
|
||
result.put("pages", page);
|
||
return result;
|
||
} finally {
|
||
if (previousTenantId != null) {
|
||
TenantContextHolder.setTenantId(previousTenantId);
|
||
} else {
|
||
TenantContextHolder.clear();
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "同步异常:" + e.getMessage());
|
||
result.put("synced", 0);
|
||
log.error("syncFromHxrAdmin failed", e);
|
||
return result;
|
||
}
|
||
}
|
||
|
||
private Optional<HxrOrderSelectResponse> fetchHxrOrderPage(
|
||
String buyTimeStart,
|
||
String buyTimeEnd,
|
||
Integer isResell,
|
||
Integer hxrOrderStatus,
|
||
int page,
|
||
HxrAdminOrderApiContext apiContext)
|
||
throws Exception {
|
||
if (hxrOrderStatus != null) {
|
||
if (hxrOrderStatus == 0) {
|
||
return hxrAdminOrderSelectService.fetchUnpaidOrderSelect(
|
||
buyTimeStart, buyTimeEnd, page, apiContext);
|
||
}
|
||
if (hxrOrderStatus == 1) {
|
||
return hxrAdminOrderSelectService.fetchPaidOrderSelect(
|
||
buyTimeStart, buyTimeEnd, page, apiContext);
|
||
}
|
||
}
|
||
return hxrAdminOrderSelectService.fetchOrderSelect(
|
||
buyTimeStart, buyTimeEnd, isResell, page, apiContext);
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Map<String, Object> generateDailySumData(
|
||
String buyTimeStart, String buyTimeEnd, String tenantId) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
String tid = tenantId.trim();
|
||
|
||
List<LbOrderRow> details = listDetailRowsByBuyTimeRange(buyTimeStart, buyTimeEnd, tid);
|
||
if (details.isEmpty()) {
|
||
result.put("success", true);
|
||
result.put("message", "时间范围内无明细数据");
|
||
result.put("generated", 0);
|
||
result.put("sourceCount", 0);
|
||
return result;
|
||
}
|
||
|
||
Map<LocalDate, List<LbOrderRow>> byDay = new LinkedHashMap<>();
|
||
int skippedNoBuyTime = 0;
|
||
for (LbOrderRow row : details) {
|
||
LocalDate day = parseBuyTimeToDate(row.getBuyTime());
|
||
if (day == null) {
|
||
skippedNoBuyTime++;
|
||
continue;
|
||
}
|
||
byDay.computeIfAbsent(day, k -> new ArrayList<>()).add(row);
|
||
}
|
||
|
||
if (byDay.isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "明细 buy_time 均无法解析为日期,无法汇总");
|
||
result.put("skippedNoBuyTime", skippedNoBuyTime);
|
||
return result;
|
||
}
|
||
|
||
String nowStr = LocalDateTime.now().format(DAY_TIME_FMT);
|
||
List<LbOrderRow> sumRows = new ArrayList<>(byDay.size());
|
||
for (Map.Entry<LocalDate, List<LbOrderRow>> entry : byDay.entrySet()) {
|
||
sumRows.add(buildDailySumRow(tid, entry.getKey(), entry.getValue(), nowStr));
|
||
}
|
||
|
||
int upserted = upsertBatch(sumRows);
|
||
boolean ok = upserted >= 0;
|
||
result.put("success", ok);
|
||
result.put("message", ok ? "按日汇总完成" : "保存失败");
|
||
result.put("generated", ok ? upserted : 0);
|
||
result.put("sourceCount", details.size());
|
||
result.put("skippedNoBuyTime", skippedNoBuyTime);
|
||
if (ok) {
|
||
result.put("data", sumRows);
|
||
}
|
||
return result;
|
||
} catch (Exception e) {
|
||
result.put("success", false);
|
||
result.put("message", "汇总异常:" + e.getMessage());
|
||
result.put("generated", 0);
|
||
return result;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> sendSellerConfirmToDingTalk(
|
||
String buyTimeStart, String buyTimeEnd, String tenantId) {
|
||
Map<String, Object> result = new HashMap<>();
|
||
try {
|
||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "tenantId不能为空");
|
||
return result;
|
||
}
|
||
String tid = tenantId.trim();
|
||
|
||
List<LbOrderRow> details = listDetailRowsByBuyTimeRange(buyTimeStart, buyTimeEnd, tid);
|
||
if (details.isEmpty()) {
|
||
result.put("success", true);
|
||
result.put("message", "时间范围内无订单明细");
|
||
result.put("recordCount", 0);
|
||
result.put("messageCount", 0);
|
||
return result;
|
||
}
|
||
|
||
List<String> sellerNames =
|
||
details.stream()
|
||
.map(this::resolveSellerDisplayName)
|
||
.distinct()
|
||
.limit(DINGTALK_SELLER_CONFIRM_BATCH_SIZE)
|
||
.collect(Collectors.toList());
|
||
|
||
int messageCount = 0;
|
||
if (!sellerNames.isEmpty()) {
|
||
dingTalkRobotService.sendText(
|
||
DINGTALK_SELLER_CONFIRM_PREFIX + String.join(",", sellerNames));
|
||
messageCount = 1;
|
||
}
|
||
|
||
result.put("success", true);
|
||
result.put("message", "发送成功");
|
||
result.put("recordCount", details.size());
|
||
result.put("messageCount", messageCount);
|
||
return result;
|
||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||
log.warn(
|
||
"发送卖家确认通知到钉钉失败, tenantId={}, buyTime={}~{}, reason={}",
|
||
tenantId,
|
||
buyTimeStart,
|
||
buyTimeEnd,
|
||
e.getMessage());
|
||
result.put("success", false);
|
||
result.put("message", e.getMessage());
|
||
return result;
|
||
} catch (Exception e) {
|
||
log.error(
|
||
"发送卖家确认通知到钉钉异常, tenantId={}, buyTime={}~{}",
|
||
tenantId,
|
||
buyTimeStart,
|
||
buyTimeEnd,
|
||
e);
|
||
result.put("success", false);
|
||
result.put("message", "发送失败:" + e.getMessage());
|
||
return result;
|
||
}
|
||
}
|
||
|
||
private List<LbOrderRow> listDetailRowsByBuyTimeRange(
|
||
String buyTimeStart, String buyTimeEnd, String tenantId) {
|
||
LambdaQueryWrapper<LbOrderRow> w = new LambdaQueryWrapper<>();
|
||
w.eq(LbOrderRow::getTenantId, tenantId);
|
||
w.eq(LbOrderRow::getDataType, SYNC_DATA_TYPE_DETAIL);
|
||
if (buyTimeStart != null && !buyTimeStart.trim().isEmpty()) {
|
||
w.ge(LbOrderRow::getBuyTime, buyTimeStart.trim());
|
||
}
|
||
if (buyTimeEnd != null && !buyTimeEnd.trim().isEmpty()) {
|
||
w.le(LbOrderRow::getBuyTime, buyTimeEnd.trim());
|
||
}
|
||
w.orderByAsc(LbOrderRow::getBuyTime).orderByAsc(LbOrderRow::getId);
|
||
return this.list(w);
|
||
}
|
||
|
||
private String resolveSellerDisplayName(LbOrderRow row) {
|
||
if (row.getSellerName() != null && !row.getSellerName().trim().isEmpty()) {
|
||
return row.getSellerName().trim();
|
||
}
|
||
if (row.getSellerId() != null) {
|
||
return String.valueOf(row.getSellerId());
|
||
}
|
||
return "未知";
|
||
}
|
||
|
||
private LbOrderRow buildDailySumRow(
|
||
String tenantId, LocalDate day, List<LbOrderRow> dayRows, String nowStr) {
|
||
BigDecimal moneySum = BigDecimal.ZERO;
|
||
int unresellCount = 0;
|
||
for (LbOrderRow row : dayRows) {
|
||
if (row.getTotalMoney() != null) {
|
||
moneySum = moneySum.add(row.getTotalMoney());
|
||
}
|
||
if (row.getIsResell() == null || row.getIsResell() != 1) {
|
||
unresellCount++;
|
||
}
|
||
}
|
||
|
||
String payTime = day.atStartOfDay().format(DAY_TIME_FMT);
|
||
Long id = resolveSumRowId(tenantId, payTime);
|
||
|
||
LbOrderRow sum = new LbOrderRow();
|
||
sum.setId(id);
|
||
sum.setTenantId(tenantId);
|
||
sum.setDataType(SUM_DATA_TYPE);
|
||
sum.setTodayTotalMoneySum(moneySum);
|
||
sum.setTodayUnresellCount(unresellCount);
|
||
sum.setTodayOrderCount(dayRows.size());
|
||
sum.setSellerId(SUM_PLACEHOLDER_USER_ID);
|
||
sum.setBuyerId(SUM_PLACEHOLDER_USER_ID);
|
||
sum.setOrderSn(SUM_ORDER_SN);
|
||
sum.setPhone("18808852688");
|
||
sum.setConsignee("老板统计");
|
||
sum.setTotalMoney(moneySum);
|
||
sum.setIsResell(1);
|
||
sum.setStatus(1);
|
||
sum.setIsShow(1);
|
||
sum.setPayTime(payTime);
|
||
sum.setBuyTime(payTime);
|
||
sum.setMerchandiseId(0L);
|
||
sum.setCreatedAt(nowStr);
|
||
sum.setUpdatedAt(nowStr);
|
||
return sum;
|
||
}
|
||
|
||
/** 同一天、同一租户已存在 sum_data 则复用其 id,否则生成占位 id */
|
||
private Long resolveSumRowId(String tenantId, String payTime) {
|
||
LambdaQueryWrapper<LbOrderRow> w = new LambdaQueryWrapper<>();
|
||
w.eq(LbOrderRow::getTenantId, tenantId)
|
||
.eq(LbOrderRow::getDataType, SUM_DATA_TYPE)
|
||
.eq(LbOrderRow::getPayTime, payTime)
|
||
.last("LIMIT 1");
|
||
LbOrderRow existing = this.getOne(w, false);
|
||
if (existing != null && existing.getId() != null) {
|
||
return existing.getId();
|
||
}
|
||
LocalDate day = LocalDate.parse(payTime.substring(0, 10), DAY_FMT);
|
||
long dayKey = day.getYear() * 10000L + day.getMonthValue() * 100L + day.getDayOfMonth();
|
||
int tenantSlot = Math.floorMod(tenantId.hashCode(), 10000);
|
||
return 10_000_000_000_000_000L + dayKey * 10_000L + tenantSlot;
|
||
}
|
||
|
||
private static LocalDate parseBuyTimeToDate(String buyTime) {
|
||
if (buyTime == null || buyTime.trim().isEmpty()) {
|
||
return null;
|
||
}
|
||
String text = buyTime.trim();
|
||
try {
|
||
return LocalDateTime.parse(text, DAY_TIME_FMT).toLocalDate();
|
||
} catch (DateTimeParseException ignored) {
|
||
// continue
|
||
}
|
||
try {
|
||
return LocalDate.parse(text.substring(0, Math.min(10, text.length())), DAY_FMT);
|
||
} catch (DateTimeParseException ignored) {
|
||
// continue
|
||
}
|
||
try {
|
||
return LocalDateTime.parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toLocalDate();
|
||
} catch (DateTimeParseException e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
private static BigDecimal parseMoney(String money) {
|
||
if (money == null || money.trim().isEmpty()) {
|
||
return null;
|
||
}
|
||
try {
|
||
return new BigDecimal(money.trim());
|
||
} catch (NumberFormatException e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 按复合主键 {@code (tenant_id, id)} 插入或更新;同批重复键保留最后一条。
|
||
*
|
||
* @return 实际 upsert 条数;无有效键时返回 0;失败返回 -1
|
||
*/
|
||
private int upsertBatch(List<LbOrderRow> entities) {
|
||
if (entities == null || entities.isEmpty()) {
|
||
return 0;
|
||
}
|
||
Map<String, LbOrderRow> deduped = new LinkedHashMap<>();
|
||
for (LbOrderRow entity : entities) {
|
||
if (entity.getId() == null) {
|
||
continue;
|
||
}
|
||
String tenantId = trimToNull(entity.getTenantId());
|
||
if (tenantId == null) {
|
||
continue;
|
||
}
|
||
entity.setTenantId(tenantId);
|
||
deduped.put(compositeKey(tenantId, entity.getId()), entity);
|
||
}
|
||
if (deduped.isEmpty()) {
|
||
return 0;
|
||
}
|
||
List<LbOrderRow> rows = new ArrayList<>(deduped.values());
|
||
try {
|
||
baseMapper.upsertBatch(rows);
|
||
return rows.size();
|
||
} catch (Exception e) {
|
||
log.error("lb_order_row upsertBatch failed, size={}", rows.size(), e);
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 按 seller_id 关联 lb_department_user.user_id,用部门用户的 name、phone 填充卖方姓名与电话。
|
||
*/
|
||
private void fillSellerInfoFromDepartmentUsers(List<LbOrderRow> entities, String tenantId) {
|
||
if (entities == null || entities.isEmpty()) {
|
||
return;
|
||
}
|
||
Set<Long> sellerIds = new HashSet<>();
|
||
for (LbOrderRow entity : entities) {
|
||
if (entity.getSellerId() != null) {
|
||
sellerIds.add(entity.getSellerId());
|
||
}
|
||
}
|
||
if (sellerIds.isEmpty()) {
|
||
return;
|
||
}
|
||
List<String> userIdStrs = new ArrayList<>(sellerIds.size());
|
||
for (Long sellerId : sellerIds) {
|
||
userIdStrs.add(String.valueOf(sellerId));
|
||
}
|
||
log.info("sellerIds:{}",userIdStrs.toString());
|
||
LambdaQueryWrapper<LbDepartmentUser> w = new LambdaQueryWrapper<>();
|
||
w.eq(LbDepartmentUser::getTenantId, tenantId)
|
||
.in(LbDepartmentUser::getUserId, userIdStrs);
|
||
List<LbDepartmentUser> users = lbDepartmentUserService.list(w);
|
||
Map<String, LbDepartmentUser> byUserId = new LinkedHashMap<>();
|
||
for (LbDepartmentUser user : users) {
|
||
if (user.getUserId() != null && !byUserId.containsKey(user.getUserId())) {
|
||
byUserId.put(user.getUserId(), user);
|
||
}
|
||
}
|
||
for (LbOrderRow entity : entities) {
|
||
if (entity.getSellerId() == null) {
|
||
continue;
|
||
}
|
||
LbDepartmentUser user = byUserId.get(String.valueOf(entity.getSellerId()));
|
||
if (user != null) {
|
||
entity.setSellerName(user.getName());
|
||
entity.setSellerPhone(user.getPhone());
|
||
}
|
||
}
|
||
}
|
||
@Autowired
|
||
private ILbUserService lbUserService;
|
||
/**
|
||
* 按 buyer_id 关联 lb_department_user.user_id,用部门用户的 name、phone 填充买方姓名与电话。
|
||
*/
|
||
private void fillBuyerInfoFromLBtUsers(List<LbOrderRow> entities, String tenantId) {
|
||
if (entities == null || entities.isEmpty()) {
|
||
return;
|
||
}
|
||
Set<Long> buyerIds = new HashSet<>();
|
||
for (LbOrderRow entity : entities) {
|
||
if (entity.getBuyerId() != null) {
|
||
buyerIds.add(entity.getBuyerId());
|
||
}
|
||
}
|
||
if (buyerIds.isEmpty()) {
|
||
return;
|
||
}
|
||
List<String> userIdStrs = new ArrayList<>(buyerIds.size());
|
||
for (Long buyerId : buyerIds) {
|
||
userIdStrs.add(String.valueOf(buyerId));
|
||
}
|
||
log.info("buyerIds:{}", userIdStrs.toString());
|
||
LambdaQueryWrapper<LbUser> w = new LambdaQueryWrapper<>();
|
||
w.eq(LbUser::getTenantId, tenantId)
|
||
.in(LbUser::getId, userIdStrs);
|
||
List<LbUser> users = lbUserService.list(w);
|
||
Map<String, LbUser> byUserId = new LinkedHashMap<>();
|
||
for (LbUser user : users) {
|
||
if (user.getId() != null && !byUserId.containsKey(user.getId())) {
|
||
byUserId.put(user.getId().toString(), user);
|
||
}
|
||
}
|
||
for (LbOrderRow entity : entities) {
|
||
if (entity.getBuyerId() == null) {
|
||
continue;
|
||
}
|
||
LbUser user = byUserId.get(String.valueOf(entity.getBuyerId()));
|
||
if (user != null) {
|
||
entity.setBuyerName(user.getNickname());
|
||
entity.setBuyerPhone(user.getMobile());
|
||
}
|
||
}
|
||
}
|
||
|
||
private static LbOrderRow toLbOrderRow(HxrOrderRow row, String tenantId) {
|
||
LbOrderRow e = new LbOrderRow();
|
||
e.setId(row.id());
|
||
e.setOldId(row.oldId());
|
||
e.setTenantId(tenantId);
|
||
e.setDataType(SYNC_DATA_TYPE_DETAIL);
|
||
e.setTodayTotalMoneySum(BigDecimal.ZERO);
|
||
e.setTodayOrderCount(0);
|
||
e.setTodayUnresellCount(0);
|
||
e.setSellerId(row.sellerId());
|
||
e.setSellerName(row.sellerName());
|
||
e.setSellerPhone(row.sellerPhone());
|
||
e.setBuyerId(row.buyerId());
|
||
e.setBuyerName(row.buyerName());
|
||
e.setBuyerPhone(row.buyerPhone());
|
||
e.setOrderSn(row.orderSn());
|
||
e.setTotalMoney(parseMoney(row.totalMoney()));
|
||
e.setPayTime(row.payTime());
|
||
e.setPayImg(row.payImg());
|
||
e.setStatus(row.status());
|
||
e.setIsResell(row.isResell());
|
||
e.setIsShow(row.isShow());
|
||
e.setConsignee(row.consignee());
|
||
e.setPhone(row.phone());
|
||
e.setProvince(row.province());
|
||
e.setCity(row.city());
|
||
e.setArea(row.area());
|
||
e.setAddress(row.address());
|
||
e.setMerchandiseId(row.merchandiseId());
|
||
e.setConfirmTime(row.confirmTime());
|
||
e.setBuyTime(row.buyTime());
|
||
e.setCreatedAt(row.createdAt());
|
||
e.setUpdatedAt(row.updatedAt());
|
||
return e;
|
||
}
|
||
|
||
private LbOrderRow getByTenantAndId(String tenantId, Long id) {
|
||
if (trimToNull(tenantId) == null || id == null) {
|
||
return null;
|
||
}
|
||
return this.getOne(
|
||
new LambdaQueryWrapper<LbOrderRow>()
|
||
.eq(LbOrderRow::getTenantId, tenantId.trim())
|
||
.eq(LbOrderRow::getId, id),
|
||
false);
|
||
}
|
||
|
||
private String resolveTenantId(String tenantIdFromParam) {
|
||
String current = trimToNull(TenantContextHolder.getTenantId());
|
||
if (current != null) {
|
||
return current;
|
||
}
|
||
return trimToNull(tenantIdFromParam);
|
||
}
|
||
|
||
private static String compositeKey(String tenantId, Long id) {
|
||
return tenantId + ":" + id;
|
||
}
|
||
|
||
private static String trimToNull(String value) {
|
||
if (value == null) {
|
||
return null;
|
||
}
|
||
String trimmed = value.trim();
|
||
return trimmed.isEmpty() ? null : trimmed;
|
||
}
|
||
}
|