RefundServiceImpl.java
6.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.diligrp.rider.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.diligrp.rider.common.exception.BizException;
import com.diligrp.rider.entity.OrderRefundReason;
import com.diligrp.rider.entity.OrderRefundRecord;
import com.diligrp.rider.entity.Orders;
import com.diligrp.rider.mapper.OrderRefundReasonMapper;
import com.diligrp.rider.mapper.OrderRefundRecordMapper;
import com.diligrp.rider.mapper.OrdersMapper;
import com.diligrp.rider.entity.*;
import com.diligrp.rider.mapper.*;
import com.diligrp.rider.service.RefundService;
import com.diligrp.rider.service.WebhookService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class RefundServiceImpl implements RefundService {
private final OrderRefundReasonMapper reasonMapper;
private final OrderRefundRecordMapper recordMapper;
private final OrdersMapper ordersMapper;
private final WebhookService webhookService;
private final ObjectMapper objectMapper;
@Override
public List<OrderRefundReason> getReasons(int role) {
return reasonMapper.selectList(new LambdaQueryWrapper<OrderRefundReason>()
.eq(role > 0, OrderRefundReason::getRole, role)
.orderByAsc(OrderRefundReason::getListOrder));
}
@Override
@Transactional
public void applyRefund(Long orderId, Long uid, int role, Long reasonId, String reason) {
Orders order = ordersMapper.selectById(orderId);
if (order == null) throw new BizException("订单不存在");
// 用户申请:必须是自己的订单且已完成或服务中
if (role == 1) {
if (!uid.equals(order.getUid())) throw new BizException("订单信息错误");
if (order.getStatus() < 3 || order.getStatus() == 10) throw new BizException("当前订单状态不可申请退款");
}
// 骑手申请:必须是自己接的单
if (role == 2) {
if (!uid.equals(order.getRiderId())) throw new BizException("订单信息错误");
if (order.getStatus() != 3 && order.getStatus() != 4) throw new BizException("当前订单状态不可申请退款");
}
// 检查是否已有退款申请
Long exists = recordMapper.selectCount(new LambdaQueryWrapper<OrderRefundRecord>()
.eq(OrderRefundRecord::getOid, orderId)
.ne(OrderRefundRecord::getStatus, 2));
if (exists > 0) throw new BizException("该订单已有退款申请,请勿重复提交");
// 更新订单状态为退款申请中
ordersMapper.update(null, new LambdaUpdateWrapper<Orders>()
.eq(Orders::getId, orderId)
.set(Orders::getStatus, 7));
// 写退款记录
OrderRefundRecord record = new OrderRefundRecord();
record.setOid(orderId);
record.setOrderNo(order.getOrderNo());
record.setUid(uid);
record.setRole(role);
record.setReasonId(reasonId);
record.setReason(reason);
record.setMoney(order.getMoneyDelivery());
record.setStatus(0);
record.setAddTime(System.currentTimeMillis() / 1000);
recordMapper.insert(record);
// 通知接入方
notifyRefundEvent(order, "order.refund_apply");
}
@Override
@Transactional
public void handleRefund(Long recordId, int status, String remark) {
OrderRefundRecord record = recordMapper.selectById(recordId);
if (record == null) throw new BizException("退款记录不存在");
if (record.getStatus() != 0) throw new BizException("该退款申请已处理");
long now = System.currentTimeMillis() / 1000;
recordMapper.update(null, new LambdaUpdateWrapper<OrderRefundRecord>()
.eq(OrderRefundRecord::getId, recordId)
.set(OrderRefundRecord::getStatus, status)
.set(OrderRefundRecord::getRemark, remark)
.set(OrderRefundRecord::getHandleTime, now));
Orders order = ordersMapper.selectById(record.getOid());
if (order == null) return;
if (status == 1) {
// 退款通过 → 订单状态改为退款成功
ordersMapper.update(null, new LambdaUpdateWrapper<Orders>()
.eq(Orders::getId, record.getOid())
.set(Orders::getStatus, 8));
notifyRefundEvent(order, "order.refund_success");
} else {
// 退款拒绝 → 订单状态改为退款拒绝
ordersMapper.update(null, new LambdaUpdateWrapper<Orders>()
.eq(Orders::getId, record.getOid())
.set(Orders::getStatus, 9));
notifyRefundEvent(order, "order.refund_reject");
}
}
@Override
public OrderRefundRecord getByOrderId(Long orderId) {
return recordMapper.selectOne(new LambdaQueryWrapper<OrderRefundRecord>()
.eq(OrderRefundRecord::getOid, orderId)
.orderByDesc(OrderRefundRecord::getId)
.last("LIMIT 1"));
}
private void notifyRefundEvent(Orders order, String event) {
try {
if (order.getAppKey() == null || order.getAppKey().isBlank()) return;
Map<String, Object> payload = new HashMap<>();
payload.put("event", event);
payload.put("outOrderNo", order.getOutOrderNo());
payload.put("deliveryOrderId", order.getId());
payload.put("orderNo", order.getOrderNo());
payload.put("status", order.getStatus());
payload.put("timestamp", System.currentTimeMillis() / 1000);
webhookService.send(event, order.getId(), objectMapper.writeValueAsString(payload));
} catch (Exception e) {
log.warn("退款事件通知失败 orderId={}", order.getId(), e);
}
}
}