下单支持堂食外带, 增加餐位费, 多次下单功能

This commit is contained in:
2024-09-25 11:11:27 +08:00
parent 31b92e21c4
commit 0f702ecbe5
19 changed files with 576 additions and 47 deletions

View File

@@ -3,6 +3,7 @@ package com.chaozhanggui.system.cashierservice.controller;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.chaozhanggui.system.cashierservice.entity.dto.ChoseCountDTO;
import com.chaozhanggui.system.cashierservice.entity.dto.QuerySpecDTO;
import com.chaozhanggui.system.cashierservice.service.CartService;
import com.chaozhanggui.system.cashierservice.service.ProductService;
@@ -10,6 +11,7 @@ import com.chaozhanggui.system.cashierservice.sign.CodeEnum;
import com.chaozhanggui.system.cashierservice.sign.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@@ -94,6 +96,17 @@ public class ProductController {
return cartService.createCart(jsonObject);
}
/**
* 餐位费选择
* @return 餐位费信息
*/
@PostMapping("/choseCount")
public Result choseCount(
@Validated @RequestBody ChoseCountDTO choseCountDTO
) {
return Result.success(CodeEnum.SUCCESS, productService.choseCount(choseCountDTO));
}
@PostMapping("cleanCart")
public Result cleanCart(@RequestBody JSONObject jsonObject) {
log.info("清空购物车数据:{}", jsonObject);

View File

@@ -0,0 +1,18 @@
package com.chaozhanggui.system.cashierservice.entity.Enum;
import lombok.Getter;
/**
* 订餐用餐类型枚举
*/
@Getter
public enum OrderUseTypeEnum {
TAKEOUT("takeout"),
DINE_IN_AFTER("dine-in-after"),
DINE_IN_BEFORE("dine-in-before");
private final String value;
OrderUseTypeEnum(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,13 @@
package com.chaozhanggui.system.cashierservice.entity.Enum;
import lombok.Getter;
@Getter
public enum PlatformTypeEnum {
MINI_APP("miniapp");
private final String value;
PlatformTypeEnum(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,18 @@
package com.chaozhanggui.system.cashierservice.entity.Enum;
import lombok.Getter;
/**
* 店铺就餐类型
*/
@Getter
public enum ShopInfoEatModelEnum {
TAKE_OUT("take-out"),
DINE_IN("dine-in");
private final String value;
ShopInfoEatModelEnum(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,20 @@
package com.chaozhanggui.system.cashierservice.entity.Enum;
import lombok.Getter;
/**
* 店铺注册类型枚举
*/
@Getter
public enum ShopInfoRegisterlEnum {
// 快餐版
MUNCHIES("munchies"),
// 餐饮版
RESTAURANT("restaurant");
private final String value;
ShopInfoRegisterlEnum(String value) {
this.value = value;
}
}

View File

@@ -1,5 +1,8 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@@ -8,6 +11,7 @@ import java.math.BigDecimal;
@Data
public class TbCashierCart implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
private String masterId;
@@ -59,7 +63,13 @@ public class TbCashierCart implements Serializable {
private Integer userId;
private String tableId;
private Byte isVip;
@TableField(exist = false)
private TbProductSpec tbProductSpec;
private String note;
private String platformType;
private String useType;
private Integer placeNum;
private static final long serialVersionUID = 1L;
@@ -70,4 +80,4 @@ public class TbCashierCart implements Serializable {
return "";
}
}
}
}

View File

@@ -1,5 +1,6 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
@@ -37,7 +38,12 @@ public class TbOrderDetail implements Serializable {
private BigDecimal priceAmount;
private BigDecimal packAmount;
@TableField(exist = false)
private String remark;
private Integer cartId;
private Integer placeNum;
private String useType;
private static final long serialVersionUID = 1L;
}

View File

@@ -1,5 +1,8 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
@@ -8,6 +11,7 @@ import java.util.List;
@Data
public class TbOrderInfo implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
//订单号
@@ -58,11 +62,15 @@ public class TbOrderInfo implements Serializable {
private Byte isVip;
private String memberId;
@TableField(exist = false)
private String userName;
@TableField(exist = false)
private String memberName;
@TableField(exist = false)
private String zdNo;
private String userId;
@TableField(exist = false)
private String imgUrl;
private Integer productScore;
@@ -97,16 +105,25 @@ public class TbOrderInfo implements Serializable {
private String masterId;
private String isBuyCoupon;
private String isUseCoupon;
@TableField(exist = false)
private Integer totalNumber;
@TableField(exist = false)
private List<TbOrderDetail> detailList;
@TableField(exist = false)
private String winnnerNo;
@TableField(exist = false)
private String isWinner;
@TableField(exist = false)
private String shopName;
private String useType;
// 下单次数
private Integer placeNum;
//根据状态返回 需付款 已付款 未付款 已退
@TableField(exist = false)
private String description;
public void setDescription(String shopName) {

View File

@@ -1,5 +1,7 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -36,6 +38,7 @@ public class TbShopTable implements Serializable {
private String qrcode;
@TableField(exist = false)
private String areaname;
@@ -176,4 +179,4 @@ public class TbShopTable implements Serializable {
public void setUpdatedAt(Long updatedAt) {
this.updatedAt = updatedAt;
}
}
}

View File

@@ -0,0 +1,18 @@
package com.chaozhanggui.system.cashierservice.entity.dto;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class ChoseCountDTO {
@NotNull
private Integer shopId;
@NotEmpty
private String tableId;
@NotNull
@Min(1)
private Integer num;
}

View File

@@ -0,0 +1,16 @@
package com.chaozhanggui.system.cashierservice.entity.dto;
import com.chaozhanggui.system.cashierservice.entity.TbShopInfo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ShopEatTypeInfoDTO {
private boolean isTakeout;
private boolean isMunchies;
private boolean isDineInAfter;
private boolean isDineInBefore;
private TbShopInfo shopInfo;
private String useType;
}

View File

@@ -0,0 +1,19 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbCashierCart;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
/**
* @author Administrator
* @description 针对表【tb_call_queue】的数据库操作Mapper
* @createDate 2024-09-13 13:44:26
* @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue
*/
public interface MpCashierCartMapper extends BaseMapper<TbCashierCart> {
}

View File

@@ -0,0 +1,19 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
/**
* @author Administrator
* @description 针对表【tb_call_queue】的数据库操作Mapper
* @createDate 2024-09-13 13:44:26
* @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue
*/
public interface MpOrderDetailMapper extends BaseMapper<TbOrderDetail> {
}

View File

@@ -0,0 +1,19 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
import com.chaozhanggui.system.cashierservice.entity.TbShopInfo;
/**
* @author Administrator
* @description 针对表【tb_call_queue】的数据库操作Mapper
* @createDate 2024-09-13 13:44:26
* @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue
*/
public interface MpOrderInfoMapper extends BaseMapper<TbOrderInfo> {
}

View File

@@ -0,0 +1,22 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbCallQueue;
import com.chaozhanggui.system.cashierservice.entity.TbShopInfo;
import com.chaozhanggui.system.cashierservice.entity.vo.CallQueueInfoVO;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tb_call_queue】的数据库操作Mapper
* @createDate 2024-09-13 13:44:26
* @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue
*/
public interface MpShopInfoMapper extends BaseMapper<TbShopInfo> {
}

View File

@@ -0,0 +1,19 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbCashierCart;
import com.chaozhanggui.system.cashierservice.entity.TbShopTable;
/**
* @author Administrator
* @description 针对表【tb_call_queue】的数据库操作Mapper
* @createDate 2024-09-13 13:44:26
* @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue
*/
public interface MpShopTableMapper extends BaseMapper<TbShopTable> {
}

View File

@@ -1,23 +1,28 @@
package com.chaozhanggui.system.cashierservice.service;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chaozhanggui.system.cashierservice.dao.*;
import com.chaozhanggui.system.cashierservice.entity.*;
import com.chaozhanggui.system.cashierservice.entity.Enum.ShopWxMsgTypeEnum;
import com.chaozhanggui.system.cashierservice.entity.Enum.*;
import com.chaozhanggui.system.cashierservice.entity.dto.ShopEatTypeInfoDTO;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mapper.MpCashierCartMapper;
import com.chaozhanggui.system.cashierservice.mapper.MpOrderDetailMapper;
import com.chaozhanggui.system.cashierservice.mapper.MpOrderInfoMapper;
import com.chaozhanggui.system.cashierservice.mapper.MpShopInfoMapper;
import com.chaozhanggui.system.cashierservice.netty.PushToAppChannelHandlerAdapter;
import com.chaozhanggui.system.cashierservice.rabbit.RabbitProducer;
import com.chaozhanggui.system.cashierservice.redis.RedisCst;
import com.chaozhanggui.system.cashierservice.redis.RedisUtil;
import com.chaozhanggui.system.cashierservice.sign.CodeEnum;
import com.chaozhanggui.system.cashierservice.sign.Result;
import com.chaozhanggui.system.cashierservice.util.DateUtils;
import com.chaozhanggui.system.cashierservice.util.JSONUtil;
import com.chaozhanggui.system.cashierservice.util.LockUtils;
import com.chaozhanggui.system.cashierservice.util.N;
import com.chaozhanggui.system.cashierservice.util.*;
import com.chaozhanggui.system.cashierservice.wxUtil.WechatUtil;
import com.chaozhanggui.system.cashierservice.wxUtil.WxAccountUtil;
import lombok.extern.slf4j.Slf4j;
@@ -37,6 +42,7 @@ import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author lyf
@@ -96,14 +102,24 @@ public class CartService {
private final StringRedisTemplate stringRedisTemplate;
private final ShopUtils shopUtils;
@Autowired
private TbProskuConMapper tbProskuConMapper;
@Autowired
TbConsInfoMapper tbConsInfoMapper;
@Autowired
private MpShopInfoMapper mpShopInfoMapper;
@Autowired
private MpOrderInfoMapper mpOrderInfoMapper;
@Autowired
private MpCashierCartMapper mpCashierCartMapper;
@Autowired
private MpOrderDetailMapper mpOrderDetailMapper;
public CartService(TbUserShopMsgMapper tbUserShopMsgMapper, WechatUtil wechatUtil, WxAccountUtil wxAccountUtil, TbShopOpenIdMapper shopOpenIdMapper, ProductService productService, TbProductMapper tbProductMapper, RedisTemplate<String, Object> redisTemplate, StringRedisTemplate stringRedisTemplate) {
public CartService(TbUserShopMsgMapper tbUserShopMsgMapper, WechatUtil wechatUtil, WxAccountUtil wxAccountUtil, TbShopOpenIdMapper shopOpenIdMapper, ProductService productService, TbProductMapper tbProductMapper, RedisTemplate<String, Object> redisTemplate, StringRedisTemplate stringRedisTemplate, ShopUtils shopUtils) {
this.tbUserShopMsgMapper = tbUserShopMsgMapper;
this.wechatUtil = wechatUtil;
this.wxAccountUtil = wxAccountUtil;
@@ -112,6 +128,37 @@ public class CartService {
this.tbProductMapper = tbProductMapper;
this.redisTemplate = redisTemplate;
this.stringRedisTemplate = stringRedisTemplate;
this.shopUtils = shopUtils;
}
/**
* 获取当前台桌当前下单次数
*
* @param tableId 台桌id
* @param shopId 店铺id
* @param shopEatTypeInfoDTO 用餐类型
* @return 对应的次数为order最后次数+1
*/
private int getCurrentPlaceNum(String tableId, Object shopId, ShopEatTypeInfoDTO shopEatTypeInfoDTO) {
TbOrderInfo orderInfo = getCurrentOrder(shopEatTypeInfoDTO, tableId, shopId);
return orderInfo == null ? 1 : orderInfo.getPlaceNum() + 1;
}
private TbOrderInfo getCurrentOrder(ShopEatTypeInfoDTO eatTypeInfoDTO, String tableId, Object shopId) {
// 获取当前台桌最新订单,先付款模式不获取
if (eatTypeInfoDTO.isDineInBefore()) {
return null;
}
List<TbOrderInfo> orderInfoList = mpOrderInfoMapper.selectPage(new Page<>(1, 1), new LambdaQueryWrapper<TbOrderInfo>()
.eq(TbOrderInfo::getStatus, "unpaid")
.eq(TbOrderInfo::getUseType, eatTypeInfoDTO.getUseType())
.eq(TbOrderInfo::getShopId, shopId)
.eq(TbOrderInfo::getTableId, tableId)
.eq(TbOrderInfo::getTradeDay, DateUtils.getDay())
.orderByDesc(TbOrderInfo::getId)).getRecords();
return orderInfoList.isEmpty() ? null : orderInfoList.get(0);
}
public void initCart(JSONObject jsonObject) {
@@ -162,10 +209,16 @@ public class CartService {
Integer type = jsonObject.getInteger("type");
Integer buyNum = jsonObject.getInteger("num");
Integer isVip = jsonObject.getInteger("isVip");
if (StringUtils.isBlank(tableId) || StringUtils.isBlank(shopId) || StringUtils.isBlank(productId)
// 商品备注
String note = jsonObject.getString("note");
if (StringUtils.isBlank(shopId) || StringUtils.isBlank(productId)
|| StringUtils.isBlank(skuId) || type == null || buyNum == null) {
return Result.fail("参数缺失");
}
// 校验就餐模式
ShopEatTypeInfoDTO shopEatTypeInfoDTO = shopUtils.checkEatModel(tableId, shopId);
String key = tableId + "-" + shopId;
TbProduct tbProduct = productMapper.selectById(Integer.valueOf(productId));
if (tbProduct == null) {
@@ -193,8 +246,9 @@ public class CartService {
}
}
// 检查耗材
List<TbProskuCon> proskuConList = tbProskuConMapper.selectByShopIdAndSkuIdAndProductId(Integer.valueOf(skuId), Integer.valueOf(shopId), Integer.valueOf(productId));
if (Objects.nonNull(proskuConList) && proskuConList.size() > 0) {
if (Objects.nonNull(proskuConList) && !proskuConList.isEmpty()) {
for (TbProskuCon proskuCon : proskuConList) {
if ("1".equals(proskuCon.getStatus())) {
TbConsInfo consInfo = tbConsInfoMapper.selectByPrimaryKey(proskuCon.getConInfoId());
@@ -208,6 +262,7 @@ public class CartService {
}
JSONArray jsonArray = new JSONArray();
ArrayList<TbCashierCart> cashierCartArrayList = new ArrayList<>();
BigDecimal amount = BigDecimal.ZERO;
try{
if (redisUtil.exists(RedisCst.TABLE_CART.concat(key))) {
@@ -215,8 +270,10 @@ public class CartService {
if (Objects.isNull(array) || array.isEmpty()) {
if (type == 1) {
TbCashierCart cashierCart = addCart(productId, skuId,
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip);
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip, note, shopEatTypeInfoDTO);
jsonArray.add(cashierCart);
cashierCart.setPlaceNum(cashierCart.getPlaceNum() == null ? 0 : cashierCart.getPlaceNum());
cashierCartArrayList.add(cashierCart);
amount = amount.add(new BigDecimal(cashierCart.getNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
}
} else {
@@ -224,15 +281,24 @@ public class CartService {
for (int i = 0; i < array.size(); i++) {
JSONObject object = array.getJSONObject(i);
TbCashierCart cashierCart = JSONUtil.parseJSONStr2T(object.toJSONString(), TbCashierCart.class);
cashierCart.setPlaceNum(cashierCart.getPlaceNum() == null ? 0 : cashierCart.getPlaceNum());
if (buyNum < cashierCart.getNumber()) {
return Result.fail("代客下单不支持小程序操作");
}
if (cashierCart.getSkuId().equals(skuId) && cashierCart.getIsVip().intValue() == isVip) {
cashierCart.setTotalNumber(buyNum);
cashierCart.setNumber(buyNum);
cashierCart.setNote(note);
if (type == 0 && isVip == 0 && tbProductSkuWithBLOBs.getSuit() != null
&& tbProductSkuWithBLOBs.getSuit() > 1 && cashierCart.getNumber() < tbProductSkuWithBLOBs.getSuit()) {
cashierCartMapper.deleteByPrimaryKey(cashierCart.getId());
continue;
}
// 设置备注
cashierCart.setNote(note);
if (cashierCart.getNumber() > 0) {
if (isVip == 1) {
cashierCart.setTotalAmount(BigDecimal.ZERO);
@@ -240,19 +306,20 @@ public class CartService {
cashierCart.setTotalAmount(new BigDecimal(cashierCart.getTotalNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
}
cashierCart.setUpdatedAt(Instant.now().toEpochMilli());
cashierCartMapper.updateByPrimaryKeySelective(cashierCart);
mpCashierCartMapper.updateById(cashierCart);
} else {
cashierCartMapper.deleteByPrimaryKey(cashierCart.getId());
mpCashierCartMapper.deleteById(cashierCart.getId());
continue;
}
flag = false;
}
jsonArray.add(cashierCart);
cashierCartArrayList.add(cashierCart);
amount = amount.add(new BigDecimal(cashierCart.getTotalNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
}
if (flag && type == 1) {
TbCashierCart cashierCart = addCart(productId, skuId,
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip);
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip, note, shopEatTypeInfoDTO);
jsonArray.add(cashierCart);
amount = amount.add(new BigDecimal(cashierCart.getTotalNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
}
@@ -260,8 +327,10 @@ public class CartService {
} else {
if (type == 1) {
TbCashierCart cashierCart = addCart(productId, skuId,
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip);
jsonObject.getInteger("userId"), buyNum, tableId, shopId,isVip, note, shopEatTypeInfoDTO);
jsonArray.add(cashierCart);
cashierCart.setPlaceNum(cashierCart.getPlaceNum() == null ? 0 : cashierCart.getPlaceNum());
cashierCartArrayList.add(cashierCart);
if (isVip != 1) {
amount = amount.add(new BigDecimal(cashierCart.getTotalNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
}
@@ -272,21 +341,40 @@ public class CartService {
return Result.fail("商品起售库存不足");
}
}
redisUtil.saveMessage(RedisCst.TABLE_CART.concat(key), jsonArray.toJSONString());
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("status", "success");
jsonObject1.put("msg", "成功");
jsonObject1.put("type", "addcart");
jsonObject1.put("data", jsonArray);
jsonObject1.put("amount", amount);
jsonObject1.put("reqData", jsonObject);
PushToAppChannelHandlerAdapter.getInstance().AppSendInfo(jsonObject1.toString(), key, "", false);
// 餐位费
TbCashierCart seatCost = cashierCartArrayList.stream().findFirst().filter(info -> "-999".equals(info.getProductId())).orElse(null);
HashMap<String, Object> data = new HashMap<>();
data.put("status", "success");
data.put("msg", "成功");
data.put("type", "addcart");
data.put("data", formatCartStruct(cashierCartArrayList));
data.put("seatFee", seatCost);
data.put("amount", amount);
data.put("reqData", jsonObject);
PushToAppChannelHandlerAdapter.getInstance().AppSendInfo(JSONObject.toJSONString(data), key, "", false);
} catch (Exception e) {
log.error("长链接错误 createCart {}", e.getMessage());
log.error("长链接错误 createCar", e);
}
return Result.success(CodeEnum.SUCCESS);
}
private List<HashMap<String, Object>> formatCartStruct(List<TbCashierCart> cashierCartList) {
// 根据placeNum进行分组
Map<Integer, List<TbCashierCart>> groupedByPlaceNum = cashierCartList.stream()
.collect(Collectors.groupingBy(TbCashierCart::getPlaceNum));
ArrayList<HashMap<String, Object>> list = new ArrayList<>();
groupedByPlaceNum.forEach((k, v) -> {
HashMap<String, Object> item = new HashMap<>();
item.put("placeNum", k);
item.put("info", v);
list.add(item);
});
return list;
}
private void rmCart(JSONObject jsonObject,String skuId, String key) {
JSONArray jsonArray = new JSONArray();
BigDecimal amount = BigDecimal.ZERO;
@@ -298,9 +386,13 @@ public class CartService {
JSONObject object = array.getJSONObject(i);
TbCashierCart cashierCart = JSONUtil.parseJSONStr2T(object.toJSONString(), TbCashierCart.class);
if (cashierCart.getSkuId().equals(skuId)) {
cashierCartMapper.deleteByPrimaryKey(cashierCart.getId());
flag = true;
continue;
if (StrUtil.isNotBlank(cashierCart.getMasterId())) {
throw new MsgException("代客下单商品不支持操作");
}else {
cashierCartMapper.deleteByPrimaryKey(cashierCart.getId());
flag = true;
continue;
}
}
jsonArray.add(cashierCart);
amount = amount.add(new BigDecimal(cashierCart.getTotalNumber()).multiply(cashierCart.getSalePrice().add(cashierCart.getPackFee())));
@@ -397,7 +489,8 @@ public class CartService {
}
}
private TbCashierCart addCart(String productId, String skuId, Integer userId, Integer num, String tableId, String shopId,Integer isVip) throws Exception{
private TbCashierCart addCart(String productId, String skuId, Integer userId, Integer num,
String tableId, String shopId,Integer isVip, String note, ShopEatTypeInfoDTO shopEatTypeInfoDTO) throws Exception{
try {
TbProduct product = productMapper.selectById(Integer.valueOf(productId));
String key = tableId + "-" + shopId;
@@ -435,6 +528,7 @@ public class CartService {
cashierCart.setNumber(num);
cashierCart.setTotalNumber(num);
}
cashierCart.setNote(note);
cashierCart.setProductId(productId);
cashierCart.setSkuId(skuId);
cashierCart.setCoverImg(product.getCoverImg());
@@ -442,7 +536,7 @@ public class CartService {
cashierCart.setCategoryId(product.getCategoryId());
cashierCart.setShopId(shopId);
cashierCart.setUserId(userId);
cashierCart.setTableId(tableId);
cashierCart.setTableId(StrUtil.isBlank(tableId) ? null : tableId);
cashierCart.setSkuName(productSku.getSpecSnap());
cashierCart.setIsPack("false");
cashierCart.setIsGift("false");
@@ -458,11 +552,12 @@ public class CartService {
cashierCart.setTotalAmount(BigDecimal.ZERO);
cashierCart.setSalePrice(BigDecimal.ZERO);
}else {
cashierCart.setIsVip(Byte.parseByte("0"));
cashierCart.setIsVip((byte) 0);
cashierCart.setTotalAmount(new BigDecimal(cashierCart.getTotalNumber()).multiply(productSku.getSalePrice().add(cashierCart.getPackFee())));
}
cashierCartMapper.insert(cashierCart);
cashierCart.setPlatformType(PlatformTypeEnum.MINI_APP.getValue());
cashierCart.setUseType(shopEatTypeInfoDTO.getUseType());
mpCashierCartMapper.insert(cashierCart);
//修改耗材数据
// JSONObject jsonObject=new JSONObject();
@@ -504,11 +599,35 @@ public class CartService {
if (tbUserInfo == null) {
MsgException.throwException("生成订单失败");
}
TbShopUser tbShopUser = shopUserMapper.selectByUserIdAndShopId(userId, shopId);
boolean isVip= false;
if (tbShopUser != null && tbShopUser.getIsVip().equals((byte) 1)) {
isVip=true;
// 获取当前下单次数和用餐类型
ShopEatTypeInfoDTO shopEatTypeInfoDTO = shopUtils.checkEatModel(tableId, shopId);
Integer currentPlaceNum = getCurrentPlaceNum(tableId, shopId, shopEatTypeInfoDTO);
// 就餐人数
Integer mealNum = null;
ArrayList<Integer> cashierIds = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JSONObject object = array.getJSONObject(i);
TbCashierCart cashierCart = JSONUtil.parseJSONStr2T(object.toJSONString(), TbCashierCart.class);
cashierIds.add(cashierCart.getId());
if ("-999".equals(cashierCart.getProductId())) {
mealNum = cashierCart.getNumber();
}
}
TbShopUser tbShopUser = shopUserMapper.selectByUserIdAndShopId(userId, shopId);
boolean isVip= tbShopUser != null && tbShopUser.getIsVip().equals((byte) 1);
// 查询历史orderDetail
List<TbOrderDetail> oldOrderDetailList = mpOrderDetailMapper.selectList(new LambdaQueryWrapper<TbOrderDetail>()
.in(TbOrderDetail::getCartId, cashierIds)
.eq(TbOrderDetail::getShopId, shopId));
HashMap<String, TbOrderDetail> oldOrderDetailMap = new HashMap<>();
oldOrderDetailList.forEach(item -> {
oldOrderDetailMap.put(item.getOrderId().toString() + item.getCartId(), item);
});
//校验 库存 耗材
for (int i = 0; i < array.size(); i++) {
JSONObject object = array.getJSONObject(i);
@@ -572,10 +691,12 @@ public class CartService {
totalAmount = totalAmount.add(cashierCart.getTotalAmount());
packAMount = packAMount.add(cashierCart.getPackFee());
originAmount = originAmount.add(cashierCart.getTotalAmount());
if (Objects.nonNull(tbProduct)) {
saleAmount = saleAmount.add(tbProduct.getSalePrice());
saleAmount = saleAmount.add(tbProduct.getSalePrice());
TbOrderDetail orderDetail = oldOrderDetailMap.get(cashierCart.getOrderId() + cashierCart.getId());
if (orderDetail == null) {
orderDetail = new TbOrderDetail();
}
TbOrderDetail orderDetail = new TbOrderDetail();
orderDetail.setCreateTime(new Date());
orderDetail.setNum(cashierCart.getNumber());
orderDetail.setPrice(cashierCart.getSalePrice());
@@ -596,11 +717,25 @@ public class CartService {
if (StringUtils.isNotEmpty(cashierCart.getOrderId())) {
orderId = Integer.valueOf(cashierCart.getOrderId());
}
orderDetail.setUseType(shopEatTypeInfoDTO.getUseType());
orderDetail.setPlaceNum(cashierCart.getPlaceNum());
// 设置下单次数
if (cashierCart.getPlaceNum() == null) {
cashierCart.setPlaceNum(currentPlaceNum);
}
orderDetails.add(orderDetail);
if (StringUtils.isNotEmpty(cashierCart.getOrderId())) {
orderId = Integer.valueOf(cashierCart.getOrderId());
}
cashierCartMapper.updateStatusById(cashierCart.getId(), "final");
cashierCart.setStatus("final");
if (cashierCart.getId() != null) {
mpCashierCartMapper.updateById(cashierCart);
}else {
mpCashierCartMapper.insert(cashierCart);
}
}
//总金额
TbShopTable shopTable = shopTableMapper.selectQRcode(jsonObject.getString("tableId"));
@@ -665,6 +800,7 @@ public class CartService {
isuseYhq = "true";
}
if (Objects.nonNull(orderInfo)) {
log.info("订单状态:" + orderInfo.getStatus());
if (!"unpaid".equals(orderInfo.getStatus())) {
@@ -679,7 +815,6 @@ public class CartService {
return;
}
orderDetailMapper.deleteByOUrderId(orderId);
orderInfo.setUpdatedAt(System.currentTimeMillis());
orderInfo.setSettlementAmount(totalAmount);
orderInfo.setUserCouponId(couponId);
@@ -693,7 +828,9 @@ public class CartService {
orderInfo.setIsUseCoupon(isuseYhq);
orderInfo.setRemark(remark);
orderInfo.setUserId(userId);
orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
orderInfo.setPlaceNum(currentPlaceNum);
orderInfo.setUseType(shopEatTypeInfoDTO.getUseType());
mpOrderInfoMapper.updateById(orderInfo);
} else {
orderInfo = getOrder(totalAmount, packAMount, shopTable, tbMerchantAccount.getId().toString(), jsonObject, originAmount);
@@ -705,6 +842,8 @@ public class CartService {
orderInfo.setUserCouponAmount(couponAmount);
orderInfo.setRemark(remark);
orderInfo.setUserId(userId);
orderInfo.setPlaceNum(currentPlaceNum);
orderInfo.setUseType(shopEatTypeInfoDTO.getUseType());
JSONObject object = new JSONObject();
String outNumber = redisUtil.getMessage(RedisCst.OUT_NUMBER.concat(jsonObject.getString("shopId")));
@@ -724,11 +863,12 @@ public class CartService {
}
orderInfo.setOutNumber(number + "");
redisUtil.saveMessage(RedisCst.OUT_NUMBER.concat(jsonObject.getString("shopId")), object.toString());
orderInfoMapper.insert(orderInfo);
mpOrderInfoMapper.insert(orderInfo);
orderId = orderInfo.getId();
}
for (TbOrderDetail orderDetail : orderDetails) {
orderDetail.setOrderId(orderId);
orderDetailMapper.insert(orderDetail);
@@ -760,13 +900,17 @@ public class CartService {
cashierCart.setUpdatedAt(System.currentTimeMillis());
cashierCart.setOrderId(orderId + "");
cashierCart.setStatus("closed");
cashierCartMapper.updateByPrimaryKeySelective(cashierCart);
cashierCart.setUseType(shopEatTypeInfoDTO.getUseType());
cashierCart.setPlaceNum(cashierCart.getPlaceNum() == null ? currentPlaceNum : cashierCart.getPlaceNum());
mpCashierCartMapper.updateById(cashierCart);
object.put("updatedAt", System.currentTimeMillis());
object.put("orderId", orderId + "");
}
if(!CollectionUtils.isEmpty(outRecords)) outRecordMapper.insertBatch(outRecords);
// 发送mq消息
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("orderId", orderInfo.getId());
@@ -781,7 +925,11 @@ public class CartService {
jsonObject1.put("msg", "成功");
jsonObject1.put("type", jsonObject.getString("type"));
jsonObject1.put("data", orderInfo);
redisUtil.deleteByKey(RedisCst.TABLE_CART.concat(jsonObject.getString("tableId")).concat("-").concat(shopId));
// 购物车缓存, 后付款订单不删除
if (!OrderUseTypeEnum.DINE_IN_AFTER.getValue().equals(shopEatTypeInfoDTO.getUseType())) {
redisUtil.deleteByKey(RedisCst.TABLE_CART.concat(jsonObject.getString("tableId")).concat("-").concat(shopId));
}
PushToAppChannelHandlerAdapter.getInstance().AppSendInfo(jsonObject1.toString(), key, jsonObject.getString("userId"), true);
JSONObject jsonObject12 = new JSONObject();
jsonObject12.put("status", "success");
@@ -792,6 +940,8 @@ public class CartService {
jsonObject12.put("data", new JSONArray());
// PushToAppChannelHandlerAdapter.getInstance().AppSendInfo(jsonObject12.toString(), jsonObject.getString("tableId").concat("-").concat(shopId), "", false);
PushToAppChannelHandlerAdapter.getInstance().AppSendInfo(jsonObject12.toString(), jsonObject.getString("tableId").concat("-").concat(shopId), jsonObject.getString("userId"));
redisUtil.saveMessage(RedisCst.ORDER_EXPIRED.concat(orderId.toString()), orderId.toString(), 60 * 16L);
ThreadUtil.execAsync(() -> {
ThreadUtil.sleep(5, TimeUnit.SECONDS);
@@ -806,7 +956,6 @@ public class CartService {
}
});
} catch (Exception e) {
log.info("长链接错误 createOrder{}", e.getMessage());
e.printStackTrace();
@@ -868,7 +1017,8 @@ public class CartService {
// }
// }
// }
cashierCartMapper.updateStatusByTableId(jsonObject.getString("tableId"), "closed");
cashierCartMapper.updateStatusByOrderIdForMini(jsonObject.getString("tableId"), "closed");
// cashierCartMapper.updateStatusByTableId(jsonObject.getString("tableId"), "closed");
redisUtil.saveMessage(RedisCst.TABLE_CART.concat(jsonObject.getString("tableId").concat("-").concat(shopId)), new JSONArray().toJSONString());
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("status", "success");

View File

@@ -6,12 +6,19 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chaozhanggui.system.cashierservice.dao.*;
import com.chaozhanggui.system.cashierservice.entity.*;
import com.chaozhanggui.system.cashierservice.entity.Enum.PlatformTypeEnum;
import com.chaozhanggui.system.cashierservice.entity.Enum.ShopInfoEatModelEnum;
import com.chaozhanggui.system.cashierservice.entity.dto.ChoseCountDTO;
import com.chaozhanggui.system.cashierservice.entity.dto.HomeDto;
import com.chaozhanggui.system.cashierservice.entity.dto.QuerySpecDTO;
import com.chaozhanggui.system.cashierservice.entity.dto.ShopEatTypeInfoDTO;
import com.chaozhanggui.system.cashierservice.entity.vo.*;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mapper.MpCashierCartMapper;
import com.chaozhanggui.system.cashierservice.mapper.MpShopTableMapper;
import com.chaozhanggui.system.cashierservice.sign.CodeEnum;
import com.chaozhanggui.system.cashierservice.sign.Result;
import com.chaozhanggui.system.cashierservice.util.*;
@@ -83,6 +90,16 @@ public class ProductService {
@Resource
private TbActivateInRecordService activateInRecordService;
private final ShopUtils shopUtils;
@Autowired
private MpShopTableMapper mpShopTableMapper;
@Autowired
private MpCashierCartMapper mpCashierCartMapper;
public ProductService(ShopUtils shopUtils) {
this.shopUtils = shopUtils;
}
public Result queryShopIdByTableCode(String userId, String openId, String code, String lat, String lng) {
if (StringUtils.isBlank(code)) return Result.fail("桌码信息为空");
if (StringUtils.isBlank(lat) || lat.equals("undefined")) {
@@ -825,4 +842,63 @@ public class ProductService {
}
}
public Object choseCount(ChoseCountDTO choseCountDTO) {
ShopEatTypeInfoDTO shopEatTypeInfoDTO = shopUtils.checkEatModel(choseCountDTO.getTableId(), choseCountDTO.getShopId());
TbShopInfo shopInfo = tbShopInfoMapper.selectByPrimaryKey(choseCountDTO.getShopId());
if (shopInfo == null) throw new MsgException("店铺信息不存在");
if (shopInfo.getIsTableFee() != null && shopInfo.getIsTableFee() == 1) {
throw new MsgException("当前店铺无需选择餐位费");
}
TbShopTable shopTable = mpShopTableMapper.selectOne(new LambdaQueryWrapper<TbShopTable>()
.eq(TbShopTable::getQrcode, choseCountDTO.getTableId()));
if (shopTable == null) {
throw new MsgException("台桌不存在");
}
if (shopTable.getMaxCapacity() < choseCountDTO.getNum()) {
throw new MsgException("当前台桌最大人数为: " + shopTable.getMaxCapacity());
}
LambdaQueryWrapper<TbCashierCart> query = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getShopId, choseCountDTO.getShopId())
.eq(TbCashierCart::getProductId, "-999")
.eq(TbCashierCart::getSkuId, "-999")
.eq(TbCashierCart::getUseType, shopEatTypeInfoDTO.getUseType())
.eq(TbCashierCart::getTableId, choseCountDTO.getTableId());
TbCashierCart tbCashierCart = mpCashierCartMapper.selectOne(query);
if (tbCashierCart == null) {
tbCashierCart = new TbCashierCart();
tbCashierCart.setStatus("create");
tbCashierCart.setCreatedAt(System.currentTimeMillis());
tbCashierCart.setTableId(choseCountDTO.getTableId());
tbCashierCart.setName("客座费");
tbCashierCart.setSalePrice(shopInfo.getTableFee());
tbCashierCart.setShopId(String.valueOf(choseCountDTO.getShopId()));
tbCashierCart.setTradeDay(DateUtils.getDay());
tbCashierCart.setStatus("create");
tbCashierCart.setTotalAmount(new BigDecimal(choseCountDTO.getNum()).multiply(shopInfo.getTableFee()));
tbCashierCart.setPlaceNum(1);
tbCashierCart.setProductId("-999");
tbCashierCart.setSkuId("-999");
tbCashierCart.setPackFee(BigDecimal.ZERO);
tbCashierCart.setNumber(choseCountDTO.getNum());
tbCashierCart.setTotalNumber(choseCountDTO.getNum());
tbCashierCart.setUseType(shopEatTypeInfoDTO.getUseType());
tbCashierCart.setPlatformType(PlatformTypeEnum.MINI_APP.getValue());
mpCashierCartMapper.insert(tbCashierCart);
} else {
tbCashierCart.setTotalAmount(new BigDecimal(choseCountDTO.getNum()).multiply(shopInfo.getTableFee()));
tbCashierCart.setNumber(choseCountDTO.getNum());
tbCashierCart.setTotalNumber(choseCountDTO.getNum());
tbCashierCart.setUseType(shopEatTypeInfoDTO.getUseType());
tbCashierCart.setPlatformType(PlatformTypeEnum.MINI_APP.getValue());
mpCashierCartMapper.updateById(tbCashierCart);
}
return tbCashierCart;
}
}

View File

@@ -0,0 +1,53 @@
package com.chaozhanggui.system.cashierservice.util;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chaozhanggui.system.cashierservice.entity.Enum.OrderUseTypeEnum;
import com.chaozhanggui.system.cashierservice.entity.Enum.ShopInfoEatModelEnum;
import com.chaozhanggui.system.cashierservice.entity.Enum.ShopInfoRegisterlEnum;
import com.chaozhanggui.system.cashierservice.entity.TbShopInfo;
import com.chaozhanggui.system.cashierservice.entity.dto.ShopEatTypeInfoDTO;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mapper.MpShopInfoMapper;
import org.springframework.stereotype.Component;
@Component
public class ShopUtils {
private final MpShopInfoMapper mpShopInfoMapper;
public ShopUtils(MpShopInfoMapper mpShopInfoMapper) {
this.mpShopInfoMapper = mpShopInfoMapper;
}
/**
* 校验就餐模式是否存在并返回就餐类型信息
* @param tableId 台桌id
* @param shopId 店铺id
* @return 就餐类型信息
*/
public ShopEatTypeInfoDTO checkEatModel(String tableId, Object shopId) {
String eatModel = StrUtil.isBlank(tableId) ? ShopInfoEatModelEnum.TAKE_OUT.getValue() : ShopInfoEatModelEnum.DINE_IN.getValue();
TbShopInfo shopInfo = mpShopInfoMapper.selectOne(new LambdaQueryWrapper<TbShopInfo>()
.eq(TbShopInfo::getId, shopId)
.eq(TbShopInfo::getStatus, 1));
if (shopInfo == null) {
throw new MsgException("店铺信息不存在");
}
if (!shopInfo.getEatModel().contains(eatModel)) {
throw new MsgException("当前店铺未开启此就餐模式");
}
boolean isTakeout = ShopInfoEatModelEnum.TAKE_OUT.getValue().equals(eatModel);
// 是否是快餐版/先付费
boolean isMunchies = StrUtil.isNotBlank(shopInfo.getRegisterType()) &&
ShopInfoRegisterlEnum.MUNCHIES.getValue().equals(shopInfo.getRegisterType());
boolean isDineInAfter = !isMunchies && !isTakeout;
boolean isDineInBefore = isMunchies && !isTakeout;
return new ShopEatTypeInfoDTO(isTakeout, isMunchies, isDineInAfter, isDineInBefore, shopInfo, isTakeout ? OrderUseTypeEnum.TAKEOUT.getValue() :
isMunchies ? OrderUseTypeEnum.DINE_IN_BEFORE.getValue() : OrderUseTypeEnum.DINE_IN_AFTER.getValue());
}
}