完善后台售后纠纷处理吗,完善数量以及数据获取,

This commit is contained in:
cb 2025-10-24 15:15:32 +08:00
parent bc96277f86
commit cb78526d0e
12 changed files with 274 additions and 86 deletions

View File

@ -30,6 +30,11 @@ public class AfterServiceDisputeRequest {
*/ */
private BigDecimal refundAmount; private BigDecimal refundAmount;
/**
* 售后纠纷平台处理原因
*/
private String platformHandleReason;
public String getRecordId() { public String getRecordId() {
return recordId; return recordId;
} }
@ -62,6 +67,14 @@ public class AfterServiceDisputeRequest {
this.refundAmount = refundAmount; this.refundAmount = refundAmount;
} }
public String getPlatformHandleReason() {
return platformHandleReason;
}
public void setPlatformHandleReason(String platformHandleReason) {
this.platformHandleReason = platformHandleReason;
}
@Override @Override
public String toString() { public String toString() {
return "AfterServiceDisputeRequest{" + return "AfterServiceDisputeRequest{" +
@ -69,6 +82,7 @@ public class AfterServiceDisputeRequest {
", orderMasterId=" + orderMasterId + ", orderMasterId=" + orderMasterId +
", orderDetailId=" + orderDetailId + ", orderDetailId=" + orderDetailId +
", refundAmount=" + refundAmount + ", refundAmount=" + refundAmount +
", platformHandleReason='" + platformHandleReason + '\'' +
'}'; '}';
} }
} }

View File

