提交修改

This commit is contained in:
quyixiao 2026-02-11 18:44:36 +08:00
parent bba1fde867
commit 4417f5fb27
2 changed files with 146 additions and 32 deletions

View File

@ -46,7 +46,12 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* App订单控制器
* 提供订单的创建查询支付发货确认收货退款等完整的订单生命周期管理功能
*
* @author heyu
*/
@Slf4j
@RestController
@RequestMapping("/app/order")
@ -130,18 +135,21 @@ public class AppOrderController {
private VvActivityDao vvActivityDao;
/***
* https://api.1024api.com/api-interface/app/order/list
/**
* 订单列表查询
* 支持按状态时间商品名称等多维度查询订单
* 支持分页查询返回订单包裹信息
*
* http://localhost:8888/app/order/list
*
* 列表
* todo quyixiao
* @param vvOrderRequest 订单查询请求参数
* @return 订单列表包含订单详情和物流信息
*/
@Describe("订单列表")
@RequestMapping("/list")
@AppRealyLogin
public R list(@RequestBody AppOrderRequest vvOrderRequest) {
log.info("[订单列表查询] 开始查询, buyerId={}, status={}, pageNum={}, pageSize={}",
vvOrderRequest.getBuyerId(), vvOrderRequest.getStatus(),
vvOrderRequest.getPageNum(), vvOrderRequest.getPageSize());
Integer commentStatus = null;
if(ApiConstants.WAIT_COMMENT.equals(vvOrderRequest.getStatus())){
commentStatus = 0;
@ -187,19 +195,25 @@ public class AppOrderController {
List<AppPackageDTO> appPackageDTOList = vvTradeOrderConvertService.buildAppPackageDTO(vvOrderListResps);
log.info("[订单列表查询] 查询完成, buyerId={}, 订单数量={}, 包裹数量={}",
vvOrderRequest.getBuyerId(), tradeOrderEntities.size(), appPackageDTOList.size());
return R.ok().setData(appPackageDTOList);
}
/***
/**
* 订单数量统计
* 统计用户各个状态的订单数量(待支付待发货配送中)
*
*
* http://localhost:8888/app/order/count
* @param appCountRequest 统计请求参数
* @return 各状态订单数量统计
*/
@Describe("订单数量")
@RequestMapping("/count")
@AppRealyLogin
public R list(@RequestBody AppCountRequest appCountRequest) {
log.info("[订单数量统计] 开始统计, buyerId={}", appCountRequest.getBuyerId());
PPageUtils waitPayCount = PPageUtils.startPage(appCountRequest.getPageNum(), appCountRequest.getPageSize())
.doSelect(new ISelect() {
@Override
@ -242,20 +256,27 @@ public class AppOrderController {
orderCountDTO.setWaitPayCount(waitPayCount.getTotal());
orderCountDTO.setWaitShippingCount(waitShippingCount.getTotal());
log.info("[订单数量统计] 统计完成, buyerId={}, 待支付={}, 待发货={}, 配送中={}",
appCountRequest.getBuyerId(), orderCountDTO.getWaitPayCount(),
orderCountDTO.getWaitShippingCount(), orderCountDTO.getShippingCount());
return R.ok().setData(orderCountDTO);
}
/***
* 订单详情
/**
* 订单详情查询
* 根据订单明细ID列表查询订单完整信息包括物流信息
*
* http://localhost:8888/app/order/detail
* @param vvOrderRequest 订单详情请求参数
* @return 订单详细信息
*/
@Describe("订单详情")
@RequestMapping("/detail")
@AppRealyLogin
public R detail(@RequestBody AppTradeOrderDetailDTO vvOrderRequest) {
log.info("[订单详情查询] 开始查询, tradeOrderLineIds={}", vvOrderRequest.getTradeOrderLineIdList());
List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByIds(vvOrderRequest.getTradeOrderLineIdList());
List<String> trackNumbers = SanUtils.getDistinctFiledList(vvTradeOrderLineEntities, VvTradeOrderLineEntity::getTrackNumber);
if (CollectionUtils.isNotEmpty(trackNumbers)) {
@ -270,35 +291,53 @@ public class AppOrderController {
List<VVOrderListResp> vvOrderListResps = vvTradeOrderConvertService.convertTradeOrderLineResp(tradeOrderEntities, vvTradeOrderLineEntities, true);
List<AppPackageDTO> appPackageDTOList = vvTradeOrderConvertService.buildAppPackageDTO(vvOrderListResps);
log.info("[订单详情查询] 查询完成, tradeOrderLineIds={}, 包裹数量={}",
vvOrderRequest.getTradeOrderLineIdList(), appPackageDTOList.size());
return R.ok().setData(appPackageDTOList);
}
/***
* 订单添加
/**
* 添加订单
* 创建订单并发起微信支付支持活动优惠和推广奖励
* 主要流程:
* 1. 校验库存
* 2. 创建订单和订单明细
* 3. 处理活动优惠和推广奖励
* 4. 调用微信支付预下单
* 5. 发送延迟关单消息
*
* http://localhost:8888/app/order/add
* @param vvOrderRequest 订单创建请求参数
* @return 微信支付参数
*/
@Describe("添加订单")
@RequestMapping("/add")
@AppRealyLogin
public R add(@RequestBody VvTradeOrderDTO vvOrderRequest) {
log.info("[添加订单] 开始创建订单, buyerId={}, skuIds={}, buyerAddressId={}",
vvOrderRequest.getBuyerId(),
SanUtils.getFieldList(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId),
vvOrderRequest.getBuyerAddressId());
List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = new ArrayList<>();
List<Long> skuIds = SanUtils.getFieldList(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId);
List<VvSkuPropertyValueEntity> vvSkuPropertyValueList = vvSkuPropertyValueDao.selectVvSkuPropertyValueBySkuIds(skuIds);
Map<Long, VvTradeOrderLineDTO> vvTradeOrderLineMap = SanUtils.groupByFiled2Map(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId);
List<VvSkuEntity> vvSkuEntities = vvSkuDao.selectVvSkuBySkuIds(skuIds);
// 校验库存
for (VvSkuEntity vvSkuEntity : vvSkuEntities) {
VvTradeOrderLineDTO vvTradeOrderLineDTO = vvTradeOrderLineMap.get(vvSkuEntity.getId());
// 如果库存少于 0 则显示库存不足
if (vvSkuEntity.getStock() - vvTradeOrderLineDTO.getNum() < 0) {
log.warn("[添加订单] 库存不足, skuId={}, 当前库存={}, 购买数量={}",
vvSkuEntity.getId(), vvSkuEntity.getStock(), vvTradeOrderLineDTO.getNum());
OrderSkuDTO orderSkuDTO = new OrderSkuDTO();
orderSkuDTO.setSkuId(vvSkuEntity.getId());
orderSkuDTO.setMessage("库存不足");
return R.error().setData(orderSkuDTO);
}
}
log.info("[添加订单] 库存校验通过, skuIds={}", skuIds);
Map<Long, VvSkuEntity> skuEntityMap = SanUtils.groupByFiled2Map(vvSkuEntities, VvSkuEntity::getId);
@ -317,10 +356,13 @@ public class AppOrderController {
VvActivityEntity vvActivityEntity = null;
if (StringUtils.isNotEmpty(activityInfo)) {
vvActivityDTO = JSONObject.parseObject(activityInfo, VvActivityDTO.class);
vvActivityEntity =vvActivityDao.selectVvActivityById(vvActivityDTO.getActivityId());
vvActivityEntity = vvActivityDao.selectVvActivityById(vvActivityDTO.getActivityId());
log.info("[添加订单] 检测到活动信息, activityId={}, discountAmount={}, awardAmount={}",
vvActivityDTO.getActivityId(), vvActivityEntity.getDiscountAmount(), vvActivityEntity.getAwardAmount());
}
Integer batchNum = SanUtils.sum(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getNum);
log.info("[添加订单] 订单总数量={}", batchNum);
for (VvTradeOrderLineDTO vvTradeOrderLineDTO : vvOrderRequest.getVvTradeOrderLineDTOList()) {
VvSkuEntity vvSkuEntity = skuEntityMap.get(vvTradeOrderLineDTO.getSkuId());
@ -409,6 +451,10 @@ public class AppOrderController {
BigDecimal tradePayAmount = SanUtils.sum(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getPayAmount);
vvTradeOrderEntity.setPayAmount(tradePayAmount);
vvTradeOrderDao.insertVvTradeOrder(vvTradeOrderEntity);
log.info("[添加订单] 创建主订单成功, tradeOrderId={}, 订单金额={}, 明细数量={}",
vvTradeOrderEntity.getId(), tradePayAmount, vvTradeOrderLineEntityList.size());
List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntityList = new ArrayList<>();
for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
@ -520,6 +566,8 @@ public class AppOrderController {
vvBuyerEntity.getOpenid()
);
log.info("[添加订单] 微信预下单成功, tradeOrderId={}, outTradeNo={}, prepayId={}",
vvTradeOrderEntity.getId(), vvTradeOrderEntity.getOutTradeNo(), jsapiPrepayResponse.getPrepayId());
String prepay_id = jsapiPrepayResponse.getPrepayId();
@ -549,6 +597,9 @@ public class AppOrderController {
message.getMessageProperties().setDelay((second) * 1000); // 毫秒为单位指定此消息的延时时长 ,+ 1 尽量保证机器人跑完了再发送消息
return message;
});
log.info("[添加订单] 发送延迟关单消息成功, tradeOrderId={}, delayTime={}秒",
vvTradeOrderEntity.getId(), second);
}
WxPayVO vo = new WxPayVO();

View File

@ -170,42 +170,65 @@ public class AppUserLoginController {
}
public void insertPromoter(String requestToken ,BuyerDTO buyerDTO) {
/**
* 处理推广关系
* 当用户通过推广链接登录时建立推广者与被推广者的关系
*
* @param requestToken 请求中的原始token可能包含活动信息
* @param buyerDTO 登录后的买家信息
*/
public void insertPromoter(String requestToken, BuyerDTO buyerDTO) {
log.info("[处理推广关系] 开始处理, requestToken={}, buyerId={}", requestToken, buyerDTO.getBuyerId());
// 从Redis获取活动信息
String activityInfo = redisUtils.get(ApiConstants.token_activity + requestToken);
if (StringUtils.isNotEmpty(activityInfo)) {
VvActivityDTO vvActivityDTO = JSONObject.parseObject(activityInfo, VvActivityDTO.class);
VvActivityDTO vvActivityDTO = JSONObject.parseObject(activityInfo, VvActivityDTO.class);
log.info("[处理推广关系] 获取到活动信息, activityId={}, promoterId={}",
vvActivityDTO.getActivityId(), vvActivityDTO.getBuyerId());
// 获取被推广买家信息
VvBuyerEntity wasBuyerEntity = vvBuyerDao.selectVvBuyerById(buyerDTO.getBuyerId());
if(wasBuyerEntity ==null ){
wasBuyerEntity = new VvBuyerEntity();
if (wasBuyerEntity == null) {
log.warn("[处理推广关系] 被推广买家不存在,使用默认值, buyerId={}", buyerDTO.getBuyerId());
wasBuyerEntity = new VvBuyerEntity();
wasBuyerEntity.setId(0L);
wasBuyerEntity.setBuyerName("0");
wasBuyerEntity.setBuyerPhone("0");
wasBuyerEntity.setBuyerWeixin("0");
}
// 获取活动信息
VvActivityEntity vvActivityEntity = vvActivityDao.selectVvActivityById(vvActivityDTO.getActivityId());
// 换token
// 计算活动剩余时间将活动信息关联到新token
Date endTime = new Date(vvActivityDTO.getActivityExpiredTime());
int second = DateUtils.betweenSecond(new Date(),endTime);
int second = DateUtils.betweenSecond(new Date(), endTime);
log.info("AppUserLoginController insertPromoter " +
"requestToken:{}," +
"loginToken:{}," +
"vvActivityDTO:{}," +
"second:{}",requestToken,buyerDTO.getToken(),JSON.toJSONString(vvActivityDTO),second);
log.info("[处理推广关系] 活动信息转移, requestToken={}, loginToken={}, activityId={}, remainSeconds={}",
requestToken, buyerDTO.getToken(), vvActivityDTO.getActivityId(), second);
redisUtils.set(ApiConstants.token_activity + buyerDTO.getToken(), JSON.toJSONString(vvActivityDTO),second);
// 将活动信息关联到新的登录token
redisUtils.set(ApiConstants.token_activity + buyerDTO.getToken(), JSON.toJSONString(vvActivityDTO), second);
// 查询推广者信息
List<Long> promoterBuyerIdList = new LinkedList<>();
promoterBuyerIdList.add(vvActivityDTO.getBuyerId());
List<VvBuyerEntity> promoterBuyerList = vvBuyerDao.selectVvBuyerByIdList(promoterBuyerIdList);
VvPromoterEntity vvPromoter = new VvPromoterEntity();
// 创建推广记录
VvPromoterEntity vvPromoter = new VvPromoterEntity();
vvPromoter.setActivityId(vvActivityDTO.getActivityId());
vvPromoter.setPromoterCode(vvActivityDTO.getPromoterCode());
vvPromoter.setCreateTimestamp(System.currentTimeMillis());
vvPromoter.setActivityName(vvActivityEntity.getActivityName());
vvPromoter.setBuyerInfo(JSONObject.toJSONString(vvActivityDTO));
vvPromoterDao.insertVvPromoter(vvPromoter);
log.info("[处理推广关系] 创建推广记录成功, promoterId={}, activityId={}, promoterCode={}",
vvPromoter.getId(), vvActivityDTO.getActivityId(), vvActivityDTO.getPromoterCode());
// 建立推广者与被推广者的关系
for (VvBuyerEntity promoterBuyerEntity : promoterBuyerList) {
VvPromoterBuyerEntity vvPromoterBuyerEntity = new VvPromoterBuyerEntity();
vvPromoterBuyerEntity.setPromoterId(vvPromoter.getId());
@ -220,28 +243,62 @@ public class AppUserLoginController {
vvPromoterBuyerEntity.setWasBuyerPhone(wasBuyerEntity.getBuyerPhone());
vvPromoterBuyerEntity.setWasBuyerWeixin(wasBuyerEntity.getBuyerWeixin());
vvPromoterBuyerDao.insertOrUpdateVvPromoterBuyer(vvPromoterBuyerEntity);
log.info("[处理推广关系] 建立推广关系成功, promoterId={}, promoterBuyerId={}, wasBuyerId={}",
vvPromoter.getId(), promoterBuyerEntity.getId(), wasBuyerEntity.getId());
}
} else {
log.info("[处理推广关系] 无活动信息,跳过推广关系处理, requestToken={}", requestToken);
}
}
/**
* 更新用户信息
* 允许用户修改昵称和头像
*
* @param request 更新请求参数包含买家ID昵称头像
* @return 更新结果包含更新后的买家信息
*/
// http://localhost:8888/app/buyer/info/update
@RequestMapping("/buyer/info/update")
@Describe("更新用户信息")
@AppRealyLogin
public R buyerInfoUpdate(@RequestBody VvAppBuyerInfoRequest request) {
log.info("[更新用户信息] 开始处理, buyerId={}, buyerName={}", request.getBuyerId(), request.getBuyerName());
VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerById(request.getBuyerId());
if (vvBuyerEntity == null) {
log.warn("[更新用户信息] 用户不存在, buyerId={}", request.getBuyerId());
return R.error("你不是内部用户");
}
// 更新用户信息
vvBuyerEntity.setBuyerName(request.getBuyerName());
vvBuyerEntity.setAvatar(request.getAvatar());
vvBuyerDao.insertOrUpdateVvBuyer(vvBuyerEntity);
log.info("[更新用户信息] 更新成功, buyerId={}, buyerName={}, avatar={}",
vvBuyerEntity.getId(), vvBuyerEntity.getBuyerName(), vvBuyerEntity.getAvatar());
return R.ok().put("buyer", vvBuyerEntity);
}
public BuyerDTO buildBuyerLoginInfoCacheRedisDB(VvBuyerEntity target, Long expireTime, String deviceId,Integer loginType) {
/**
* 构建买家登录信息并缓存到Redis
* 生成token并将买家信息存储到Redis中
*
* @param target 买家实体信息
* @param expireTime token过期时间()
* @param deviceId 设备ID用于匿名登录
* @param loginType 登录类型(0:匿名登录, 1:微信登录)
* @return 买家DTO包含token等信息
*/
public BuyerDTO buildBuyerLoginInfoCacheRedisDB(VvBuyerEntity target, Long expireTime, String deviceId, Integer loginType) {
log.info("[构建登录信息] 开始构建, buyerId={}, loginType={}, expireTime={}秒",
target.getId(), loginType, expireTime);
BuyerDTO buyerDTO = new BuyerDTO();
buyerDTO.setBuyerId(target.getId());
buyerDTO.setBuyerName(target.getBuyerName());
@ -250,9 +307,15 @@ public class AppUserLoginController {
buyerDTO.setLoginType(loginType);
buyerDTO.setBuyerPhone(target.getBuyerPhone());
buyerDTO.setBuyerWeixin(target.getBuyerWeixin());
// 生成token并缓存到Redis
String token = TokenUtils.generateToken(target.getId() + deviceId);
redisUtils.set(token, JSON.toJSONString(buyerDTO), expireTime);
buyerDTO.setToken(token);
log.info("[构建登录信息] 构建完成, buyerId={}, token={}, expireTime={}秒",
target.getId(), token, expireTime);
return buyerDTO;
}