From 7d2b4f7fdb81cd0f5bd85f054190a3ad2f51122e Mon Sep 17 00:00:00 2001 From: cb <275647614@qq.com> Date: Thu, 4 Sep 2025 17:12:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=95=86=E5=93=81=E5=94=AE?= =?UTF-8?q?=E5=90=8E=E5=A4=A7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/AfterServiceRecordController.java | 15 ++ .../ghy/order/domain/AfterServiceRecord.java | 4 + .../service/IAfterServiceRecordService.java | 8 + .../impl/AfterServiceRecordServiceImpl.java | 151 ++++++++++++++++++ .../mapper/order/AfterServiceRecordMapper.xml | 18 ++- 5 files changed, 189 insertions(+), 7 deletions(-) diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/order/AfterServiceRecordController.java b/ghy-admin/src/main/java/com/ghy/web/controller/order/AfterServiceRecordController.java index 0a478bd0..3c09611f 100644 --- a/ghy-admin/src/main/java/com/ghy/web/controller/order/AfterServiceRecordController.java +++ b/ghy-admin/src/main/java/com/ghy/web/controller/order/AfterServiceRecordController.java @@ -141,6 +141,21 @@ public class AfterServiceRecordController extends BaseController { } } + /** + * 修改商品售后记录 + */ + @PostMapping("/editGoods") + @ResponseBody + public AjaxResult editGoodsSave(@RequestBody AfterServiceRecord afterServiceRecord) { + logger.info("修改商品售后记录:{}", afterServiceRecord); + try { + return afterServiceRecordService.updateGoodsAfterServiceRecord(afterServiceRecord); + } catch (Exception exception) { + logger.error(ExceptionUtils.getStackTrace(exception)); + return AjaxResult.error(exception.getMessage()); + } + } + /** * 删除售后记录 */ diff --git a/ghy-order/src/main/java/com/ghy/order/domain/AfterServiceRecord.java b/ghy-order/src/main/java/com/ghy/order/domain/AfterServiceRecord.java index 4bfe3caa..60c0aed1 100644 --- a/ghy-order/src/main/java/com/ghy/order/domain/AfterServiceRecord.java +++ b/ghy-order/src/main/java/com/ghy/order/domain/AfterServiceRecord.java @@ -89,6 +89,10 @@ public class AfterServiceRecord extends BaseEntity @Excel(name = "是否自动处理:0-否,1-是") private Integer isAutoProcessed; + /** 售后大类:1-商品售后,2-服务售后 */ + @Excel(name = "售后大类:1-服务售后,2-商品售后") + private Integer afterServiceCategory; + /** 售后类型:1-未收到货退单退款,2-未收到货退款,3-已收到货退款退货 */ @Excel(name = "售后类型:1-未收到货退单退款,2-未收到货退款,3-已收到货退款退货") private Integer afterServiceType; diff --git a/ghy-order/src/main/java/com/ghy/order/service/IAfterServiceRecordService.java b/ghy-order/src/main/java/com/ghy/order/service/IAfterServiceRecordService.java index dd58e507..9698edf1 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/IAfterServiceRecordService.java +++ b/ghy-order/src/main/java/com/ghy/order/service/IAfterServiceRecordService.java @@ -93,6 +93,14 @@ public interface IAfterServiceRecordService { */ void resumeConfirmTimeout(Long orderDetailId); + /** + * 修改商品售后记录 + * + * @param afterServiceRecord 售后记录 + * @return 结果 + */ + AjaxResult updateGoodsAfterServiceRecord(AfterServiceRecord afterServiceRecord) throws BaseAdaPayException; + /** * 师傅重发/补发操作 * 师傅端点击重发补发按钮,保存重发/补发方案 diff --git a/ghy-order/src/main/java/com/ghy/order/service/impl/AfterServiceRecordServiceImpl.java b/ghy-order/src/main/java/com/ghy/order/service/impl/AfterServiceRecordServiceImpl.java index 6167a8ac..e3e1d6d6 100644 --- a/ghy-order/src/main/java/com/ghy/order/service/impl/AfterServiceRecordServiceImpl.java +++ b/ghy-order/src/main/java/com/ghy/order/service/impl/AfterServiceRecordServiceImpl.java @@ -120,6 +120,9 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService log.warn("订单[{}]存在未完成的售后记录", afterServiceRecord.getOrderDetailId()); throw new BaseException("存在未完成的售后记录,请勿重复申请!"); } + // 根据订单类型自动设置售后大类 + setAfterServiceCategory(afterServiceRecord); + int result = afterServiceRecordMapper.insertAfterServiceRecord(afterServiceRecord); // 暂停确认中倒计时 @@ -334,6 +337,130 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService return AjaxResult.success(); } + /** + * 修改商品售后记录 + * + * @param param 售后记录 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public AjaxResult updateGoodsAfterServiceRecord(AfterServiceRecord param) throws BaseAdaPayException { + Long one = 1L; + Long two = 2L; + AfterServiceRecord afterServiceRecord = this.selectAfterServiceRecordById(param.getId()); + Assert.notNull(afterServiceRecord, "售后记录不存在!"); + OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId()); + boolean drawCash = orderDetail.getDrawCashTime() != null; + // 更新为售后未超时 + orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0); + log.info("商品售后-客户是否同意{},客户操作{}",one.equals(param.getCustomerFinalCheck()),param); + log.info("商品售后-修改后的售后订单{}",orderDetail); + + // 新增:处理客户同意上门重做方案 + if (param.getCustomerAgreeRedo() != null) { + afterServiceRecord.setCustomerAgreeRedo(param.getCustomerAgreeRedo()); + afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); + log.info("商品售后-客户同意上门重做方案状态已更新:{}", param.getCustomerAgreeRedo()); + return AjaxResult.success("客户同意方案状态已更新"); + } + + // 新增:处理师傅重做/补做完成 + if (param.getWorkerFeedbackResult() != null && param.getWorkerFeedbackResult().equals(3L)) { + afterServiceRecord.setWorkerFeedbackResult(3L); + afterServiceRecord.setRedoCompleteTime(new Date()); + if (param.getRedoCompleteRemark() != null) { + afterServiceRecord.setRedoCompleteRemark(param.getRedoCompleteRemark()); + } + if (param.getRedoCompleteImages() != null) { + afterServiceRecord.setRedoCompleteImages(param.getRedoCompleteImages()); + } + afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); + log.info("商品售后-师傅重做/补做完成,记录ID:{},完成时间:{}", param.getId(), afterServiceRecord.getRedoCompleteTime()); + return AjaxResult.success("重做/补做完成状态已更新"); + } + + if (param.getCustomerFinalCheck()!=null ) { + // 检查是否已经被自动处理过,防止重复退款 + if (afterServiceRecord.getIsAutoProcessed() != null && afterServiceRecord.getIsAutoProcessed() == 1) { + log.warn("商品售后记录[{}]已被自动处理,不允许手动重复操作", afterServiceRecord.getId()); + return AjaxResult.error("该售后记录已被系统自动处理,无法重复操作"); + } + + // 商品售后的处理逻辑(简化版,主要处理客户同意/不同意) + if (one.equals(param.getCustomerFinalCheck())) { + afterServiceRecord.setCustomerFinalCheck(1L); + log.info("商品售后-客户同意处理方案"); + } else { + afterServiceRecord.setCustomerFinalCheck(0L); + // 客户不同意时,保存不同意图片和理由 + if (param.getCustomerDisagreeImages() != null) { + afterServiceRecord.setCustomerDisagreeImages(param.getCustomerDisagreeImages()); + } + if (param.getCustomerDisagreeReason() != null) { + afterServiceRecord.setCustomerDisagreeReason(param.getCustomerDisagreeReason()); + } + // 更新子单和主单的售后状态为售后纠纷 + updateAfterServiceStatus(afterServiceRecord.getOrderDetailId(), 1); + log.info("商品售后-客户不同意处理方案"); + } + + afterServiceRecord.setRefundApplyTime(new Date()); + + // 商品售后客户回复通知 + // 通知师傅新订单 + try { + Worker worker = workerService.selectById(orderDetail.getWorkerId()); + OrderMaster orderMaster = orderMasterService.selectById(orderDetail.getOrderMasterId()); + // 推送公众号通知数据。 + // 消息组装。 + Map paramsNew = new HashMap<>(); + // 订单编号 + paramsNew.put("thing9", "您有1条商品售后/投诉单,客户已回复"); + // 名称 + paramsNew.put("thing11", "请进入【我的订单--售后中】查看处理"); + CustomerAddress address = customerAddressService.selectByCustomerAddressId(orderMaster.getAddressId()); + paramsNew.put("thing10", address.getName()); + // 预约时间 + paramsNew.put("time13", com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date())); + WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), worker.getWxOpenId(), WxMsgEnum.AFTER_SALES_ORDER, paramsNew); + } catch (Exception e) { + log.error("商品售后通知发送失败", e); + } + + // DrawCashTime不为空说明已经发起过分账 + if (drawCash) { + log.warn("商品售后-子单[{}]已发起分账,不能退款", afterServiceRecord.getOrderDetailId()); + afterServiceRecord.setOriginalRefund(BigDecimal.ZERO); + afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); + return AjaxResult.error("本单已划款,师傅/服务人员已到帐或即将到帐,双方达成退款的,请对方线下支付后点对方已退款"); + } else { + agreeRefund(afterServiceRecord); + } +// orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0); + } else if (one.equals(afterServiceRecord.getWorkerFeedbackResult()) && param.getCustomerFinalCheck() == null) { + // 师傅同意 且 客户未处理 + afterServiceRecordMapper.updateAfterServiceRecord(param); + return drawCash ? AjaxResult.error("本单银联已确认货款结算完毕(订单支付完成),款项已到达或即将到达您所绑定帐户,需同意退款的同意后您线下与客户另行操作,系统无法提供原路返回退款!") : AjaxResult.success(); + } else { + if(two.equals(param.getCustomerFinalCheck())){ + // 客户不同意师傅的意见,如果订单是确认中,则需要将订单改为服务中 + if(orderDetail.getOrderStatus() == OrderStatus.FINISH_CHECK.code() && orderDetail.getDrawCashTime()!= null ){ + orderDetail.setOrderStatus(OrderStatus.SERVER.code()); + orderDetailService.updateOrderDetail(orderDetail); + // 如果发现是唯一子单,则需要将主单也更新为服务中 + OrderMaster orderMaster = orderMasterService.selectById(orderDetail.getOrderMasterId()); + if(orderMaster.getOrderStatus() == OrderStatus.FINISH_CHECK.code()){ + orderMaster.setOrderStatus(OrderStatus.SERVER.code()); + orderMasterService.updateOrderMaster(orderMaster); + } + } + } + afterServiceRecordMapper.updateAfterServiceRecord(param); + } + return AjaxResult.success(); + } + private int agreeRefund(AfterServiceRecord afterServiceRecord) throws BaseAdaPayException { OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId()); Assert.notNull(orderDetail, "子单不存在!"); @@ -744,6 +871,30 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService } } + /** + * 根据订单类型设置售后大类 + * @param afterServiceRecord 售后记录 + */ + private void setAfterServiceCategory(AfterServiceRecord afterServiceRecord) { + try { + OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId()); + if (orderDetail != null && orderDetail.getOrderType() != null) { + // 根据订单类型设置售后大类 + if (orderDetail.getOrderType() == 0) { + // 服务订单 + afterServiceRecord.setAfterServiceCategory(1); + } else if (orderDetail.getOrderType() == 1) { + // 商品订单 + afterServiceRecord.setAfterServiceCategory(2); + } + log.info("根据订单类型设置售后大类,子单ID:{},订单类型:{},售后大类:{}", + orderDetail.getId(), orderDetail.getOrderType(), afterServiceRecord.getAfterServiceCategory()); + } + } catch (Exception e) { + log.error("设置售后大类失败,子单ID:{}", afterServiceRecord.getOrderDetailId(), e); + } + } + /** * 计算确认中倒计时的剩余时间 * @param orderDetail 子单信息 diff --git a/ghy-order/src/main/resources/mapper/order/AfterServiceRecordMapper.xml b/ghy-order/src/main/resources/mapper/order/AfterServiceRecordMapper.xml index b5c54a33..f464fd54 100644 --- a/ghy-order/src/main/resources/mapper/order/AfterServiceRecordMapper.xml +++ b/ghy-order/src/main/resources/mapper/order/AfterServiceRecordMapper.xml @@ -28,6 +28,7 @@ + @@ -48,7 +49,7 @@ select id, customer_reason_type, customer_reason, order_detail_id, oper_type, worker_feedback_result, worker_feedback_reason_type, worker_feedback_reason, refund, agreed_refund, original_refund, customer_final_check, create_by, create_time, update_by, update_time, remark, refund_apply_time, customer_agree_redo, - redo_complete_time, redo_complete_remark, redo_complete_images, is_auto_processed, after_service_type, return_status, + redo_complete_time, redo_complete_remark, redo_complete_images, is_auto_processed, after_service_category, after_service_type, return_status, return_address, return_contact, return_phone, return_type, return_remark, return_images, return_tracking_number, return_ship_time, merchant_receive_time, worker_resend_plan, customer_disagree_images, customer_disagree_reason from after_service_record @@ -100,8 +101,9 @@ redo_complete_time, redo_complete_remark, redo_complete_images, - is_auto_processed, - after_service_type, + is_auto_processed, + after_service_category, + after_service_type, return_status, return_address, return_contact, @@ -135,8 +137,9 @@ #{redoCompleteTime}, #{redoCompleteRemark}, #{redoCompleteImages}, - #{isAutoProcessed}, - #{afterServiceType}, + #{isAutoProcessed}, + #{afterServiceCategory}, + #{afterServiceType}, #{returnStatus}, #{returnAddress}, #{returnContact}, @@ -176,8 +179,9 @@ redo_complete_time = #{redoCompleteTime}, redo_complete_remark = #{redoCompleteRemark}, redo_complete_images = #{redoCompleteImages}, - is_auto_processed = #{isAutoProcessed}, - after_service_type = #{afterServiceType}, + is_auto_processed = #{isAutoProcessed}, + after_service_category = #{afterServiceCategory}, + after_service_type = #{afterServiceType}, return_status = #{returnStatus}, return_address = #{returnAddress}, return_contact = #{returnContact},