feat:订单支付发起

pull/1121/head
梁宇奇 2025-04-07 18:08:03 +08:00
parent 554968a9ff
commit 4629533dda
16 changed files with 379 additions and 26 deletions

View File

@ -41,6 +41,7 @@
<spring-framework.version>5.3.39</spring-framework.version>
<!-- aliyun -->
<aliyun-sdk-oss.version>3.17.4</aliyun-sdk-oss.version>
<alipay-sdk.version>4.40.54.ALL</alipay-sdk.version>
</properties>
<!-- 依赖声明 -->
@ -252,6 +253,12 @@
<version>${aliyun-sdk-oss.version}</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>${alipay-sdk.version}</version>
</dependency>
<!-- ES相关 begin-->
<dependency>
<groupId>co.elastic.clients</groupId>

View File

@ -5,12 +5,17 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.XktBaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddReqVO;
import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddRespVO;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.manager.PaymentManager;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -18,6 +23,8 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author liangyq
* @date 2025-04-03 14:18
@ -29,6 +36,8 @@ public class StoreOrderController extends XktBaseController {
@Autowired
private IStoreOrderService storeOrderService;
@Autowired
private List<PaymentManager> paymentManagers;
/**
*
@ -39,8 +48,30 @@ public class StoreOrderController extends XktBaseController {
public R<StoreOrderAddRespVO> create(@RequestBody StoreOrderAddReqVO vo) {
StoreOrderAddDTO dto = BeanUtil.toBean(vo, StoreOrderAddDTO.class);
dto.setOrderUserId(SecurityUtils.getUserId());
StoreOrderAddResultDTO resultDTO = storeOrderService.createOrder(dto);
//TODO
return success();
//初始化订单
StoreOrderInfo orderInfo = storeOrderService.createOrder(dto);
//发起支付
PaymentManager paymentManager = getPaymentManager(EPayChannel.of(vo.getPayChannel()));
String rtnStr = paymentManager.payForOrder(orderInfo.getOrder().getId(), EPayFrom.of(vo.getPayFrom()));
//返回信息
StoreOrderAddRespVO respVO = new StoreOrderAddRespVO(orderInfo.getOrder().getId(),
orderInfo.getOrder().getOrderNo(), rtnStr);
return success(respVO);
}
/**
*
*
* @param payChannel
* @return
*/
private PaymentManager getPaymentManager(EPayChannel payChannel) {
Assert.notNull(payChannel);
for (PaymentManager paymentManager : paymentManagers) {
if (paymentManager.channel() == payChannel) {
return paymentManager;
}
}
throw new ServiceException("未知支付渠道");
}
}

View File

@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* Controller
*
@ -34,8 +36,8 @@ public class StoreProductColorController extends XktBaseController {
@PreAuthorize("@ss.hasPermi('system:color:query')")
@ApiOperation(value = "模糊查询档口所有的商品颜色分类", httpMethod = "GET", response = R.class)
@GetMapping(value = "/fuzzy")
public R<StoreProdColorResVO> fuzzyQueryColorList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum,
@RequestParam("storeId") Long storeId) {
public R<List<StoreProdColorResVO>> fuzzyQueryColorList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum,
@RequestParam("storeId") Long storeId) {
return success(BeanUtil.copyToList(storeProdColorService.fuzzyQueryColorList(storeId, prodArtNum), StoreProdColorResVO.class));
}

View File

