feat:机器订单支付速度优化

This commit is contained in:
dzc committed 2026-09-10 16:23:11 +08:00
1 parent 241e9b0c46
commit 10eec976c2
4 files changed
+165 -12

No files matched your search

@@ -0,0 +1,35 @@
package com.bsd.pjcloud.hard.api.vo.order;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 一次商品查询同时完成购物车落库、总价计算和商品描述的结果。
* <p>
* 用于收银下单路径合并原本 computerCarTotalPrice/createCard/computerCarSubject
* 三次重复的商品远程查询。
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class HardCreateCardComputeVo {
/**
* 新建的父购物车 id
*/
private Long parentCarId;
/**
* 按商品快照计算出的总价(分)
*/
private Integer totalPrice;
/**
* 商品描述,如 "苹果x2;香蕉x0.5/kg;"
*/
private String subject;
}
@@ -10,6 +10,7 @@ import com.bsd.pjcloud.hard.api.dto.order.HardCreateCarDto;
import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardParentCarEntity;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCreateCardComputeVo;
import com.bsd.pjcloud.thirdparty.dto.pay.PayDto;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@@ -40,6 +41,14 @@ public interface HardCarService extends IService<HardCarEntity> {
*/
Long createCard(Long userId, Long merchantId, HardTypeEnum sysType, HardOrderTypeEnum orderTYpe, List<HardCreateCarDto> list);
/**
* 一次商品查询同时完成购物车落库、总价计算和商品描述拼装。
* <p>
* 仅覆盖收银下单路径(食堂线上/线下、超市线下);其他业态组合返回 null,
* 调用方需回落到 computerCarTotalPrice + createCard + computerCarSubject 三段式调用。
*/
HardCreateCardComputeVo createCardWithCompute(Long userId, Long merchantId, HardTypeEnum sysType, HardOrderTypeEnum orderType, List<HardCreateCarDto> list);
/**
* 创建第三方支付购物车
*/
@@ -24,6 +24,7 @@ import com.bsd.pjcloud.hard.api.entity.order.HardParentCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import com.bsd.pjcloud.hard.api.entity.spu.HardSpuEntity;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCreateCardComputeVo;
import com.bsd.pjcloud.hard.mapper.order.HardCarMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.mapper.order.HardParentCarMapper;
@@ -288,6 +289,92 @@ public class HardCarServiceImpl extends ServiceImpl<HardCarMapper, HardCarEntity
return parentCarObj.getId();
}
/**
* 收银下单路径合并实现:一次商品查询同时产出购物车、总价和描述,
* 价格公式、落库字段、描述拼法均与 computerCarTotalPrice/appCreateCard/computerCarSubject 保持一致。
*/
@Override
@Transactional(rollbackFor = Exception.class)
public HardCreateCardComputeVo createCardWithCompute(Long userId, Long merchantId, HardTypeEnum sysType, HardOrderTypeEnum orderType, List<HardCreateCarDto> list) {
List<Long> productIds = list.stream().map(HardCreateCarDto::getProductId).toList();
List<HardCarEntity> carObjectList = new ArrayList<>();
StringBuffer subject = new StringBuffer();
AtomicInteger totalPrice = new AtomicInteger();
// 食堂
if (ObjectUtil.equals(sysType, HardTypeEnum.CANTEEN)) {
// 线上
if (ObjectUtil.equals(HardOrderTypeEnum.RESERVE, orderType)) {
List<CanteenOnlineSpuAppVO> supList = onlineCanteenSpuService.getSpuListByIds(productIds).getData();
for (HardCreateCarDto v : list) {
supList.stream().filter(i -> ObjectUtil.equals(i.getId(), v.getProductId())).findFirst().ifPresent(spu -> {
int itemTotalPrice = v.getProductCount() * spu.getPrice();
totalPrice.addAndGet(itemTotalPrice);
subject.append(spu.getName()).append("x").append(v.getProductCount()).append(";");
carObjectList.add(HardCarEntity.builder().parentCarId(null).productId(spu.getId()).productName(spu.getName())
.productPrice(spu.getPrice()).productPic(spu.getPicUrl()).totalPrice((long) itemTotalPrice)
.productNature(ObjectUtil.isNotEmpty(v.getProductNature()) ? v.getProductNature().getType() : null)
.productCount(v.getProductCount()).productWeight(new BigDecimal(0))
.isDiscountsProduct(buildIsPriceIncreased(v)).build());
});
}
}
// 线下
else if (ObjectUtil.equals(HardOrderTypeEnum.BELOW, orderType)) {
List<CanteenSpuEntity> supList = canteenSpuService.getSpuListByIds(productIds).getData();
for (HardCreateCarDto v : list) {
supList.stream().filter(i -> ObjectUtil.equals(i.getId(), v.getProductId())).findFirst().ifPresent(spu -> {
int itemTotalPrice = v.getProductCount() * spu.getPrice();
totalPrice.addAndGet(itemTotalPrice);
subject.append(spu.getName()).append("x").append(v.getProductCount()).append(";");
carObjectList.add(HardCarEntity.builder().parentCarId(null).productId(spu.getId()).productName(spu.getName())
.productPrice(spu.getPrice()).productPic(spu.getPicUrl()).totalPrice((long) itemTotalPrice)
.productNature(ObjectUtil.isNotEmpty(v.getProductNature()) ? v.getProductNature().getType() : null)
.productCount(v.getProductCount()).productWeight(new BigDecimal(0))
.isDiscountsProduct(buildIsPriceIncreased(v)).build());
});
}
} else {
return null;
}
}
// 超市
else if (ObjectUtil.equals(sysType, HardTypeEnum.SUPERMARKET) && ObjectUtil.equals(HardOrderTypeEnum.BELOW, orderType)) {
List<SmErpUnitWithSpuVo> supList = supermarketUnitSkuService.getSupermarketUnits(productIds).getData();
for (HardCreateCarDto v : list) {
supList.stream().filter(i -> ObjectUtil.equals(i.getId(), v.getProductId())).findFirst().ifPresent(spu -> {
Integer price = getSupermarket(spu);
int itemTotalPrice = 0;
if (ObjectUtil.isNotEmpty(v.getProductCount()) && !ObjectUtil.equals(v.getProductCount(), 0)) {
// 按数量
itemTotalPrice = v.getProductCount() * price;
} else if (ObjectUtil.isNotEmpty(v.getProductWeight()) && v.getProductWeight().compareTo(BigDecimal.valueOf(0)) != 0) {
// 按重量,向上取整
itemTotalPrice = v.getProductWeight().multiply(BigDecimal.valueOf(price)).setScale(0, RoundingMode.CEILING).intValue();
}
totalPrice.addAndGet(itemTotalPrice);
subject.append(spu.getProductName()).append("x").append(v.getProductCount()).append(";");
carObjectList.add(HardCarEntity.builder().parentCarId(null).productId(spu.getId()).productName(spu.getProductName())
.productPrice(price).productPic(spu.getPicUrl()).totalPrice((long) itemTotalPrice)
.productNature(ObjectUtil.isNotEmpty(v.getProductNature()) ? v.getProductNature().getType() : null)
.productCount(v.getProductCount()).productWeight(v.getProductWeight())
.isDiscountsProduct(buildIsPriceIncreased(v)).build());
});
}
} else {
return null;
}
// 创建父订单,状态与 createCard 保持一致
HardParentCarEntity parentCarObj = HardParentCarEntity.builder().userId(userId).merchantId(merchantId).hardType(sysType.getType()).orderStatus(HardOrderStatusEnum.PAY.getType()).build();
hardParentCarMapper.insert(parentCarObj);
carObjectList.forEach(item -> item.setParentCarId(parentCarObj.getId()));
baseMapper.insert(carObjectList);
return HardCreateCardComputeVo.builder().parentCarId(parentCarObj.getId()).totalPrice(totalPrice.get()).subject(subject.toString()).build();
}
private String buildIsPriceIncreased(HardCreateCarDto v) {
return ObjectUtil.isNotEmpty(v.getIsPriceIncreased()) && v.getIsPriceIncreased() ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode();
}
/**
* 创建第三方支付购物车
*/
@@ -62,6 +62,7 @@ import com.bsd.pjcloud.hard.api.entity.spu.HardSpuEntity;
import com.bsd.pjcloud.hard.api.vo.HardDoorFlowVo;
import com.bsd.pjcloud.hard.api.vo.manager.HardManagerVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCreateCardComputeVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCreateHardQrCodeScanOrderVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
import com.bsd.pjcloud.hard.api.vo.spu.HardSpuJoinVo;
@@ -319,7 +320,21 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
if (isCancel) throw new RuntimeException("该二维码已被核销");
}
int totalPrice = 0, extraPrice = 0, payPrice = 0;
totalPrice = hardCarService.computerCarTotalPrice(dto.getSysType(), dto.getOrderType(), dto.getList());
// 收银主路径一次商品查询同时产出购物车、总价和描述,替代三次重复的商品远程查询
HardCreateCardComputeVo computed = hardCarService.createCardWithCompute(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
Long parentCarId;
String subject;
if (ObjectUtil.isNotEmpty(computed)) {
totalPrice = computed.getTotalPrice();
parentCarId = computed.getParentCarId();
subject = computed.getSubject();
} else {
totalPrice = hardCarService.computerCarTotalPrice(dto.getSysType(), dto.getOrderType(), dto.getList());
// 添加购物车
parentCarId = hardCarService.createCard(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
// 获取商品描述
subject = hardCarService.computerCarSubject(dto.getSysType(), dto.getOrderType(), dto.getList());
}
if (isExtraPrice && ObjectUtil.isNotEmpty(dto.getExtraPrice())) {
extraPrice = dto.getExtraPrice();
}
@@ -330,10 +345,6 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
// 判断余额够不够支付
if (wallet.getBalance() < payPrice) throw new RuntimeException("钱包余额不足");
}
// 添加购物车
Long parentCarId = hardCarService.createCard(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
// 获取商品描述
String subject = hardCarService.computerCarSubject(dto.getSysType(), dto.getOrderType(), dto.getList());
// 添加硬件订单
HardOrderEntity orderObj = HardOrderEntity.builder()
.androidOrderCode(dto.getAndroidOrderCode())
@@ -425,17 +436,27 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
if (ObjectUtil.notEqual(mch.getTypes(), MerchantTypeEnum.SELF_SUPERMARKET.getType())) {
throw new RuntimeException("该订单不是设备扫一扫订单");
}
// 添加购物车
Long parentCarId = hardCarService.createCard(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
// 获取商品描述
String subject = hardCarService.computerCarSubject(dto.getSysType(), dto.getOrderType(), dto.getList());
// 一次商品查询同时产出购物车、总价和描述;扫一扫订单固定为超市线下路径
int totalPrice = 0, extraPrice = 0, payPrice = 0;
Long parentCarId;
String subject;
HardCreateCardComputeVo computed = hardCarService.createCardWithCompute(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
if (ObjectUtil.isNotEmpty(computed)) {
totalPrice = computed.getTotalPrice();
parentCarId = computed.getParentCarId();
subject = computed.getSubject();
} else {
// 添加购物车
parentCarId = hardCarService.createCard(dto.getUserId(), dto.getMerchantId(), dto.getSysType(), dto.getOrderType(), dto.getList());
// 获取商品描述
subject = hardCarService.computerCarSubject(dto.getSysType(), dto.getOrderType(), dto.getList());
totalPrice = hardCarService.computerCarTotalPrice(dto.getSysType(), dto.getOrderType(), dto.getList());
}
// 是否需要支付额外金额
boolean isExtraPrice = isExtraPrice(dto.getSysType());
SysUser sysUser = null;
int totalPrice = 0, extraPrice = 0, payPrice = 0;
totalPrice = hardCarService.computerCarTotalPrice(dto.getSysType(), dto.getOrderType(), dto.getList());
if (isExtraPrice) extraPrice = computeExtraPrice(totalPrice, mch, sysUser);
payPrice = totalPrice + extraPrice;
@@ -1981,7 +2002,8 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
if (ObjectUtil.isEmpty(mch.getData())) {
throw new RuntimeException("商户不存在");
}
HardManagerEntity hard = hardManagerService.getByHardId(dto.getHardwareId());
// 此处只取 deptId,按主键直查即可;getByHardId 还会联查部门和商户两次远程调用
HardManagerEntity hard = hardManagerService.getById(dto.getHardwareId());
if (ObjectUtil.isEmpty(hard)) {
throw new RuntimeException("设备不存在");
}