调度补齐卖家姓名和电话
This commit is contained in:
@@ -17,11 +17,28 @@ public class HxrAdminProperties {
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 完整请求 URL(含查询串),与浏览器地址栏一致即可。
|
||||
* 订单列表基础 URL(含分页等通用查询串);各业务在代码中覆盖查询参数,或使用独立 URL 配置。
|
||||
*/
|
||||
private String orderSelectUrl =
|
||||
"https://hxrdhoutai.hxrdsm.cn/app/admin/order/select?page=1&limit=90";
|
||||
|
||||
/**
|
||||
* 未支付订单拉取 URL(含 {@code status=0} 等业务筛选),供 {@link LBAdminPullScheduler#pullOrdersForUnPay} 使用。
|
||||
*/
|
||||
private String orderSelectUnPayUrl =
|
||||
"https://hxrdhoutai.hxrdsm.cn/app/admin/order/select?page=1&limit=90&status=0";
|
||||
|
||||
/**
|
||||
* 已支付订单拉取 URL(含 {@code status=1}),供 {@link LBAdminPullScheduler#pullOrdersForUnPay} 使用。
|
||||
*/
|
||||
private String orderSelectPaidUrl =
|
||||
"https://hxrdhoutai.hxrdsm.cn/app/admin/order/select?page=1&limit=90&status=1";
|
||||
|
||||
/**
|
||||
* 定时将 hxrd 订单同步到 {@code lb_order_row} 时使用的租户 id;未配置时跳过订单状态同步。
|
||||
*/
|
||||
private String syncTenantId = "TENANT_ID_CST_2026";
|
||||
|
||||
/**
|
||||
* 请求头 Cookie 完整取值,例如 {@code PHPSID=xxxx}。非空时优先于 {@link #phpsid}。
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,8 @@ public record HxrOrderRow(
|
||||
long id,
|
||||
Long oldId,
|
||||
long sellerId,
|
||||
String sellerName,
|
||||
String sellerPhone,
|
||||
long buyerId,
|
||||
String orderSn,
|
||||
String totalMoney,
|
||||
|
||||
@@ -40,6 +40,14 @@ public class LbOrderRow implements Serializable {
|
||||
@Schema(description = "卖家 id")
|
||||
private Long sellerId;
|
||||
|
||||
@TableField("seller_name")
|
||||
@Schema(description = "卖家姓名")
|
||||
private String sellerName;
|
||||
|
||||
@TableField("seller_phone")
|
||||
@Schema(description = "卖家电话")
|
||||
private String sellerPhone;
|
||||
|
||||
@TableField("buyer_id")
|
||||
@Schema(description = "买家 id")
|
||||
private Long buyerId;
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
package com.rj.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.rj.entity.LbOrderRow;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface LbOrderRowMapper extends BaseMapper<LbOrderRow> {
|
||||
|
||||
/**
|
||||
* 按订单 id(主键)插入或更新;跳过租户行拦截,避免 listByIds 因 tenant_id 过滤漏判导致重复插入。
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
int upsertBatch(@Param("list") List<LbOrderRow> list);
|
||||
}
|
||||
|
||||
@@ -3,16 +3,21 @@ package com.rj.scheduler;
|
||||
import com.rj.config.AppConfig;
|
||||
import com.rj.config.HxrAdminProperties;
|
||||
import com.rj.service.HxrAdminOrderSelectService;
|
||||
import com.rj.service.ILbOrderRowService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* hxrd 后台订单列表定时拉取:每 50 分钟触发一次,仅工作日(周一至周五)且在每天 18:10~23:59:59(应用时区)内真正执行。
|
||||
@@ -22,11 +27,15 @@ import java.time.ZonedDateTime;
|
||||
@RequiredArgsConstructor
|
||||
public class LBAdminPullScheduler {
|
||||
|
||||
private static final long FIFTY_MINUTES_MS = 50L * 60L * 1000L;
|
||||
private static final long FIFTY_MINUTES_MS = 30L * 60L * 1000L;
|
||||
private static final long UnPay_MINUTES_MS = 20L * 60L * 1000L;
|
||||
|
||||
private static final DateTimeFormatter BUY_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private final AppConfig appConfig;
|
||||
private final HxrAdminProperties hxrAdminProperties;
|
||||
private final HxrAdminOrderSelectService hxrAdminOrderSelectService;
|
||||
private final ILbOrderRowService lbOrderRowService;
|
||||
private final Clock clock;
|
||||
|
||||
@Scheduled(
|
||||
@@ -63,4 +72,80 @@ public class LBAdminPullScheduler {
|
||||
log.error("未寄卖 admin 订单拉取失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int HXR_ORDER_STATUS_UNPAID = 0;
|
||||
private static final int HXR_ORDER_STATUS_PAID = 1;
|
||||
|
||||
/**
|
||||
* 未支付/已支付订单同步:工作日每天 11:00~15:00(应用时区),仅在窗口内真正执行。
|
||||
*/
|
||||
@Scheduled(
|
||||
fixedRate = UnPay_MINUTES_MS,
|
||||
initialDelayString = "${hxr.admin.pull-initial-delay-ms:0}")
|
||||
public void pullOrdersForUnPay() {
|
||||
try {
|
||||
if (!appConfig.getScheduler().isStart()) {
|
||||
log.debug("全局调度未启用,跳过 未支付 订单拉取");
|
||||
return;
|
||||
}
|
||||
if (!hxrAdminProperties.isEnabled()) {
|
||||
log.debug("hxr.admin.enabled=false,跳过订单拉取");
|
||||
return;
|
||||
}
|
||||
ZoneId zone = ZoneId.of(appConfig.getTimezone());
|
||||
ZonedDateTime nowZdt = ZonedDateTime.now(clock.withZone(zone));
|
||||
DayOfWeek dow = nowZdt.getDayOfWeek();
|
||||
if (dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY) {
|
||||
log.debug("当前为周末 {},跳过 未支付 订单拉取", dow);
|
||||
return;
|
||||
}
|
||||
LocalTime now = nowZdt.toLocalTime();
|
||||
LocalTime windowStart = LocalTime.of(11, 0);
|
||||
LocalTime windowEnd = LocalTime.of(15, 0);
|
||||
if (now.isBefore(windowStart) || now.isAfter(windowEnd)) {
|
||||
log.debug("当前时刻 {} 不在窗口 {}~{},跳过 未支付 订单拉取", now, windowStart, windowEnd);
|
||||
return;
|
||||
}
|
||||
|
||||
String tenantId = hxrAdminProperties.getSyncTenantId();
|
||||
if (tenantId == null || tenantId.isBlank()) {
|
||||
log.warn("hxr.admin.sync-tenant-id 未配置,跳过订单状态同步");
|
||||
return;
|
||||
}
|
||||
|
||||
LocalDate today = nowZdt.toLocalDate();
|
||||
String buyTimeStart = today.atStartOfDay().format(BUY_TIME_FMT);
|
||||
String buyTimeEnd = today.atTime(23, 59, 59).format(BUY_TIME_FMT);
|
||||
String tid = tenantId.trim();
|
||||
|
||||
syncOrdersByHxrStatus(tid, buyTimeStart, buyTimeEnd, HXR_ORDER_STATUS_UNPAID, "未支付");
|
||||
syncOrdersByHxrStatus(tid, buyTimeStart, buyTimeEnd, HXR_ORDER_STATUS_PAID, "已支付");
|
||||
} catch (Exception e) {
|
||||
log.error("订单状态同步失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncOrdersByHxrStatus(
|
||||
String tenantId, String buyTimeStart, String buyTimeEnd, int hxrOrderStatus, String label) {
|
||||
log.info(
|
||||
"开始执行 {} 订单同步 status={} tenantId={} buyTime={}~{}",
|
||||
label,
|
||||
hxrOrderStatus,
|
||||
tenantId,
|
||||
buyTimeStart,
|
||||
buyTimeEnd);
|
||||
Map<String, Object> syncResult =
|
||||
lbOrderRowService.syncFromHxrAdmin(buyTimeStart, buyTimeEnd, tenantId, null, hxrOrderStatus);
|
||||
if (Boolean.TRUE.equals(syncResult.get("success"))) {
|
||||
log.info(
|
||||
"{}订单同步完成 synced={} remoteCount={}",
|
||||
label,
|
||||
syncResult.get("synced"),
|
||||
syncResult.get("remoteCount"));
|
||||
} else {
|
||||
log.warn("{}订单同步失败: {}", label, syncResult.get("message"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,13 @@ public class HxrAdminOrderSelectService {
|
||||
return fetchOrderSelectInternal(properties.getOrderSelectUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取未支付订单,使用 {@link HxrAdminProperties#getOrderSelectUnPayUrl()}。
|
||||
*/
|
||||
public Optional<HxrOrderSelectResponse> fetchUnpaidOrderSelect() throws Exception {
|
||||
return fetchOrderSelectInternal(properties.getOrderSelectUnPayUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 按购买时间区间、转卖状态等条件拉取订单列表(在配置的 {@code orderSelectUrl} 上覆盖查询参数)。
|
||||
*
|
||||
@@ -62,6 +69,24 @@ public class HxrAdminOrderSelectService {
|
||||
return fetchOrderSelectInternal(buildOrderSelectUrl(buyTimeStart, buyTimeEnd, isResell, page));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按购买时间区间及页码拉取未支付订单({@code status=0},基于 {@link HxrAdminProperties#getOrderSelectUnPayUrl()})。
|
||||
*/
|
||||
public Optional<HxrOrderSelectResponse> fetchUnpaidOrderSelect(
|
||||
String buyTimeStart, String buyTimeEnd, int page) throws Exception {
|
||||
return fetchOrderSelectInternal(
|
||||
buildStatusOrderSelectUrl(properties.getOrderSelectUnPayUrl(), buyTimeStart, buyTimeEnd, page));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按购买时间区间及页码拉取已支付订单({@code status=1},基于 {@link HxrAdminProperties#getOrderSelectPaidUrl()})。
|
||||
*/
|
||||
public Optional<HxrOrderSelectResponse> fetchPaidOrderSelect(
|
||||
String buyTimeStart, String buyTimeEnd, int page) throws Exception {
|
||||
return fetchOrderSelectInternal(
|
||||
buildStatusOrderSelectUrl(properties.getOrderSelectPaidUrl(), buyTimeStart, buyTimeEnd, page));
|
||||
}
|
||||
|
||||
private Optional<HxrOrderSelectResponse> fetchOrderSelectInternal(String requestUri) throws Exception {
|
||||
String cookieHeader = properties.resolveCookieHeader();
|
||||
if (cookieHeader == null || cookieHeader.isBlank()) {
|
||||
@@ -115,16 +140,35 @@ public class HxrAdminOrderSelectService {
|
||||
return b.build().encode().toUriString();
|
||||
}
|
||||
|
||||
private String buildStatusOrderSelectUrl(String baseUrl, String buyTimeStart, String buyTimeEnd, int page) {
|
||||
UriComponentsBuilder b = UriComponentsBuilder.fromUriString(baseUrl);
|
||||
b.replaceQueryParam("buy_time[0]", buyTimeStart == null ? "" : buyTimeStart);
|
||||
b.replaceQueryParam("buy_time[1]", buyTimeEnd == null ? "" : buyTimeEnd);
|
||||
b.replaceQueryParam("page", Math.max(1, page));
|
||||
return b.build().encode().toUriString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取并逐条打日志(一行一条 JSON)。
|
||||
*/
|
||||
public void fetchAndLogEachOrder() throws Exception {
|
||||
Optional<HxrOrderSelectResponse> opt = fetchOrderSelect();
|
||||
fetchAndLogEachOrder(fetchOrderSelect(), "未寄卖");
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取未支付订单({@code status=0})并逐条打日志。
|
||||
*/
|
||||
public void fetchAndLogUnpaidOrders() throws Exception {
|
||||
fetchAndLogEachOrder(fetchUnpaidOrderSelect(), "未支付");
|
||||
}
|
||||
|
||||
private void fetchAndLogEachOrder(
|
||||
Optional<HxrOrderSelectResponse> opt, String label) throws Exception {
|
||||
if (opt.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
HxrOrderSelectResponse body = opt.get();
|
||||
log.info("未寄卖 order/select ok count={} allMoney={}", body.count(), body.allMoney());
|
||||
log.info("{} order/select ok count={} allMoney={}", label, body.count(), body.allMoney());
|
||||
for (HxrOrderRow row : body.data()) {
|
||||
log.info("hxr order row {}", JSON.writeValueAsString(row));
|
||||
}
|
||||
|
||||
@@ -34,6 +34,17 @@ public interface ILbOrderRowService extends IService<LbOrderRow> {
|
||||
String tenantId,
|
||||
Integer isResell);
|
||||
|
||||
/**
|
||||
* 同 {@link #syncFromHxrAdmin(String, String, String, Integer)};{@code hxrOrderStatus} 非空时按后台
|
||||
* {@code status} 筛选拉取(如 {@code 0} 未支付、{@code 1} 已支付),为 null 时使用通用订单列表 URL。
|
||||
*/
|
||||
Map<String, Object> syncFromHxrAdmin(
|
||||
String buyTimeStart,
|
||||
String buyTimeEnd,
|
||||
String tenantId,
|
||||
Integer isResell,
|
||||
Integer hxrOrderStatus);
|
||||
|
||||
/**
|
||||
* 按购买时间区间与租户查询明细,按天汇总为 {@code sum_data} 写入 {@code lb_order_row}。
|
||||
*/
|
||||
|
||||
@@ -5,10 +5,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
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.mapper.LbOrderRowMapper;
|
||||
import com.rj.service.HxrAdminOrderSelectService;
|
||||
import com.rj.service.ILbDepartmentUserService;
|
||||
import com.rj.service.ILbOrderRowService;
|
||||
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;
|
||||
@@ -20,11 +24,14 @@ 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;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrderRow> implements ILbOrderRowService {
|
||||
|
||||
@@ -47,6 +54,9 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
@Autowired
|
||||
private HxrAdminOrderSelectService hxrAdminOrderSelectService;
|
||||
|
||||
@Autowired
|
||||
private ILbDepartmentUserService lbDepartmentUserService;
|
||||
|
||||
@Override
|
||||
public Map<String, Object> add(LbOrderRow entity) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
@@ -224,6 +234,13 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
@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()) {
|
||||
@@ -234,13 +251,15 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
|
||||
|
||||
String tid = tenantId.trim();
|
||||
String previousTenantId = TenantContextHolder.getTenantId();
|
||||
TenantContextHolder.setTenantId(tid);
|
||||
try {
|
||||
HxrOrderSelectResponse firstBody = null;
|
||||
int page = 1;
|
||||
int totalSynced = 0;
|
||||
while (true) {
|
||||
Optional<HxrOrderSelectResponse> opt =
|
||||
hxrAdminOrderSelectService.fetchOrderSelect(
|
||||
buyTimeStart, buyTimeEnd, isResell, page);
|
||||
fetchHxrOrderPage(buyTimeStart, buyTimeEnd, isResell, hxrOrderStatus, page);
|
||||
if (opt.isEmpty()) {
|
||||
if (page == 1) {
|
||||
result.put("success", false);
|
||||
@@ -273,9 +292,9 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
for (HxrOrderRow row : rows) {
|
||||
entities.add(toLbOrderRow(row, tid));
|
||||
}
|
||||
|
||||
boolean ok = this.saveOrUpdateBatch(entities);
|
||||
if (!ok) {
|
||||
fillSellerInfoFromDepartmentUsers(entities, tid);
|
||||
int upserted = upsertBatch(entities);
|
||||
if (upserted < 0) {
|
||||
result.put("success", false);
|
||||
result.put("message", "第 " + page + " 页保存失败,已成功同步前 "
|
||||
+ (page - 1) + " 页共 " + totalSynced + " 条");
|
||||
@@ -285,7 +304,7 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
result.put("pages", page - 1);
|
||||
return result;
|
||||
}
|
||||
totalSynced += entities.size();
|
||||
totalSynced += upserted;
|
||||
|
||||
if (rows.size() < HXR_ORDER_PAGE_SIZE ) {
|
||||
break;
|
||||
@@ -309,14 +328,40 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
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)
|
||||
throws Exception {
|
||||
if (hxrOrderStatus != null) {
|
||||
if (hxrOrderStatus == 0) {
|
||||
return hxrAdminOrderSelectService.fetchUnpaidOrderSelect(buyTimeStart, buyTimeEnd, page);
|
||||
}
|
||||
if (hxrOrderStatus == 1) {
|
||||
return hxrAdminOrderSelectService.fetchPaidOrderSelect(buyTimeStart, buyTimeEnd, page);
|
||||
}
|
||||
}
|
||||
return hxrAdminOrderSelectService.fetchOrderSelect(buyTimeStart, buyTimeEnd, isResell, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> generateDailySumData(
|
||||
@@ -373,10 +418,11 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
sumRows.add(buildDailySumRow(tid, entry.getKey(), entry.getValue(), nowStr));
|
||||
}
|
||||
|
||||
boolean ok = this.saveOrUpdateBatch(sumRows);
|
||||
int upserted = upsertBatch(sumRows);
|
||||
boolean ok = upserted >= 0;
|
||||
result.put("success", ok);
|
||||
result.put("message", ok ? "按日汇总完成" : "保存失败");
|
||||
result.put("generated", ok ? sumRows.size() : 0);
|
||||
result.put("generated", ok ? upserted : 0);
|
||||
result.put("sourceCount", details.size());
|
||||
result.put("skippedNoBuyTime", skippedNoBuyTime);
|
||||
if (ok) {
|
||||
@@ -481,6 +527,78 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按外部订单 id(主键)插入或更新;同批重复 id 保留最后一条。
|
||||
*
|
||||
* @return 实际 upsert 条数;无有效 id 时返回 0;失败返回 -1
|
||||
*/
|
||||
private int upsertBatch(List<LbOrderRow> entities) {
|
||||
if (entities == null || entities.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
Map<Long, LbOrderRow> deduped = new LinkedHashMap<>();
|
||||
for (LbOrderRow entity : entities) {
|
||||
if (entity.getId() != null) {
|
||||
deduped.put(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));
|
||||
}
|
||||
LambdaQueryWrapper<LbDepartmentUser> w = new LambdaQueryWrapper<>();
|
||||
w.eq(LbDepartmentUser::getTenantId, tenantId)
|
||||
.in(LbDepartmentUser::getUserId, userIdStrs)
|
||||
.orderByDesc(LbDepartmentUser::getUpdateTime)
|
||||
.orderByDesc(LbDepartmentUser::getCreateTime);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static LbOrderRow toLbOrderRow(HxrOrderRow row, String tenantId) {
|
||||
LbOrderRow e = new LbOrderRow();
|
||||
e.setId(row.id());
|
||||
@@ -491,6 +609,8 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
||||
e.setTodayOrderCount(0);
|
||||
e.setTodayUnresellCount(0);
|
||||
e.setSellerId(row.sellerId());
|
||||
e.setSellerName(row.sellerName());
|
||||
e.setSellerPhone(row.sellerPhone());
|
||||
e.setBuyerId(row.buyerId());
|
||||
e.setOrderSn(row.orderSn());
|
||||
e.setTotalMoney(parseMoney(row.totalMoney()));
|
||||
|
||||
@@ -600,7 +600,7 @@ public class LbPurchaseApplyServiceImpl
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
LocalDateTime vipTime = HxrAdminUserService.computeVipExpireTime(row.getApplyDate(), 3);
|
||||
LocalDateTime vipTime = HxrAdminUserService.computeVipExpireTime(row.getApplyDate(), 2);
|
||||
String vipTimeStr = HxrAdminUserService.formatVipTime(vipTime);
|
||||
one.put("viptime", vipTimeStr);
|
||||
|
||||
@@ -940,7 +940,6 @@ public class LbPurchaseApplyServiceImpl
|
||||
.orderByAsc(LbPurchaseApply::getApplyDate)
|
||||
.orderByAsc(LbPurchaseApply::getId);
|
||||
List<LbPurchaseApply> rows = this.list(queryWrapper);
|
||||
Map<String, Integer> maxOrderByColleaguePhone = loadColleagueMaxOrderCache(rows);
|
||||
|
||||
LinkedHashMap<LocalDate, List<LbPurchaseApply>> grouped = new LinkedHashMap<>();
|
||||
for (LbPurchaseApply row : rows) {
|
||||
@@ -983,7 +982,7 @@ public class LbPurchaseApplyServiceImpl
|
||||
createExportCell(row, 2, nullToEmpty(item.getApplyUser()), dataStyle);
|
||||
createExportCell(row, 3, nullToEmpty(item.getApplyPhone()), dataStyle);
|
||||
createExportCell(row, 4, formatPrivilegeRange(item), dataStyle);
|
||||
createExportCell(row, 5, formatRecommender(item, maxOrderByColleaguePhone), dataStyle);
|
||||
createExportCell(row, 5, formatRecommender(item), dataStyle);
|
||||
createExportCell(row, 6, nullToEmpty(item.getColleaguePhone()), dataStyle);
|
||||
createExportCell(row, 7, nullToEmpty(item.getTeamLeader()), dataStyle);
|
||||
createExportCell(row, 8, formatActivationDate(item.getApplyDate()), dataStyle);
|
||||
@@ -1026,25 +1025,6 @@ public class LbPurchaseApplyServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Integer> loadColleagueMaxOrderCache(List<LbPurchaseApply> rows) {
|
||||
Map<String, Integer> cache = new HashMap<>();
|
||||
Set<String> phones = new HashSet<>();
|
||||
for (LbPurchaseApply row : rows) {
|
||||
if (row.getColleaguePhone() != null && !row.getColleaguePhone().trim().isEmpty()) {
|
||||
phones.add(row.getColleaguePhone().trim());
|
||||
}
|
||||
}
|
||||
for (String phone : phones) {
|
||||
try {
|
||||
Optional<HxrUserRow> userOpt = hxrAdminUserService.fetchFirstUserByMobile(phone);
|
||||
userOpt.map(HxrUserRow::maxOrder).ifPresent(maxOrder -> cache.put(phone, maxOrder));
|
||||
} catch (Exception ex) {
|
||||
log.debug("导出时查询推荐人 max_order 失败,phone={}", phone, ex);
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
private static String formatDatePeopleLabel(LocalDate applyDate, int count) {
|
||||
if (applyDate == null || applyDate.equals(LocalDate.MIN)) {
|
||||
return "未知日期招商" + count + "人";
|
||||
@@ -1062,20 +1042,12 @@ public class LbPurchaseApplyServiceImpl
|
||||
return start.format(PRIVILEGE_RANGE_FMT) + " 到 " + endDate.format(PRIVILEGE_RANGE_FMT);
|
||||
}
|
||||
|
||||
private static String formatRecommender(LbPurchaseApply item, Map<String, Integer> maxOrderByPhone) {
|
||||
private static String formatRecommender(LbPurchaseApply item) {
|
||||
String name = item.getColleagueName();
|
||||
if (name == null || name.trim().isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
String trimmedName = name.trim();
|
||||
String phone = item.getColleaguePhone() == null ? "" : item.getColleaguePhone().trim();
|
||||
if (!phone.isEmpty()) {
|
||||
Integer maxOrder = maxOrderByPhone.get(phone);
|
||||
if (maxOrder != null) {
|
||||
return trimmedName + " " + maxOrder;
|
||||
}
|
||||
}
|
||||
return trimmedName;
|
||||
return name.trim();
|
||||
}
|
||||
|
||||
private static String formatActivationDate(LocalDate applyDate) {
|
||||
|
||||
Reference in New Issue
Block a user