增加商品售后大类

This commit is contained in:
cb 2025-09-04 17:12:02 +08:00
parent 7a2f71624b
commit 7d2b4f7fdb
5 changed files with 189 additions and 7 deletions

View File

@ -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());
}
}
/** /**
* 删除售后记录 * 删除售后记录
*/ */

View File

@ -89,6 +89,10 @@ public class AfterServiceRecord extends BaseEntity
@Excel(name = "是否自动处理0-否1-是") @Excel(name = "是否自动处理0-否1-是")
private Integer isAutoProcessed; private Integer isAutoProcessed;
/** 售后大类1-商品售后2-服务售后 */
@Excel(name = "售后大类1-服务售后2-商品售后")
private Integer afterServiceCategory;
/** 售后类型1-未收到货退单退款2-未收到货退款3-已收到货退款退货 */ /** 售后类型1-未收到货退单退款2-未收到货退款3-已收到货退款退货 */
@Excel(name = "售后类型1-未收到货退单退款2-未收到货退款3-已收到货退款退货") @Excel(name = "售后类型1-未收到货退单退款2-未收到货退款3-已收到货退款退货")
private Integer afterServiceType; private Integer afterServiceType;

View File

@ -93,6 +93,14 @@ public interface IAfterServiceRecordService {
*/ */
void resumeConfirmTimeout(Long orderDetailId); void resumeConfirmTimeout(Long orderDetailId);
/**
* 修改商品售后记录
*
* @param afterServiceRecord 售后记录
* @return 结果
*/
AjaxResult updateGoodsAfterServiceRecord(AfterServiceRecord afterServiceRecord) throws BaseAdaPayException;
/** /**
* 师傅重发/补发操作 * 师傅重发/补发操作
* 师傅端点击重发补发按钮保存重发/补发方案 * 师傅端点击重发补发按钮保存重发/补发方案

View File

@ -120,6 +120,9 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
log.warn("订单[{}]存在未完成的售后记录", afterServiceRecord.getOrderDetailId()); log.warn("订单[{}]存在未完成的售后记录", afterServiceRecord.getOrderDetailId());
throw new BaseException("存在未完成的售后记录,请勿重复申请!"); throw new BaseException("存在未完成的售后记录,请勿重复申请!");
} }
// 根据订单类型自动设置售后大类
setAfterServiceCategory(afterServiceRecord);
int result = afterServiceRecordMapper.insertAfterServiceRecord(afterServiceRecord); int result = afterServiceRecordMapper.insertAfterServiceRecord(afterServiceRecord);
// 暂停确认中倒计时 // 暂停确认中倒计时
@ -334,6 +337,130 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
return AjaxResult.success(); 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<String, Object> 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 { private int agreeRefund(AfterServiceRecord afterServiceRecord) throws BaseAdaPayException {
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId()); OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
Assert.notNull(orderDetail, "子单不存在!"); 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 子单信息 * @param orderDetail 子单信息

View File

@ -28,6 +28,7 @@
<result property="redoCompleteRemark" column="redo_complete_remark" /> <result property="redoCompleteRemark" column="redo_complete_remark" />
<result property="redoCompleteImages" column="redo_complete_images" /> <result property="redoCompleteImages" column="redo_complete_images" />
<result property="isAutoProcessed" column="is_auto_processed" /> <result property="isAutoProcessed" column="is_auto_processed" />
<result property="afterServiceCategory" column="after_service_category" />
<result property="afterServiceType" column="after_service_type" /> <result property="afterServiceType" column="after_service_type" />
<result property="returnStatus" column="return_status" /> <result property="returnStatus" column="return_status" />
<result property="returnAddress" column="return_address" /> <result property="returnAddress" column="return_address" />
@ -48,7 +49,7 @@
select id, customer_reason_type, customer_reason, order_detail_id, oper_type, worker_feedback_result, 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, 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, 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, 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 customer_disagree_images, customer_disagree_reason
from after_service_record from after_service_record
@ -101,6 +102,7 @@
<if test="redoCompleteRemark != null">redo_complete_remark,</if> <if test="redoCompleteRemark != null">redo_complete_remark,</if>
<if test="redoCompleteImages != null">redo_complete_images,</if> <if test="redoCompleteImages != null">redo_complete_images,</if>
<if test="isAutoProcessed != null">is_auto_processed,</if> <if test="isAutoProcessed != null">is_auto_processed,</if>
<if test="afterServiceCategory != null">after_service_category,</if>
<if test="afterServiceType != null">after_service_type,</if> <if test="afterServiceType != null">after_service_type,</if>
<if test="returnStatus != null">return_status,</if> <if test="returnStatus != null">return_status,</if>
<if test="returnAddress != null">return_address,</if> <if test="returnAddress != null">return_address,</if>
@ -136,6 +138,7 @@
<if test="redoCompleteRemark != null">#{redoCompleteRemark},</if> <if test="redoCompleteRemark != null">#{redoCompleteRemark},</if>
<if test="redoCompleteImages != null">#{redoCompleteImages},</if> <if test="redoCompleteImages != null">#{redoCompleteImages},</if>
<if test="isAutoProcessed != null">#{isAutoProcessed},</if> <if test="isAutoProcessed != null">#{isAutoProcessed},</if>
<if test="afterServiceCategory != null">#{afterServiceCategory},</if>
<if test="afterServiceType != null">#{afterServiceType},</if> <if test="afterServiceType != null">#{afterServiceType},</if>
<if test="returnStatus != null">#{returnStatus},</if> <if test="returnStatus != null">#{returnStatus},</if>
<if test="returnAddress != null">#{returnAddress},</if> <if test="returnAddress != null">#{returnAddress},</if>
@ -177,6 +180,7 @@
<if test="redoCompleteRemark != null">redo_complete_remark = #{redoCompleteRemark},</if> <if test="redoCompleteRemark != null">redo_complete_remark = #{redoCompleteRemark},</if>
<if test="redoCompleteImages != null">redo_complete_images = #{redoCompleteImages},</if> <if test="redoCompleteImages != null">redo_complete_images = #{redoCompleteImages},</if>
<if test="isAutoProcessed != null">is_auto_processed = #{isAutoProcessed},</if> <if test="isAutoProcessed != null">is_auto_processed = #{isAutoProcessed},</if>
<if test="afterServiceCategory != null">after_service_category = #{afterServiceCategory},</if>
<if test="afterServiceType != null">after_service_type = #{afterServiceType},</if> <if test="afterServiceType != null">after_service_type = #{afterServiceType},</if>
<if test="returnStatus != null">return_status = #{returnStatus},</if> <if test="returnStatus != null">return_status = #{returnStatus},</if>
<if test="returnAddress != null">return_address = #{returnAddress},</if> <if test="returnAddress != null">return_address = #{returnAddress},</if>