师傅立即重发补发方案 以及定时处理

This commit is contained in:
cb 2025-09-04 17:42:21 +08:00
parent 3eb0bd846f
commit 6532c9d460
5 changed files with 149 additions and 2 deletions

View File

@ -141,6 +141,18 @@ public class AfterServiceRecord extends BaseEntity
@Excel(name = "师傅重发/补发方案")
private Integer workerResendPlan;
/** 师傅重发/补发时间 */
@Excel(name = "师傅重发/补发时间", cellType = Excel.ColumnType.STRING)
private Date workerResendTime;
/** 师傅重发/补发方式1-快递/物流2-送货上门3-自提 */
@Excel(name = "师傅重发/补发方式1-快递/物流2-送货上门3-自提")
private Integer workerResendType;
/** 师傅重发/补发物流单号(快递/物流时必填) */
@Excel(name = "师傅重发/补发物流单号")
private String workerResendTrackingNumber;
/** 客户不同意图片 */
@Excel(name = "客户不同意图片")
private String customerDisagreeImages;

View File

@ -136,4 +136,42 @@ public class AfterServiceTimeoutTask {
log.info("客户确认超时处理完成,共处理{}条记录", timeoutRecords.size());
}
/**
* 师傅重发补发超时处理
* 快递/物流6天倒计时
* 非快递24小时倒计时
* 超时后自动按客户同意处理
*/
@Scheduled(fixedRate = 5 * 60 * 1000) // 5分钟执行一次
public void handleWorkerResendTimeout() {
log.info("开始处理师傅重发补发超时...");
// 查询需要处理的师傅重发补发超时记录
List<AfterServiceRecord> timeoutRecords = afterServiceRecordService.selectWorkerResendTimeoutRecords();
for (AfterServiceRecord record : timeoutRecords) {
try {
log.info("处理师傅重发补发超时售后记录:{}", record.getId());
// 自动设置为客户同意
record.setCustomerFinalCheck(1L);
record.setIsAutoProcessed(1);
record.setRefundApplyTime(new Date());
// 更新记录
afterServiceRecordService.updateAfterServiceRecord(record);
// 恢复确认中倒计时
afterServiceRecordService.resumeConfirmTimeout(record.getOrderDetailId());
log.info("师傅重发补发超时自动同意售后记录ID{},重发方式:{}",
record.getId(), record.getWorkerResendType());
} catch (Exception e) {
log.error("处理师傅重发补发超时异常售后记录ID{}", record.getId(), e);
}
}
log.info("师傅重发补发超时处理完成,共处理{}条记录", timeoutRecords.size());
}
}

View File

@ -120,4 +120,12 @@ public interface IAfterServiceRecordService {
AjaxResult returnGoods(AfterServiceRecord afterServiceRecord);
AfterServiceRecord unfinished(Long id);
/**
* 查询师傅重发补发超时的售后记录
* 快递/物流6天倒计时
* 非快递24小时倒计时
* @return 超时的售后记录列表
*/
List<AfterServiceRecord> selectWorkerResendTimeoutRecords();
}

View File

@ -380,6 +380,30 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
return AjaxResult.success("重做/补做完成状态已更新");
}
// 新增处理师傅重发/补发方案
if (param.getWorkerResendPlan() != null) {
// 验证快递/物流方式必须提供单号
if (param.getWorkerResendType() != null && param.getWorkerResendType() == 1) {
if (param.getWorkerResendTrackingNumber() == null || param.getWorkerResendTrackingNumber().trim().isEmpty()) {
return AjaxResult.error("快递/物流方式必须提供物流单号");
}
}
afterServiceRecord.setWorkerResendPlan(param.getWorkerResendPlan());
afterServiceRecord.setWorkerResendTime(new Date());
afterServiceRecord.setWorkerResendType(param.getWorkerResendType()); // 1-快递/物流2-送货上门3-自提
afterServiceRecord.setWorkerResendTrackingNumber(param.getWorkerResendTrackingNumber()); // 物流单号
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
// 发送重发补发通知给客户
// sendWorkerResendNotification(orderDetail, afterServiceRecord);
log.info("商品售后-师傅重发/补发方案已提交记录ID{},方案:{},方式:{},单号:{}",
param.getId(), param.getWorkerResendPlan(), param.getWorkerResendType(), param.getWorkerResendTrackingNumber());
return AjaxResult.success("重发/补发方案已提交,等待客户确认");
}
if (param.getCustomerFinalCheck()!=null ) {
// 检查是否已经被自动处理过防止重复退款
if (afterServiceRecord.getIsAutoProcessed() != null && afterServiceRecord.getIsAutoProcessed() == 1) {
@ -387,10 +411,15 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
return AjaxResult.error("该售后记录已被系统自动处理,无法重复操作");
}
// 商品售后的处理逻辑简化版主要处理客户同意/不同意
// 商品售后的处理逻辑
if (one.equals(param.getCustomerFinalCheck())) {
afterServiceRecord.setCustomerFinalCheck(1L);
log.info("商品售后-客户同意处理方案");
// 注意客户同意重发补发方案后不立即结束售后流程
// 而是等待倒计时结束由定时器自动处理
// 这样可以给师傅时间完成重发补发操作
} else {
afterServiceRecord.setCustomerFinalCheck(0L);
// 客户不同意时保存不同意图片和理由
@ -915,4 +944,37 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
return Math.max(0, elapsedTime); // 确保不为负数
}
/**
* 发送师傅重发补发通知给客户
* @param orderDetail 订单详情
* @param afterServiceRecord 售后记录
*/
private void sendWorkerResendNotification(OrderDetail orderDetail, AfterServiceRecord afterServiceRecord) {
try {
// 这里可以发送微信通知短信通知等给客户
// 通知客户师傅已提交重发补发方案需要客户确认
log.info("发送师傅重发补发通知给客户子单ID{},方案:{},方式:{}",
orderDetail.getId(), afterServiceRecord.getWorkerResendPlan(), afterServiceRecord.getWorkerResendType());
// TODO: 实现具体的通知逻辑比如微信模板消息短信等
// 可以根据workerResendType判断倒计时时间
// 1-快递/物流6天倒计时
// 2-送货上门3-自提24小时倒计时
} catch (Exception e) {
log.error("发送师傅重发补发通知失败子单ID{}", orderDetail.getId(), e);
}
}
/**
* 查询师傅重发补发超时的售后记录
* 快递/物流6天倒计时
* 非快递24小时倒计时
* @return 超时的售后记录列表
*/
@Override
public List<AfterServiceRecord> selectWorkerResendTimeoutRecords() {
return afterServiceRecordMapper.selectWorkerResendTimeoutRecords();
}
}

