拉取买家订单列表

This commit is contained in:
2026-06-06 07:32:52 +08:00
parent 1a44a5befb
commit 1477ec943b
13 changed files with 714 additions and 2 deletions

View File

@@ -3,18 +3,31 @@ 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.LbBuyerShoppingPullRequest;
import com.rj.dto.hxr.HxrBuyerOrderApiContext;
import com.rj.dto.hxr.HxrOrderRow;
import com.rj.dto.hxr.HxrUserLoginApiContext;
import com.rj.entity.LbBuyerShopping;
import com.rj.mapper.LbBuyerShoppingMapper;
import com.rj.service.HxrAdminBuyerOrderSelectService;
import com.rj.service.HxrAdminUserLoginService;
import com.rj.service.ILbBuyerShoppingService;
import com.rj.service.ILbThirdIntegrationConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 买方购物表 lb_buyer_shopping 服务实现
@@ -25,6 +38,17 @@ public class LbBuyerShoppingServiceImpl
extends ServiceImpl<LbBuyerShoppingMapper, LbBuyerShopping>
implements ILbBuyerShoppingService {
private static final String DEFAULT_SIMULATE_LOGIN_PASSWORD = "123456";
@Autowired
private ILbThirdIntegrationConfigService lbThirdIntegrationConfigService;
@Autowired
private HxrAdminUserLoginService hxrAdminUserLoginService;
@Autowired
private HxrAdminBuyerOrderSelectService hxrAdminBuyerOrderSelectService;
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -261,6 +285,311 @@ public class LbBuyerShoppingServiceImpl
}
}
@Override
public Map<String, Object> pullFromThirdParty(LbBuyerShoppingPullRequest request) {
Map<String, Object> result = new HashMap<>();
try {
if (request == null) {
result.put("success", false);
result.put("message", "请求体不能为空");
return result;
}
if (request.getTenantId() == null || request.getTenantId().trim().isEmpty()) {
result.put("success", false);
result.put("message", "tenantId不能为空");
return result;
}
if (request.getMobiles() == null || request.getMobiles().isEmpty()) {
result.put("success", false);
result.put("message", "手机号列表不能为空");
return result;
}
String tenantId = request.getTenantId().trim();
Optional<HxrUserLoginApiContext> loginCtxOpt =
lbThirdIntegrationConfigService.resolveUserLoginApiContext(tenantId);
if (loginCtxOpt.isEmpty()) {
result.put("success", false);
result.put("message",
"未找到该租户的第三方集成配置或配置未启用、URL 不完整(请检查 lb_third_integration_config");
return result;
}
HxrUserLoginApiContext loginCtx = loginCtxOpt.get();
List<Map<String, Object>> items = new ArrayList<>();
int successCount = 0;
int failCount = 0;
int totalSaved = 0;
int totalFetched = 0;
String requestPassword = request.getPassword() != null ? request.getPassword().trim() : "";
for (String rawMobile : request.getMobiles()) {
Map<String, Object> item = new LinkedHashMap<>();
if (rawMobile == null || rawMobile.trim().isEmpty()) {
item.put("mobile", rawMobile);
item.put("loginSuccess", false);
item.put("orderFetchSuccess", false);
item.put("apiCode", -1);
item.put("apiMsg", "手机号为空");
items.add(item);
failCount++;
continue;
}
String mobile = rawMobile.trim();
item.put("mobile", mobile);
String password = !requestPassword.isEmpty()
? requestPassword
: DEFAULT_SIMULATE_LOGIN_PASSWORD;
try {
HxrAdminUserLoginService.LoginApiResult loginResult =
hxrAdminUserLoginService.login(mobile, password, loginCtx);
item.put("httpStatus", loginResult.httpStatus());
item.put("apiCode", loginResult.apiCode());
item.put("apiMsg", loginResult.apiMsg());
item.put("loginSuccess", loginResult.success());
item.put("parsed", loginResult.parsed());
if (!loginResult.success()) {
item.put("orderFetchSuccess", false);
failCount++;
items.add(item);
continue;
}
String token = HxrAdminUserLoginService.extractToken(loginResult.parsed());
if (token == null || token.isBlank()) {
item.put("orderFetchSuccess", false);
item.put("orderFetchMsg", "响应中无 data.userinfo.token");
failCount++;
items.add(item);
continue;
}
Optional<HxrBuyerOrderApiContext> orderCtxOpt =
lbThirdIntegrationConfigService.resolveBuyerOrderApiContext(tenantId, token);
if (orderCtxOpt.isEmpty()) {
item.put("orderFetchSuccess", false);
item.put("orderFetchMsg",
"未找到买方订单 API 配置或配置未启用、URL/凭证不完整(请检查 lb_third_integration_config");
failCount++;
items.add(item);
continue;
}
HxrBuyerOrderApiContext orderCtx = orderCtxOpt.get();
item.put("buyerOrderListUrl", orderCtx.buyerOrderListBaseUrl());
Map<String, Object> fetchResult = fetchAndSaveBuyerOrders(orderCtx, mobile);
item.putAll(fetchResult);
if (Boolean.TRUE.equals(fetchResult.get("orderFetchSuccess"))) {
successCount++;
totalSaved += toInt(fetchResult.get("ordersSaved"));
totalFetched += toInt(fetchResult.get("ordersFetched"));
} else {
failCount++;
}
} catch (Exception e) {
log.warn("买方购物第三方拉取异常 mobile={} tenantId={}", mobile, tenantId, e);
item.put("loginSuccess", false);
item.put("orderFetchSuccess", false);
item.put("apiCode", -1);
item.put("apiMsg", "请求异常:" + e.getMessage());
failCount++;
}
items.add(item);
}
result.put("success", true);
result.put("message", "买方购物列表拉取完成");
result.put("data", items);
result.put("successCount", successCount);
result.put("failCount", failCount);
result.put("ordersSaved", totalSaved);
result.put("ordersFetched", totalFetched);
result.put("loginApiUrl", loginCtx.loginApiUrl());
return result;
} catch (Exception e) {
log.error("买方购物第三方拉取异常", e);
result.put("success", false);
result.put("message", "拉取异常:" + e.getMessage());
return result;
}
}
private Map<String, Object> fetchAndSaveBuyerOrders(HxrBuyerOrderApiContext ctx, String buyerMobile) {
Map<String, Object> result = new LinkedHashMap<>();
int page = 1;
int totalSaved = 0;
int totalFetched = 0;
Integer remoteCount = null;
String allMoney = null;
HxrAdminBuyerOrderSelectService.BuyerOrderPageResult firstPage = null;
try {
while (true) {
Optional<HxrAdminBuyerOrderSelectService.BuyerOrderPageResult> opt =
hxrAdminBuyerOrderSelectService.fetchBuyerOrderPage(page, ctx);
if (opt.isEmpty()) {
if (page == 1) {
result.put("orderFetchSuccess", false);
result.put("orderFetchMsg",
"未拉取到买方订单(请检查 lb_third_integration_config 中 token、appStr、URL 或网络)");
result.put("ordersSaved", 0);
result.put("ordersFetched", 0);
return result;
}
result.put("orderFetchSuccess", false);
result.put("orderFetchMsg", "" + page + " 页拉取失败,已成功保存前 "
+ (page - 1) + " 页共 " + totalSaved + " 条订单");
result.put("ordersSaved", totalSaved);
result.put("ordersFetched", totalFetched);
if (remoteCount != null) {
result.put("remoteCount", remoteCount);
}
if (allMoney != null) {
result.put("allMoney", allMoney);
}
result.put("orderPages", page - 1);
return result;
}
HxrAdminBuyerOrderSelectService.BuyerOrderPageResult pageResult = opt.get();
if (firstPage == null) {
firstPage = pageResult;
remoteCount = pageResult.count();
allMoney = pageResult.allMoney();
}
List<HxrOrderRow> rows = pageResult.rows();
if (rows == null || rows.isEmpty()) {
break;
}
totalFetched += rows.size();
for (HxrOrderRow row : rows) {
LbBuyerShopping entity = toLbBuyerShopping(row, buyerMobile);
if (entity.getId() == null) {
continue;
}
applyDefaults(entity);
if (entity.getCreatedAt() == null) {
entity.setCreatedAt(LocalDateTime.now());
}
try {
LbBuyerShopping existing = this.getById(entity.getId());
boolean ok = existing != null ? this.updateById(entity) : this.save(entity);
if (ok) {
totalSaved++;
}
} catch (DuplicateKeyException e) {
if (this.updateById(entity)) {
totalSaved++;
}
}
}
int pageLimit = ctx.pageLimit() > 0 ? ctx.pageLimit() : 90;
boolean hasMore = pageResult.hasMore();
int lastPage = pageResult.lastPage();
if (pageResult.rows().size() < pageLimit) {
break;
}
if (!hasMore || page >= lastPage) {
break;
}
page++;
}
result.put("orderFetchSuccess", true);
result.put("orderFetchMsg", totalSaved == 0 ? "接口成功,无订单数据" : "买方订单拉取完成");
result.put("ordersSaved", totalSaved);
result.put("ordersFetched", totalFetched);
result.put("remoteCount", remoteCount != null ? remoteCount : totalFetched);
if (allMoney != null && !allMoney.isBlank()) {
result.put("allMoney", allMoney);
}
result.put("lastPage", firstPage != null ? firstPage.lastPage() : page);
result.put("orderPages", page);
return result;
} catch (Exception e) {
log.warn("拉取买方订单异常 buyerMobile={}", buyerMobile, e);
result.put("orderFetchSuccess", false);
result.put("orderFetchMsg", "拉取买方订单异常:" + e.getMessage());
result.put("ordersSaved", totalSaved);
result.put("ordersFetched", totalFetched);
if (remoteCount != null) {
result.put("remoteCount", remoteCount);
}
result.put("orderPages", page > 1 ? page - 1 : 0);
return result;
}
}
private static LbBuyerShopping toLbBuyerShopping(HxrOrderRow row, String fallbackBuyerMobile) {
LbBuyerShopping entity = new LbBuyerShopping();
entity.setId(row.id());
entity.setSellerId(row.sellerId());
entity.setMerchandiseId(row.merchandiseId());
entity.setBuyerId(row.buyerId());
entity.setOrderSn(row.orderSn());
entity.setTotalMoney(parseMoney(row.totalMoney()));
entity.setCreatedAt(parseFlexibleDateTime(row.createdAt()));
entity.setBuyTime(parseFlexibleDateTime(row.buyTime()));
entity.setConfirmTime(parseFlexibleDateTime(row.confirmTime()));
entity.setSellerNickname(row.sellerName());
entity.setSellerMobile(row.sellerPhone());
entity.setBuyerNickname(row.buyerName());
String buyerMobile = row.buyerPhone();
if (buyerMobile == null || buyerMobile.isBlank()) {
buyerMobile = fallbackBuyerMobile;
}
entity.setBuyerMobile(buyerMobile);
return entity;
}
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;
}
}
private static LocalDateTime parseFlexibleDateTime(String text) {
if (text == null || text.trim().isEmpty()) {
return null;
}
String trimmed = text.trim();
try {
return LocalDateTime.parse(trimmed, DATE_TIME_FORMATTER);
} catch (DateTimeParseException ignored) {
// continue
}
try {
return LocalDateTime.parse(trimmed, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} catch (DateTimeParseException e) {
return null;
}
}
private static int toInt(Object value) {
if (value instanceof Number number) {
return number.intValue();
}
if (value == null) {
return 0;
}
try {
return Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
return 0;
}
}
private void applyDefaults(LbBuyerShopping entity) {
if (entity.getTotalMoney() == null) {
entity.setTotalMoney(BigDecimal.ZERO);

View File

@@ -8,6 +8,7 @@ import com.rj.common.LbThirdIntegrationConstants;
import com.rj.dto.LbThirdIntegrationCredentialUpdateRequest;
import com.rj.dto.hxr.HxrAdminOrderApiContext;
import com.rj.dto.hxr.HxrAdminUserApiContext;
import com.rj.dto.hxr.HxrBuyerOrderApiContext;
import com.rj.dto.hxr.HxrFansApiContext;
import com.rj.dto.hxr.HxrGoodsApiContext;
import com.rj.dto.hxr.HxrUserLoginApiContext;
@@ -398,6 +399,37 @@ public class LbThirdIntegrationConfigServiceImpl
}
}
@Override
public Optional<HxrBuyerOrderApiContext> resolveBuyerOrderApiContext(String tenantId, String token) {
if (!StringUtils.hasText(tenantId) || !StringUtils.hasText(token)) {
return Optional.empty();
}
LbThirdIntegrationConfig config = getByTenantIdOrNull(tenantId.trim());
if (config == null) {
return Optional.empty();
}
if (config.getEnabled() == null || config.getEnabled() != 1) {
return Optional.empty();
}
String appStr = config.getGoodsApiAppStr();
if (!StringUtils.hasText(appStr)) {
return Optional.empty();
}
try {
return Optional.of(new HxrBuyerOrderApiContext(
LbThirdIntegrationConfigUtil.resolveBuyerOrderListBaseUrl(config),
LbThirdIntegrationConfigUtil.resolveBuyerOrderListLimit(config),
LbThirdIntegrationConfigUtil.resolveGoodsApiOrigin(config),
LbThirdIntegrationConfigUtil.resolveOrderReferer(config),
token.trim(),
appStr.trim()));
} catch (IllegalStateException e) {
return Optional.empty();
}
}
@Override
public Optional<HxrFansApiContext> resolveFansApiContext(String tenantId, String token) {
if (!StringUtils.hasText(tenantId) || !StringUtils.hasText(token)) {
@@ -431,6 +463,15 @@ public class LbThirdIntegrationConfigServiceImpl
@Override
public Optional<HxrAdminOrderApiContext> resolveAdminOrderApiContext(String tenantId) {
return resolveAdminOrderApiContext(tenantId, false);
}
@Override
public Optional<HxrAdminOrderApiContext> resolveAdminBuyerOrderApiContext(String tenantId) {
return resolveAdminOrderApiContext(tenantId, true);
}
private Optional<HxrAdminOrderApiContext> resolveAdminOrderApiContext(String tenantId, boolean buyerOrderList) {
if (!StringUtils.hasText(tenantId)) {
return Optional.empty();
}
@@ -448,9 +489,15 @@ public class LbThirdIntegrationConfigServiceImpl
}
try {
String baseUrl = buyerOrderList
? LbThirdIntegrationConfigUtil.resolveBuyerOrderListBaseUrl(config)
: LbThirdIntegrationConfigUtil.resolveOrderSelectBaseUrl(config);
int pageLimit = buyerOrderList
? LbThirdIntegrationConfigUtil.resolveBuyerOrderListLimit(config)
: LbThirdIntegrationConfigUtil.resolveOrderPageLimit(config);
return Optional.of(new HxrAdminOrderApiContext(
LbThirdIntegrationConfigUtil.resolveOrderSelectBaseUrl(config),
LbThirdIntegrationConfigUtil.resolveOrderPageLimit(config),
baseUrl,
pageLimit,
cookieHeader.trim(),
LbThirdIntegrationConfigUtil.resolveOrderReferer(config)));
} catch (IllegalStateException e) {
@@ -581,6 +628,9 @@ public class LbThirdIntegrationConfigServiceImpl
if (!StringUtils.hasText(entity.getBuyApiPath())) {
entity.setBuyApiPath(LbThirdIntegrationConstants.DEFAULT_BUY_API_PATH);
}
if (!StringUtils.hasText(entity.getBuyerOrderListPath())) {
entity.setBuyerOrderListPath(LbThirdIntegrationConstants.DEFAULT_BUYER_ORDER_LIST_PATH);
}
if (!StringUtils.hasText(entity.getFansApiPath())) {
entity.setFansApiPath(LbThirdIntegrationConstants.DEFAULT_FANS_API_PATH);
}
@@ -590,6 +640,9 @@ public class LbThirdIntegrationConfigServiceImpl
if (entity.getOrderPageLimit() == null) {
entity.setOrderPageLimit(LbThirdIntegrationConstants.DEFAULT_ORDER_PAGE_LIMIT);
}
if (entity.getBuyerOrderListLimit() == null) {
entity.setBuyerOrderListLimit(LbThirdIntegrationConstants.DEFAULT_BUYER_ORDER_LIST_LIMIT);
}
if (entity.getUserPageLimit() == null) {
entity.setUserPageLimit(LbThirdIntegrationConstants.DEFAULT_USER_PAGE_LIMIT);
}