package com.matrix.system.shopXcx.api.service.impl; import cn.hutool.core.collection.CollUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.matrix.component.rabbitmq.RabiitMqTemplate; import com.matrix.component.redis.RedisUserLoginUtils; import com.matrix.component.tools.WxUtils; import com.matrix.component.wechat.externalInterface.protocol.paramProtocol.BrandWCPayRequestData; import com.matrix.component.wechat.externalInterface.weixinUtil.WeixinServiceUtil; import com.matrix.core.exception.GlobleException; import com.matrix.core.pojo.AjaxResult; import com.matrix.core.tools.LogUtil; import com.matrix.system.common.bean.BusParameterSettings; import com.matrix.system.common.constance.AppConstance; import com.matrix.system.common.dao.BusParameterSettingsDao; import com.matrix.system.common.dao.CustomerDataDictionaryDao; import com.matrix.system.common.interceptor.HostInterceptor; import com.matrix.system.hive.bean.SysVipInfo; import com.matrix.system.hive.dao.ShoppingGoodsDao; import com.matrix.system.hive.dao.SysVipInfoDao; import com.matrix.system.score.dao.ScoreVipDetailDao; import com.matrix.system.shopXcx.api.action.PayThreadPool; import com.matrix.system.shopXcx.api.pojo.OrderCouponGroup; import com.matrix.system.shopXcx.api.pojo.OrderInfoQueryPOJO; import com.matrix.system.shopXcx.api.pojo.OrderItemDto; import com.matrix.system.shopXcx.api.pojo.ShopOrderDto; import com.matrix.system.shopXcx.api.service.OrderCouponGroupService; import com.matrix.system.shopXcx.api.service.ShoppingCartService; import com.matrix.system.shopXcx.api.service.WXShopOrderService; import com.matrix.system.shopXcx.api.service.WxShopCouponService; import com.matrix.system.shopXcx.api.tools.WxShopOrderUtil; import com.matrix.system.shopXcx.api.vo.CouponReceiveInfoVO; import com.matrix.system.shopXcx.bean.*; import com.matrix.system.shopXcx.dao.*; import com.matrix.system.shopXcx.dto.DiscountExplain; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * @author jyy * @description 订单服务层 * @date 2019-06-10 10:58 */ @Service public class WXShopOrderServiceImpl implements WXShopOrderService { @Autowired private WxShopOrderUtil wxShopOrderUtil; @Autowired private RedisUserLoginUtils redisUserLoginUtils; @Autowired private WeixinServiceUtil weixinServiceUtil; @Autowired private ShopSkuDao shopSkuDao; @Autowired private ShopReceiveAddressDao shopReceiveAddressDao; @Autowired private ShopOrderDao shopOrderDao; @Autowired private ShopOrderDetailsDao shopOrderDetailsDao; @Autowired private ShopProductDao shopProductDao; @Autowired private ShopCouponRecordDao shopCouponRecordDao; @Autowired ShoppingGoodsDao shoppingGoodsDao; @Autowired ShoppingCartService shoppingCartService; @Autowired WxShopCouponService wxShopCouponService; @Autowired private ShopActivitiesGroupJoinDao shopActivitiesGroupJoinDao; @Autowired private ShopShoppingCartDao shoppingCartDao; @Autowired private ShopActivitiesGroupJoinUserDao shopActivitiesGroupJoinUserDao; @Autowired OrderCouponGroupService orderCouponGroupService; @Autowired CustomerDataDictionaryDao dataDictionaryDao; @Value("${wx_pay_debug_onoff}") private boolean isDebug; @Autowired private BusParameterSettingsDao busParameterSettingsDao; @Autowired private ScoreVipDetailDao scoreVipDetailDao; @Autowired private SysVipInfoDao sysVipInfoDao; @Override public BigDecimal calculationPostage(BigDecimal payPrice, Long companyId) { BigDecimal postage = BigDecimal.ZERO; BusParameterSettings yf = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.PACKAGE_PRICE, companyId); BusParameterSettings myje = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.FREE_PACKAGE_PRICE, companyId); if (yf != null && myje != null) { if (Double.parseDouble(myje.getParamValue()) > payPrice.doubleValue()) { postage = new BigDecimal(yf.getParamValue()); } } return postage; } /** * 创建订单 * * @param shopOrderDto * @return * @throws Exception */ @Transactional(rollbackFor = Exception.class) @Override public ShopOrder createShopOrder(ShopOrderDto shopOrderDto) throws Exception { SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class); ShopReceiveAddress shopReceiveAddress = shopReceiveAddressDao.selectById(shopOrderDto.getReceiveAddrId()); //计算订单优惠信息 AjaxResult caculateResult= buildDiscountExplain(shopOrderDto); DiscountExplain discountExplain= (DiscountExplain) caculateResult.getMapInfo().get("discountExplain"); if(discountExplain.getScorePay()!=null){ //校验用户积分是否够用 int score=scoreVipDetailDao.selectUserTotalScore(sysVipInfo.getId()); if(score details = new ArrayList<>(); Integer orderCount = 0; for (OrderItemDto orderItemDto : shopOrderDto.getOrderItemList()) { ShopOrderDetails shopOrderDetails = new ShopOrderDetails(); shopOrderDetails.setCreateBy(AppConstance.SYSTEM_USER); shopOrderDetails.setUpdateBy(AppConstance.SYSTEM_USER); shopOrderDetails.setpId(orderItemDto.getProductId()); shopOrderDetails.setsId(orderItemDto.getSkuId()); shopOrderDetails.setCount(orderItemDto.getCount()); if(ShopOrderDetails.PAYTYPE_MICRO==orderItemDto.getPayType()){ shopOrderDetails.setPrice(orderItemDto.getShopSku().getPrice()); }else{ shopOrderDetails.setPrice(orderItemDto.getShopSku().getScorePrice()); shopOrderDetails.setScoreCount(BigDecimal.valueOf(orderItemDto.getShopSku().getScoreCount())); shopOrderDetails.setTotalScoreCount(shopOrderDetails.getScoreCount().multiply(BigDecimal.valueOf(shopOrderDetails.getCount()))); } shopOrderDetails.setTotalPrice(shopOrderDetails.getPrice().multiply(BigDecimal.valueOf(shopOrderDetails.getCount()))); shopOrderDetails.setPayType(orderItemDto.getPayType()); shopOrderDetails.setsTitle(orderItemDto.getShopProduct().getTitle() + orderItemDto.getShopSku().getName()); shopOrderDetails.setDiscountAmount(BigDecimal.ZERO); details.add(shopOrderDetails); orderCount += shopOrderDetails.getCount(); if(orderItemDto.getCartId()!=null){ //删除用户购物车选中的产品 shoppingCartDao.deleteById(orderItemDto.getCartId()); } } //校验商品是否限购 wxShopOrderUtil.verifyProductLimitInfo(details, sysVipInfo.getOpenId()); //TODO 更新库存和销量 更新库存和销量[考虑和erp库存联动] wxShopOrderUtil.updateProductAndSkuInfo(details); //用户openId shopOrder.setUserId(sysVipInfo.getId()); shopOrder.setCreateBy("微信小程序生成"); shopOrder.setUpdateBy("微信小程序生成"); shopOrder.setPayMethod(shopOrderDto.getPayMethod()); shopOrder.setCommodityPrice(discountExplain.getBillPrice()); shopOrder.setPurchaseQuantity(orderCount); shopOrder.setOrderType(ShopOrder.ORDER_TYPE_GOODS); //购买方式 shopOrder.setShippingMethod(shopOrderDto.getDeliverySelect()); //生成订单号 shopOrder.setOrderNo(WxUtils.getOrderNum()); //设置支付状态 shopOrder.setPayStatus(ShopOrder.ORDER_STATUS_WAIT_PAY); //设置订单状态 shopOrder.setOrderStatus(ShopOrder.ORDER_PAY_STATUS_WAIT); //设置退款费用(注:下次优化从数据字典表获取) shopOrder.setRefundCharge(BigDecimal.ZERO); //客户电话 shopOrder.setUserTel(shopReceiveAddress.getAddrTelephone()); //客户姓名 shopOrder.setUserName(shopReceiveAddress.getAddrLiaisonman()); //备注 shopOrder.setRemarks(shopOrderDto.getRemarks()); //删除标识 shopOrder.setDelFlag(AppConstance.DATA_USEABLE); //微信订单号 shopOrder.setWxOrderNo(""); //微信支付结果 shopOrder.setPayResult(ShopOrder.ORDER_WX_STATUS_WAIT_PAY); //如果没有提交购买方式或配送方式不是物流 //获取邮费 shopOrder.setPostage(discountExplain.getPostage()); shopOrder.setOrderMoney(discountExplain.getPayPrice()); shopOrder.setScorePay(discountExplain.getScorePay()); Gson g = new GsonBuilder().create(); shopOrder.setDiscountExplain(g.toJson(discountExplain)); shopOrder.setDiscountAmount(discountExplain.getActivityPrice().add(discountExplain.getCouponPrice())); shopOrder.setCompanyId(HostInterceptor.getCompanyId()); shopOrderDao.insert(shopOrder); wxShopOrderUtil.insertSendPackageInfo(shopOrder, shopOrderDto.getDeliverySelect(), shopReceiveAddress); //给订单详情表添加订单ID for (ShopOrderDetails shopOrderDetails : details) { shopOrderDetails.setOrderId(shopOrder.getId()); } if (CollectionUtils.isNotEmpty(details)) { shopOrderDetailsDao.batchInsert(details); } //更新使用的优惠券状态 if (shopOrderDto.getCouponReceiveId() != null) { ShopCouponRecord record = new ShopCouponRecord(); record.setIsUsing(AppConstance.MY_COUPON_USE); record.setOrderId(shopOrder.getId()); record.setId(shopOrderDto.getCouponReceiveId()); shopCouponRecordDao.updateByModel(record); } return shopOrder; } @Override public AjaxResult buildDiscountExplain(ShopOrderDto shopOrderDto) { if(CollUtil.isEmpty(shopOrderDto.getOrderItemList())){ return AjaxResult.buildFailInstance("请选择购买的明细"); } //订单计价说明 DiscountExplain discountExplain = new DiscountExplain(); //账单总金额 BigDecimal billPrice = BigDecimal.ZERO; //活动优惠金额 BigDecimal activityTotal = BigDecimal.ZERO; //优惠券惠金额 BigDecimal couponPrice = BigDecimal.ZERO; //支付总积分 Integer scoreCount=0; SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class); //计算购物车中物品的优惠信息 List orderItemDtos = shopOrderDto.getOrderItemList() .stream().map(orderItemDto -> { return orderCouponGroupService.buildOrderCouponElement(orderItemDto); }) .collect(Collectors.toList()); //计算未优惠的总金额 for (OrderItemDto orderItemDto :orderItemDtos ){ if(orderItemDto.getPayType()==ShopShoppingCart.CAR_TYPE_MICRO){ billPrice=billPrice.add(orderItemDto.getShopSku().getPrice().multiply(new BigDecimal(orderItemDto.getCount()))); }else{ billPrice=billPrice.add(orderItemDto.getShopSku().getScorePrice().multiply(new BigDecimal(orderItemDto.getCount()))); scoreCount+=orderItemDto.getShopSku().getScoreCount()*orderItemDto.getCount(); } } discountExplain.setScorePay(scoreCount); //计算用户的产品可以参与的店铺优惠活动分组 List shopActiveList = new ArrayList<>();//记录用户可以参与的门店活动 List orderCouponGroupList = new ArrayList<>(); int conditionsGroupCount = 0; if (shopOrderDto.getJoinActive() == ShopOrderDto.JOIN_ACTIVE) {//用户参与优惠活动 orderCouponGroupList = orderCouponGroupService.buildOrderCouponGroupList(orderItemDtos); conditionsGroupCount = orderCouponGroupList.stream().map(orderCouponGroup -> { if (orderCouponGroup.isSatisfactionCoupon()&&orderCouponGroup.getCoupon()!=null) { shopActiveList.add(orderCouponGroup.getCoupon()); return 1; } else { return 0; } }).mapToInt(Integer::intValue).sum(); } if(CollUtil.isNotEmpty(shopActiveList)){ activityTotal=shopActiveList.stream().map(ShopCoupon:: getOffsetAmount).reduce(BigDecimal.ZERO,BigDecimal::add); } //门店活动优惠金额 discountExplain.setActivityPrice(activityTotal); List usefulCoupon = new ArrayList<>(); CouponReceiveInfoVO shopCoupon = new CouponReceiveInfoVO(); //满足店铺活动的订单不能使用优惠券 if (conditionsGroupCount > 0) { //计算可用优惠券 usefulCoupon = wxShopCouponService.getCartVoCouponList(sysVipInfo.getCompanyId(), orderItemDtos); //获取用户使用的优惠券 if (shopOrderDto.getCouponReceiveId() == null) { //如果用户没有选择优惠券则默认选优惠金额最高的 //计算使用优惠券后的价格 if (CollectionUtils.isNotEmpty(usefulCoupon)) { //根据优惠券ID用户ID查询优惠券信息 shopCoupon = usefulCoupon.get(0); } } else if (shopOrderDto.getCouponReceiveId() != 1) { //用户选择了优惠券 shopCoupon = shopCouponRecordDao.selectMyCouponByReceiveId(shopOrderDto.getCouponReceiveId()); } else { //用户不使用优惠券 } //计算优惠券 if (shopCoupon.getCouponId() != null) { couponPrice=shopCoupon.getOffsetAmount(); } //优惠券金额 discountExplain.setCouponPrice(couponPrice); } //计算运费 discountExplain.setPostage(calculationPostage(discountExplain.getPayPrice(), HostInterceptor.getCompanyId())); //账单总金额 discountExplain.setBillPrice(billPrice.add(discountExplain.getPostage())); BigDecimal payPrice=discountExplain.getBillPrice().subtract(activityTotal).subtract(couponPrice); //应付金额 discountExplain.setPayPrice(payPrice.doubleValue()>0?payPrice:BigDecimal.ONE); AjaxResult result = AjaxResult.buildSuccessInstance(""); //结算金额信息 result.putInMap("discountExplain", discountExplain); //用户优惠券 result.putInMap("usefulCoupon", usefulCoupon); //用户选中的优惠券 result.putInMap("shopCoupon", shopCoupon); //店铺优惠活动 result.putInMap("shopActiveList", shopActiveList); return result; } /** * 根据订单ID结算订单 * * @param orderId * @return * @throws Exception */ @Override public AjaxResult orderSettlement(int orderId) throws Exception { ShopOrder shopOrder = shopOrderDao.selectById(orderId); if (shopOrder == null) { return AjaxResult.buildFailInstance("订单不存在!"); } if (ShopOrder.SHOP_ORDER_PAY_METHOD_WX != shopOrder.getPayMethod()) { return AjaxResult.buildFailInstance("支付方式错误"); } if (!shopOrder.getPayResult().equals(ShopOrder.ORDER_PAY_STATUS_WAIT)) { return AjaxResult.buildFailInstance("该订单不是待支付状态!"); } if(shopOrder.getScorePay()!=null){ //校验用户积分是否够用 int score=scoreVipDetailDao.selectUserTotalScore(shopOrder.getUserId()); if(score= 1) { orderInfoQueryPOJO.setOffset((orderInfoQueryPOJO.getOffset() - 1) * orderInfoQueryPOJO.getLimit()); } List result = shopOrderDao.selectMyOrderByStatus(sysVipInfo.getId(), orderInfoQueryPOJO); return new AjaxResult(AjaxResult.STATUS_SUCCESS, result); } /** * 根据订单ID查询订单详情 * * @param orderId * @return */ @Override public AjaxResult getOrderInfoById(Integer orderId) { SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class); ShopOrder shopOrder = shopOrderDao.selectOrderInfoById(sysVipInfo.getId(), orderId); return new AjaxResult(AjaxResult.STATUS_SUCCESS, Arrays.asList(shopOrder)); } /** * 取消待付款订单 * * @param orderId * @return */ @Transactional(rollbackFor = Exception.class) @Override public AjaxResult cancelOrderWhenWaitPay(Integer orderId) { updateStockAndVolumeById(orderId); ShopOrder shopOrder = shopOrderDao.selectById(orderId); //如果订单不是待付款状态 if (ShopOrder.ORDER_PAY_STATUS_WAIT != shopOrder.getOrderStatus()) { throw new GlobleException("该订单不是待付款状态!"); } if (shopOrder.getDiscountAmount() != null && shopOrder.getDiscountAmount().compareTo(BigDecimal.ZERO) > 0) { ShopCouponRecord shopCouponRecord = new ShopCouponRecord(); SysVipInfo sysVipInfo = redisUserLoginUtils.getLoginUser(SysVipInfo.class); shopCouponRecord.setUserId(sysVipInfo.getId()); shopCouponRecord.setOrderId(orderId); List recordList = shopCouponRecordDao.selectByModel(shopCouponRecord); if (CollectionUtils.isNotEmpty(recordList)) { for (ShopCouponRecord record : recordList) { Map modifyMap = new HashMap<>(); modifyMap.put("id", record.getId()); modifyMap.put("orderId", 0); modifyMap.put("isUsing", AppConstance.MY_COUPON_NOT_USE); shopCouponRecordDao.updateByMap(modifyMap); } } } ShopActivitiesGroupJoinUser joinUser = shopActivitiesGroupJoinUserDao.selectGroupJoinUserByOrderId(orderId.longValue()); if (joinUser != null) { joinUser.setIsHasCancel(ShopActivitiesGroupJoinUser.IS_HAS_CANCEL_Y); shopActivitiesGroupJoinUserDao.updateByModel(joinUser); if (joinUser.getIsHead() == ShopActivitiesGroupJoinUser.USER_IS_HEAD_Y) { ShopActivitiesGroupJoin groupJoin = new ShopActivitiesGroupJoin(); groupJoin.setId(joinUser.getGjId()); groupJoin.setGjStatus(ShopActivitiesGroupJoin.ACTIVITIES_JOIN_FAIL); shopActivitiesGroupJoinDao.updateByModel(groupJoin); } } //构建需要修改订单信息Map Map modifyMap = new HashMap<>(); modifyMap.put("id", orderId); modifyMap.put("orderStatus", ShopOrder.ORDER_STATUS_CANCEL); shopOrderDao.updateByMap(modifyMap); return new AjaxResult(AjaxResult.STATUS_SUCCESS, "订单取消成功!"); } /** * 删除已取消订单 * * @param orderId * @return */ @Override public AjaxResult delOrderById(Integer orderId) { ShopOrder order = shopOrderDao.selectById(orderId); if (order == null) { throw new GlobleException("没有找到该订单!"); } if (!order.getOrderStatus().equals(ShopOrder.ORDER_STATUS_CANCEL)) { throw new GlobleException("该订单不是取消状态,不能删除!"); } //构建需要修改订单信息Map Map modifyMap = new HashMap<>(); modifyMap.put("id", order.getId()); modifyMap.put("delFlag", AppConstance.DATA_DISABLE); shopOrderDao.updateByMap(modifyMap); return new AjaxResult(AjaxResult.STATUS_SUCCESS, "删除成功!"); } /** * 订单确认收货 * * @param orderId * @return */ @Override public AjaxResult confirmPackageById(Integer orderId) { ShopOrder shopOrder = shopOrderDao.selectById(orderId); //如果不是待收货状态 if (ShopOrder.ORDER_STATUS_WAIT_RECEIVE != shopOrder.getOrderStatus()) { throw new GlobleException("该订单不是待收货状态!"); } shopOrder.setOrderStatus(ShopOrder.ORDER_STATUS_WAIT_REMARK); shopOrderDao.updateByModel(shopOrder); return new AjaxResult(AjaxResult.STATUS_SUCCESS, "订单收货成功!"); } /** * 加库存减销量 * * @param orderId * @return wlz */ @Override public AjaxResult updateStockAndVolumeById(Integer orderId) { //通过订单ID查询订单详情 List shopOrderDetails = shopOrderDetailsDao.selectByOrderId(orderId); if (CollectionUtils.isNotEmpty(shopOrderDetails)) { for (ShopOrderDetails orderDetails : shopOrderDetails) { Integer count = orderDetails.getCount(); Integer pId = orderDetails.getpId(); Integer sId = orderDetails.getsId(); ShopProduct shopProduct = shopProductDao.selectById(pId); //获取此产品的总展示销量和真实销量 Integer dsVolume = shopProduct.getDsVolume(); Integer rsVolume = shopProduct.getRsVolume(); //退货减销量 Integer updateDs = dsVolume - count; Integer updateRs = rsVolume - count; Map modifyMap = new HashMap<>(); modifyMap.put("id", pId); modifyMap.put("dsVolume", updateDs); modifyMap.put("rsVolume", updateRs); shopProductDao.updateByMap(modifyMap); //加库存 ShopSku shopSku = shopSkuDao.selectById(sId); Integer stock = shopSku.getStock(); Integer updateStock = stock + count; Map modifyStock = new HashMap<>(); modifyStock.put("id", sId); modifyStock.put("stock", updateStock); shopSkuDao.updateByMap(modifyStock); } } return new AjaxResult(AjaxResult.STATUS_SUCCESS, "加库存减销量修改成功!"); } /** * 查询订单支付状态 * * @param orderId * @return */ @Autowired RabiitMqTemplate rabiitMqTemplate; @Override public AjaxResult findOrderPayStatus(Integer orderId) { AjaxResult result = new AjaxResult(AjaxResult.STATUS_SUCCESS, ""); result.putInMap("status", "err"); result.putInMap("msg", "查询支付信息失败,请联系客服或者刷新支付信息(错误码:005)"); ShopOrder order = shopOrderDao.selectById(orderId); if (order.getPayStatus().equals(ShopOrder.ORDER_PAY_STATUS_SUCCESS)) { result.putInMap("status", "success"); result.putInMap("msg", "支付成功"); } else if (order.getPayStatus().equals(ShopOrder.ORDER_PAY_STATUS_FAIL)) { result.putInMap("status", "err"); result.putInMap("msg", "查询支付信息失败,请联系客服或者刷新支付信息"); } else { LogUtil.debug("订单等待支付中={}。。。", orderId); PayThreadPool.waitThread(orderId, new Object()); result = PayThreadPool.getThreadResult(orderId); LogUtil.debug("订单支付完成={}。。。", orderId); } ShopActivitiesGroupJoin groupBuyStatus = shopActivitiesGroupJoinDao.selectGroupBuyByOrderId(orderId); if (groupBuyStatus != null) { result.putInMap("groupBuyStatus", groupBuyStatus.getGjStatus()); result.putInMap("gjId", groupBuyStatus.getId()); } return result; } }