下单用户非必填

This commit is contained in:
wangw 2025-02-24 18:28:25 +08:00
parent 6f35f159d9
commit 46742bbf45
11 changed files with 150 additions and 50 deletions

View File

@ -28,6 +28,11 @@ public class OrderPayController {
@Resource
private PayService payService;
@PostMapping("/creditPay")
public CzgResult<Object> creditPayOrder(@Validated @RequestBody OrderPayParamDTO payParam) {
payParam.setShopId(StpKit.USER.getShopId());
return payService.creditPayOrder(payParam);
}
@PostMapping("/cashPay")
public CzgResult<Object> cashPayOrder(@Validated @RequestBody OrderPayParamDTO payParam) {

View File

@ -1,20 +1,19 @@
package com.czg.controller.admin;
import com.czg.order.dto.*;
import com.czg.order.dto.OrderInfoAddDTO;
import com.czg.order.dto.OrderInfoQueryDTO;
import com.czg.order.dto.OrderInfoRefundDTO;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoService;
import com.czg.order.vo.HistoryOrderVo;
import com.czg.order.vo.OrderInfoVo;
import com.czg.resp.CzgResult;
import com.czg.sa.StpKit;
import com.czg.utils.AssertUtil;
import com.czg.utils.ServletUtil;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
@ -39,9 +38,13 @@ public class AdminOrderController {
return CzgResult.success(orderInfoService.getOrderByPage(queryDTO));
}
@GetMapping("/historyOrder")
public CzgResult<HistoryOrderVo> historyOrder(Long orderId) {
return CzgResult.success(orderInfoService.historyOrder(orderId));
}
@PostMapping("/createOrder")
public CzgResult<OrderInfo> createOrder(@Validated @RequestBody OrderInfoAddDTO addDto) {
AssertUtil.isNull(addDto.getUserId(), "请选择下单用户后使用");
addDto.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
addDto.setStaffId(StpKit.USER.getLoginIdAsLong());
addDto.setShopId(StpKit.USER.getShopId());
@ -60,11 +63,9 @@ public class AdminOrderController {
* 订单全额退款 只传订单id
* 部分退款 传参refundDetailMap {"详情id":"数量","详情id":"数量"}
*
* @param refundDTO
* @return
*/
// @PostMapping("/refundOrder")
// public CzgResult<Object> refundOrder(@Validated @RequestBody OrderInfoRefundDTO refundDTO) {
// return orderInfoService.refundOrder(refundDTO);
// }
@PostMapping("/refundOrder")
public CzgResult<Object> refundOrder(@Validated @RequestBody OrderInfoRefundDTO refundDTO) {
return orderInfoService.refundOrder(refundDTO);
}
}

View File

@ -4,6 +4,7 @@ import com.czg.order.dto.OrderInfoAddDTO;
import com.czg.order.dto.OrderInfoQueryDTO;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoService;
import com.czg.order.vo.HistoryOrderVo;
import com.czg.order.vo.OrderInfoVo;
import com.czg.resp.CzgResult;
import com.czg.sa.StpKit;
@ -37,6 +38,11 @@ public class UserOrderController {
return CzgResult.success(orderInfoService.getOrderByPage(queryDTO));
}
@GetMapping("/historyOrder")
public CzgResult<HistoryOrderVo> historyOrder(Long orderId) {
return CzgResult.success(orderInfoService.historyOrder(orderId));
}
/**
* 生成订单
*/

View File

@ -30,12 +30,18 @@ public class OrderInfoRefundDTO implements Serializable {
/**
* 退单总金额
* 支付后的 退款金额 (累计总金额 不可超过 支付金额pay_amount - 已退金额refund_amount)
* <p>
* 部分商品退款为 退单数量*单价* 订单的discount_ratio 向下取整 该全退时 为该条详情总金额 * 订单的discount_ratio 向下取整
* 整单退款 为支付金额pay_amount
* <p>
* 支付前退款为 退菜 金额为 单价*数量 如果有部分打包 优先退非打包 (退打包时 记得计算打包费)
*/
@NotNull(message = "退单金额不能为空")
private BigDecimal refundAmount;
/**
* 退款金额 默认为 退单数量*单价 的和
* 退款金额 默认为 退单数量*单价* 订单 discount_ratio
* 整单退款 为订单orderAmount
* 如果自定义退款金额 则金额不进行校验 直接退款
*/

View File

@ -156,18 +156,20 @@ public class OrderInfo implements Serializable {
private String payMode;
/**
* {@link com.czg.order.enums.PayEnums}
* 支付类型
* 主扫 main-scan
* 被扫 back-scan
* 微信小程序 wechat-mini
* 支付宝小程序 alipay-mini
* 会员支付 vip-pay
* 现金支付 cash-pay
* 主扫 main_scan
* 被扫 back_scan
* 微信小程序 wechat_mini
* 支付宝小程序 alipay_mini
* 会员支付 vip_pay
* 现金支付 cash_pay
* 挂账支付 credit_pay
*/
private String payType;
/**
* OrderStatusEnums 枚举类
* {@link com.czg.service.order.enums.OrderStatusEnums}
* 状态: unpaid-待支付;in-production 制作中;wait-out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part-refund 部分退单;cancelled-取消订单
*/
private String status;

View File

@ -15,6 +15,7 @@ public enum PayEnums {
ALIPAY_MINI("alipay_mini", "支付宝小程序"),
VIP_PAY("vip_pay", "会员支付"),
CASH_PAY("cash_pay", "现金支付"),
CREDIT_PAY("credit_pay", "挂账支付"),
H5_PAY("h5_pay", "h5支付");

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
import com.czg.order.dto.*;
import com.czg.order.entity.OrderInfo;
import com.czg.order.enums.PayEnums;
import com.czg.order.vo.HistoryOrderVo;
import com.czg.order.vo.OrderInfoVo;
import com.czg.resp.CzgResult;
import com.mybatisflex.core.paginate.Page;
@ -23,6 +24,7 @@ import java.time.LocalDateTime;
public interface OrderInfoService extends IService<OrderInfo> {
Page<OrderInfoVo> getOrderByPage(OrderInfoQueryDTO param);
HistoryOrderVo historyOrder(Long orderId);
OrderInfo createOrder(OrderInfoAddDTO param);
// void updateOrder(OrderInfoUpDTO upDTO);
@ -35,5 +37,5 @@ public interface OrderInfoService extends IService<OrderInfo> {
void refundCallBackOrder(@NotBlank String orderNo, @NotNull JSONObject resultJson);
void upOrderInfo(Long orderId, BigDecimal payAmount, LocalDateTime payTime, Long payOrderId, PayEnums payType);
void upOrderInfo(OrderInfo orderInfo, BigDecimal payAmount, LocalDateTime payTime, Long payOrderId, PayEnums payType);
}

View File

@ -0,0 +1,18 @@
package com.czg.order.vo;
import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* @author ww
* @description
*/
@Data
public class HistoryOrderVo {
private OrderInfo info;
private Map<Integer, List<OrderDetail>> detailMap;
}

View File

@ -17,6 +17,10 @@ import java.util.Map;
* @author ww
*/
public interface PayService {
/**
* 挂账
*/
CzgResult<Object> creditPayOrder(OrderPayParamDTO payParam);
/**
* 现金支付
*/

View File

@ -24,6 +24,7 @@ import com.czg.order.service.CashierCartService;
import com.czg.order.service.OrderDetailService;
import com.czg.order.service.OrderInfoService;
import com.czg.order.service.OrderPaymentService;
import com.czg.order.vo.HistoryOrderVo;
import com.czg.order.vo.OrderDetailSmallVO;
import com.czg.order.vo.OrderInfoVo;
import com.czg.resp.CzgResult;
@ -123,6 +124,26 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
return orderInfoVoPage;
}
@Override
public HistoryOrderVo historyOrder(Long orderId) {
HistoryOrderVo historyOrderVo = new HistoryOrderVo();
OrderInfo orderInfo = getById(orderId);
AssertUtil.isNull(orderInfo, "订单不存在");
historyOrderVo.setInfo(orderInfo);
List<OrderDetail> orderDetails = orderDetailService.queryChain().select()
.eq(OrderDetail::getOrderId, orderId).list();
Map<Integer, List<OrderDetail>> resultMap = new HashMap<>();
// 遍历订单详情列表
for (OrderDetail orderDetail : orderDetails) {
// 获取当前订单详情的 placeNum
Integer placeNum = orderDetail.getPlaceNum();
// 检查 Map 中是否已经存在该 placeNum 对应的列表
resultMap.computeIfAbsent(placeNum, k -> new ArrayList<>()).add(orderDetail);
}
historyOrderVo.setDetailMap(resultMap);
return historyOrderVo;
}
@Override
@Transactional
public OrderInfo createOrder(OrderInfoAddDTO param) {
@ -138,8 +159,10 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
throw new ValidateException("生成订单失败,该店铺不支持使用会员价");
}
UserInfo userInfo = userInfoService.getById(param.getUserId());
AssertUtil.isNull(userInfo, "生成订单失败,用户信息不存在");
if (param.getUserId() != null) {
UserInfo userInfo = userInfoService.getById(param.getUserId());
AssertUtil.isNull(userInfo, "生成订单失败,用户信息不存在");
}
ShopTable table = shopTableService.getOneByTableCode(param.getShopId(), param.getTableCode());
if (table == null) {
param.setPayMode("no-table");
@ -169,6 +192,11 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
//生成订单
OrderInfo orderInfo = initOrderInfo(param, shopInfo, table);
orderDetailService.createOrderDetails(orderInfo.getId(), orderDetails);
if ("after-pay".equals(orderInfo.getPayMode())) {
//发送打票信息
rabbitPublisher.sendOrderPrintMsg(orderInfo.getId().toString());
}
rabbitPublisher.sendOrderStockMsg(orderInfo.getId().toString());
return orderInfo;
}
@ -221,14 +249,18 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
if (param.getPointsNum() > 0 && !pointSetting.getEnableDeduction().equals(1)) {
throw new ValidateException("生成支付订单失败,该店铺未开启积分抵扣");
}
UserInfo userInfo = userInfoService.getById(param.getUserId());
AssertUtil.isNull(userInfo, "生成支付订单失败,用户信息不存在");
ShopUser shopUser = shopUserService.getShopUserInfo(shopId, param.getUserId());
if (!shopUser.getIsVip().equals(1) && pointSetting.getDeductionGroup().contains("vip")) {
throw new ValidateException("生成支付订单失败,该店铺仅会员可使用积分抵扣");
}
if (param.getDiscountRatio().compareTo(BigDecimal.ZERO) <= 0 && param.getDiscountRatio().compareTo(BigDecimal.ONE) > 0) {
throw new ValidateException("生成支付订单失败,折扣比例不正确");
ShopUser shopUser = null;
if (param.getUserId() != null) {
UserInfo userInfo = userInfoService.getById(param.getUserId());
AssertUtil.isNull(userInfo, "生成支付订单失败,用户信息不存在");
shopUser = shopUserService.getShopUserInfo(shopId, param.getUserId());
if (!shopUser.getIsVip().equals(1) && pointSetting.getDeductionGroup().contains("vip")) {
throw new ValidateException("生成支付订单失败,该店铺仅会员可使用积分抵扣");
}
if (param.getDiscountRatio().compareTo(BigDecimal.ZERO) <= 0 && param.getDiscountRatio().compareTo(BigDecimal.ONE) > 0) {
throw new ValidateException("生成支付订单失败,折扣比例不正确");
}
param.setUserId(userInfo.getId());
}
//商品券 <商品id数量>
Map<Long, Integer> prodCouponMap = new HashMap<>();
@ -285,10 +317,12 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
}
//生成订单 //discount_info 所有折扣 几折 折扣金额 满减金额 优惠券金额 积分抵扣金额 抹零
upOrderPayInfo(orderInfo, param);
//更新优惠券信息
orderDetailService.updateBatch(orderDetails);
//券消耗
couponService.use(param.getCouponList(), shopUser.getId(), orderInfo.getId());
//更新优惠券信息
if (CollUtil.isNotEmpty(param.getCouponList()) && shopUser != null) {
//券消耗
couponService.use(param.getCouponList(), shopUser.getId(), orderInfo.getId());
}
return orderInfo;
}
@ -305,23 +339,26 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
if (CollUtil.isNotEmpty(param.getRefundDetails())) {
for (OrderDetail refundDetail : param.getRefundDetails()) {
AssertUtil.isNull(refundDetail.getNum(), "退单数量不能为空");
AssertUtil.isNull(refundDetail.getReturnAmount(), "退单金额不能为空");
//退款金额
BigDecimal refundAmount;
//退款数量
BigDecimal refNum;
//退优惠券数量 <商品id数量>
Map<Long, Integer> returnCouponMap = new HashMap<>();
OrderDetail orderDetail = detailService.getById(refundDetail.getId());
//可退数量=订单数量-退单数量-退菜数量
BigDecimal returnNum = orderDetail.getNum().subtract(orderDetail.getRefundNum()).subtract(orderDetail.getReturnNum());
if (returnNum.compareTo(BigDecimal.ZERO) <= 0 || returnNum.compareTo(refundDetail.getNum()) < 0) {
throw new ValidateException("退单失败,可退数量不足");
throw new ValidateException("退单失败," + orderDetail.getProductName() + "可退数量不足");
}
//可退数量 大于优惠券数量
if (returnNum.compareTo(orderDetail.getCouponNum()) > 0) {
//实际计算金额的数量
refNum = returnNum.subtract(orderDetail.getCouponNum());
if (refundDetail.getNum().compareTo(refNum) > 0) {
refundAmount = (refNum).multiply(orderDetail.getPrice());
//退单数量 大于 实际计算金额的数量
if (refundDetail.getNum().compareTo(refNum) >= 0) {
refundAmount = refNum.multiply(orderDetail.getPrice());
returnCouponMap.put(orderDetail.getProductId(), refundDetail.getNum().subtract(refNum).intValue());
refNum = refundDetail.getNum();
} else {
refNum = refundDetail.getNum();
@ -479,9 +516,9 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
prodCouponMap.compute(record.getProId(), (key, oldValue) -> oldValue == null ? 1 : oldValue + 1);
}
}
}
if (discountAmount.compareTo(param.getFullCouponDiscountAmount()) != 0) {
throw new ValidateException("生成支付订单失败,满减券减免金额不正确");
if (discountAmount.compareTo(param.getFullCouponDiscountAmount()) != 0) {
throw new ValidateException("生成支付订单失败,满减券减免金额不正确");
}
}
}
@ -498,7 +535,11 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
if ("TRADE_SUCCESS".equals(czgCallBackDto.getState())) {
if ("order".equals(payment.getPayType())) {
upOrderInfo(payment.getSourceId(), new BigDecimal(czgCallBackDto.getAmount() / 100L),
OrderInfo orderInfo = getById(payment.getSourceId());
if (orderInfo == null) {
log.error("订单支付回调失败,订单不存在,支付记录Id,{}", payment.getId());
}
upOrderInfo(orderInfo, new BigDecimal(czgCallBackDto.getAmount() / 100L),
DateUtil.parseLocalDateTime(czgCallBackDto.getPayTime()), payment.getId(), null);
} else if ("memberIn".equals(payment.getPayType())) {
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
@ -565,12 +606,12 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
* 其它支付为 tb_order_payment.id
*/
@Override
public void upOrderInfo(Long orderId, BigDecimal payAmount, LocalDateTime payTime, Long payOrderId, PayEnums payType) {
public void upOrderInfo(OrderInfo orderInfo, BigDecimal payAmount, LocalDateTime payTime, Long payOrderId, PayEnums payType) {
UpdateChain<OrderInfo> updateChain = updateChain()
.set(OrderInfo::getPayAmount, payAmount)
.set(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())
.set(OrderInfo::getPaidTime, payTime)
.where(OrderInfo::getId).eq(orderId);
.where(OrderInfo::getId).eq(orderInfo.getId());
if (payOrderId != null) {
updateChain.set(OrderInfo::getPayOrderId, payOrderId);
}
@ -578,8 +619,10 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
updateChain.set(OrderInfo::getPayType, payType.getValue());
}
updateChain.update();
//发送打票信息
rabbitPublisher.sendOrderPrintMsg(orderId.toString());
if (!"after-pay".equals(orderInfo.getPayMode())) {
//发送打票信息
rabbitPublisher.sendOrderPrintMsg(orderInfo.getId().toString());
}
}
/**
@ -643,11 +686,12 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
orderInfo.setProductCouponDiscountAmount(param.getProductCouponDiscountAmount());
orderInfo.setFullCouponDiscountAmount(param.getFullCouponDiscountAmount());
orderInfo.setDiscountAmount(param.getDiscountAmount());
orderInfo.setDiscountRatio(param.getDiscountRatio());
//优惠券
orderInfo.setCouponInfoList(JSONObject.toJSONString(param.getCouponList()));
//折扣信息
orderInfo.setDiscountInfo(buildDiscountInfo(orderInfo));
//最终折扣
orderInfo.setDiscountRatio(param.getOriginAmount().divide(param.getOrderAmount(), 2, RoundingMode.UP));
saveOrUpdate(orderInfo);
}

View File

@ -83,11 +83,22 @@ public class PayServiceImpl implements PayService {
return orderInfoService.checkOrderPay(checkOrderPay);
}
@Override
@Transactional
public CzgResult<Object> creditPayOrder(OrderPayParamDTO payParam) {
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
orderInfoService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
LocalDateTime.now(), null, PayEnums.CREDIT_PAY);
//TODO 挂账后续逻辑
return CzgResult.success();
}
@Override
@Transactional
public CzgResult<Object> cashPayOrder(OrderPayParamDTO payParam) {
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
orderInfoService.upOrderInfo(orderInfo.getId(), orderInfo.getOrderAmount(),
orderInfoService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
LocalDateTime.now(), null, PayEnums.CASH_PAY);
return CzgResult.success();
}
@ -135,7 +146,7 @@ public class PayServiceImpl implements PayService {
.build();
//更新会员余额 并生成流水
Long flowId = shopUserService.updateMoney(shopUser.getShopId(), shopUserMoneyEditDTO);
orderInfoService.upOrderInfo(orderInfo.getId(), orderInfo.getOrderAmount(),
orderInfoService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
LocalDateTime.now(), flowId, PayEnums.VIP_PAY);
return CzgResult.success();
}