ApiOrderNewServiceImpl.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. package com.ydd.app.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.github.binarywang.wxpay.exception.WxPayException;
  6. import com.ijpay.core.enums.TradeType;
  7. import com.ydd.app.dto.AddressReq;
  8. import com.ydd.app.dto.OrderReq;
  9. import com.ydd.app.dto.ValuationRes;
  10. import com.ydd.app.listener.DeliveryOrderEvent;
  11. import com.ydd.app.service.ApiCouponService;
  12. import com.ydd.app.service.ApiOrderNewService;
  13. import com.ydd.app.service.ApiOrderService;
  14. import com.ydd.app.service.ApiProductService;
  15. import com.ydd.common.constant.RedisKeyConstant;
  16. import com.ydd.common.core.redis.RedisCache;
  17. import com.ydd.common.enums.WaimaiTypeEnums;
  18. import com.ydd.common.utils.DateUtils;
  19. import com.ydd.common.utils.StringUtils;
  20. import com.ydd.ecloud.core.utils.BigDecimalUtils;
  21. import com.ydd.ecloud.core.utils.JsonMapper;
  22. import com.ydd.module.domain.*;
  23. import com.ydd.module.dto.CouponDto;
  24. import com.ydd.module.dto.OrderFreightDto;
  25. import com.ydd.module.enums.*;
  26. import com.ydd.module.expection.CustomAppException;
  27. import com.ydd.module.pay.alipay.AliPayService;
  28. import com.ydd.module.pay.dto.OrderPaySignResponse;
  29. import com.ydd.module.pay.wechat.service.WechatPayService;
  30. import com.ydd.module.push.MessagePushService;
  31. import com.ydd.module.service.*;
  32. import com.ydd.system.service.ISysConfigService;
  33. import lombok.RequiredArgsConstructor;
  34. import lombok.extern.slf4j.Slf4j;
  35. import org.apache.commons.collections4.CollectionUtils;
  36. import org.springframework.beans.factory.annotation.Autowired;
  37. import org.springframework.context.ApplicationContext;
  38. import org.springframework.stereotype.Service;
  39. import org.springframework.transaction.annotation.Transactional;
  40. import org.springframework.transaction.support.TransactionSynchronizationAdapter;
  41. import org.springframework.transaction.support.TransactionSynchronizationManager;
  42. import java.math.BigDecimal;
  43. import java.util.*;
  44. import java.util.concurrent.TimeUnit;
  45. /**
  46. * Project:lb-server
  47. * Class:ApiOrderServiceImpl
  48. * Description:TODO
  49. * Time:2021/2/23 14:41
  50. *
  51. * @author zoe
  52. */
  53. @Slf4j
  54. @Service
  55. @RequiredArgsConstructor(onConstructor_ = @Autowired)
  56. public class ApiOrderNewServiceImpl implements ApiOrderNewService {
  57. private final ApiProductService apiProductService;
  58. private final ApiCouponService apiCouponService;
  59. private final IOrderService iOrderService;
  60. private final IOrderLogService iOrderLogService;
  61. private final IMemberService iMemberService;
  62. private final IMemberBalanceLogService iMemberBalanceLogService;
  63. private final IWaimaiOrderService iWaimaiOrderService;
  64. private final ApplicationContext applicationContext;
  65. private final ISysConfigService iSysConfigService;
  66. private final IDspConfigService iDspConfigService;
  67. private final ApiCacheUserAddress apiCacheUserAddress;
  68. private final IAgentService iAgentService;
  69. private final AliPayService aliPayService;
  70. private final WechatPayService wechatPayService;
  71. private final IPaymentService paymentService;
  72. private final IWaimaiOrderDetailService iWaimaiOrderDetailService;
  73. private final IMerchantService iMerchantService;
  74. private final MessagePushService messagePushService;
  75. private final ApiOrderService apiOrderService;
  76. private final IMerchantDeliveryFeeService iMerchantDeliveryFeeService;
  77. private final RedisCache redisCache;
  78. private final IOrderFreightService iOrderFreightService;
  79. @Override
  80. @Transactional(rollbackFor = Exception.class)
  81. public Object createOrder(Long loginId, OrderReq req, Integer type) {
  82. log.info("<===========>提交下单参数" + JsonMapper.nonEmptyMapper().toJson(req));
  83. // try {
  84. if (CollectionUtils.isEmpty(req.getValuationRes())) {
  85. throw new CustomAppException("暂无运力, 下单失败!");
  86. }
  87. String orderNo = req.getValuationRes().get(0).getOrderNo();
  88. List<Order> orderLists = iOrderService.list(new QueryWrapper<Order>().eq("order_sn", orderNo));
  89. if (CollectionUtils.isNotEmpty(orderLists)) {
  90. req.setOrderId(orderLists.get(0).getId());
  91. // 校验订单状态
  92. Integer status = orderLists.get(0).getStatus();
  93. if (!PayStatusEnum.NO_PAYED.status.equals(status)) {
  94. log.warn("orderSn:{}, status: {}, 该状态不支持下单操作!", orderNo, status);
  95. throw new CustomAppException("该状态不支持下单操作!");
  96. }
  97. }
  98. Member member = iMemberService.getById(loginId);
  99. if (member.getMemberType().equals(MemberTypeEnum.SHOP.type)) {
  100. member = iMemberService.getOne(new QueryWrapper<Member>().eq("member_type", MemberTypeEnum.MERCHANT.type).eq("merchant_id", member.getMerchantId()));
  101. }
  102. Product product = apiProductService.findById(req.getProductId());
  103. if (product == null) {
  104. throw new CustomAppException(ExceptionEnum.PRODUCT_NOT_EXISTS);
  105. }
  106. CouponDto couponDto = null;
  107. if (req.getCouponId() != null) {
  108. couponDto = apiCouponService.findDetail(req.getCouponId());
  109. if (couponDto == null && type.intValue() != 3) {
  110. throw new CustomAppException("优惠券不存在!");
  111. }
  112. }
  113. //地址处理重复楼层
  114. address(req);
  115. // 保存发件信息, 如果发件Id不存在, 则为手工录入信息, 保存到缓存
  116. // apiCacheUserAddress.cacheAddress(loginId, req);
  117. try {
  118. apiCacheUserAddress.cacheSendReceiveAddress(loginId, req.getSendAddress(), req.getReceiptAddress());
  119. } catch (Exception e) {
  120. log.error("缓存收发件地址异常, {}", e.getMessage());
  121. }
  122. Order order = createOrder(product, couponDto, req, loginId);
  123. if (order.getId() != null && order.getDeliveryStatus() != null && order.getDeliveryStatus() >= DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status && order.getDeliveryStatus() != DeliveryStatusEnum.FINISH.status) {
  124. return null;
  125. }
  126. if (order.getId() != null && order.getDeliveryStatus() != null && (DeliveryStatusEnum.CANCEL.status.equals(order.getDeliveryStatus())
  127. || DeliveryStatusEnum.FINISH.status.equals(order.getDeliveryStatus())
  128. || DeliveryStatusEnum.ABNORMAL.status.equals(order.getDeliveryStatus()))) {
  129. resetOrder(order, product);
  130. }
  131. // 获取达达收付配送商计价信息
  132. OrderFreightDto orderFreightDto = redisCache.getCacheObject(orderNo);
  133. // 达达配送订单订单标识
  134. boolean isDadaOrder = false;
  135. // 达达收付订单订单标识
  136. boolean isDadaRapDelivery = false;
  137. if (orderFreightDto != null && orderFreightDto.getValuationType() != null) {
  138. isDadaOrder = true;
  139. if (orderFreightDto.getValuationType() == 2) {
  140. order.setDadaDspType(OrderDadaDspTypeEnum.DELIVERY.type);
  141. } else {
  142. isDadaRapDelivery = true;
  143. order.setDadaDspType(OrderDadaDspTypeEnum.DELIVERY_RAP.type);
  144. }
  145. order.setDadaDspId(orderFreightDto.getDadaDspId());
  146. }
  147. order.setMemberId(loginId);
  148. order.setCreateTime(new Date());
  149. order.setTakeType(req.getTakeType());
  150. if (TakeTypeEnum.APPOINTMENT.type.equals(req.getTakeType())) {
  151. if (DateUtils.addMinutes(new Date(), 130).compareTo(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, req.getTakeTime())) > 0) {
  152. //order.setTakeTime(null);
  153. order.setTakeType(TakeTypeEnum.APPOINTMENT_2.type);
  154. } else {
  155. order.setTakeTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, req.getTakeTime()));
  156. }
  157. }
  158. BigDecimal tip = BigDecimal.ZERO;
  159. if (req.getTipAmount() != null && req.getTipAmount().compareTo(BigDecimal.ZERO) > 0) {
  160. order.setUseTip(StatusEnum.SHOW.status);
  161. tip = req.getTipAmount();
  162. order.setTipAmount(tip);
  163. }
  164. //发单算钱
  165. List<ValuationRes> resList = req.getValuationRes();
  166. List<ValuationRes> maxReslIst = new ArrayList<>();
  167. if (couponDto != null) {
  168. for (ValuationRes res : resList) {
  169. if (couponDto.getType().equals(CouponTypeEnum.MAN_JIAN.type)) {
  170. if (res.getDeliveryAmount().compareTo(couponDto.getLimitFee()) >= 0 && res.getIsMine() == 0) {
  171. res.setDeliveryAmount(res.getDeliveryAmount().subtract(couponDto.getMoney()));
  172. res.setCouponAmount(couponDto.getMoney());
  173. }
  174. } else if (couponDto.getType().equals(CouponTypeEnum.LI_JIAN.type) && res.getIsMine() == 0) {
  175. res.setDeliveryAmount(res.getDeliveryAmount().subtract(couponDto.getMoney()));
  176. res.setCouponAmount(couponDto.getMoney());
  177. } else if (couponDto.getType().equals(CouponTypeEnum.ZHE_KOU.type) && res.getIsMine() == 0) {
  178. BigDecimal discount = res.getDeliveryAmount().multiply(couponDto.getDiscount()).divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP);
  179. if ((res.getDeliveryAmount().subtract(discount)).compareTo(couponDto.getMaxDiscount()) > 0) {
  180. discount = res.getDeliveryAmount().subtract(couponDto.getMaxDiscount());
  181. } else {
  182. discount = res.getDeliveryAmount().subtract(res.getDeliveryAmount().subtract(discount));
  183. }
  184. res.setCouponAmount(res.getDeliveryAmount().subtract(discount));
  185. res.setDeliveryAmount(discount);
  186. }
  187. }
  188. }
  189. // 默认没有选择绑定三方运力下单
  190. List<Long> deliveryIds = new ArrayList<>();
  191. for (ValuationRes r : resList) {
  192. if (r.getIsMine() == 0) {
  193. maxReslIst.add(r);
  194. }
  195. if (r.getIsMine() == 1) {
  196. // 自运力
  197. deliveryIds.add(r.getDeliveryId());
  198. }
  199. }
  200. Optional<ValuationRes> max = null;
  201. // false用我们平台支付,true用用户自己绑定三方平台支付
  202. boolean isMine = false;
  203. if (maxReslIst != null && maxReslIst.size() > 0) {
  204. max = maxReslIst.stream().max(Comparator.comparing(ValuationRes::getDeliveryAmount));
  205. } else {
  206. max = resList.stream().max(Comparator.comparing(ValuationRes::getDeliveryAmount));
  207. isMine = true;
  208. }
  209. if (order.getWaimaiOrderId() != null) {
  210. getWaiMaiInfo(order, req);
  211. } else {
  212. this.setOrderSource(order, req);
  213. }
  214. //金额折扣
  215. BigDecimal deliveryAmount = max.get().getDeliveryAmount();//取最高价
  216. // req.setOrderSn(max.get().getOrderSn());
  217. order.setOrderSn(max.get().getOrderNo());
  218. //计算优惠券
  219. order.setTotalAmount(deliveryAmount.add(tip));
  220. order.setMaxAmount(deliveryAmount.add(tip));
  221. order.setCouponAmount(BigDecimal.ZERO);
  222. if (couponDto != null && !isDadaOrder) {
  223. if (couponDto.getType().equals(CouponTypeEnum.MAN_JIAN.type)) {
  224. if (order.getTotalAmount().compareTo(couponDto.getLimitFee()) >= 0 && !isMine) {
  225. log.info("进入满减券!");
  226. order.setCouponAmount(couponDto.getMoney());
  227. order.setCouponId(Long.valueOf(couponDto.getId()));
  228. couponDto.setStatus(MemberCouponStatusEnum.USED.getStatus());
  229. }
  230. } else if (couponDto.getType().equals(CouponTypeEnum.LI_JIAN.type) && !isMine) {
  231. log.info("进入立减券!");
  232. order.setCouponAmount(couponDto.getMoney());
  233. order.setCouponId(Long.valueOf(couponDto.getId()));
  234. couponDto.setStatus(MemberCouponStatusEnum.USED.getStatus());
  235. } else if (couponDto.getType().equals(CouponTypeEnum.ZHE_KOU.type) && !isMine) {
  236. log.info("进入折扣券!");
  237. BigDecimal discount = order.getTotalAmount().multiply(couponDto.getDiscount()).divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP);
  238. if ((order.getTotalAmount().subtract(discount)).compareTo(couponDto.getMaxDiscount()) > 0) {
  239. discount = order.getTotalAmount().subtract(couponDto.getMaxDiscount());
  240. }
  241. order.setCouponAmount(order.getTotalAmount().subtract(discount));
  242. order.setCouponId(Long.valueOf(couponDto.getId()));
  243. couponDto.setStatus(MemberCouponStatusEnum.USED.getStatus());
  244. }
  245. }
  246. // // 此处是判断货拉拉下单不享受新人优惠, 前端请求接口外卖单未传transport字段
  247. // Integer deliveryType = null;
  248. // if (CollectionUtils.isNotEmpty(resList)) {
  249. // deliveryType = resList.get(0).getDeliveryType();
  250. // }
  251. BigDecimal firstCoupon = BigDecimal.ZERO;//取消新人首单立减
  252. // if (!isMine && !DeliveryTypeEnums.HUO_LA_LA.getType().equals(deliveryType) && !isDadaOrder) {
  253. // //新用户只要没有产生过订单数据的算首单,并且是用平台支付
  254. // List<Order> orderList;
  255. // if (member.getShopId() != null) {
  256. // orderList = iOrderService.list(new QueryWrapper<Order>().eq("shop_id", member.getShopId()).eq("status", PayStatusEnum.PAYED.status));
  257. // } else {
  258. // orderList = iOrderService.list(new QueryWrapper<Order>().eq("member_id", loginId).eq("status", PayStatusEnum.PAYED.status));
  259. // }
  260. // if (CollectionUtils.isEmpty(orderList)) {
  261. // String configValue = iSysConfigService.selectConfigByKey("NEW_COMERS");
  262. // firstCoupon = new BigDecimal(configValue);
  263. // }
  264. // }
  265. order.setFirstCoupon(firstCoupon);
  266. order.setPayAmount(order.getTotalAmount().subtract(firstCoupon));
  267. if (order.getCouponAmount().compareTo(order.getTotalAmount().add(order.getCouponAmount())) > 0) {
  268. order.setPayAmount(BigDecimal.ZERO);
  269. order.setCommission(BigDecimal.ZERO);
  270. } else if (order.getPayAmount().compareTo(BigDecimal.ZERO) < 0) {
  271. order.setPayAmount(BigDecimal.ZERO);
  272. } else {
  273. //代理商佣金
  274. order.setCommission(max.get().getCommission());
  275. }
  276. if (order.getDadaDspType() != null) {
  277. order.setCommission(BigDecimal.ZERO);
  278. }
  279. // 非自运力下单、或自运力达达收付配送商下单, 校验猎豹账户余额
  280. if ((!isMine || isDadaRapDelivery) && order.getPayAmount().compareTo(member.getAmount()) > 0 && PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType())) {
  281. log.error("余额不足, memberId: {}, orderSn: {}", member.getId(), order.getOrderSn());
  282. return "amount_not_enough";
  283. }
  284. // 下单运力中含有自运力校验账户余额, 达达配送商模式无需校验
  285. if (deliveryIds.size() > 0 && isMine && !isDadaOrder) {
  286. checkMemberAmount(member, deliveryIds);
  287. }
  288. //下单
  289. req.setProduct(product);
  290. order.setMerchantId(member.getMerchantId());
  291. if (!isDadaOrder) {
  292. if (member.getAgentId() != null) {
  293. order.setAgentId(member.getAgentId());
  294. order.setAgentIdSource(member.getAgentSource());
  295. if (member.getPersonnelId() != null) {
  296. order.setPersonnelId(member.getPersonnelId());
  297. }
  298. } else {
  299. // 判断区域,只给一级代理商
  300. Agent agent = iAgentService.findByArea(order.getSendCityName(), order.getSendDistrictName());
  301. if (agent != null) {
  302. order.setAgentId(agent.getId());
  303. order.setAgentIdSource(AgentSourceEnum.QU_YU.status);
  304. }
  305. }
  306. }
  307. if (isMine && PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType()) && !isDadaRapDelivery) {
  308. order.setPaymentType(PaymentTypeEnum.LOCAL.type);
  309. } else if ((!isMine || isDadaRapDelivery) && PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType())) {
  310. order.setPaymentType(PaymentTypeEnum.BALANCE.type);
  311. } else {
  312. order.setPaymentType(req.getPaymentType());
  313. }
  314. Object resp = "ok";
  315. BigDecimal payAmount = order.getPayAmount().setScale(2, BigDecimal.ROUND_HALF_UP);
  316. if (PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType()) && isMine) {
  317. order.setStatus(PayStatusEnum.PAYED.status);
  318. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  319. }
  320. if (PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType()) && (!isMine || isDadaRapDelivery)) {
  321. order.setStatus(PayStatusEnum.PAYED.status);
  322. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  323. // 判断余额是否低于50/100
  324. checkAmount(member.getId());
  325. } else if (PaymentTypeEnum.ZHI_FU_BAO.type.equals(req.getPaymentType()) && order.getPayAmount().compareTo(BigDecimal.ZERO) > 0) {
  326. // PC下单
  327. if (req.getCreateType() != null && req.getCreateType() == 1) {
  328. resp = apiOrderService.getPaymentQRCode(payAmount, order.getOrderSn(), PaymentTypeEnum.ZHI_FU_BAO.type);
  329. } else {
  330. // APP下单
  331. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_BILLED.status);
  332. order.setStatus(PayStatusEnum.NO_PAYED.status);
  333. resp = aliPayService.pay(order.getOrderSn(), payAmount.toString(), order.getOrderSn());
  334. }
  335. } else if (PaymentTypeEnum.WEI_XIN.type.equals(req.getPaymentType()) && order.getPayAmount().compareTo(BigDecimal.ZERO) > 0) {
  336. // PC下单
  337. if (req.getCreateType() != null && req.getCreateType() == 1) {
  338. resp = apiOrderService.getPaymentQRCode(payAmount, order.getOrderSn(), PaymentTypeEnum.WEI_XIN.type);
  339. } else {
  340. // APP下单
  341. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_BILLED.status);
  342. order.setStatus(PayStatusEnum.NO_PAYED.status);
  343. OrderPaySignResponse.WechatPayParam respon = null;
  344. try {
  345. respon = wechatPayService.pay(payAmount, order.getOrderSn(), order.getOrderSn(), TradeType.APP);
  346. } catch (WxPayException e) {
  347. // e.printStackTrace();
  348. }
  349. resp = JSONObject.toJSONString(respon);
  350. }
  351. }
  352. if (payAmount.compareTo(BigDecimal.ZERO) == 0) {
  353. order.setStatus(PayStatusEnum.PAYED.status);
  354. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  355. }
  356. if (order.getPayAmount().compareTo(BigDecimal.ZERO) > 0) {
  357. paymentService.savePayment(order.getMemberId(), order.getOrderSn(), order.getPayAmount(), req.getPaymentType(), TradeTypeEnum.ORDER.type, JSONObject.toJSONString(resList), order.getOrderSn());
  358. }
  359. order.setRefundMoney(BigDecimal.ZERO);
  360. // 设置外卖平台, 订单流水号
  361. if ((order.getShopId() != null || order.getMemberId() != null) && req.getPlatformType() != null) {
  362. if (req.getPlatformType() != 0 && req.getDaySeq() == null) {
  363. throw new CustomAppException("流水号不能为空!");
  364. }
  365. if (req.getPlatformType() == 0) {
  366. // 猎豹平台生成流水号
  367. String daySeq = this.getLieBaoDaySeq(order.getShopId(), order.getMemberId());
  368. req.setDaySeq(daySeq);
  369. }
  370. order.setPlatformType(req.getPlatformType());
  371. order.setLbDaySeq(req.getDaySeq());
  372. }
  373. if (order.getId() != null) {
  374. iOrderService.updateById(order);
  375. } else {
  376. iOrderService.save(order);
  377. }
  378. // 达达收付配送商计价明细入库
  379. if (isDadaRapDelivery) {
  380. OrderFreight orderFreight = new OrderFreight();
  381. BeanUtil.copyProperties(orderFreightDto, orderFreight);
  382. orderFreight.setOrderId(order.getId());
  383. iOrderFreightService.save(orderFreight);
  384. }
  385. // iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.ORDER_CREATE.status);
  386. iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.NO_PAYED.status);
  387. if (PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType())) {
  388. iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.PAYED.status);
  389. iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  390. if (!isMine || isDadaRapDelivery) {
  391. //扣款
  392. iMemberService.updateAmount(member.getId(), payAmount.negate());
  393. //扣款记录
  394. iMemberBalanceLogService.saveLog(loginId, LogTypeEnum.REDUCE.type, "下单支付", LogSourceEnum.CONSUMPTION.status, order.getPayAmount(), member.getMerchantId(), order.getId(), order.getPaymentType());
  395. }
  396. }
  397. if (PaymentTypeEnum.BALANCE.type.equals(req.getPaymentType()) || payAmount.compareTo(BigDecimal.ZERO) == 0) {
  398. //更改优惠券状态
  399. apiCouponService.updateCoupon(couponDto);
  400. // 发单
  401. if (CollectionUtils.isNotEmpty(resList)) {
  402. // order.setProduct(product);
  403. CouponDto finalCouponDto = couponDto;
  404. TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
  405. @Override
  406. public void afterCommit() {
  407. applicationContext.publishEvent(new DeliveryOrderEvent(order, resList, finalCouponDto));
  408. }
  409. });
  410. }
  411. }
  412. return resp;
  413. // }catch (Exception e){
  414. // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  415. // log.error("下单异常",e);
  416. // return null;
  417. // }
  418. }
  419. private void setOrderSource(Order order, OrderReq req) {
  420. Integer platformType = req.getPlatformType();
  421. if (platformType != null && platformType > 0) {
  422. order.setPoiSeq(req.getDaySeq());
  423. // 美团、美团闪购
  424. if (platformType == 1 || platformType == 5) {
  425. order.setOrderSource("101");
  426. } else if (platformType == 2) {
  427. // 饿了么
  428. order.setOrderSource("102");
  429. } else if (platformType == 3) {
  430. // 饿百零售
  431. order.setOrderSource("103");
  432. }
  433. }
  434. }
  435. private String getLieBaoDaySeq(Long shopId, Long memberId) {
  436. int daySeq = 1;
  437. String memberKey = RedisKeyConstant.MEMBER_DAY_SEQ + DateUtils.getDate() + ":member_id:" + memberId;
  438. Boolean hasMemberKey = redisCache.hasKey(memberKey);
  439. if (shopId == null) {
  440. if (hasMemberKey) {
  441. daySeq = redisCache.increment(memberKey).intValue();
  442. } else {
  443. // 36小时后过期自动清除
  444. redisCache.setCacheObject(memberKey, daySeq, 36, TimeUnit.HOURS);
  445. }
  446. } else {
  447. String shopKey = RedisKeyConstant.SHOP_DAY_SEQ + DateUtils.getDate() + ":shop_id:" + shopId;
  448. if (redisCache.hasKey(shopKey)) {
  449. daySeq = redisCache.increment(shopKey).intValue();
  450. } else {
  451. // 个人申请成为门店账号, 订单流水号不间断
  452. if (hasMemberKey) {
  453. daySeq = redisCache.increment(memberKey).intValue();
  454. }
  455. // 36小时后过期自动清除
  456. redisCache.setCacheObject(shopKey, daySeq, 36, TimeUnit.HOURS);
  457. }
  458. }
  459. return Integer.toString(daySeq);
  460. }
  461. private Order createOrder(Product product, CouponDto couponDto, OrderReq req, Long memberId) {
  462. Order order = new Order();
  463. if (req.getOrderId() != null) {
  464. order = iOrderService.getById(req.getOrderId());
  465. order.setPersonnelId(null);
  466. if (order.getWaimaiOrderId() == null) {
  467. order.setProductAmount(req.getProductAmount());
  468. order.setTakeType(req.getTakeType());
  469. order.setTakeRemark(req.getTakeRemark());
  470. } else {
  471. if (StringUtils.isNotBlank(req.getTakeRemark())) {
  472. order.setTakeRemark(req.getTakeRemark());
  473. }
  474. }
  475. return order;
  476. }
  477. order.setMemberId(memberId);
  478. order.setWeight(req.getWeight());
  479. order.setTakeType(req.getTakeType());
  480. order.setTakeDate(DateUtils.parseDate(req.getTakeTime()));
  481. order.setTakeTime(DateUtils.parseDate(req.getTakeTime()));
  482. order.setTakeRemark(req.getTakeRemark());
  483. order.setDeliveryType(req.getDeliveryType());
  484. order.setPreDeliveryIds(req.getPreDeliveryIds());
  485. order.setOrderSn(req.getOrderNo());
  486. order.setProductId(product.getId());
  487. order.setProductName(product.getName());
  488. order.setCouponAmount(BigDecimal.ZERO);
  489. order.setTaxpayerId(req.getTaxpayerId());
  490. order.setInvoiceTitle(req.getInvoiceTitle());
  491. // order.setProduct(product);
  492. Long shopId = req.getShopId();
  493. if (shopId == null) {
  494. Member member = iMemberService.getById(memberId);
  495. if (member.getShopId() != null) {
  496. shopId = member.getShopId();
  497. order.setDefaultShop(DefaultShopEnum.SHOW.status);
  498. }
  499. }
  500. order.setShopId(shopId);
  501. if (couponDto != null) {
  502. order.setCouponAmount(couponDto.getMoney());
  503. order.setCouponId(Long.valueOf(couponDto.getId()));
  504. }
  505. AddressReq sendAddress = req.getSendAddress();
  506. AddressReq receiveAddress = req.getReceiptAddress();
  507. if (StringUtils.isNotBlank(sendAddress.getStreet())) {
  508. order.setSendStreet(sendAddress.getStreet());
  509. }
  510. order.setSendAddress(sendAddress.getAddress());
  511. order.setSendAddressId(sendAddress.getId());
  512. order.setSendCityName(sendAddress.getCityName());
  513. order.setSendContactName(sendAddress.getContact());
  514. order.setSendPhone(sendAddress.getPhone());
  515. order.setSendExtension(sendAddress.getExtension());
  516. order.setSendDistrictName((String) sendAddress.getDistrictName());
  517. order.setSendProvinceName(sendAddress.getProvinceName());
  518. order.setSendLat(sendAddress.getLat());
  519. order.setSendLng(sendAddress.getLng());
  520. order.setSendCityCode(sendAddress.getCityCode());
  521. if (StringUtils.isNotBlank(receiveAddress.getStreet())) {
  522. order.setReceiptStreet(receiveAddress.getStreet());
  523. }
  524. order.setReceiptAddress(receiveAddress.getAddress());
  525. order.setReceiptAddressId(receiveAddress.getId());
  526. order.setReceiptCityName(receiveAddress.getCityName());
  527. order.setReceiptContactName(receiveAddress.getContact());
  528. order.setReceiptPhone(receiveAddress.getPhone());
  529. order.setReceiptExtension(receiveAddress.getExtension());
  530. order.setReceiptDistrictName((String) receiveAddress.getDistrictName());
  531. order.setReceiptProvinceName(receiveAddress.getProvinceName());
  532. order.setReceiptLat(receiveAddress.getLat());
  533. order.setReceiptLng(receiveAddress.getLng());
  534. order.setReceiptCityCode(receiveAddress.getCityCode());
  535. if (order.getWaimaiOrderId() != null) {
  536. order.setWaimaiOrderId(order.getWaimaiOrderId());
  537. } else {
  538. order.setWaimaiOrderId(req.getWaimaiOrderId());
  539. }
  540. order.setProductAmount(req.getProductAmount());
  541. return order;
  542. }
  543. @Override
  544. public void refund(String orderNo, BigDecimal refundMoney, String remark, Long memberId, Long merchantId) {
  545. Order order = iOrderService.getOne(new QueryWrapper<Order>().eq("order_sn", orderNo).eq("deleted", IsDeleteEnum.NORMAL.status));
  546. Member member = iMemberService.getById(memberId);
  547. if (member.getMemberType().equals(MemberTypeEnum.SHOP.type)) {
  548. member = iMemberService.getOne(new QueryWrapper<Member>().eq("member_type", MemberTypeEnum.MERCHANT.type).eq("merchant_id", member.getMerchantId()));
  549. }
  550. if (PaymentTypeEnum.BALANCE.type.equals(order.getPaymentType())) {
  551. iMemberService.updateAmount(member.getId(), refundMoney);
  552. } else if (PaymentTypeEnum.ZHI_FU_BAO.type.equals(order.getPaymentType())) {
  553. aliPayService.alipayRefundRequest(orderNo, refundMoney.doubleValue());
  554. } else if (PaymentTypeEnum.WEI_XIN.type.equals(order.getPaymentType())) {
  555. Payment payment = paymentService.getOne(new QueryWrapper<Payment>().eq("child_order_sn", orderNo).eq("payment_type", PaymentTypeEnum.WEI_XIN.type));
  556. wechatPayService.refund(orderNo, payment.getTotalAmount(), refundMoney, "");
  557. }
  558. iMemberBalanceLogService.saveLog(memberId, LogTypeEnum.INCREASE.type, remark, LogSourceEnum.REFUND.status, refundMoney, merchantId, order.getId(), order.getPaymentType());
  559. // 是否需要退服务费-绑定三方运力下单
  560. if (order.getBindFee().compareTo(BigDecimal.ZERO) == 1) {
  561. iMemberService.updateAmount(member.getId(), order.getBindFee());
  562. iMemberBalanceLogService.saveLog(memberId, LogTypeEnum.INCREASE.type, "订单取消,服务费退款", LogSourceEnum.REFUND.status, order.getBindFee(), merchantId, order.getId(), order.getPaymentType());
  563. }
  564. }
  565. public void refundTip(List<OrderTip> orderTips, String remark, Long memberId, Long merchantId) {
  566. BigDecimal tips = orderTips.stream().map(OrderTip::getAmount).reduce(BigDecimal.ZERO, BigDecimalUtils::sum);
  567. Member member = iMemberService.getById(memberId);
  568. if (member.getMemberType().equals(MemberTypeEnum.SHOP.type)) {
  569. member = iMemberService.getOne(new QueryWrapper<Member>().eq("member_type", MemberTypeEnum.MERCHANT.type).eq("merchant_id", member.getMerchantId()));
  570. }
  571. for (OrderTip orderTip : orderTips) {
  572. if (PaymentTypeEnum.BALANCE.type.equals(orderTip.getPayType())) {
  573. iMemberService.updateAmount(member.getId(), orderTip.getAmount());
  574. } else if (PaymentTypeEnum.ZHI_FU_BAO.type.equals(orderTip.getPayType())) {
  575. aliPayService.alipayRefundRequest(orderTip.getChildOrderNo(), orderTip.getAmount().doubleValue());
  576. } else if (PaymentTypeEnum.WEI_XIN.type.equals(orderTip.getPayType())) {
  577. wechatPayService.refund(orderTip.getChildOrderNo(), orderTip.getTotalAmout(), orderTip.getAmount(), "");
  578. }
  579. }
  580. if (tips.compareTo(BigDecimal.ZERO) > 0) {
  581. iMemberBalanceLogService.saveLog(memberId, LogTypeEnum.INCREASE.type, remark, LogSourceEnum.REFUND.status, tips, merchantId, Long.valueOf(orderTips.get(0).getOrderId()), orderTips.get(0).getPayType());
  582. }
  583. }
  584. @Override
  585. public void getWaiMaiInfo(Order order, OrderReq req) {
  586. WaimaiOrder waimaiOrder = iWaimaiOrderService.findById(order.getWaimaiOrderId());
  587. req.setAmount(waimaiOrder.getTotalPrice());
  588. order.setWmAmount(waimaiOrder.getTotalPrice());
  589. order.setShopId(waimaiOrder.getShopId());
  590. String remark = waimaiOrder.getCaution();
  591. req.setWaiMaiRemark(remark);
  592. order.setWaiMaiRemark(remark);
  593. // if (StringUtils.isNotBlank(remark) && remark.contains("收餐人隐私号")) {
  594. // remark = remark.substring(0, waimaiOrder.getCaution().indexOf("收餐人隐私号"));
  595. // }
  596. // if(StringUtils.isNotBlank(order.getTakeRemark())&&!order.getTakeRemark().equals(remark)){
  597. // remark = "【"+order.getTakeRemark()+"】" + remark;
  598. // }
  599. // if(StringUtils.isNotBlank(remark)&&remark.length()>200){
  600. // remark = remark.substring(0,200);
  601. // }
  602. // order.setTakeRemark(remark);
  603. // if (waimaiOrder.getCaution().contains("收餐人隐私号")){
  604. // order.setTakeRemark(waimaiOrder.getCaution().substring(0,waimaiOrder.getCaution().indexOf("收餐人隐私号")));
  605. // }else {
  606. // order.setTakeRemark(waimaiOrder.getCaution());
  607. // }
  608. if (DefaultShopEnum.SHOW.status.equals(order.getDefaultShop())) {
  609. order.setDefaultShop(DefaultShopEnum.STOP.status);
  610. }
  611. //order.setShopName(waimaiOrder.getPoiName());
  612. order.setPoiSeq(waimaiOrder.getDaySeq());
  613. order.setOrderingSourceNo(waimaiOrder.getOutOrderId());
  614. if (waimaiOrder.getOrderType().equals(WaimaiTypeEnums.MEI_TUAN.getType())) {
  615. order.setOrderSource("101");
  616. } else if (waimaiOrder.getOrderType().equals(WaimaiTypeEnums.E_LE_ME.getType())) {
  617. // 饿了么
  618. order.setOrderSource("102");
  619. } else if (waimaiOrder.getOrderType().equals(WaimaiTypeEnums.E_LE_ME_RETAIL.getType())) {
  620. // 饿百
  621. order.setOrderSource("103");
  622. }else if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.MEI_TUAN_SG.getType())) {
  623. order.setOrderSource("101");
  624. }
  625. order.setPoiSeq(waimaiOrder.getDaySeq());
  626. // 外卖商品信息
  627. List<WaimaiOrderDetail> waiMaiOrderDetails = iWaimaiOrderDetailService.findList(order.getWaimaiOrderId());
  628. order.setWaimaiOrderDetails(waiMaiOrderDetails);
  629. }
  630. /**
  631. * 校验用户绑定三方运力,下单机制(这里校验的都是商家)
  632. */
  633. @Transactional(rollbackFor = Exception.class)
  634. public void checkMemberAmount(Member member, List<Long> deliveryIds) {
  635. if (member.getMerchantId() == null) {
  636. return;
  637. }
  638. MerchantDeliveryFee fee = iMerchantDeliveryFeeService.getByMerchantAndDeliveryIds(member.getMerchantId(), deliveryIds);
  639. if (fee == null) {
  640. return;
  641. }
  642. if (member.getAmount().compareTo(fee.getAmount()) == -1) {
  643. log.warn("选择运力为绑定运力,当前余额少于服务费,请充值后再下单!deliveryId: {}", fee.getDeliveryId());
  644. throw new CustomAppException("选择运力为绑定运力,当前余额少于服务费,请充值后再下单!", 250);
  645. }
  646. }
  647. @Override
  648. public boolean addRemark(Long orderId, String remark) {
  649. Order order = new Order();
  650. order.setTakeRemark(remark);
  651. order.setId(orderId);
  652. return iOrderService.updateById(order);
  653. }
  654. private void address(OrderReq req) {
  655. String sendAddress = req.getSendAddress().getAddress();
  656. String sendStreet = req.getSendAddress().getStreet();
  657. String receiptAddress = req.getReceiptAddress().getAddress();
  658. String receiptStreet = req.getReceiptAddress().getStreet();
  659. if (StringUtils.isNotBlank(sendStreet) && sendAddress.endsWith(sendStreet)) {
  660. req.getSendAddress().setAddress(sendAddress.substring(0, sendAddress.lastIndexOf(sendStreet)));
  661. }
  662. if (StringUtils.isNotBlank(receiptStreet) && receiptAddress.endsWith(receiptStreet)) {
  663. req.getReceiptAddress().setAddress(receiptAddress.substring(0, receiptAddress.lastIndexOf(receiptStreet)));
  664. }
  665. }
  666. private void resetOrder(Order order, Product product) {
  667. order.setId(null);
  668. order.setRefundMoney(BigDecimal.ZERO);
  669. order.setOutTradeNo("");
  670. order.setTakeDate(null);
  671. order.setDeliveryId(null);
  672. order.setDeliveryLogo("");
  673. order.setDeliveryName("");
  674. order.setDeliveryTime(null);
  675. order.setShipperName("");
  676. order.setShipperPhone("");
  677. order.setShipperLat(null);
  678. order.setShipperLng(null);
  679. order.setStatus(PayStatusEnum.NO_PAYED.status);
  680. order.setDeliveryStatus(null);
  681. order.setPaymentType(null);
  682. order.setCouponId(null);
  683. order.setCouponAmount(null);
  684. //order.setProduct(product);
  685. order.setCancelReason("");
  686. order.setTipAmount(null);
  687. order.setFirstCoupon(null);
  688. order.setUseTip(0);
  689. order.setTakeTime(new Date());
  690. // order.setTakeType(null);
  691. order.setProductId(product.getId());
  692. order.setProductName(product.getName());
  693. order.setBindFee(BigDecimal.ZERO);
  694. order.setCancelType(null);
  695. }
  696. /**
  697. * 判断用户余额
  698. *
  699. * @param memberId
  700. */
  701. public void checkAmount(Long memberId) {
  702. Member member = iMemberService.getById(memberId);
  703. if (member.getMerchantId() != null) {
  704. List<Member> members = iMemberService.selectListByMerchantId(member.getMerchantId().intValue());
  705. List<Long> mIds = new ArrayList<>();
  706. log.info("推送用户===" + JSONObject.toJSONString(members));
  707. if (member.getAmount().compareTo(new BigDecimal(50)) < 0) {
  708. // 自动配送关闭,关闭该商家的所有门店
  709. for (Member m : members) {
  710. // 判断用户是否开启自配送
  711. // MemberConfigDto memberConfigDto = iMemberConfigService.findDetail(m.getId());
  712. // if (memberConfigDto == null || memberConfigDto.getOpenAutodelivery().equals(0)){
  713. // continue;
  714. // }
  715. // MemberConfig memberConfig = iMemberConfigService.getById(memberConfigDto.getId());
  716. // memberConfig.setOpenAutodelivery(0);
  717. // iMemberConfigService.updateById(memberConfig);
  718. mIds.add(m.getId());
  719. }
  720. // 发推送
  721. if (CollectionUtils.isNotEmpty(mIds)) {
  722. messagePushService.memberAmountMessage(mIds, "您的平台余额低于50元", "您的平台余额已不足50元,可能导致自动发单失败,请及时充值!", 1);
  723. }
  724. return;
  725. }
  726. if (member.getAmount().compareTo(new BigDecimal(100)) < 0) {
  727. for (Member m : members) {
  728. mIds.add(m.getId());
  729. }
  730. // 发推送
  731. if (CollectionUtils.isNotEmpty(mIds)) {
  732. messagePushService.memberAmountMessage(mIds, "您的平台余额低于100元", "您的平台余额已不足100元,可能导致自动发单失败,请及时充值!", 2);
  733. }
  734. }
  735. }
  736. }
  737. }