View File

@ -41,6 +41,9 @@
<result property="returnShipTime" column="return_ship_time" />
<result property="merchantReceiveTime" column="merchant_receive_time" />
<result property="workerResendPlan" column="worker_resend_plan" />
<result property="workerResendTime" column="worker_resend_time" />
<result property="workerResendType" column="worker_resend_type" />
<result property="workerResendTrackingNumber" column="worker_resend_tracking_number" />
<result property="customerDisagreeImages" column="customer_disagree_images" />
<result property="customerDisagreeReason" column="customer_disagree_reason" />
</resultMap>
@ -50,7 +53,7 @@
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_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, worker_resend_time, worker_resend_type, worker_resend_tracking_number,
customer_disagree_images, customer_disagree_reason
from after_service_record
</sql>
@ -115,6 +118,9 @@
<if test="returnShipTime != null">return_ship_time,</if>
<if test="merchantReceiveTime != null">merchant_receive_time,</if>
<if test="workerResendPlan != null">worker_resend_plan,</if>
<if test="workerResendTime != null">worker_resend_time,</if>
<if test="workerResendType != null">worker_resend_type,</if>
<if test="workerResendTrackingNumber != null">worker_resend_tracking_number,</if>
<if test="customerDisagreeImages != null">customer_disagree_images,</if>
<if test="customerDisagreeReason != null">customer_disagree_reason,</if>
<if test="createBy != null">create_by,</if>
@ -151,6 +157,9 @@
<if test="returnShipTime != null">#{returnShipTime},</if>
<if test="merchantReceiveTime != null">#{merchantReceiveTime},</if>
<if test="workerResendPlan != null">#{workerResendPlan},</if>
<if test="workerResendTime != null">#{workerResendTime},</if>
<if test="workerResendType != null">#{workerResendType},</if>
<if test="workerResendTrackingNumber != null">#{workerResendTrackingNumber},</if>
<if test="customerDisagreeImages != null">#{customerDisagreeImages},</if>
<if test="customerDisagreeReason != null">#{customerDisagreeReason},</if>
<if test="createBy != null">#{createBy},</if>
@ -193,6 +202,9 @@
<if test="returnShipTime != null">return_ship_time = #{returnShipTime},</if>
<if test="merchantReceiveTime != null">merchant_receive_time = #{merchantReceiveTime},</if>
<if test="workerResendPlan != null">worker_resend_plan = #{workerResendPlan},</if>
<if test="workerResendTime != null">worker_resend_time = #{workerResendTime},</if>
<if test="workerResendType != null">worker_resend_type = #{workerResendType},</if>
<if test="workerResendTrackingNumber != null">worker_resend_tracking_number = #{workerResendTrackingNumber},</if>
<if test="customerDisagreeImages != null">customer_disagree_images = #{customerDisagreeImages},</if>
<if test="customerDisagreeReason != null">customer_disagree_reason = #{customerDisagreeReason},</if>
<if test="createBy != null">create_by = #{createBy},</if>
@ -246,4 +258,19 @@
)
</select>
<select id="selectWorkerResendTimeoutRecords" resultMap="AfterServiceRecordResult">
<include refid="selectAfterServiceRecordVo"/>
WHERE worker_resend_plan IS NOT NULL
AND worker_resend_time IS NOT NULL
AND customer_final_check IS NULL
AND (is_auto_processed IS NULL OR is_auto_processed = 0)
AND (
-- 快递/物流6天倒计时
(worker_resend_type = 1 AND worker_resend_time &lt;= DATE_SUB(NOW(), INTERVAL 6 DAY))
OR
-- 非快递24小时倒计时
(worker_resend_type IN (2, 3) AND worker_resend_time &lt;= DATE_SUB(NOW(), INTERVAL 24 HOUR))
)
</select>
</mapper>