1.代客下单 会员支付实现

This commit is contained in:
2024-08-23 09:20:51 +08:00
parent c408e8e168
commit 9e26fad331
8 changed files with 137 additions and 25 deletions

View File

@@ -23,4 +23,5 @@ public class TbPayController {
payService.scanPay(scanPayDTO);
return null;
}
}

View File

@@ -15,5 +15,5 @@ public class CreateOrderDTO {
@NotEmpty
private Long tableId;
private String note;
private boolean print;
private boolean postPay;
}

View File

@@ -2,7 +2,7 @@ package cn.ysk.cashier.enums;
public enum TableStateEnum {
IDLE("idle"),
CLOSED("closed"), PAYING("paying"), PENDING("pending");
CLOSED("closed"), PAYING("paying"), PENDING("pending"), USING("using");
private String state = "closed";
TableStateEnum(String state) {

View File

@@ -5,7 +5,9 @@ import cn.ysk.cashier.mybatis.entity.TbMShopUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
import java.util.Map;
/**
@@ -36,6 +38,8 @@ public interface TbMShopUserMapper extends BaseMapper<TbMShopUser> {
"</script>")
Map<String, Object> selectUserSummary(@Param("shopId") String shopId, @Param("isVip") Integer isVip);
@Update("update tb_shop_user set amount=amount-#{orderAmount}, consume_amount=consume_amount+#{orderAmount} where id=#{vipUserId} and amount >= 0")
long decrBalance(@Param("vipUserId") Integer vipUserId, @Param("orderAmount") BigDecimal orderAmount);
}

View File

@@ -2,6 +2,10 @@ package cn.ysk.cashier.service;
import cn.ysk.cashier.dto.ScanPayDTO;
import javax.validation.constraints.NotNull;
public interface TbPayService {
void scanPay(ScanPayDTO scanPayDTO);
void vipPay(@NotNull Integer shopId, @NotNull Integer orderId);
}

View File

@@ -1,40 +1,32 @@
package cn.ysk.cashier.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.ysk.cashier.dto.ScanPayDTO;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.entity.TbMShopUser;
import cn.ysk.cashier.mybatis.entity.TbOrderPayment;
import cn.ysk.cashier.mybatis.mapper.TbCashierCartMapper;
import cn.ysk.cashier.mybatis.mapper.TbOrderDetailMapper;
import cn.ysk.cashier.mybatis.mapper.TbOrderInfoMapper;
import cn.ysk.cashier.mybatis.mapper.TbShopPayTypeMapper;
import cn.ysk.cashier.mybatis.entity.TbShopUserFlow;
import cn.ysk.cashier.mybatis.mapper.*;
import cn.ysk.cashier.mybatis.service.TbOrderPaymentService;
import cn.ysk.cashier.mybatis.vo.pay.ScanPayReq;
import cn.ysk.cashier.pojo.TbShopPayType;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
import cn.ysk.cashier.pojo.order.TbOrderInfo;
import cn.ysk.cashier.pojo.shop.TbMerchantThirdApply;
import cn.ysk.cashier.pojo.shop.TbShopUser;
import cn.ysk.cashier.repository.shop.TbMerchantThirdApplyRepository;
import cn.ysk.cashier.service.TbPayService;
import cn.ysk.cashier.utils.BeanUtil;
import cn.ysk.cashier.utils.MD5Util;
import cn.ysk.cashier.utils.RabbitMsgUtils;
import cn.ysk.cashier.utils.SnowFlakeUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
@@ -61,7 +53,7 @@ public class TbPayServiceImpl implements TbPayService {
private final RabbitMsgUtils rabbitMsgUtils;
public TbPayServiceImpl(TbOrderInfoMapper orderInfoMapper, TbCashierCartMapper cashierCartMapper, TbMerchantThirdApplyRepository merchantThirdApplyRepository, TbOrderPaymentService orderPaymentService, TbShopPayTypeMapper shopPayTypeMapper, TbOrderDetailMapper orderDetailMapper,RabbitTemplate rabbitTemplate, RabbitMsgUtils rabbitMsgUtils) {
public TbPayServiceImpl(TbOrderInfoMapper orderInfoMapper, TbCashierCartMapper cashierCartMapper, TbMerchantThirdApplyRepository merchantThirdApplyRepository, TbOrderPaymentService orderPaymentService, TbShopPayTypeMapper shopPayTypeMapper, TbOrderDetailMapper orderDetailMapper, RabbitTemplate rabbitTemplate, RabbitMsgUtils rabbitMsgUtils, TbMShopUserMapper shopUserMapper, TbShopUserFlowMapper shopUserFlowMapper) {
this.orderInfoMapper = orderInfoMapper;
this.cashierCartMapper = cashierCartMapper;
this.merchantThirdApplyRepository = merchantThirdApplyRepository;
@@ -70,6 +62,8 @@ public class TbPayServiceImpl implements TbPayService {
this.orderDetailMapper = orderDetailMapper;
this.rabbitTemplate = rabbitTemplate;
this.rabbitMsgUtils = rabbitMsgUtils;
this.shopUserMapper = shopUserMapper;
this.shopUserFlowMapper = shopUserFlowMapper;
}
@Override
@@ -293,4 +287,75 @@ public class TbPayServiceImpl implements TbPayService {
// }
}
private final TbMShopUserMapper shopUserMapper;
private final TbShopUserFlowMapper shopUserFlowMapper;
@Override
public void vipPay(@NotNull Integer shopId, @NotNull Integer orderId) {
TbOrderInfo orderInfo = orderInfoMapper.selectById(orderId);
if (ObjectUtil.isEmpty(orderInfo)) {
throw new BadRequestException("订单不存在");
}
if (!"unpaid".equals(orderInfo.getStatus())) {
throw new BadRequestException("订单非未支付状态");
}
// 扣减会员余额
TbMShopUser shopUser = shopUserMapper.selectOne(new LambdaUpdateWrapper<TbMShopUser>()
.eq(TbMShopUser::getStatus, 1)
.eq(TbMShopUser::getId, orderInfo.getUserId()));
if (shopUser == null) {
throw new BadRequestException("用户不存在或已被禁用");
}
long flag = shopUserMapper.decrBalance(Integer.valueOf(orderInfo.getUserId()), orderInfo.getOrderAmount());
if (flag < 1) {
throw new BadRequestException("余额不足或扣除余额失败");
}
TbShopUserFlow userFlow = new TbShopUserFlow();
userFlow.setAmount(orderInfo.getOrderAmount());
userFlow.setBalance(shopUser.getAmount());
userFlow.setShopUserId(shopUser.getId());
userFlow.setBizCode("vipCardCash");
userFlow.setBizName("代客下单会员余额支付");
userFlow.setCreateTime(DateUtil.date());
userFlow.setType("-");
shopUserFlowMapper.insert(userFlow);
orderInfo.setPayAmount(orderInfo.getOrderAmount());
orderInfo.setPayType("cash");
orderInfo.setStatus("closed");
orderInfo.setPayOrderNo("cash".concat(SnowFlakeUtil.generateOrderNo()));
orderInfoMapper.updateById(orderInfo);
//更新购物车状态
int cartCount = cashierCartMapper.update(null, new LambdaUpdateWrapper<TbCashierCart>()
.eq(TbCashierCart::getOrderId, orderId)
.set(TbCashierCart::getStatus, "final"));
orderDetailMapper.update(null, new LambdaUpdateWrapper<TbOrderDetail>()
.eq(TbOrderDetail::getOrderId, orderId)
.set(TbOrderDetail::getStatus, "closed"));
log.info("更新购物车:{}", cartCount);
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", null);
jsonObject.put("type", "create");
jsonObject.put("orderId", orderId);
rabbitMsgUtils.sendOrderCollectMsg(jsonObject);
rabbitMsgUtils.printTicket(String.valueOf(orderId));
// 发送库存记录mq消息
JSONObject mqData = new JSONObject();
mqData.put("orderId", orderId);
mqData.put("type", "pc");
rabbitMsgUtils.sendStockMsg(mqData);
}
}

View File

@@ -42,6 +42,7 @@ import cn.ysk.cashier.repository.order.TbCashierCartRepository;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import cn.ysk.cashier.service.impl.TbPayServiceImpl;
import cn.ysk.cashier.utils.*;
import cn.ysk.cashier.vo.PendingCountVO;
import com.alibaba.fastjson.JSONObject;
@@ -110,6 +111,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
*/
private final String QRCODE = "https://kysh.sxczgkj.cn/codeplate?code=";
private final RabbitMsgUtils rabbitMsgUtils;
private final TbPayServiceImpl tbPayServiceImpl;
@Override
public Map<String, Object> queryAll(TbShopTableQueryCriteria criteria, Pageable pageable) {
@@ -395,6 +397,17 @@ public class TbShopTableServiceImpl implements TbShopTableService {
@Override
public void removeCart(RemoveCartDTO removeCartDTO) {
// 会员点单
TbCashierCart cashierCart = cashierCartMapper.selectOne(new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getShopId, removeCartDTO.getShopId())
.eq(TbCashierCart::getId, removeCartDTO.getCartId()));
if (cashierCart == null) {
throw new BadRequestException("购物车商品不存在");
}
if (cashierCart.getOrderId() != null) {
orderDetailMapper.delete(new LambdaQueryWrapper<TbOrderDetail>()
.eq(TbOrderDetail::getOrderId, cashierCart.getOrderId()));
}
cashierCartMapper.delete(new LambdaQueryWrapper<TbCashierCart>().eq(TbCashierCart::getShopId, removeCartDTO.getShopId())
.eq(TbCashierCart::getId, removeCartDTO.getCartId()));
}
@@ -419,7 +432,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
Integer size, Integer shopId, Integer vipUserId, String masterId) {
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getTableId, tableId)
.in(TbCashierCart::getStatus, "create", "refund")
.in(TbCashierCart::getStatus, "create")
.eq(TbCashierCart::getMasterId, masterId)
.eq(TbCashierCart::getShopId, shopId)
.and(query -> {
@@ -808,6 +821,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
String orderNo = generateOrderNumber();
orderInfo = new TbOrderInfo();
orderInfo.setOrderNo(orderNo);
orderInfo.setUseType(createOrderDTO.isPostPay() ? "postPay" : "afterPay");
orderInfo.setAmount(totalAmount);
orderInfo.setPackFee(packAMount);
orderInfo.setSettlementAmount(totalAmount);
@@ -824,6 +838,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
orderInfo.setMasterId(createOrderDTO.getMasterId());
orderInfo.setRemark(createOrderDTO.getNote());
orderInfo.setUserId(String.valueOf(createOrderDTO.getVipUserId()));
orderInfo.setCreatedAt(DateUtil.current());
orderInfoMapper.insert(orderInfo);
}
@@ -852,7 +867,13 @@ public class TbShopTableServiceImpl implements TbShopTableService {
cashierCartMapper.updateById(cashierCart);
}
if (isFirst) {
addGlobalCode(day, "pc", String.valueOf(createOrderDTO.getShopId()));
// 后付费,不增加当前台桌取餐号
if (createOrderDTO.isPostPay()) {
addGlobalCode(day, "pc", String.valueOf(createOrderDTO.getShopId()));
}else {
String key = "SHOP:CODE:USER:pc" + ":" + createOrderDTO.getShopId() + ":" + day + ":" + orderInfo.getTableId();
redisTemplate.delete(key);
}
}
// 推送耗材信息
@@ -860,7 +881,11 @@ public class TbShopTableServiceImpl implements TbShopTableService {
mpShopTableMapper.update(null, new LambdaUpdateWrapper<TbShopTable>()
.eq(TbShopTable::getQrcode, createOrderDTO.getTableId())
.set(TbShopTable::getStatus, TableStateEnum.PENDING.getState()));
.set(TbShopTable::getStatus, TableStateEnum.USING.getState()));
if (createOrderDTO.isPostPay()) {
rabbitMsgUtils.printTicket(String.valueOf(orderId));
}
return orderInfo;
}
@@ -914,7 +939,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
createOrderDTO.setShopId(pendingDTO.getShopId());
createOrderDTO.setMasterId(pendingDTO.getMasterId());
createOrderDTO.setVipUserId(pendingDTO.getVipUserId());
orderId = createOrder(createOrderDTO, false).getId();
orderId = createOrder(createOrderDTO, true).getId();
}
@@ -997,6 +1022,13 @@ public class TbShopTableServiceImpl implements TbShopTableService {
@Override
public Object pay(PayDTO payDTO) {
switch (payDTO.getPayType()) {
case "vipPay":
tbPayServiceImpl.vipPay(payDTO.getShopId(), payDTO.getOrderId());
return null;
}
TbOrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaUpdateWrapper<TbOrderInfo>()
.eq(TbOrderInfo::getId, payDTO.getOrderId())
.eq(TbOrderInfo::getShopId, payDTO.getShopId()));
@@ -1058,9 +1090,11 @@ public class TbShopTableServiceImpl implements TbShopTableService {
.eq(TbShopTable::getQrcode, orderInfo.getTableId())
.set(TbShopTable::getStatus, TableStateEnum.IDLE.getState()));
String day = DateUtils.getDay();
String key = "SHOP:CODE:USER:pc" + ":" + payDTO.getShopId() + ":" + day + ":" + orderInfo.getTableId();
redisTemplate.delete(key);
if ("postPay".equals(orderInfo.getUseType())) {
String day = DateUtils.getDay();
String key = "SHOP:CODE:USER:pc" + ":" + payDTO.getShopId() + ":" + day + ":" + orderInfo.getTableId();
redisTemplate.delete(key);
}
return null;
}

View File

@@ -42,4 +42,8 @@ public class RabbitMsgUtils implements RabbitTemplate.ConfirmCallback {
sendMsg(RabbitConstants.PRINT_MECHINE_COLLECT_PUT, RabbitConstants.PRINT_MECHINE_COLLECT_ROUTINGKEY_PUT, orderId, "打印票", false);
}
public <T> void sendStockMsg(T mqData) {
// 发送库存记录mq消息
sendMsg(RabbitConstants.EXCHANGE_STOCK_RECORD, RabbitConstants.ROUTING_STOCK_RECORD_SALE, mqData, "库存记录", true);
}
}