| | |
| | | |
| | | @Autowired |
| | | private MemberCouponMapper memberCouponMapper; |
| | | @Autowired |
| | | private CouponMapper couponMapper; |
| | | |
| | | @Autowired |
| | | private AreasBiz areasBiz; |
| | |
| | | .le(MemberCoupon::getLimitPrice, totalPrice) |
| | | .ge(MemberCoupon::getEndDate, now) |
| | | .orderByDesc(MemberCoupon::getPrice) |
| | | .orderByAsc(MemberCoupon::getEndDate)); |
| | | .orderByAsc(MemberCoupon::getCreateDate)); |
| | | result.setAvailableCoupons(availableCoupons); |
| | | |
| | | if (couponId == null) { |
| | |
| | | if (Objects.isNull(order)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | // 实付金额 = 支付金额 - 退款金额 + 逾期费用 |
| | | long pay = order.getPayAmount() != null ? order.getPayAmount() : 0L; |
| | | long refund = order.getRefundAmount() != null ? order.getRefundAmount() : 0L; |
| | | long overdue = order.getOverdueAmount() != null ? order.getOverdueAmount() : 0L; |
| | | order.setPayAmount(pay - refund + overdue); |
| | | |
| | | OrderDetailVO vo = new OrderDetailVO(); |
| | | vo.setOrder(order); |
| | |
| | | for (OrderItemVO v:vo.getDetailList()) { |
| | | v.setTypeName(category.getName()); |
| | | } |
| | | } |
| | | |
| | | // 评价信息 |
| | | List<OrderComment> comments = orderCommentMapper.selectList(new QueryWrapper<OrderComment>().lambda() |
| | | .eq(OrderComment::getOrderId, id) |
| | | .eq(OrderComment::getDeleted, Constants.ZERO)); |
| | | if (CollectionUtils.isNotEmpty(comments)) { |
| | | for (OrderComment c : comments) { |
| | | if (Constants.equalsInteger(c.getTargetType(), Constants.ONE)) { |
| | | vo.setDepositScore(c.getScore()); |
| | | } else if (Constants.equalsInteger(c.getTargetType(), Constants.TWO)) { |
| | | vo.setTakeScore(c.getScore()); |
| | | } else if (Constants.equalsInteger(c.getTargetType(), Constants.THREE)) { |
| | | vo.setDriverScore(c.getScore()); |
| | | } |
| | | } |
| | | vo.setCommentContent(comments.get(0).getContent()); |
| | | vo.setCommentTime(comments.get(0).getCreateTime()); |
| | | vo.setCommentImages(getFileUrls(id, Constants.FileType.COMMENT_ATTACH.getKey(), imgPrefix)); |
| | | } |
| | | |
| | | // 取消/退款状态时查询退款记录 |
| | |
| | | cal.set(Calendar.MINUTE, 0); |
| | | cal.set(Calendar.SECOND, 0); |
| | | cal.set(Calendar.MILLISECOND, 0); |
| | | wrapper.ge(Orders::getFinishTime, cal.getTime()); |
| | | wrapper.ge(Orders::getFinishTime, cal.getTime()) |
| | | .eq(Orders::getStatus, Constants.OrderStatus.finished.getKey()); |
| | | } |
| | | } |
| | | // 关键词搜索:收件人/收件人电话模糊、订单号精准 |
| | |
| | | fillOverdueStatus(vo, o, details); |
| | | // 优惠券抵扣金额 |
| | | vo.setDeductionAmount(o.getDeductionAmount()); |
| | | // 异常订单标识 |
| | | vo.setAbnormalOrder(o.getExceptionStatus()); |
| | | // 可开票金额(支付金额 - 退款金额) |
| | | if (model != null && model.getInvoiceStatus() != null && Constants.equalsInteger(model.getInvoiceStatus(), Constants.ONE)) { |
| | | long payAmt = o.getPayAmount() != null ? o.getPayAmount() : 0L; |
| | |
| | | .or(w3-> w3.eq(Orders::getType, Constants.ONE).eq(Orders::getDepositShopId, shopId) |
| | | .eq(Orders::getStatus, Constants.OrderStatus.waitDeposit.getStatus())) |
| | | .or(w2 -> w2.eq(Orders::getType, Constants.ONE).eq(Orders::getTakeShopId, shopId) |
| | | .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus()))) |
| | | .in(Orders::getStatus, Constants.OrderStatus.arrived.getStatus(),Constants.OrderStatus.delivering.getStatus()))) |
| | | ); |
| | | } else { |
| | | wrapper.and(w -> w.eq(Orders::getDepositShopId, shopId).or().eq(Orders::getTakeShopId, shopId)); |
| | |
| | | vo.setUrgentAmount(order.getUrgentAmount()); |
| | | vo.setIsUrgent(order.getIsUrgent()); |
| | | vo.setActualPayAmount(Constants.equalsInteger(order.getPayStatus(), Constants.ONE)?order.getPayAmount():order.getEstimatedAmount()); |
| | | vo.setDeductionAmount(order.getDeductionAmount()); |
| | | |
| | | // 标记 |
| | | vo.setExceptionStatus(order.getExceptionStatus()); |
| | |
| | | vo.setPayCountdownMs(calcPayCountdownMs(order)); |
| | | } |
| | | //序号 |
| | | vo.setSortnum(Constants.formatIntegerNum(order.getDepositShopId())+"-"+order.getId()); |
| | | if(order.getTakeShopId()!=null){ |
| | | // vo.setSortnum(Constants.formatIntegerNum(order.getDepositShopId())+"-"+order.getId()); |
| | | String dateStr = new SimpleDateFormat("dd").format(order.getPayTime() != null ? order.getPayTime() : new Date()); |
| | | String autoNumStr = String.format("%03d", order.getAutoNum() != null ? order.getAutoNum() : 0); |
| | | String sort = order.getTakeShopId() + "-" + dateStr + "-" + autoNumStr; |
| | | vo.setSortnumTake(sort); |
| | | } |
| | | String sort = order.getDepositShopId() + "-" + dateStr + "-" + autoNumStr; |
| | | vo.setSortnum(sort); |
| | | vo.setDepositShopId(order.getDepositShopId()); |
| | | // 存件门店 |
| | | if (order.getDepositShopId() != null) { |
| | | ShopInfo depositShop = shopInfoMapper.selectById(order.getDepositShopId()); |
| | |
| | | * 保存取消订单操作日志 |
| | | */ |
| | | private void restoreCoupon(Orders order) { |
| | | // if (order.getCouponId() == null || order.getDeductionAmount() == null || order.getDeductionAmount() <= 0) { |
| | | // return; |
| | | // } |
| | | // memberCouponMapper.update(new UpdateWrapper<MemberCoupon>().lambda() |
| | | // .set(MemberCoupon::getStatus, Constants.CouponStatus.claimed.getKey()) |
| | | // .set(MemberCoupon::getUseDate, null) |
| | | // .set(MemberCoupon::getOrderId, null) |
| | | // .eq(MemberCoupon::getId, order.getCouponId()) |
| | | // .eq(MemberCoupon::getOrderId, order.getId()) |
| | | // .eq(MemberCoupon::getStatus, Constants.CouponStatus.used.getKey())); |
| | | if (order.getCouponId() == null || order.getDeductionAmount() == null || order.getDeductionAmount() <= 0) { |
| | | return; |
| | | } |
| | | memberCouponMapper.update(new UpdateWrapper<MemberCoupon>().lambda() |
| | | .set(MemberCoupon::getStatus, Constants.CouponStatus.claimed.getKey()) |
| | | .set(MemberCoupon::getUseDate, null) |
| | | .set(MemberCoupon::getOrderId, null) |
| | | .eq(MemberCoupon::getId, order.getCouponId()) |
| | | .eq(MemberCoupon::getOrderId, order.getId()) |
| | | .eq(MemberCoupon::getStatus, Constants.CouponStatus.used.getKey())); |
| | | } |
| | | |
| | | private void giftOrderCoupon(Integer memberId) { |
| | | String orderCountStr = operationConfigBiz.getConfig().getOrderCouponOrderCount(); |
| | | String giftCountStr = operationConfigBiz.getConfig().getOrderCouponGiftCount(); |
| | | String couponIdsStr = operationConfigBiz.getConfig().getOrderCouponId(); |
| | | if (StringUtils.isAnyBlank(orderCountStr, giftCountStr, couponIdsStr)) return; |
| | | |
| | | int orderCount = Integer.parseInt(orderCountStr); |
| | | int maxGift = Integer.parseInt(giftCountStr); |
| | | |
| | | Member member = memberMapper.selectById(memberId); |
| | | if (member == null) return; |
| | | int gifted = member.getOrderCouponGiftCount() != null ? member.getOrderCouponGiftCount() : 0; |
| | | if (gifted >= maxGift) return; |
| | | |
| | | long completedCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getMemberId, memberId) |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .notIn(Orders::getStatus, |
| | | Constants.OrderStatus.waitPay.getKey(), |
| | | Constants.OrderStatus.waitDeposit.getKey())); |
| | | if (completedCount < orderCount || completedCount % orderCount != 0) return; |
| | | |
| | | String[] idArr = couponIdsStr.split(","); |
| | | Date now = new Date(); |
| | | for (String idStr : idArr) { |
| | | String trimmed = idStr.trim(); |
| | | if (StringUtils.isBlank(trimmed)) continue; |
| | | Coupon coupon = couponMapper.selectById(Integer.valueOf(trimmed)); |
| | | if (coupon == null || Constants.equalsInteger(coupon.getIsdeleted(), Constants.ONE)) continue; |
| | | MemberCoupon mc = new MemberCoupon(); |
| | | mc.setCouponId(coupon.getId()); |
| | | mc.setMemberId(memberId); |
| | | mc.setStatus(Constants.CouponStatus.waitClaim.getKey()); |
| | | Calendar validCal = Calendar.getInstance(); |
| | | validCal.add(Calendar.DAY_OF_MONTH, coupon.getPushDays() != null ? coupon.getPushDays() : 7); |
| | | mc.setValidDate(validCal.getTime()); |
| | | mc.setName(coupon.getName()); |
| | | mc.setInfo(coupon.getInfo()); |
| | | mc.setType(coupon.getType()); |
| | | mc.setLimitPrice(coupon.getLimitPrice()); |
| | | mc.setPrice(coupon.getPrice()); |
| | | mc.setGetMethod(coupon.getGetMethod()); |
| | | mc.setCouponType(coupon.getCouponType()); |
| | | mc.setPushDays(coupon.getPushDays()); |
| | | mc.setValidDays(coupon.getValidDays()); |
| | | mc.setIsdeleted(Constants.ZERO); |
| | | mc.setCreateDate(now); |
| | | mc.setEditDate(now); |
| | | memberCouponMapper.insert(mc); |
| | | } |
| | | |
| | | member.setOrderCouponGiftCount(gifted + 1); |
| | | memberMapper.updateById(member); |
| | | } |
| | | |
| | | private void saveCancelLog(Orders order, Constants.OrderLogType logType, String reason, Integer memberId) { |
| | |
| | | refund.setRefundTime(now); |
| | | ordersRefundMapper.updateById(refund); |
| | | // 退款成功,执行扣款 |
| | | processManualRefundDeduction(order, depositShopDeduct, takeShopDeduct, driverDeduct); |
| | | //processManualRefundDeduction(order, depositShopDeduct, takeShopDeduct, driverDeduct); |
| | | } else if (com.wechat.pay.java.service.refund.model.Status.PROCESSING.equals(refundStatus)) { |
| | | refund.setStatus(Constants.ZERO); // 退款中,等回调 |
| | | ordersRefundMapper.updateById(refund); |
| | |
| | | // 7. 更新订单:标记已手动退款,累加退款金额 |
| | | ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getManualRefund, Constants.ONE) |
| | | .setSql(" REFUND_AMOUNT = IFNULL(REFUND_AMOUNT, 0) + " + dto.getRefundAmount()) |
| | | .set(Orders::getUpdateTime, now) |
| | | .eq(Orders::getId, order.getId())); |
| | | } |
| | |
| | | Long driverDeduct = deductJson.getLong("driverDeduct"); |
| | | processManualRefundDeduction(order, depositShopDeduct, takeShopDeduct, driverDeduct); |
| | | |
| | | // 标记订单已手动退款,累加退款金额 |
| | | // 标记订单已手动退款,累加退款金额,同步更新totalAmount |
| | | ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getManualRefund, Constants.ONE) |
| | | .setSql(" REFUND_AMOUNT = IFNULL(REFUND_AMOUNT, 0) + " + refundRecord.getRefundAmount()) |
| | | .setSql(" TOTAL_AMOUNT = IFNULL(TOTAL_AMOUNT, 0) - " + refundRecord.getRefundAmount()) |
| | | .set(Orders::getUpdateTime, new Date()) |
| | | .eq(Orders::getId, order.getId())); |
| | | } |
| | |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(), |
| | | "orderNo", order.getCode(), "shopName", shopName); |
| | | } |
| | | // 寄存成功赠送优惠券 |
| | | giftOrderCoupon(order.getMemberId()); |
| | | } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) { |
| | | // 异地寄存 + 无取件门店 → 无法核销(客户自取,无门店操作) |
| | | if (Constants.equalsInteger(order.getType(), Constants.ONE) && order.getTakeShopId() == null) { |
| | |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "核销码无效"); |
| | | } |
| | | |
| | | // 仅异地寄存 + 有取件门店 + 派送中(4) 可核销 |
| | | if (!Constants.equalsInteger(order.getType(), Constants.ONE)) { |
| | | // 仅异地寄存 + 有取件门店 + 派送中(4) 可核销(异常订单允许) |
| | | if (!Constants.equalsInteger(order.getType(), Constants.ONE) |
| | | && !Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅异地寄存订单支持司机核销"); |
| | | } |
| | | if (order.getTakeShopId() == null) { |
| | | if (order.getTakeShopId() == null && !Constants.equalsInteger(order.getExceptionStatus(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单无取件门店,无需司机核销"); |
| | | } |
| | | if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus())) { |
| | | if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus()) |
| | | && !Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.deposited.getStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前订单状态不允许核销"); |
| | | } |
| | | |
| | |
| | | sendSmsNotify(member != null ? member.getTelephone() : null, |
| | | Constants.SmsNotify.MEMBER_CANCELLED, "orderNo", order.getCode()); |
| | | } |
| | | |
| | | restoreCoupon(order); |
| | | count++; |
| | | } catch (Exception e) { |
| | | log.error("取消超时订单异常, orderId={}, error={}", order.getId(), e.getMessage()); |
| | |
| | | } |
| | | targetLat = order.getDepositLat(); |
| | | targetLgt = order.getDepositLgt(); |
| | | } else if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus())) { |
| | | // status=5 门店完成核销 |
| | | if (Constants.equalsInteger(order.getType(), Constants.ZERO)) { |
| | | } else if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus())&&Constants.equalsInteger(order.getType(), Constants.ZERO)) { |
| | | // 就地存取 → 对比存件门店 |
| | | if (!Constants.equalsInteger(order.getDepositShopId(), userId)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "无权操作该订单"); |
| | | } |
| | | targetLat = order.getDepositLat(); |
| | | targetLgt = order.getDepositLgt(); |
| | | } else { |
| | | } else if ((Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.delivering.getStatus())||Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.arrived.getStatus()))&&Constants.equalsInteger(order.getType(), Constants.ONE)) { |
| | | // 异地存取 → 对比取件门店 |
| | | if (!Constants.equalsInteger(order.getTakeShopId(), userId)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "无权操作该订单"); |
| | | } |
| | | targetLat = order.getTakeLat(); |
| | | targetLgt = order.getTakeLgt(); |
| | | } |
| | | } else { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "订单状态不允许此操作"); |
| | | } |
| | | } else if (Constants.equalsInteger(userType, Constants.ONE)) { |
| | | // 司机操作 |
| | | if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.deposited.getStatus())) { |
| | | if (Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.accepted.getStatus())) { |
| | | // status=2 司机取件 |
| | | if (!Constants.equalsInteger(order.getAcceptDriver(), userId)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "无权操作该订单"); |
| | |
| | | if (original.getTakeShopId() != null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单已关联取件门店,不支持异常处理"); |
| | | } |
| | | if (!Constants.equalsInteger(original.getStatus(), Constants.FIVE)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅支持已送达状态的订单"); |
| | | if (!Constants.equalsInteger(original.getStatus(), Constants.OrderStatus.delivering.getKey())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "仅支持配送中的订单进行异常处理"); |
| | | } |
| | | if (Constants.equalsInteger(original.getExceptionStatus(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "该订单已处理过异常,请勿重复操作"); |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public ManualRefundDetailVO getManualRefundDetail(Integer orderId) { |
| | | OrdersRefund refundRecord = ordersRefundMapper.selectOne(new QueryWrapper<OrdersRefund>().lambda() |
| | | .eq(OrdersRefund::getOrderId, orderId) |
| | | .eq(OrdersRefund::getType, Constants.FOUR) |
| | | .eq(OrdersRefund::getDeleted, Constants.ZERO) |
| | | .orderByDesc(OrdersRefund::getCreateTime) |
| | | .last("limit 1")); |
| | | if (refundRecord == null) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | ManualRefundDetailVO vo = new ManualRefundDetailVO(); |
| | | vo.setRefundAmount(refundRecord.getRefundAmount()); |
| | | if (StringUtils.isNotBlank(refundRecord.getDeductInfo())) { |
| | | JSONObject json = JSONObject.parseObject(refundRecord.getDeductInfo()); |
| | | vo.setDepositShopDeduct(json.getLong("depositShopDeduct")); |
| | | vo.setTakeShopDeduct(json.getLong("takeShopDeduct")); |
| | | vo.setDriverDeduct(json.getLong("driverDeduct")); |
| | | } |
| | | vo.setRefundRemark(refundRecord.getRefundRemark()); |
| | | return vo; |
| | | } |
| | | |
| | | } |