@ -19,10 +19,6 @@ public class StoreOrderAddReqVO {
*/
@ApiModelProperty(value = "档口ID")
private Long storeId;
// /**
// * 下单用户ID
// */
// private Long orderUserId;
/**
*
*/
@ -79,6 +75,12 @@ public class StoreOrderAddReqVO {
@ApiModelProperty(value = "明细列表")
private List<Detail> detailList;
@ApiModelProperty(value = "支付渠道[1:支付宝]")
private Integer payChannel;
@ApiModelProperty(value = "支付来源[1:电脑网站 2:手机网站]")
private Integer payFrom;
@ApiModel(value = "明细")
@Data
public static class Detail {

View File

@ -1,7 +1,10 @@
package com.ruoyi.web.controller.xkt.vo.order;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liangyq
@ -9,6 +12,17 @@ import lombok.Data;
*/
@ApiModel
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StoreOrderAddRespVO {
@ApiModelProperty(value = "订单ID")
private Long storeOrderId;
@ApiModelProperty(value = "订单号")
private String orderNo;
@ApiModelProperty(value = "支付渠道返回值: 跳转页面数据/签名字符串/支付跳转链接/预支付交易会话标识(根据选择的支付渠道和支付来源确定)")
private String payRtnStr;
}

View File

@ -109,7 +109,7 @@ public class XktBaseController {
/**
*
*/
public R success(Object data) {
public <T> R<T> success(T data) {
return R.ok(data);
}

View File

@ -28,6 +28,11 @@
<artifactId>ruoyi-common</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
</dependency>
<!-- Swagger3依赖 -->
<dependency>

View File

@ -15,7 +15,7 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StoreOrderAddResultDTO {
public class StoreOrderInfo {
private StoreOrder order;

View File

@ -0,0 +1,41 @@
package com.ruoyi.xkt.dto.payment;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liangyq
* @date 2025-04-07 16:15
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AlipayReqDTO {
/**
*
*/
@JsonProperty("subject")
private String subject;
/**
*
*/
@JsonProperty("out_trade_no")
private String outTradeNo;
/**
*
*/
@JsonProperty("timeout_express")
private String timeoutExpress;
/**
*
*/
@JsonProperty("total_amount")
private String totalAmount;
/**
*
*/
@JsonProperty("product_code")
private String productCode;
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.xkt.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author liangyq
* @date 2025-04-02 23:42
*/
@Getter
@AllArgsConstructor
public enum EPayChannel {
ALI_PAY(1, "支付宝");
private final Integer value;
private final String label;
public static EPayChannel of(Integer value) {
for (EPayChannel e : EPayChannel.values()) {
if (e.getValue().equals(value)) {
return e;
}
}
return null;
}
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.xkt.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author liangyq
* @date 2025-04-07 10:01
*/
@Getter
@AllArgsConstructor
public enum EPayFrom {
WEB(1, "电脑网站"),
WAP(2, "手机网站"),
;
private final Integer value;
private final String label;
public static EPayFrom of(Integer value) {
for (EPayFrom e : EPayFrom.values()) {
if (e.getValue().equals(value)) {
return e;
}
}
return null;
}
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.xkt.manager;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
/**
* @author liangyq
* @date 2025-04-06 19:36
*/
public interface PaymentManager {
/**
*
*
* @return
*/
EPayChannel channel();
/**
*
*
* @param storeOrderId
* @param payFrom
* @return ///&
*/
String payForOrder(Long storeOrderId, EPayFrom payFrom);
}

View File

@ -0,0 +1,120 @@
package com.ruoyi.xkt.manager.impl;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.dto.payment.AlipayReqDTO;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.manager.PaymentManager;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author liangyq
* @date 2025-04-06 19:36
*/
@Slf4j
@Component
public class AliPaymentMangerImpl implements PaymentManager {
/**
* ID,APPIDAPPID
*/
@Value("${alipay.appId:9021000144616672}")
private String appId;
/**
* PKCS8RSA2
*/
@Value("${alipay.privateKey:MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3x52ARikELwpOPvPcpY9jj7aEWIPivfBwkf3YRyUKnM7L6mOTxD1v3b7QLcL1+l0QmvOPSGgt2O3Qbjtvq+5ih4T32TlAzHGe8VqGVqrEv7ANQicsXz600ze5LdxCDRgBZWhO/GroGJKfenHf7K+arN4KXWWmHyZHCYD5z85TEvZZoA9e9MTMskXeDS8+fwP6McuNf4fR07kVuzblks+wWm1PsWfxFM7qNwSYKXbmEoyDe7+M9vBr7cwuj2OB3PEtj/FZjKMxVnFyVm61KiFAGUf3oUqWmPASTPDkFboRCS/njv980hk3sPba/qMDfMEpjoMZrcLBVzoj747oEi/DAgMBAAECggEAcVoXlRSxG7l/278MXl1nUXtEkeCeh+2rLWN+dDV9bUxGaJOLE4sIccUNeg2foGPpnuJTs15vk0endtVmp3weLntz0gMTQxpWQjiPIyi1b2Djz2msC7w7SwCz7+2PWtYEpmfLrFwX/Eubs+2r6vdrYDWbRj1RAuNXkp0UBgDcO3P9AFeGln5gUWxni4biN6B9sGGdsSwcm1A9biBPRsH2zMSVVWkhLVq+S73smm2Sh7WTIVEyeAuWEDeMs5oI2jQjPHMlUKmWW6JZ3uD5xbRm3Nkvve/nvfJ4ZXx58ABTI9EWzcBlEuLYef4T+P9q4KHZQljpJ4UliIxUVIDSk3GNMQKBgQDevjYnLW2FBNDYQvPf6FkD2iNzKFe80cQYR0+/jiSBgkmtQhXZgyJ2ZqQ5t20MjgLpeY0WJL2twBlFcYGico6Vnv+JMiJDtIjTu1UozAqV2VPeJ34nX34nqJptGwehiPXJupAiulAWtvTqsiYWlFHsr3dMtj6z07M+gDV8PU7P/QKBgQDTOCGgdrS3XYD680eH9vGKbH1DpIOMr3JokLk6kv4yui9Jxk5DMCxcJWkEQRnCrw2UYM8PfX17FqXrwhccmR9hskSmmbLONYzk4SDB73fM2nPqBw+VLO6jbWctylUsGaYfVxDOLDWPQkktKUsHK8pQHLNQ4jwlP5SGQUoIM/OqvwKBgHfRrmPIxh9GBeovqeyKmke+Mk+iJgBGfsvooHeUyQJ5yZRP9lz5c7JpaHI7v4d/ZQWfA0wkG3y5115JvshaA2VtEF0HAPOWy/vJy/eUOyV8sObSK8SWU9CVm+yRG7vDZyRLHXnw62AsrvcJOf/vbVp60RwM9RHbEZLPePYKLLkpAoGADPMaDK56ceuHptsXfZyEPopcO7NwZUW0a/jDgnXUo+OKVqmTzsa7UYLxp1MeczMsT/aHe1mkQdGnpoalyBkTNXgqgVRXBBGAa9/plDpMTADwrl50dB7nGpnwg3wuMJ/58V3zJ9DKD9huiBhKA0yKANNhownbyiTVxE1oboxQ2h0CgYEAkV4hjGe4t6mu5rhqvuIZkDskjuSOwO0dZsGXBZ/sOZusKNmskxeNZht4BajnATN4EaPg265k8ytWnOEQH041J8Wac1M+jAQQp6D1nkQWZZlrclTu7xvM+p6ypVtqNFTseIQtEhtyPw+fcsYrXM4u8LHpGlAzlwQ30lFg+K/Q++Y=}")
private String privateKey;
/**
* ,https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
*/
@Value("${alipay.publicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}")
private String alipayPublicKey;
/**
*
*/
@Value("${alipay.notifyUrl:}")
private String notifyUrl;
/**
*
*/
@Value("${alipay.returnUrl:}")
private String returnUrl;
/**
*
*/
@Value("${alipay.signType:RSA2}")
private String signType;
/**
*
*/
@Value("${alipay.charset:UTF-8}")
private String charset;
/**
*
*/
@Value("${alipay.gatewayUrl:https://openapi-sandbox.dl.alipaydev.com/gateway.do}")
private String gatewayUrl;
@Autowired
private IStoreOrderService storeOrderService;
@Override
public EPayChannel channel() {
return EPayChannel.ALI_PAY;
}
@Override
public String payForOrder(Long storeOrderId, EPayFrom payFrom) {
Assert.notNull(storeOrderId);
Assert.notNull(payFrom);
//订单状态更新为支付中
StoreOrderInfo order = storeOrderService.preparePayOrder(storeOrderId);
AlipayReqDTO reqDTO = new AlipayReqDTO();
reqDTO.setOutTradeNo(order.getOrder().getOrderNo());
reqDTO.setTotalAmount(order.getOrder().getTotalAmount().toPlainString());
reqDTO.setSubject("代发订单" + order.getOrder().getOrderNo());
reqDTO.setProductCode("FAST_INSTANT_TRADE_PAY"); //这个是固定的
String reqStr = JSON.toJSONString(reqDTO);
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", charset,
alipayPublicKey, signType);
switch (payFrom) {
case WEB:
AlipayTradePagePayRequest webReq = new AlipayTradePagePayRequest();
webReq.setReturnUrl(returnUrl);
webReq.setNotifyUrl(notifyUrl);
webReq.setBizContent(reqStr);
try {
return alipayClient.pageExecute(webReq).getBody();
} catch (AlipayApiException e) {
log.error("支付发起异常", e);
throw new ServiceException("支付发起失败");
}
case WAP:
AlipayTradeWapPayRequest wapReq = new AlipayTradeWapPayRequest();
wapReq.setReturnUrl(returnUrl);
wapReq.setNotifyUrl(notifyUrl);
wapReq.setBizContent(reqStr);
try {
return alipayClient.pageExecute(wapReq).getBody();
} catch (AlipayApiException e) {
log.error("支付发起异常", e);
throw new ServiceException("支付发起失败");
}
default:
throw new ServiceException("未知的支付来源");
}
}
}

View File

@ -1,8 +1,7 @@
package com.ruoyi.xkt.service;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfoDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
/**
* @author liangyq
@ -15,5 +14,12 @@ public interface IStoreOrderService {
* @param storeOrderAddDTO
* @return
*/
StoreOrderAddResultDTO createOrder(StoreOrderAddDTO storeOrderAddDTO);
StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO);
/**
*
*
* @param storeOrderId
*/
StoreOrderInfo preparePayOrder(Long storeOrderId);
}

View File

@ -8,9 +8,9 @@ import com.ruoyi.xkt.mapper.StoreOrderOperationRecordMapper;
import com.ruoyi.xkt.service.IOperationRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author liangyq
@ -22,14 +22,13 @@ public class OperationRecordServiceImpl implements IOperationRecordService {
@Autowired
private StoreOrderOperationRecordMapper storeOrderOperationRecordMapper;
@Transactional
@Override
public void addOrderOperationRecords(List<StoreOrderOperationRecordAddDTO> recordList) {
if (CollUtil.isEmpty(recordList)) {
return;
}
List<StoreOrderOperationRecord> list = recordList.stream()
.map(dto -> BeanUtil.toBean(dto, StoreOrderOperationRecord.class))
.collect(Collectors.toList());
List<StoreOrderOperationRecord> list = BeanUtil.copyToList(recordList, StoreOrderOperationRecord.class);
storeOrderOperationRecordMapper.batchInsert(list);
}

View File

@ -6,13 +6,14 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.SimpleEntity;
import com.ruoyi.common.core.domain.XktBaseEntity;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.xkt.domain.*;
import com.ruoyi.xkt.dto.express.ExpressContactDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.dto.order.StoreOrderOperationRecordAddDTO;
import com.ruoyi.xkt.enums.*;
import com.ruoyi.xkt.mapper.*;
@ -53,7 +54,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
@Transactional
@Override
public StoreOrderAddResultDTO createOrder(StoreOrderAddDTO storeOrderAddDTO) {
public StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO) {
Long orderUserId = storeOrderAddDTO.getOrderUserId();
Long storeId = storeOrderAddDTO.getStoreId();
Long expressId = storeOrderAddDTO.getExpressId();
@ -159,7 +160,48 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
});
//操作记录
addOperationRecords(orderId, orderDetailIdList, orderUserId, new Date(), EOrderAction.ADD_ORDER);
return new StoreOrderAddResultDTO(order, orderDetailList);
return new StoreOrderInfo(order, orderDetailList);
}
@Transactional
@Override
public StoreOrderInfo preparePayOrder(Long storeOrderId) {
Assert.notNull(storeOrderId);
StoreOrder order = storeOrderMapper.selectById(storeOrderId);
Assert.isTrue(EOrderType.SALES_ORDER.getValue().equals(order.getOrderType()),
"非销售订单无法发起支付");
Assert.isTrue(BeanValidators.exists(order), "订单不存在");
List<StoreOrderDetail> orderDetails = storeOrderDetailMapper.selectList(
Wrappers.lambdaQuery(StoreOrderDetail.class)
.eq(StoreOrderDetail::getStoreOrderId, storeOrderId)
.eq(SimpleEntity::getDelFlag, Constants.UNDELETED));
checkPreparePayStatus(order.getPayStatus());
StoreOrder updateOrder = new StoreOrder();
updateOrder.setId(storeOrderId);
updateOrder.setPayStatus(EPayStatus.PAYING.getValue());
updateOrder.setVersion(order.getVersion());
int orderSuccess = storeOrderMapper.updateById(updateOrder);
if (orderSuccess == 0) {
throw new ServiceException("系统繁忙请稍后再试");
}
for (StoreOrderDetail orderDetail : orderDetails) {
checkPreparePayStatus(orderDetail.getPayStatus());
StoreOrderDetail orderDetailUpdate = new StoreOrderDetail();
orderDetailUpdate.setId(orderDetail.getId());
orderDetailUpdate.setPayStatus(EPayStatus.PAYING.getValue());
orderDetailUpdate.setVersion(orderDetail.getVersion());
int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetailUpdate);
if (orderDetailSuccess == 0) {
throw new ServiceException("系统繁忙请稍后再试");
}
}
return new StoreOrderInfo(order, orderDetails);
}
private void checkPreparePayStatus(Integer payStatus) {
if (!EPayStatus.INIT.getValue().equals(payStatus) && !EPayStatus.PAYING.getValue().equals(payStatus)) {
throw new ServiceException("订单状态异常无法发起支付");
}
}
/**
@ -212,11 +254,12 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
BigDecimal price = productColorPrice.getPrice();
if (ProductSizeStatus.UN_STANDARD.getValue().equals(storeProductColorSize.getStandard())) {
//非标准尺码
StoreProduct product = storeProductMapper.selectById(storeProductColorSize.getStoreProdId());
BigDecimal addPrice = BigDecimal.valueOf(NumberUtil.nullToZero(product.getOverPrice()));
price = NumberUtil.add(price, addPrice);
// StoreProduct product = storeProductMapper.selectById(storeProductColorSize.getStoreProdId());
// BigDecimal addPrice = BigDecimal.valueOf(NumberUtil.nullToZero(product.getOverPrice()));
// price = NumberUtil.add(price, addPrice);
//非标准尺码不存在线上下单
throw new ServiceException("商品尺码异常");
}
//TODO 客户优惠
return price;
}