@ -1656,7 +1656,13 @@ public class OrderController extends BaseController {
}); });
// 设置是否显示售后记录字段 // 设置是否显示售后记录字段
if (!mewAfterServiceRecords.isEmpty()) { if (!mewAfterServiceRecords.isEmpty()) {
hasMatchingAfterService = true; // 检查售后记录状态如果存在afterServiceStatus不为1的记录则显示售后记录按钮
for (AfterServiceRecord record : mewAfterServiceRecords) {
if (record.getAfterServiceStatus() != 1) {
hasMatchingAfterService = true;
break;
}
}
} }
for (OrderGoods orderGoods : orderStandardList) { for (OrderGoods orderGoods : orderStandardList) {
@ -1852,7 +1858,19 @@ public class OrderController extends BaseController {
} }
orderListResponse.setShowAfterServiceRecord( 1); // 检查售后记录状态决定是否显示售后记录按钮
List<AfterServiceRecord> currentDetailRecords = detailRecordMap.get(detail.getId());
int showAfterServiceRecord = 0;
if (currentDetailRecords != null && !currentDetailRecords.isEmpty()) {
// 遍历售后记录如果存在afterServiceStatus不为1的记录则显示售后记录按钮
for (AfterServiceRecord record : currentDetailRecords) {
if (record.getAfterServiceStatus() != 1) {
showAfterServiceRecord = 1;
break;
}
}
}
orderListResponse.setShowAfterServiceRecord(showAfterServiceRecord);
// 编辑返回属性 // 编辑返回属性
orderListResponse.setGoodsBrand(orderMaster.getGoodsBrand()); orderListResponse.setGoodsBrand(orderMaster.getGoodsBrand());
orderListResponse.setGoodsSpecification(orderMaster.getGoodsSpecification()); orderListResponse.setGoodsSpecification(orderMaster.getGoodsSpecification());

View File

@ -31,7 +31,7 @@ import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService; import com.ghy.system.service.ISysAreaService;
import com.ghy.system.service.IWxMsgService; import com.ghy.system.service.IWxMsgService;
import com.ghy.common.utils.BaiduMapUtils; import com.ghy.common.utils.BaiduMapUtils;
import com.ghy.web.pojo.vo.OrderChangePriceRequest; import com.ghy.web.pojo.vo .OrderChangePriceRequest;
import com.ghy.web.pojo.vo.OrderListResponse; import com.ghy.web.pojo.vo.OrderListResponse;
import com.ghy.web.pojo.vo.OrderStandard; import com.ghy.web.pojo.vo.OrderStandard;
import com.ghy.web.service.InsuranceService; import com.ghy.web.service.InsuranceService;
@ -805,7 +805,11 @@ public class OrderDetailController extends BaseController {
AfterServiceRecord afterServiceRecord=new AfterServiceRecord(); AfterServiceRecord afterServiceRecord=new AfterServiceRecord();
afterServiceRecord.setOrderDetailId(detail.getId()); afterServiceRecord.setOrderDetailId(detail.getId());
List<AfterServiceRecord> afterServiceRecordList=afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord); List<AfterServiceRecord> afterServiceRecordList=afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);
orderListResponse.setShowAfterServiceRecord(1);
// 判断售后状态如果售后状态不为1才显示售后记录按钮
boolean hasNonDisputeStatus = afterServiceRecordList.stream()
.anyMatch(record -> record.getAfterServiceStatus() != null && record.getAfterServiceStatus().equals(1));
orderListResponse.setShowAfterServiceRecord(hasNonDisputeStatus ? 0 : 1);
orderListResponse.setIsNeedBill(orderMaster.getIsNeedBill()); orderListResponse.setIsNeedBill(orderMaster.getIsNeedBill());
orderListResponse.setIsMonitoredOrder(orderMaster.getIsMonitoredOrder()); orderListResponse.setIsMonitoredOrder(orderMaster.getIsMonitoredOrder());
orderListResponse.setOrderImages(orderMaster.getOrderImages()); orderListResponse.setOrderImages(orderMaster.getOrderImages());
@ -1677,9 +1681,9 @@ public class OrderDetailController extends BaseController {
orderDetail.setAfterServiceStatus(1); orderDetail.setAfterServiceStatus(1);
// 设置部门权限 // 设置部门权限
if (this.getSysUser().getDept().getParentId() != 101) { // if (this.getSysUser().getDept().getParentId() != 101) {
orderDetail.setDeptId(this.getSysUser().getDept().getParentId()); // orderDetail.setDeptId(this.getSysUser().getDept().getParentId());
} // }
return AjaxResult.success(orderDetailService.countOrderDetailList(orderDetail)); return AjaxResult.success(orderDetailService.countOrderDetailList(orderDetail));
} catch (Exception e) { } catch (Exception e) {

View File

@ -1528,44 +1528,44 @@ public class OrderMasterController extends BaseController {
@ResponseBody @ResponseBody
public AjaxResult countAfterDisputeList(@RequestBody OrderMaster orderMaster) { public AjaxResult countAfterDisputeList(@RequestBody OrderMaster orderMaster) {
// 查所有售后纠纷的单 // 查所有售后纠纷的单
AfterServiceRecord afterServiceRecord = new AfterServiceRecord(); // AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
afterServiceRecord.setExcludeAfterServiceFinished(Boolean.TRUE); // afterServiceRecord.setExcludeAfterServiceFinished(Boolean.TRUE);
// 只查询售后纠纷的记录客户不同意的记录 // // 只查询售后纠纷的记录客户不同意的记录
afterServiceRecord.setCustomerFinalCheck(0L); // 客户不同意 // afterServiceRecord.setCustomerFinalCheck(0L); // 客户不同意
List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService // List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService
.selectAfterServiceRecordList(afterServiceRecord); // .selectAfterServiceRecordList(afterServiceRecord);
// 踢重后的子单ids // // 踢重后的子单ids
List<Long> detailIds = afterServiceRecordList.stream().map(AfterServiceRecord::getOrderDetailId).distinct() // List<Long> detailIds = afterServiceRecordList.stream().map(AfterServiceRecord::getOrderDetailId).distinct()
.collect(Collectors.toList()); // .collect(Collectors.toList());
StringBuilder orderDetailIds = new StringBuilder(); // StringBuilder orderDetailIds = new StringBuilder();
OrderDetail orderDetail = new OrderDetail(); // OrderDetail orderDetail = new OrderDetail();
orderDetail.setCustomerId(orderMaster.getCustomerId()); // orderDetail.setCustomerId(orderMaster.getCustomerId());
orderDetail.setDeptId(orderMaster.getDeptId()); // orderDetail.setDeptId(orderMaster.getDeptId());
detailIds.forEach(id -> { // detailIds.forEach(id -> {
orderDetailIds.append(id).append(","); // orderDetailIds.append(id).append(",");
}); // });
String ids = orderDetailIds.toString(); // String ids = orderDetailIds.toString();
if (StringUtils.isNotEmpty(ids)) { // if (StringUtils.isNotEmpty(ids)) {
orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1)); // orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1));
} else { // } else {
orderDetail.setOrderDetailIds("0"); // orderDetail.setOrderDetailIds("0");
} // }
// 所有售后纠纷的子单
List<OrderDetail> orderDetailList = orderDetailService.selectOrderDetailList(orderDetail);
StringBuilder orderMasterIds = new StringBuilder();
orderDetailList.stream().map(OrderDetail::getOrderMasterId).distinct()
.collect(Collectors.toList()).forEach(id -> {
orderMasterIds.append(id).append(",");
});
String orderIds = orderMasterIds.toString();
if (StringUtils.isNotEmpty(orderIds)) {
orderMaster.setOrderMasterIds(orderIds.substring(0, orderIds.length() - 1));
} else {
orderMaster.setOrderMasterIds("0");
}
// // 所有售后纠纷的子单
// List<OrderDetail> orderDetailList = orderDetailService.selectOrderDetailList(orderDetail);
// StringBuilder orderMasterIds = new StringBuilder();
// orderDetailList.stream().map(OrderDetail::getOrderMasterId).distinct()
// .collect(Collectors.toList()).forEach(id -> {
// orderMasterIds.append(id).append(",");
// });
// String orderIds = orderMasterIds.toString();
// if (StringUtils.isNotEmpty(orderIds)) {
// orderMaster.setOrderMasterIds(orderIds.substring(0, orderIds.length() - 1));
// } else {
// orderMaster.setOrderMasterIds("0");
// }
orderMaster.setAfterServiceStatus(1);
return AjaxResult.success(orderMasterService.countOrderMasterList(orderMaster)); return AjaxResult.success(orderMasterService.countOrderMasterList(orderMaster));
} }
@ -1671,6 +1671,7 @@ public class OrderMasterController extends BaseController {
@PostMapping("/after/dispute/handle") @PostMapping("/after/dispute/handle")
@ResponseBody @ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult handleAfterServiceDispute(@RequestBody AfterServiceDisputeRequest request) { public AjaxResult handleAfterServiceDispute(@RequestBody AfterServiceDisputeRequest request) {
try { try {
logger.info("处理售后纠纷退款记录ID{},退款金额:{}", request.getRecordId(), request.getRefundAmount()); logger.info("处理售后纠纷退款记录ID{},退款金额:{}", request.getRecordId(), request.getRefundAmount());
@ -1686,10 +1687,11 @@ public class OrderMasterController extends BaseController {
return AjaxResult.error("该记录不是售后纠纷,无法处理"); return AjaxResult.error("该记录不是售后纠纷,无法处理");
} }
// 设置退款金额 // 设置退款金额和处理原因
record.setRefund(request.getRefundAmount()); record.setRefund(request.getRefundAmount());
record.setAgreedRefund(request.getRefundAmount()); record.setAgreedRefund(request.getRefundAmount());
record.setRefundApplyTime(new Date()); record.setRefundApplyTime(new Date());
record.setPlatformHandleReason(request.getPlatformHandleReason());
// 更新售后记录 // 更新售后记录
afterServiceRecordService.updateAfterServiceRecord(record); afterServiceRecordService.updateAfterServiceRecord(record);
@ -1697,7 +1699,27 @@ public class OrderMasterController extends BaseController {
// 执行退款逻辑 // 执行退款逻辑
try { try {
afterServiceRecordService.executeRefundLogic(record); afterServiceRecordService.executeRefundLogic(record);
logger.info("售后纠纷退款处理成功记录ID{},退款金额:{}", request.getRecordId(), request.getRefundAmount());
// 退款成功后更新子单和主单的售后状态为已完成
OrderDetail orderDetail = orderDetailService.selectById(record.getOrderDetailId());
if (orderDetail != null) {
orderDetail.setAfterServiceStatus(2);
orderDetailService.updateOrderDetail(orderDetail);
logger.info("已将子单[{}]售后状态设置为已完成", orderDetail.getId());
OrderMaster orderMaster = orderMasterService.selectById(orderDetail.getOrderMasterId());
if (orderMaster != null) {
orderMaster.setAfterServiceStatus(2);
orderMasterService.updateOrderMaster(orderMaster);
logger.info("已将主单[{}]售后状态设置为已完成", orderMaster.getId());
}
}
// 退款成功后更新售后记录状态为已完成
record.setAfterServiceStatus(1);
afterServiceRecordService.updateAfterServiceRecord(record);
logger.info("售后纠纷退款处理成功记录ID{},退款金额:{},处理原因:{}", request.getRecordId(), request.getRefundAmount(), request.getPlatformHandleReason());
return AjaxResult.success("退款处理成功"); return AjaxResult.success("退款处理成功");
} catch (Exception e) { } catch (Exception e) {
logger.error("售后纠纷退款执行失败记录ID{},错误:{}", request.getRecordId(), e.getMessage()); logger.error("售后纠纷退款执行失败记录ID{},错误:{}", request.getRecordId(), e.getMessage());
@ -2089,14 +2111,15 @@ public class OrderMasterController extends BaseController {
// 检查是否是售后纠纷查询 // 检查是否是售后纠纷查询
if (orderMaster.getOrderStatusName() != null && "售后纠纷".equals(orderMaster.getOrderStatusName())) { if (orderMaster.getOrderStatusName() != null && "售后纠纷".equals(orderMaster.getOrderStatusName())) {
// 通过查询AfterServiceRecord表中customerFinalCheck=0的记录获取售后纠纷的主单ID // 通过查询AfterServiceRecord表中customerFinalCheck=0的记录获取售后纠纷的主单ID
List<Long> disputeOrderMasterIds = getDisputeOrderMasterIds(); // List<Long> disputeOrderMasterIds = getDisputeOrderMasterIds();
if (disputeOrderMasterIds.isEmpty()) { // if (disputeOrderMasterIds.isEmpty()) {
// 如果没有售后纠纷记录返回空结果 // // 如果没有售后纠纷记录返回空结果
return getDataTable(new ArrayList<>()); // return getDataTable(new ArrayList<>());
} // }
// 将售后纠纷的主单ID设置到查询条件中 // // 将售后纠纷的主单ID设置到查询条件中
String ids = disputeOrderMasterIds.stream().map(String::valueOf).collect(Collectors.joining(",")); // String ids = disputeOrderMasterIds.stream().map(String::valueOf).collect(Collectors.joining(","));
orderMaster.setOrderMasterIds(ids); // orderMaster.setOrderMasterIds(ids);
orderMaster.setAfterServiceStatus(1);
orderMaster.setOrderStatus(null); // 清除orderStatus条件避免冲突 orderMaster.setOrderStatus(null); // 清除orderStatus条件避免冲突
} else if (orderMaster.getSearchAfterList() != null && orderMaster.getSearchAfterList()) { } else if (orderMaster.getSearchAfterList() != null && orderMaster.getSearchAfterList()) {
// 保持原有的售后查询逻辑 // 保持原有的售后查询逻辑

View File

@ -1035,7 +1035,7 @@
modalContent += '<th>师傅反馈</th>'; modalContent += '<th>师傅反馈</th>';
modalContent += '<th>客户确认</th>'; modalContent += '<th>客户确认</th>';
modalContent += '<th>申请退款金额</th>'; modalContent += '<th>申请退款金额</th>';
modalContent += '<th>操作</th>'; modalContent += '<th style="width: 280px;">操作</th>';
modalContent += '</tr></thead><tbody>'; modalContent += '</tr></thead><tbody>';
disputeRecords.forEach(function(record) { disputeRecords.forEach(function(record) {
@ -1046,8 +1046,15 @@
modalContent += '<td>' + getCustomerCheckText(record.customerFinalCheck) + '</td>'; modalContent += '<td>' + getCustomerCheckText(record.customerFinalCheck) + '</td>';
modalContent += '<td>¥' + (record.agreedRefund || 0) + '</td>'; modalContent += '<td>¥' + (record.agreedRefund || 0) + '</td>';
modalContent += '<td>'; modalContent += '<td>';
modalContent += '<input type="number" class="form-control" id="refundAmount_' + record.id + '" placeholder="输入退款金额" value="' + (record.agreedRefund || 0) + '" style="width: 120px; display: inline-block;">'; modalContent += '<div style="margin-bottom: 8px;">';
modalContent += '<button class="btn btn-primary btn-xs" onclick="processRefund(' + record.id + ', ' + orderDetailId + ')" style="margin-left: 5px;">处理退款</button>'; modalContent += '<label style="font-size: 12px; color: #666; margin-bottom: 2px; display: block;">退款金额:</label>';
modalContent += '<input type="number" class="form-control" id="refundAmount_' + record.id + '" placeholder="输入退款金额" value="' + (record.agreedRefund || 0) + '" style="width: 100%; font-size: 12px; height: 28px;">';
modalContent += '</div>';
modalContent += '<div style="margin-bottom: 8px;">';
modalContent += '<label style="font-size: 12px; color: #666; margin-bottom: 2px; display: block;">处理原因:</label>';
modalContent += '<input type="text" class="form-control" id="processReason_' + record.id + '" placeholder="请输入处理原因" style="width: 100%; font-size: 12px; height: 28px;">';
modalContent += '</div>';
modalContent += '<button class="btn btn-primary btn-xs" onclick="processRefund(' + record.id + ', ' + orderDetailId + ')" style="width: 100%; font-size: 12px; height: 28px;">处理退款</button>';
modalContent += '</td>'; modalContent += '</td>';
modalContent += '</tr>'; modalContent += '</tr>';
}); });
@ -1069,21 +1076,30 @@
// 处理退款 // 处理退款
function processRefund(recordId, orderDetailId) { function processRefund(recordId, orderDetailId) {
var refundAmount = $('#refundAmount_' + recordId).val(); var refundAmount = $('#refundAmount_' + recordId).val();
var processReason = $('#processReason_' + recordId).val();
if (!refundAmount || refundAmount <= 0) { if (!refundAmount || refundAmount <= 0) {
$.modal.msgError("请输入有效的退款金额"); $.modal.msgError("请输入有效的退款金额");
return; return;
} }
$.modal.confirm("确认处理退款吗?退款金额:¥" + refundAmount, function() { if (!processReason || processReason.trim() === '') {
$.modal.msgError("请输入处理原因");
return;
}
$.modal.confirm("确认处理退款吗?<br/>退款金额:¥" + refundAmount + "<br/>处理原因:" + processReason, function() {
$.ajax({ $.ajax({
type: "POST", type: "POST",
dataType: "json", dataType: "json",
url: prefix + "/after/dispute/handle", contentType: "application/json",
data: { url: ctx + "order/master/after/dispute/handle",
data: JSON.stringify({
recordId: recordId, recordId: recordId,
orderDetailId: orderDetailId, orderDetailId: orderDetailId,
refundAmount: refundAmount refundAmount: refundAmount,
}, platformHandleReason: processReason
}),
success: function (result) { success: function (result) {
if (result.code == web_status.SUCCESS) { if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("退款处理成功"); $.modal.msgSuccess("退款处理成功");

View File

@ -1279,12 +1279,16 @@
html += '<td>¥' + (record.refund || 0) + '</td>'; html += '<td>¥' + (record.refund || 0) + '</td>';
html += '<td>' + getWorkerFeedbackText(record.workerFeedbackResult) + '</td>'; html += '<td>' + getWorkerFeedbackText(record.workerFeedbackResult) + '</td>';
html += '<td>' + getCustomerCheckText(record.customerFinalCheck) + '</td>'; html += '<td>' + getCustomerCheckText(record.customerFinalCheck) + '</td>';
html += '<td>'; html += '<td style="width: 280px;">';
html += '<div class="input-group" style="width: 200px;">'; html += '<div style="margin-bottom: 8px;">';
html += '<input type="number" class="form-control" id="refundAmount_' + record.id + '" placeholder="退款金额" value="' + (record.refund || 0) + '" min="0" step="0.01">'; html += '<label style="font-size: 12px; color: #666; margin-bottom: 2px; display: block;">退款金额:</label>';
html += '<div class="input-group-append">'; html += '<input type="number" class="form-control" id="refundAmount_' + record.id + '" placeholder="输入退款金额" value="' + (record.refund || 0) + '" style="width: 100%; font-size: 12px; height: 28px;" min="0" step="0.01">';
html += '<button class="btn btn-primary btn-sm" onclick="processRefund(\'' + record.id + '\', \'' + orderMasterId + '\')">处理退款</button>'; html += '</div>';
html += '</div></div>'; html += '<div style="margin-bottom: 8px;">';
html += '<label style="font-size: 12px; color: #666; margin-bottom: 2px; display: block;">处理原因:</label>';
html += '<input type="text" class="form-control" id="processReason_' + record.id + '" placeholder="请输入处理原因" style="width: 100%; font-size: 12px; height: 28px;">';
html += '</div>';
html += '<button class="btn btn-primary btn-xs" onclick="processRefund(\'' + record.id + '\', \'' + orderMasterId + '\')" style="width: 100%; font-size: 12px; height: 28px;">处理退款</button>';
html += '</td>'; html += '</td>';
html += '</tr>'; html += '</tr>';
}); });
@ -1313,11 +1317,18 @@
// 处理退款 // 处理退款
function processRefund(recordId, orderMasterId) { function processRefund(recordId, orderMasterId) {
var refundAmount = $('#refundAmount_' + recordId).val(); var refundAmount = $('#refundAmount_' + recordId).val();
var processReason = $('#processReason_' + recordId).val();
if (!refundAmount || refundAmount <= 0) { if (!refundAmount || refundAmount <= 0) {
$.modal.msgError("请输入有效的退款金额"); $.modal.msgError("请输入有效的退款金额");
return; return;
} }
if (!processReason || processReason.trim() === '') {
$.modal.msgError("请输入处理原因");
return;
}
$.modal.confirm("确认处理退款 ¥" + refundAmount + " 吗?", function() { $.modal.confirm("确认处理退款 ¥" + refundAmount + " 吗?", function() {
$.ajax({ $.ajax({
type: "POST", type: "POST",
@ -1327,7 +1338,8 @@
data: JSON.stringify({ data: JSON.stringify({
recordId: recordId, recordId: recordId,
orderMasterId: orderMasterId, orderMasterId: orderMasterId,
refundAmount: parseFloat(refundAmount) refundAmount: parseFloat(refundAmount),
platformHandleReason: processReason.trim()
}), }),
success: function (result) { success: function (result) {
if (result.code == web_status.SUCCESS) { if (result.code == web_status.SUCCESS) {

View File

@ -72,13 +72,6 @@ public class AfterServiceRecord extends BaseEntity
@Excel(name = "售后状态0-进行中1-已完成2-已取消3-已超时") @Excel(name = "售后状态0-进行中1-已完成2-已取消3-已超时")
private Integer afterServiceStatus; private Integer afterServiceStatus;
public Integer getAfterServiceStatus() {
return afterServiceStatus;
}
public void setAfterServiceStatus(Integer afterServiceStatus) {
this.afterServiceStatus = afterServiceStatus;
}
/** 协商后的退款金额 */ /** 协商后的退款金额 */
@Excel(name = "协商后的退款金额") @Excel(name = "协商后的退款金额")
@ -205,6 +198,10 @@ public class AfterServiceRecord extends BaseEntity
@Excel(name = "客户不同意理由") @Excel(name = "客户不同意理由")
private String customerDisagreeReason; private String customerDisagreeReason;
/** 售后纠纷平台处理原因 */
@Excel(name = "售后纠纷平台处理原因")
private String platformHandleReason;
/** 子单号(用于显示,非数据库字段) */ /** 子单号(用于显示,非数据库字段) */
private String orderDetailCode; private String orderDetailCode;

View File

@ -264,7 +264,7 @@ public class OrderDetail extends BaseEntity {
/** /**
* 售后状态0-无售后1-售后纠纷 * 售后状态0-无售后1-售后纠纷
*/ */
@Excel(name = "售后状态0-无售后1-售后纠纷") @Excel(name = "售后状态0-无售后1-售后纠纷2-售后已完成")
private Integer afterServiceStatus; private Integer afterServiceStatus;
/** /**

View File

@ -90,4 +90,11 @@ public interface AfterServiceRecordMapper {
* @return 超时的售后记录列表 * @return 超时的售后记录列表
*/ */
List<AfterServiceRecord> selectWorkerResendTimeoutRecords(); List<AfterServiceRecord> selectWorkerResendTimeoutRecords();
/**
* 批量更新售后状态当客户最终确认为1时将售后状态设置为1
*
* @return 更新的记录数
*/
int updateAfterServiceStatusByCustomerFinalCheck();
} }

View File

@ -274,6 +274,13 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
AfterServiceRecord afterServiceRecord = this.selectAfterServiceRecordById(param.getId()); AfterServiceRecord afterServiceRecord = this.selectAfterServiceRecordById(param.getId());
Assert.notNull(afterServiceRecord, "售后记录不存在!"); Assert.notNull(afterServiceRecord, "售后记录不存在!");
OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId()); OrderDetail orderDetail = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
// 检查orderDetail是否为null避免NullPointerException
if (orderDetail == null) {
log.error("订单详情不存在售后记录ID{}订单详情ID{}", afterServiceRecord.getId(), afterServiceRecord.getOrderDetailId());
return AjaxResult.error("订单详情不存在,无法处理售后记录");
}
boolean drawCash = orderDetail.getDrawCashTime() != null; boolean drawCash = orderDetail.getDrawCashTime() != null;
// 更新为售后未超时 // 更新为售后未超时
orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0); orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0);
@ -440,9 +447,14 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
orderMaster.setAfterServiceStatus(1); orderMaster.setAfterServiceStatus(1);
orderMasterService.updateOrderMaster(orderMaster); orderMasterService.updateOrderMaster(orderMaster);
log.info("客户不同意处理方案,已将主单[{}]标记为售后纠纷状态", orderMaster.getId()); log.info("客户不同意处理方案,已将主单[{}]标记为售后纠纷状态", orderMaster.getId());
// 同时更新子单的售后纠纷状态
orderDetail.setAfterServiceStatus(1);
orderDetailService.updateOrderDetail(orderDetail);
log.info("客户不同意处理方案,已将子单[{}]标记为售后纠纷状态", orderDetail.getId());
} }
} catch (Exception e) { } catch (Exception e) {
log.error("更新主单售后纠纷状态失败主单ID{}", orderDetail.getOrderMasterId(), e); log.error("更新主单和子单售后纠纷状态失败,主单ID{},子单ID{}", orderDetail.getOrderMasterId(), orderDetail.getId(), e);
} }
} }
@ -469,6 +481,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
if (afterServiceRecord.getCustomerFinalCheck().equals(0L)) { if (afterServiceRecord.getCustomerFinalCheck().equals(0L)) {
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
return AjaxResult.success("客户不同意师傅方案,进入售后纠纷处理。"); return AjaxResult.success("客户不同意师傅方案,进入售后纠纷处理。");
} }
// 新增如果师傅拒绝workerFeedbackResult=2且客户同意则不执行退款流程 // 新增如果师傅拒绝workerFeedbackResult=2且客户同意则不执行退款流程
@ -486,7 +499,35 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
return AjaxResult.error("本单已划款,师傅/服务人员已到帐或即将到帐,双方达成退款的,请对方线下支付后点对方已退款"); return AjaxResult.error("本单已划款,师傅/服务人员已到帐或即将到帐,双方达成退款的,请对方线下支付后点对方已退款");
} else { } else {
agreeRefund(afterServiceRecord); // 执行退款逻辑
int refundResult = agreeRefund(afterServiceRecord);
// 退款成功后将售后状态设置为已完成
if (refundResult > 0) {
try {
// 设置售后记录状态为已完成2表示已完成
afterServiceRecord.setAfterServiceStatus(2);
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
log.info("客户同意处理方案且退款成功,已将售后记录[{}]状态设置为已完成", afterServiceRecord.getId());
// 更新对应主单和子单的售后状态为已完成
OrderDetail orderDetail1 = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
if (orderDetail1 != null) {
orderDetail1.setAfterServiceStatus(2);
orderDetailService.updateOrderDetail(orderDetail1);
log.info("已将子单[{}]售后状态设置为已完成", orderDetail1.getId());
OrderMaster orderMaster = orderMasterService.selectById(orderDetail1.getOrderMasterId());
if (orderMaster != null) {
orderMaster.setAfterServiceStatus(2);
orderMasterService.updateOrderMaster(orderMaster);
log.info("已将主单[{}]售后状态设置为已完成", orderMaster.getId());
}
}
} catch (Exception e) {
log.error("更新售后完成状态失败售后记录ID{}", afterServiceRecord.getId(), e);
}
}
} }
// orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0); // orderDetailService.updateAfterTimeout(afterServiceRecord.getOrderDetailId(), 0, 0);
} else if (one.equals(afterServiceRecord.getWorkerFeedbackResult()) && param.getCustomerFinalCheck() == null) { } else if (one.equals(afterServiceRecord.getWorkerFeedbackResult()) && param.getCustomerFinalCheck() == null) {
@ -553,6 +594,19 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
if (param.getRedoCompleteImages() != null) { if (param.getRedoCompleteImages() != null) {
afterServiceRecord.setRedoCompleteImages(param.getRedoCompleteImages()); afterServiceRecord.setRedoCompleteImages(param.getRedoCompleteImages());
} }
// 新增处理重发/补发相关字段
if (param.getWorkerResendType() != null) {
afterServiceRecord.setWorkerResendType(param.getWorkerResendType());
}
if (param.getWorkerResendTrackingNumber() != null) {
afterServiceRecord.setWorkerResendTrackingNumber(param.getWorkerResendTrackingNumber());
}
if (param.getWorkerResendRemark() != null) {
afterServiceRecord.setWorkerResendRemark(param.getWorkerResendRemark());
}
if (param.getWorkerResendImages() != null) {
afterServiceRecord.setWorkerResendImages(param.getWorkerResendImages());
}
if (param.getUpdateBy() != null) { if (param.getUpdateBy() != null) {
afterServiceRecord.setUpdateBy(param.getUpdateBy()); afterServiceRecord.setUpdateBy(param.getUpdateBy());
} }
@ -706,8 +760,13 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
orderMasterService.updateOrderMaster(orderMaster); orderMasterService.updateOrderMaster(orderMaster);
log.info("客户不同意处理方案,已将主单[{}]标记为售后纠纷状态", orderMaster.getId()); log.info("客户不同意处理方案,已将主单[{}]标记为售后纠纷状态", orderMaster.getId());
} }
// 同时更新子单的售后纠纷状态
orderDetail.setAfterServiceStatus(1);
orderDetailService.updateOrderDetail(orderDetail);
log.info("客户不同意处理方案,已将子单[{}]标记为售后纠纷状态", orderDetail.getId());
} catch (Exception e) { } catch (Exception e) {
log.error("更新主单售后纠纷状态失败主单ID{}", orderDetail.getOrderMasterId(), e); log.error("更新主单/子单售后纠纷状态失败,主单ID{},子单ID{}", orderDetail.getOrderMasterId(), orderDetail.getId(), e);
} }
log.info("商品售后-客户不同意处理方案"); log.info("商品售后-客户不同意处理方案");
@ -736,13 +795,38 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
log.error("商品售后通知发送失败", e); log.error("商品售后通知发送失败", e);
} }
if (afterServiceRecord.getCustomerFinalCheck().equals(0L)) { if (afterServiceRecord.getCustomerFinalCheck().equals(0L)) {
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
return AjaxResult.success("客户不同意师傅方案,进入售后纠纷处理。"); return AjaxResult.success("客户不同意师傅方案,进入售后纠纷处理。");
} }
// 新增如果师傅拒绝workerFeedbackResult=2且客户同意则不执行退款流程 // 新增如果师傅拒绝workerFeedbackResult=2且客户同意则不执行退款流程
if (afterServiceRecord.getWorkerFeedbackResult() != null && afterServiceRecord.getWorkerFeedbackResult().equals(0L) && one.equals(param.getCustomerFinalCheck())) { if (afterServiceRecord.getWorkerFeedbackResult() != null && afterServiceRecord.getWorkerFeedbackResult().equals(0L) && one.equals(param.getCustomerFinalCheck())) {
log.info("商品售后-师傅拒绝且客户同意不执行退款流程售后记录ID{}", afterServiceRecord.getId()); log.info("商品售后-师傅拒绝且客户同意不执行退款流程售后记录ID{}", afterServiceRecord.getId());
afterServiceRecord.setRefundApplyTime(new Date()); afterServiceRecord.setRefundApplyTime(new Date());
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
// 师傅拒绝且客户同意售后流程结束设置状态为已完成
try {
afterServiceRecord.setAfterServiceStatus(2);
afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
log.info("师傅拒绝且客户同意,已将售后记录[{}]状态设置为已完成", afterServiceRecord.getId());
// 更新对应主单和子单的售后状态为已完成
OrderDetail orderDetail1 = orderDetailService.selectById(afterServiceRecord.getOrderDetailId());
if (orderDetail1 != null) {
orderDetail.setAfterServiceStatus(2);
orderDetailService.updateOrderDetail(orderDetail1);
log.info("已将子单[{}]售后状态设置为已完成", orderDetail1.getId());
OrderMaster orderMaster = orderMasterService.selectById(orderDetail1.getOrderMasterId());
if (orderMaster != null) {
orderMaster.setAfterServiceStatus(2);
orderMasterService.updateOrderMaster(orderMaster);
log.info("已将主单[{}]售后状态设置为已完成", orderMaster.getId());
}
}
} catch (Exception e) {
log.error("更新售后完成状态失败售后记录ID{}", afterServiceRecord.getId(), e);
}
return AjaxResult.success("客户同意师傅拒绝方案,售后流程结束,不执行退款"); return AjaxResult.success("客户同意师傅拒绝方案,售后流程结束,不执行退款");
} }
@ -779,6 +863,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
return AjaxResult.success(); return AjaxResult.success();
} }
@Transactional(rollbackFor = Exception.class)
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, "子单不存在!");
@ -888,6 +973,8 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
} }
} }
afterServiceRecord.setRefundApplyTime(new Date()); afterServiceRecord.setRefundApplyTime(new Date());
// 退款成功后更新售后状态为已完成
afterServiceRecord.setAfterServiceStatus(1);
return afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); return afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
} }
@ -955,6 +1042,7 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
* @param afterServiceRecord 售后记录 * @param afterServiceRecord 售后记录
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void executeRefundLogic(AfterServiceRecord afterServiceRecord) { public void executeRefundLogic(AfterServiceRecord afterServiceRecord) {
try { try {
// 检查是否已分账如果已分账则不能退款 // 检查是否已分账如果已分账则不能退款
@ -1035,6 +1123,11 @@ public class AfterServiceRecordServiceImpl implements IAfterServiceRecordService
afterServiceRecord.setWorkerResendImages(param.getWorkerResendImages()); afterServiceRecord.setWorkerResendImages(param.getWorkerResendImages());
} }
// 新增设置师傅反馈结果
if (param.getWorkerFeedbackResult() != null) {
afterServiceRecord.setWorkerFeedbackResult(param.getWorkerFeedbackResult());
}
// 更新数据库 // 更新数据库
int result = afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord); int result = afterServiceRecordMapper.updateAfterServiceRecord(afterServiceRecord);
if (result > 0) { if (result > 0) {

View File

@ -53,6 +53,7 @@
<result property="customerDisagreeImages" column="customer_disagree_images" /> <result property="customerDisagreeImages" column="customer_disagree_images" />
<result property="customerDisagreeReason" column="customer_disagree_reason" /> <result property="customerDisagreeReason" column="customer_disagree_reason" />
<result property="afterServiceStatus" column="after_service_status" /> <result property="afterServiceStatus" column="after_service_status" />
<result property="platformHandleReason" column="platform_handle_reason" />
</resultMap> </resultMap>
<sql id="selectAfterServiceRecordVo"> <sql id="selectAfterServiceRecordVo">
@ -61,7 +62,7 @@
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_category, 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, worker_resend_time, worker_resend_type, worker_resend_tracking_number, worker_receive_status, worker_agree_type, worker_receive_confirm, worker_resend_remark, worker_resend_images, 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, worker_receive_status, worker_agree_type, worker_receive_confirm, worker_resend_remark, worker_resend_images,
customer_disagree_images, customer_disagree_reason, after_service_status customer_disagree_images, customer_disagree_reason, after_service_status, platform_handle_reason
from after_service_record from after_service_record
</sql> </sql>
@ -138,6 +139,7 @@
<if test="customerDisagreeImages != null">customer_disagree_images,</if> <if test="customerDisagreeImages != null">customer_disagree_images,</if>
<if test="customerDisagreeReason != null">customer_disagree_reason,</if> <if test="customerDisagreeReason != null">customer_disagree_reason,</if>
<if test="afterServiceStatus != null">after_service_status,</if> <if test="afterServiceStatus != null">after_service_status,</if>
<if test="platformHandleReason != null">platform_handle_reason,</if>
<if test="createBy != null">create_by,</if> <if test="createBy != null">create_by,</if>
<if test="updateBy != null">update_by,</if> <if test="updateBy != null">update_by,</if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
@ -184,6 +186,7 @@
<if test="customerDisagreeImages != null">#{customerDisagreeImages},</if> <if test="customerDisagreeImages != null">#{customerDisagreeImages},</if>
<if test="customerDisagreeReason != null">#{customerDisagreeReason},</if> <if test="customerDisagreeReason != null">#{customerDisagreeReason},</if>
<if test="afterServiceStatus != null">#{afterServiceStatus},</if> <if test="afterServiceStatus != null">#{afterServiceStatus},</if>
<if test="platformHandleReason != null">#{platformHandleReason},</if>
<if test="createBy != null">#{createBy},</if> <if test="createBy != null">#{createBy},</if>
<if test="updateBy != null">#{updateBy},</if> <if test="updateBy != null">#{updateBy},</if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
@ -236,6 +239,7 @@
<if test="customerDisagreeImages != null">customer_disagree_images = #{customerDisagreeImages},</if> <if test="customerDisagreeImages != null">customer_disagree_images = #{customerDisagreeImages},</if>
<if test="customerDisagreeReason != null">customer_disagree_reason = #{customerDisagreeReason},</if> <if test="customerDisagreeReason != null">customer_disagree_reason = #{customerDisagreeReason},</if>
<if test="afterServiceStatus != null">after_service_status = #{afterServiceStatus},</if> <if test="afterServiceStatus != null">after_service_status = #{afterServiceStatus},</if>
<if test="platformHandleReason != null">platform_handle_reason = #{platformHandleReason},</if>
<if test="createBy != null">create_by = #{createBy},</if> <if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if> <if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if> <if test="updateBy != null">update_by = #{updateBy},</if>
@ -291,11 +295,8 @@
AND customer_final_check IS NULL AND customer_final_check IS NULL
AND (is_auto_processed IS NULL OR is_auto_processed = 0) AND (is_auto_processed IS NULL OR is_auto_processed = 0)
AND ( AND (
-- 快递/物流6天倒计时 -- 所有类型统一5天倒计时
(worker_resend_type = 1 AND worker_resend_time &lt;= DATE_SUB(NOW(), INTERVAL 6 DAY)) worker_resend_time &lt;= DATE_SUB(NOW(), INTERVAL 4 DAY)
OR
-- 非快递24小时倒计时
(worker_resend_type IN (2, 3) AND worker_resend_time &lt;= DATE_SUB(NOW(), INTERVAL 24 HOUR))
) )
</select> </select>

View File

@ -414,6 +414,9 @@
FROM order_master om FROM order_master om
LEFT JOIN financial_master fm ON om.id = fm.order_master_id LEFT JOIN financial_master fm ON om.id = fm.order_master_id
<where> <where>
<if test="afterServiceStatus != null">
AND om.after_service_status = #{afterServiceStatus}
</if>
<if test="isMonitoredOrder"> <if test="isMonitoredOrder">
AND om.show_in_monitor = 1 AND om.order_status in (1,2,3,4) AND om.show_in_monitor = 1 AND om.order_status in (1,2,3,4)
</if> </if>