package com.sinata.rest.modular.mall.service.impl;
|
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.sinata.common.enums.EnumMemberGrade;
|
import com.sinata.common.enums.EnumPayType;
|
import com.sinata.common.enums.EnumUserBankDetailDoneType;
|
import com.sinata.common.enums.EnumUserBankDetailType;
|
import com.sinata.common.enums.mall.EnumMallGoodsGroupType;
|
import com.sinata.common.enums.mall.EnumMallGoodsState;
|
import com.sinata.common.enums.mall.EnumMallOrderPrefix;
|
import com.sinata.common.enums.mall.EnumMallOrderState;
|
import com.sinata.rest.common.ApiUtils;
|
import com.sinata.rest.core.util.DailyIncrementIdGenerator;
|
import com.sinata.rest.core.util.DateUtils;
|
import com.sinata.rest.core.util.ToolUtil;
|
import com.sinata.rest.modular.auth.util.ThreadPoolUtil;
|
import com.sinata.rest.modular.mall.controller.body.BodyMallOrder;
|
import com.sinata.rest.modular.mall.controller.body.BodyMallOrderDetail;
|
import com.sinata.rest.modular.mall.controller.vo.*;
|
import com.sinata.rest.modular.mall.dao.MallOrderMapper;
|
import com.sinata.rest.modular.mall.dao.NoticeMapper;
|
import com.sinata.rest.modular.mall.model.*;
|
import com.sinata.rest.modular.mall.service.*;
|
import com.sinata.rest.modular.member.model.MemMerchant;
|
import com.sinata.rest.modular.member.model.MemUser;
|
import com.sinata.rest.modular.member.model.MemUserBankDetail;
|
import com.sinata.rest.modular.member.model.MyCoupon;
|
import com.sinata.rest.modular.member.service.*;
|
import com.sinata.rest.modular.system.dao.AreaCityMapper;
|
import com.sinata.rest.modular.system.model.AreaCity;
|
import com.sinata.rest.modular.system.service.ISystemSetService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.Assert;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 商品订单 服务实现类
|
* </p>
|
*
|
* @author goku
|
* @since 2023-03-10
|
*/
|
@Slf4j
|
@Service
|
@Transactional
|
public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder> implements IMallOrderService {
|
|
@Autowired
|
IMallGoodsService goodsService;
|
@Autowired
|
IMallGoodsSkuService goodsSkuService;
|
@Autowired
|
IMallOrderMainService orderMainService;
|
@Autowired
|
IMallOrderDetailService orderDetailService;
|
@Autowired
|
ISystemSetService systemSetService;
|
@Autowired
|
IMemMerchantBankService merchantBankService;
|
@Autowired
|
IMemMerchantService merchantService;
|
@Autowired
|
IMallOrderDetailUseService mallOrderDetailUseService;
|
@Autowired
|
IMyUserCouponService myUserCouponService;
|
@Autowired
|
IMyCouponService myCouponService;
|
@Autowired
|
IMemUserRelationService memUserRelationService;
|
|
@Autowired
|
IMemUserService memUserService;
|
|
@Resource
|
NoticeMapper noticeMapper;
|
|
@Resource
|
private AreaCityMapper areaCityMapper;
|
|
@Resource
|
private DailyIncrementIdGenerator dailyIncrementIdGenerator;
|
|
@Override
|
public List<VoMallOrder> getOrderByUserIdList(Integer userId, Integer saleUserId, Integer state, Page page) {
|
return this.baseMapper.getOrderByUserIdList(userId, saleUserId, state, page);
|
}
|
|
@Override
|
public VoMallOrder getOrderByOrderNo(String orderNo) {
|
return this.baseMapper.getOrderByOrderNo(orderNo);
|
}
|
|
@Override
|
public List<VoMallOrderDetail> getOrderDetailByUserIdList(Integer userId, String state, Page page) {
|
String[] stateArray = null;
|
if(state != null) {
|
stateArray = state.split(",");
|
}
|
return this.baseMapper.getOrderDetailByUserIdList(userId, stateArray);
|
}
|
|
@Override
|
public List<VoMallOrderDetail> getOrderDetailByOrderNoList(String orderNo) {
|
List<VoMallOrderDetail> detailList = this.baseMapper.getOrderDetailByOrderNoList(orderNo);
|
detailList.stream().forEach(detail->{
|
LambdaQueryWrapper<MallOrderDetailUse> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(MallOrderDetailUse::getOrderDetailNo,detail.getOrderDetailNo());
|
detail.setUseList(mallOrderDetailUseService.list(queryWrapper));
|
});
|
return detailList;
|
}
|
|
@Override
|
public Object createOrder(List<BodyMallOrder> list) {
|
// 持久化数据组
|
List<MallOrder> orderList = new ArrayList<>();
|
List<MallOrderDetail> orderDetailList = new ArrayList<>();
|
|
// 获取用户ID
|
Integer userId = ThreadPoolUtil.getUserId();
|
MemUser user = memUserService.getById(userId);
|
|
// 主订单
|
MallOrderMain orderMain = new MallOrderMain();
|
orderMain.setOrderNo(EnumMallOrderPrefix.MAIN_ORDER.index + DateUtils.format(new Date(), "yyMMddHHmmSSS") + ToolUtil.getRandomNumber(6));
|
orderMain.setUserId(userId);
|
// 主订单总金额
|
BigDecimal mainGoodsMoney = BigDecimal.ZERO;
|
|
for (BodyMallOrder body : list) {
|
// 商品订单
|
MallOrder order = new MallOrder();
|
order.setOrderMainNo(orderMain.getOrderNo());
|
order.setSaleUserId(body.getSaleUserId());
|
order.setMerchantId(body.getMerchantId());
|
order.setCityCode(body.getCityCode());
|
order.setUserId(userId);
|
order.setTakeName(body.getTakeName());
|
order.setPhone(body.getPhone());
|
order.setIdCard(body.getIdCard());
|
order.setNumber(body.getNumber());
|
order.setState(EnumMallOrderState.WAIT_PAY.index);
|
// 生成订单编号
|
order.setOrderNo(dailyIncrementIdGenerator.generateId());
|
|
String provinceCode = null;
|
String cityCode = null;
|
String countyCode = null;
|
if (StrUtil.isNotBlank(body.getCityCode())) {
|
AreaCity areaCity = areaCityMapper.selectById(body.getCityCode());
|
if (areaCity != null) {
|
provinceCode = areaCity.getProvinceCode();
|
cityCode = areaCity.getCityCode();
|
countyCode = areaCity.getCountyCode();
|
}
|
}
|
|
// 商品总金额
|
BigDecimal goodsMoney = BigDecimal.ZERO;
|
// 验证SKU商品(是否下架)
|
Object[] skuIdArray = body.getSkuList().stream().map(BodyMallOrderDetail::getSkuId).collect(Collectors.toList()).toArray();
|
// 查询商品SKU
|
List<VoGoodsSku> skuVoListTemp = goodsService.getGoodsBySkuIdArray(skuIdArray);
|
List<VoGoodsSku> skuVoList = new ArrayList<>();
|
for (VoGoodsSku o : skuVoListTemp) {
|
if (o.getGroupType() == EnumMallGoodsGroupType.GOODS.index && body.getMerchantId().equals(o.getMerchantId())) {
|
// 普通商品
|
skuVoList.add(o);
|
} else if (o.getGroupType() != EnumMallGoodsGroupType.GOODS.index && o.getMerchantId() == 0) {
|
if (order.getSaleUserId() == null || order.getSaleUserId() == 0) {
|
return ApiUtils.returnNG(null, "套餐订单销售员ID为空");
|
}
|
|
// 套餐商品
|
skuVoList.add(o);
|
|
order.setOrderNo(EnumMallOrderPrefix.GOODS_GROUP_ORDER.index + order.getOrderNo());
|
}
|
order.setOrderType(o.getGroupType());
|
}
|
|
// 商品ID
|
Integer goodsId = null;
|
// 套餐开始结束时间
|
Date startTime = null, endTime = null;
|
|
for(BodyMallOrderDetail boSku : body.getSkuList()) {
|
for (VoGoodsSku skuVo : skuVoList) {
|
if(skuVo.getId().intValue() == boSku.getSkuId() || skuVo.getSkuId().intValue() == boSku.getSkuId() ) {
|
// 判断商品状态是否正常
|
if(skuVo.getState() != EnumMallGoodsState.FOR_SALE.index) {
|
return ApiUtils.returnNG(null, "商品:" + skuVo.getGoodsName() + "," + EnumMallGoodsState.getMarkByIndex(skuVo.getState()));
|
}
|
// 判断库存是否充足
|
if(skuVo.getStock() < boSku.getGoodsNum()) {
|
return ApiUtils.returnNG(null, "商品:" + skuVo.getGoodsName() + ",库存不足");
|
}
|
// 减去库存
|
goodsSkuService.updateStock(skuVo.getSkuId(), -boSku.getGoodsNum());
|
|
// 商品价格
|
BigDecimal sellCost;
|
if (skuVo.getGroupType() == EnumMallGoodsGroupType.GOODS.index) {
|
// 普通商品(是否指定美天销售价,优先会员价,非会员使用门店价)
|
if (boSku.getIsPriceSale() != null && boSku.getIsPriceSale()) {
|
// 美天销售价
|
sellCost = skuVo.getPriceSale();
|
} else {
|
if (user != null && user.getMemberGradeId() != EnumMemberGrade.G_1.index) {
|
// 会员价
|
sellCost = skuVo.getPriceMember();
|
} else {
|
// 门店价
|
sellCost = skuVo.getPriceMerchant();
|
}
|
}
|
} else {
|
// 套餐商品(优先销售价(门店价存得值),未设置为美天销售价)
|
if (skuVo.getPriceMerchant() == null || skuVo.getPriceMerchant().compareTo(BigDecimal.ZERO) <= 0) {
|
// 美天销售价
|
sellCost = skuVo.getPriceSale();
|
} else {
|
// 销售价
|
sellCost = skuVo.getPriceMerchant();
|
}
|
}
|
|
// 总金额
|
BigDecimal totalMoney = sellCost.multiply(BigDecimal.valueOf(boSku.getGoodsNum()));
|
|
// 订单详细信息
|
MallOrderDetail orderDetail = new MallOrderDetail();
|
orderDetail.setOrderDetailNo(EnumMallOrderPrefix.ORDER_DETAIL.index + DateUtils.format(new Date(), "yyMMddHHmmSSS") + ToolUtil.getRandomNumber(6));
|
orderDetail.setOrderNo(order.getOrderNo());
|
orderDetail.setTotalMoney(totalMoney);
|
orderDetail.setGoodsId(skuVo.getGoodsId());
|
orderDetail.setSkuId(skuVo.getSkuId());
|
orderDetail.setGoodsSku(JSON.toJSONString(skuVo));
|
orderDetail.setSellCost(sellCost);
|
orderDetail.setGoodsNum(boSku.getGoodsNum());
|
orderDetail.setGoodsName(skuVo.getGoodsName());
|
orderDetail.setGrepName(skuVo.getGrepName());
|
orderDetail.setSpecGrep(skuVo.getSpecGrep());
|
orderDetail.setGoodsImage(skuVo.getGoodsImage());
|
orderDetail.setProvinceCode(StrUtil.isNotBlank(provinceCode) ? provinceCode : skuVo.getProvinceCode());
|
orderDetail.setCityCode(StrUtil.isNotBlank(cityCode) ? cityCode : skuVo.getCityCode());
|
orderDetail.setCountyCode(StrUtil.isNotBlank(countyCode) ? countyCode : skuVo.getCountyCode());
|
|
// 累加商品金额
|
goodsMoney = goodsMoney.add(totalMoney);
|
|
// 加入待持久化数组
|
orderDetailList.add(orderDetail);
|
|
// 商品ID
|
goodsId = skuVo.getGoodsId();
|
|
// 套餐开始结束时间
|
startTime = skuVo.getStartTime();
|
endTime = skuVo.getEndTime();
|
}
|
}
|
}
|
|
// 商品ID
|
order.setGoodsId(goodsId);
|
// 套餐开始结束时间
|
order.setStartTime(startTime);
|
order.setEndTime(endTime);
|
|
BigDecimal couponMoney = BigDecimal.ZERO;
|
if (body.getCouponId() != null) {
|
// 获取优惠券信息
|
MyCoupon myCoupon = myCouponService.getById(body.getCouponId());
|
if (myCoupon != null && myCoupon.getCouponType() != null && myCoupon.getCouponType() != 3) {
|
// 优惠券类型 1 满减 2折扣 3礼品
|
if (myCoupon.getCouponType() == 1) {
|
couponMoney = myCoupon.getAmount();
|
}
|
if (myCoupon.getCouponType() == 2) {
|
couponMoney = goodsMoney.multiply(myCoupon.getAmount()).multiply(BigDecimal.valueOf(0.1));
|
}
|
// 订单使用优惠券
|
myCouponService.updateUseCoupon(userId, myCoupon.getId(), 1);
|
}
|
order.setCouponId(body.getCouponId());
|
order.setCouponMoney(couponMoney);
|
}
|
|
// 商品金额
|
order.setGoodsMoney(goodsMoney);
|
// 设置支付金额 = 订单金额 - 优惠券金额
|
BigDecimal payMoney = goodsMoney.subtract(couponMoney);
|
if (payMoney.compareTo(BigDecimal.ZERO) <= 0) {
|
// 如果支付金额 <= 0 付 0.01
|
payMoney = BigDecimal.valueOf(0.01);
|
}
|
order.setPayMoney(payMoney);
|
|
// 加入待持久化数组
|
orderList.add(order);
|
|
mainGoodsMoney = mainGoodsMoney.add(goodsMoney);
|
|
orderMain.setGoodsMoney(mainGoodsMoney);
|
orderMain.setPayMoney(payMoney);
|
orderMain.setState(EnumMallOrderState.WAIT_PAY.index);
|
|
// 保存下单数据
|
orderMain.insert();
|
this.saveBatch(orderList);
|
orderDetailService.saveBatch(orderDetailList);
|
|
// 增加销量
|
Map<String, Integer> goodsBuyCountMap = new HashMap();
|
goodsBuyCountMap.put("goodsId", order.getGoodsId());
|
goodsBuyCountMap.put("stock", order.getNumber());
|
goodsService.addGoodsBuyCount(Arrays.asList(goodsBuyCountMap));
|
|
// 返回支付信息
|
orderMain.setCreateTime(new Date());
|
if(orderList != null && orderList.size() == 1) {
|
// 如果是单商品订单,则直接返回子订单编号
|
orderMain.setOrderNo(orderList.get(0).getOrderNo());
|
}
|
}
|
|
return ApiUtils.returnOK(orderMain);
|
}
|
|
@Override
|
public Object payCallbackOrderMain(String orderNo, BigDecimal payMoney, EnumPayType payType, String transactionNo) {
|
// 获取主订单信息
|
MallOrderMain orderMain = orderMainService.getById(orderNo);
|
Assert.notNull(orderMain, "订单信息错误");
|
|
// 修改订单状态
|
orderMain.setState(EnumMallOrderState.WAIT_CHECK.index);
|
orderMain.updateById();
|
|
// 订单列表
|
List<MallOrder> list = this.list(new LambdaQueryWrapper<MallOrder>().eq(MallOrder::getOrderMainNo, orderNo));
|
for (MallOrder order : list) {
|
// 订单回调信息
|
payCallback(order, payMoney, payType, transactionNo, orderMain.getOrderNo());
|
}
|
return null;
|
}
|
|
@Override
|
public Object payCallback(MallOrder order, BigDecimal payMoney, EnumPayType payType, String transactionNo, String outTradeNo) {
|
Assert.notNull(order, "订单信息错误");
|
|
if (EnumPayType.WECHAT.index == payType.index
|
&& payMoney.doubleValue() != order.getPayMoney().multiply(BigDecimal.valueOf(100)).doubleValue()) {
|
log.error("订单{}交易{}微信支付金额{}错误!", outTradeNo, transactionNo, payMoney);
|
Assert.notNull(order, "订单支付金额错误!");
|
}
|
|
// 修改订单状态
|
order.setState(EnumMallOrderState.WAIT_CHECK.index);
|
order.setTransactionNo(transactionNo);
|
order.setPayType(payType);
|
order.setPayTime(new Date());
|
// 保存支付的订单编号
|
order.setOutTradeNo(outTradeNo);
|
order.setPayTotalFee(payMoney);
|
order.updateById();
|
|
// 插入用户账户明细
|
MemUserBankDetail bankDetail = new MemUserBankDetail();
|
bankDetail.setPayType(payType.index);
|
bankDetail.setUserId(order.getUserId());
|
bankDetail.setAmount(order.getGoodsMoney());
|
bankDetail.setType(EnumUserBankDetailType.CASH.index);
|
bankDetail.setDoneType(EnumUserBankDetailDoneType.MALL_GOODS_PAY);
|
bankDetail.setMark(EnumUserBankDetailDoneType.getMarkByIndex(EnumUserBankDetailDoneType.MALL_GOODS_PAY.index));
|
bankDetail.insert();
|
|
//插入预约通知
|
if(Objects.nonNull(order.getMerchantId())){
|
noticeMapper.addMerchantNotice(order.getMerchantId(),1,"您有新的预约订单");
|
}
|
// 消费得积分(每消费X元得Y积分)
|
memUserService.addIntegralOrder(order.getUserId(), order.getPayMoney(), order.getOrderNo());
|
|
if (order.getSaleUserId() != null) {
|
// 推荐分享商品且购买成功
|
memUserService.addIntegralShareCommission(order.getSaleUserId(), order.getPayMoney());
|
}
|
|
// 购买套餐成功 即 VIP会员,申请入司 为 黄金营销员/城市合伙人
|
if (EnumMallGoodsGroupType.GOODS.index != order.getOrderType()) {
|
// 判断用是否为普通会员
|
MemUser user = memUserService.getById(order.getUserId());
|
if (user != null && user.getMemberGradeId() == EnumMemberGrade.G_1.index) {
|
// 修改用户为VIP会员
|
MemUser u = new MemUser();
|
u.setId(order.getUserId());
|
u.setMemberGradeId(EnumMemberGrade.G_2.index);
|
u.updateById();
|
}
|
}
|
return null;
|
}
|
|
@Override
|
public List<Map<String, Object>> getOrderWaitEvaluate(Date outTime) {
|
return this.baseMapper.getOrderWaitEvaluate(outTime);
|
}
|
|
@Override
|
public void defaultOrderEvaluate(Date outTime) {
|
this.baseMapper.defaultOrderEvaluate(outTime);
|
}
|
|
@Override
|
public synchronized Object receiptCompleted(String orderNo) {
|
MallOrder order = this.getById(orderNo);
|
if(order != null && order.getState() == EnumMallOrderState.WAIT_CHECK.index) {
|
// 确认收货
|
order.setState(EnumMallOrderState.SUCCESS.index);
|
order.setTakeTime(new Date());
|
this.updateById(order);
|
|
// 商品库存修改
|
List<Map<String, Integer>> goodsStockList = new ArrayList<>();
|
|
// 获取门店用户ID
|
Integer merchantUserId = merchantService.getOne(
|
new LambdaQueryWrapper<MemMerchant>()
|
.select(MemMerchant::getUserId)
|
.eq(MemMerchant::getId, order.getMerchantId())
|
).getUserId();
|
|
// 查询订单详细列表
|
LambdaQueryWrapper<MallOrderDetail> detailWrapper = new LambdaQueryWrapper<MallOrderDetail>().eq(MallOrderDetail::getOrderNo, orderNo);
|
List<MallOrderDetail> detailList = orderDetailService.list(detailWrapper);
|
for (MallOrderDetail detail : detailList) {
|
// 订单详细->待评价、已结算米粒
|
detail.setIsEvaluate(0);
|
detail.updateById();
|
|
// 设置商品需要添加的库存
|
goodsStockList = goodsService.setGoodsBuyCountList(goodsStockList, detail.getGoodsId(), detail.getGoodsNum());
|
}
|
|
if(goodsStockList != null && goodsStockList.size() > 0) {
|
// 增加商品销售量
|
goodsService.addGoodsBuyCount(goodsStockList);
|
}
|
return ApiUtils.returnOK();
|
}
|
return ApiUtils.returnNG();
|
}
|
|
@Override
|
public Object cancel(String orderNo) {
|
MallOrder order = this.getById(orderNo);
|
if(order != null && order.getState() == EnumMallOrderState.WAIT_PAY.index) {
|
// 取消订单
|
order.setState(EnumMallOrderState.CANCEL.index);
|
order.setCancelTime(new Date());
|
order.setCancelType(0);
|
order.setCause("用户取消");
|
this.updateById(order);
|
|
// 获取订单详情
|
LambdaQueryWrapper<MallOrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<MallOrderDetail>()
|
.select(MallOrderDetail::getSkuId, MallOrderDetail::getGoodsNum)
|
.eq(MallOrderDetail::getOrderNo, orderNo);
|
List<MallOrderDetail> orderDetails = orderDetailService.list(orderDetailLambdaQueryWrapper);
|
for (MallOrderDetail od : orderDetails) {
|
// 增加库存
|
goodsSkuService.updateStock(od.getSkuId(), od.getGoodsNum());
|
}
|
|
if (order.getCouponId() != null && order.getCouponId() != 0) {
|
// 退还优惠券
|
myCouponService.updateUseCoupon(order.getUserId(), order.getCouponId(), 0);
|
}
|
|
// 减少销量
|
Map<String, Integer> goodsBuyCountMap = new HashMap();
|
goodsBuyCountMap.put("goodsId", order.getGoodsId());
|
goodsBuyCountMap.put("stock", -1 * order.getNumber());
|
goodsService.addGoodsBuyCount(Arrays.asList(goodsBuyCountMap));
|
|
return ApiUtils.returnOK();
|
}
|
return ApiUtils.returnNG();
|
}
|
|
@Override
|
public VoMallOrderPayInfo getOrderPayInfoByOrderDetailNo(String orderDetailNo) {
|
return baseMapper.getOrderPayInfoByOrderDetailNo(orderDetailNo);
|
}
|
|
@Override
|
public BigDecimal getSumMoneyBySaleUser(List<Integer> saleUserIdList, List<Integer> stateList, String beginTime, String endTime) {
|
return baseMapper.getSumMoneyBySaleUser(saleUserIdList, stateList, beginTime, endTime);
|
}
|
|
@Override
|
public BigDecimal getV3DirectTeamSumMoney(Integer userId, List<Integer> stateList, String beginTime, String endTime) {
|
// 直属团队(v3黄金营销员)
|
List<VoTeamUser> v3DirectTeamList = memUserRelationService.directTeam(
|
userId,
|
Arrays.asList(EnumMemberGrade.G_3.index),
|
null,
|
null
|
);
|
// 直属团队含本人
|
List<Integer> teamUserIds = new ArrayList<>();
|
teamUserIds.add(userId);
|
if (v3DirectTeamList != null && v3DirectTeamList.size() > 0) {
|
teamUserIds.addAll(v3DirectTeamList.stream().map(VoTeamUser::getId).collect(Collectors.toList()));
|
}
|
|
// 直属团队业绩
|
BigDecimal directTeamMoney = this.getSumMoneyBySaleUser(
|
teamUserIds,
|
stateList,
|
beginTime,
|
endTime
|
);
|
return directTeamMoney;
|
}
|
|
@Override
|
public List<VoMallOrder> getNotCommissionSettlementOrderList() {
|
return this.baseMapper.getNotCommissionSettlementOrderList();
|
}
|
}
|