增加定时处理
This commit is contained in:
parent
08e5353b4e
commit
9090b61095
|
|
@ -85,6 +85,10 @@ public class AfterServiceRecord extends BaseEntity
|
|||
@Excel(name = "重做/补做完成图片")
|
||||
private String redoCompleteImages;
|
||||
|
||||
/** 是否自动处理:0-否,1-是(用于防止重复处理) */
|
||||
@Excel(name = "是否自动处理:0-否,1-是")
|
||||
private Integer isAutoProcessed;
|
||||
|
||||
private boolean excludeAfterServiceFinished;
|
||||
|
||||
private List<AfterServiceImgs> imgsList;
|
||||
|
|
|
|||
|
|
@ -65,4 +65,21 @@ public interface AfterServiceRecordMapper {
|
|||
* @return 未完成的售后记录
|
||||
*/
|
||||
AfterServiceRecord unfinished(Long orderDetailId);
|
||||
|
||||
/**
|
||||
* 查询师傅反馈超时的售后记录
|
||||
* 倒计时1:客户发起后,师傅24小时不操作任何反馈
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
List<AfterServiceRecord> selectWorkerFeedbackTimeoutRecords();
|
||||
|
||||
/**
|
||||
* 查询客户确认超时的售后记录
|
||||
* 倒计时2:师傅重做完成后客户36小时不操作
|
||||
* 倒计时3:师傅拒绝后客户36小时不操作
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
List<AfterServiceRecord> selectCustomerConfirmTimeoutRecords();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
package com.ghy.order.quartz;
|
||||
|
||||
import com.ghy.common.utils.DateUtils;
|
||||
import com.ghy.order.domain.AfterServiceRecord;
|
||||
import com.ghy.order.service.IAfterServiceRecordService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Date: 2024-12-19
|
||||
* @Author: 系统
|
||||
* @Version: v1.0
|
||||
* @Description: 售后倒计时定时任务
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class AfterServiceTimeoutTask {
|
||||
|
||||
private final IAfterServiceRecordService afterServiceRecordService;
|
||||
|
||||
/**
|
||||
* 售后倒计时定时任务 - 每5分钟执行一次
|
||||
* 处理3种倒计时场景:
|
||||
* 1. 师傅24小时不操作自动同意完单
|
||||
* 2. 师傅重做完成后客户36小时不操作自动同意完单
|
||||
* 3. 师傅拒绝后客户36小时不操作自动取消售后
|
||||
*/
|
||||
@Scheduled(cron = "0 0/5 * * * ?")
|
||||
public void afterServiceTimeoutProcess() {
|
||||
log.info("{}开始售后倒计时定时任务", DateUtils.timeFormat(new Date()));
|
||||
|
||||
try {
|
||||
// 处理师傅24小时不操作的情况
|
||||
processWorkerFeedbackTimeout();
|
||||
|
||||
// 处理客户36小时不操作的情况
|
||||
processCustomerConfirmTimeout();
|
||||
|
||||
log.info("{}售后倒计时定时任务执行完成", DateUtils.timeFormat(new Date()));
|
||||
} catch (Exception e) {
|
||||
log.error("售后倒计时定时任务执行异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理师傅24小时不操作的情况
|
||||
* 倒计时1:客户发起后,师傅24小时不操作任何反馈,直接按同意完单
|
||||
*/
|
||||
private void processWorkerFeedbackTimeout() {
|
||||
log.info("开始处理师傅反馈超时情况");
|
||||
|
||||
// 查询需要处理的售后记录
|
||||
List<AfterServiceRecord> timeoutRecords = afterServiceRecordService.selectWorkerFeedbackTimeoutRecords();
|
||||
|
||||
for (AfterServiceRecord record : timeoutRecords) {
|
||||
try {
|
||||
log.info("处理师傅反馈超时售后记录:{}", record.getId());
|
||||
|
||||
// 师傅24小时不操作,直接设置为师傅同意并客户同意,完成售后
|
||||
record.setWorkerFeedbackResult(1L);
|
||||
record.setCustomerFinalCheck(1L);
|
||||
record.setRefundApplyTime(new Date());
|
||||
record.setIsAutoProcessed(1); // 自动处理
|
||||
|
||||
// 更新记录
|
||||
afterServiceRecordService.updateAfterServiceRecord(record);
|
||||
|
||||
// 师傅24小时不操作,需要执行退款逻辑
|
||||
try {
|
||||
afterServiceRecordService.executeRefundLogic(record);
|
||||
log.info("师傅24小时不操作,自动执行退款逻辑完成,售后记录ID:{}", record.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("师傅24小时不操作,自动执行退款逻辑异常,售后记录ID:{}", record.getId(), e);
|
||||
}
|
||||
|
||||
log.info("师傅反馈超时自动处理完成,售后记录ID:{}", record.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("处理师傅反馈超时异常,售后记录ID:{}", record.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("师傅反馈超时处理完成,共处理{}条记录", timeoutRecords.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理客户36小时不操作的情况
|
||||
* 倒计时2:师傅重做完成后客户36小时不操作自动同意完单
|
||||
* 倒计时3:师傅拒绝后客户36小时不操作自动取消售后
|
||||
*/
|
||||
private void processCustomerConfirmTimeout() {
|
||||
log.info("开始处理客户确认超时情况");
|
||||
|
||||
// 查询需要处理的售后记录
|
||||
List<AfterServiceRecord> timeoutRecords = afterServiceRecordService.selectCustomerConfirmTimeoutRecords();
|
||||
|
||||
for (AfterServiceRecord record : timeoutRecords) {
|
||||
try {
|
||||
log.info("处理客户确认超时售后记录:{}", record.getId());
|
||||
|
||||
// 根据师傅反馈结果决定处理方式
|
||||
if (record.getWorkerFeedbackResult() != null && record.getWorkerFeedbackResult().equals(3L)) {
|
||||
// 倒计时2:师傅重做完成后客户36小时不操作自动同意完单
|
||||
record.setCustomerFinalCheck(1L);
|
||||
// 师傅重做完成,客户同意,订单完成,不需要退款,不设置refundApplyTime
|
||||
record.setIsAutoProcessed(1); // 自动处理
|
||||
|
||||
log.info("师傅重做完成后客户超时自动同意,订单完成,售后记录ID:{}", record.getId());
|
||||
} else if (record.getWorkerFeedbackResult() != null &&
|
||||
(record.getWorkerFeedbackResult().equals(0L) || record.getWorkerFeedbackResult().equals(1L))) {
|
||||
// 倒计时3:师傅拒绝或同意后客户36小时不操作自动取消售后
|
||||
record.setCustomerFinalCheck(NULL);
|
||||
// 售后单取消完成,不需要退款,不设置refundApplyTime
|
||||
record.setIsAutoProcessed(1); // 自动处理
|
||||
|
||||
log.info("师傅拒绝/同意后客户超时自动取消,售后单取消完成,售后记录ID:{}", record.getId());
|
||||
}
|
||||
|
||||
// 更新记录
|
||||
afterServiceRecordService.updateAfterServiceRecord(record);
|
||||
|
||||
log.info("客户确认超时自动处理完成,售后记录ID:{}", record.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("处理客户确认超时异常,售后记录ID:{}", record.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("客户确认超时处理完成,共处理{}条记录", timeoutRecords.size());
|
||||
}
|
||||
}
|
||||
|
|
@ -61,4 +61,29 @@ public interface IAfterServiceRecordService {
|
|||
* @return 结果
|
||||
*/
|
||||
int deleteAfterServiceRecordById(String id);
|
||||
|
||||
/**
|
||||
* 查询师傅反馈超时的售后记录
|
||||
* 倒计时1:客户发起后,师傅24小时不操作任何反馈
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
List<AfterServiceRecord> selectWorkerFeedbackTimeoutRecords();
|
||||
|
||||
/**
|
||||
* 查询客户确认超时的售后记录
|
||||
* 倒计时2:师傅重做完成后客户36小时不操作
|
||||
* 倒计时3:师傅拒绝后客户36小时不操作
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
List<AfterServiceRecord> selectCustomerConfirmTimeoutRecords();
|
||||
|
||||
/**
|
||||
* 执行退款逻辑
|
||||
* 用于定时器自动处理退款
|
||||
*
|
||||
* @param afterServiceRecord 售后记录
|
||||
*/
|
||||
void executeRefundLogic(AfterServiceRecord afterServiceRecord);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,8 +209,41 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
|
|||
}
|
||||
|
||||
if (param.getCustomerFinalCheck()!=null ) {
|
||||
// 师傅同意 且 客户同意退款
|
||||
//afterServiceRecord.setCustomerFinalCheck(1L);
|
||||
// 检查师傅是否已经重做完成
|
||||
if (afterServiceRecord.getWorkerFeedbackResult() != null && afterServiceRecord.getWorkerFeedbackResult().equals(3L)) {
|
||||
// 师傅已重做完成
|
||||
if (one.equals(param.getCustomerFinalCheck())) {
|
||||
// 客户同意重做结果,订单完成结束,不执行退款
|
||||
afterServiceRecord.setCustomerFinalCheck(1L);
|
||||
afterServiceRecord.setRefundApplyTime(new Date());
|
||||
log.info("师傅重做完成后,客户同意重做结果,订单完成结束,不执行退款");
|
||||
|
||||
// // 售后客户回复通知
|
||||
// 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.getMessage(), e);
|
||||
// }
|
||||
|
||||
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
|
||||
return AjaxResult.success("订单完成结束");
|
||||
} else {
|
||||
// 客户不同意重做结果,按之前的逻辑走(可能需要退款)
|
||||
log.info("师傅重做完成后,客户不同意重做结果,按原逻辑处理");
|
||||
// 继续执行下面的退款逻辑
|
||||
}
|
||||
}
|
||||
|
||||
// 师傅未重做完成,按原逻辑处理退款
|
||||
if (one.equals(param.getCustomerFinalCheck())) {
|
||||
afterServiceRecord.setCustomerFinalCheck(1L);
|
||||
}else{
|
||||
|
|
@ -242,7 +275,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
|
|||
log.warn("子单[{}]已发起分账,不能退款", afterServiceRecord.getOrderDetailId());
|
||||
afterServiceRecord.setOriginalRefund(BigDecimal.ZERO);
|
||||
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
|
||||
return AjaxResult.error("本单已划款,师傅/服务人员已到帐或即将到帐,双方达成退款的,请对方线下支付后点“对方已退款”");
|
||||
return AjaxResult.error("本单已划款,师傅/服务人员已到帐或即将到帐,双方达成退款的,请对方线下支付后点对方已退款");
|
||||
} else {
|
||||
agreeRefund(afterServiceRecord);
|
||||
}
|
||||
|
|
@ -401,4 +434,54 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
|
|||
return afterServiceRecordMapper.deleteAfterServiceRecordById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询师傅反馈超时的售后记录
|
||||
* 倒计时1:客户发起后,师傅24小时不操作任何反馈
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<AfterServiceRecord> selectWorkerFeedbackTimeoutRecords() {
|
||||
return afterServiceRecordMapper.selectWorkerFeedbackTimeoutRecords();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询客户确认超时的售后记录
|
||||
* 倒计时2:师傅重做完成后客户36小时不操作
|
||||
* 倒计时3:师傅拒绝后客户36小时不操作
|
||||
*
|
||||
* @return 超时的售后记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<AfterServiceRecord> selectCustomerConfirmTimeoutRecords() {
|
||||
return afterServiceRecordMapper.selectCustomerConfirmTimeoutRecords();
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行退款逻辑
|
||||
* 用于定时器自动处理退款
|
||||
*
|
||||
* @param afterServiceRecord 售后记录
|
||||
*/
|
||||
@Override
|
||||
public void executeRefundLogic(AfterServiceRecord afterServiceRecord) {
|
||||
try {
|
||||
// 检查是否已分账,如果已分账则不能退款
|
||||
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
|
||||
if (orderDetail != null && orderDetail.getDrawCashTime() != null) {
|
||||
log.warn("子单[{}]已发起分账,不能自动退款", afterServiceRecord.getOrderDetailId());
|
||||
afterServiceRecord.setOriginalRefund(BigDecimal.ZERO);
|
||||
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行退款逻辑
|
||||
agreeRefund(afterServiceRecord);
|
||||
log.info("定时器自动执行退款逻辑完成,售后记录ID:{}", afterServiceRecord.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("定时器自动执行退款逻辑异常,售后记录ID:{}", afterServiceRecord.getId(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@
|
|||
<result property="redoCompleteTime" column="redo_complete_time" />
|
||||
<result property="redoCompleteRemark" column="redo_complete_remark" />
|
||||
<result property="redoCompleteImages" column="redo_complete_images" />
|
||||
<result property="isAutoProcessed" column="is_auto_processed" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAfterServiceRecordVo">
|
||||
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
|
||||
redo_complete_time, redo_complete_remark, redo_complete_images, is_auto_processed
|
||||
from after_service_record
|
||||
</sql>
|
||||
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
<if test="redoCompleteTime != null">redo_complete_time,</if>
|
||||
<if test="redoCompleteRemark != null">redo_complete_remark,</if>
|
||||
<if test="redoCompleteImages != null">redo_complete_images,</if>
|
||||
<if test="isAutoProcessed != null">is_auto_processed,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
|
|
@ -103,6 +105,7 @@
|
|||
<if test="redoCompleteTime != null">#{redoCompleteTime},</if>
|
||||
<if test="redoCompleteRemark != null">#{redoCompleteRemark},</if>
|
||||
<if test="redoCompleteImages != null">#{redoCompleteImages},</if>
|
||||
<if test="isAutoProcessed != null">#{isAutoProcessed},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
|
|
@ -129,6 +132,7 @@
|
|||
<if test="redoCompleteTime != null">redo_complete_time = #{redoCompleteTime},</if>
|
||||
<if test="redoCompleteRemark != null">redo_complete_remark = #{redoCompleteRemark},</if>
|
||||
<if test="redoCompleteImages != null">redo_complete_images = #{redoCompleteImages},</if>
|
||||
<if test="isAutoProcessed != null">is_auto_processed = #{isAutoProcessed},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
|
|
@ -149,4 +153,35 @@
|
|||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 查询师傅反馈超时的售后记录 -->
|
||||
<!-- 倒计时1:客户发起后,师傅24小时不操作任何反馈 -->
|
||||
<select id="selectWorkerFeedbackTimeoutRecords" resultMap="AfterServiceRecordResult">
|
||||
<include refid="selectAfterServiceRecordVo"/>
|
||||
WHERE worker_feedback_result IS NULL
|
||||
AND customer_final_check IS NULL
|
||||
AND (is_auto_processed IS NULL OR is_auto_processed = 0)
|
||||
AND create_time <= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||||
AND create_time > DATE_SUB(NOW(), INTERVAL 24*60+5 MINUTE)
|
||||
</select>
|
||||
|
||||
<!-- 查询客户确认超时的售后记录 -->
|
||||
<!-- 倒计时2:师傅重做完成后客户36小时不操作 -->
|
||||
<!-- 倒计时3:师傅拒绝后客户36小时不操作 -->
|
||||
<select id="selectCustomerConfirmTimeoutRecords" resultMap="AfterServiceRecordResult">
|
||||
<include refid="selectAfterServiceRecordVo"/>
|
||||
WHERE customer_final_check IS NULL
|
||||
AND (is_auto_processed IS NULL OR is_auto_processed = 0)
|
||||
AND (
|
||||
-- 倒计时2:师傅重做完成后客户36小时不操作
|
||||
(worker_feedback_result = 3
|
||||
AND redo_complete_time <= DATE_SUB(NOW(), INTERVAL 36 HOUR)
|
||||
AND redo_complete_time > DATE_SUB(NOW(), INTERVAL 36*60+5 MINUTE))
|
||||
OR
|
||||
-- 倒计时3:师傅拒绝或同意后客户36小时不操作
|
||||
(worker_feedback_result IN (0, 1)
|
||||
AND update_time <= DATE_SUB(NOW(), INTERVAL 36 HOUR)
|
||||
AND update_time > DATE_SUB(NOW(), INTERVAL 36*60+5 MINUTE))
|
||||
)
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue