记得上下班打卡 | git大法好,push需谨慎
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liquidnet-bus-v1
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
董敬伟
liquidnet-bus-v1
Commits
7f74125e
Commit
7f74125e
authored
Jun 18, 2026
by
wangyifan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化用户退款接口
parent
bdbcf1f6
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
365 additions
and
256 deletions
+365
-256
GoblinOrderAppServiceImpl.java
...ervice/goblin/service/impl/GoblinOrderAppServiceImpl.java
+365
-256
No files found.
liquidnet-bus-service/liquidnet-service-goblin/liquidnet-service-goblin-impl/src/main/java/com/liquidnet/service/goblin/service/impl/GoblinOrderAppServiceImpl.java
View file @
7f74125e
...
...
@@ -243,9 +243,16 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
return
ResponseDto
.
success
(
true
);
}
/**
* 用户发起退款申请。
* <p>
* 发货前(status=2):整单自动退款,含运费,直接调支付网关。
* 发货后(status=3/4):可选整单或指定SKU,生成待审核退款单,不含运费。
*/
@Override
public
ResponseDto
<
Boolean
>
applyRefund
(
GoblinAppOrderRefundParam
param
)
{
// ---- 准备 SQL 容器 ----
LinkedList
<
String
>
sqls
=
CollectionUtil
.
linkedListString
();
sqls
.
add
(
SqlMapping
.
get
(
"goblin_order.user.applyRefundAuto"
));
sqls
.
add
(
SqlMapping
.
get
(
"goblin_order.store.orderStatus"
));
...
...
@@ -253,30 +260,30 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
sqls
.
add
(
SqlMapping
.
get
(
"goblin_order.store.refundLog"
));
sqls
.
add
(
SqlMapping
.
get
(
"candy_user_coupon.update_apply_refund"
));
LinkedList
<
Object
[]>
applyRefund
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
orderStatus
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
orderSkuStatus
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
refundLog
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
updateC
andyUserC
ouponObjs
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
applyRefund
Objs
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
orderStatus
Objs
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
orderSkuStatus
Objs
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
refundLog
Objs
=
CollectionUtil
.
linkedListObjectArr
();
LinkedList
<
Object
[]>
updateCouponObjs
=
CollectionUtil
.
linkedListObjectArr
();
String
uid
=
CurrentUtil
.
getCurrentUid
();
LocalDateTime
now
=
LocalDateTime
.
now
();
String
nowStr
=
DateUtil
.
getNowTime
();
// ---- 1. 订单基础校验 ----
GoblinStoreOrderVo
orderVo
=
redisUtils
.
getGoblinOrder
(
param
.
getOrderId
());
if
(
orderVo
==
null
)
{
return
ResponseDto
.
failure
(
"不可操作"
);
}
// if (!orderVo.getUserId().equals(uid)) {
// return ResponseDto.failure("无权操作");
// }
//
分布式锁防并发重复退款
//
---- 2. 分布式锁防并发重复退款 ----
String
lockKey
=
GoblinRedisConst
.
REFUND_ORDER_LOCK
+
param
.
getOrderId
();
if
(!
redisUtils
.
redisUtil
.
lock
(
lockKey
,
1
,
30
))
{
return
ResponseDto
.
failure
(
"退款处理中,请勿重复操作"
);
}
try
{
// ---- 3. 退款前置校验 ----
// 3a. 是否有处理中的退款单
List
<
String
>
backOrderIds
=
redisUtils
.
getBackOrderByOrderId
(
param
.
getOrderId
());
for
(
String
backOrderId
:
backOrderIds
)
{
GoblinBackOrderVo
backOrderVo
=
redisUtils
.
getBackOrderVo
(
backOrderId
);
...
...
@@ -284,262 +291,106 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
return
ResponseDto
.
failure
(
"申请失败"
);
}
}
if
(!(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
()
||
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_3
.
getValue
()
||
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_4
.
getValue
()))
{
// 3b. 订单状态:仅允许待发货(2) / 待收货(3) / 已完成(4)
int
orderStatus
=
orderVo
.
getStatus
();
if
(!(
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
()
||
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_3
.
getValue
()
||
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_4
.
getValue
()))
{
return
ResponseDto
.
failure
(
"不可操作"
);
}
//
判断7天
//
3c. 7天可退窗口
LocalDateTime
canRefundTime
=
getCanRefundTime
(
orderVo
);
if
(
canRefundTime
==
null
)
{
if
(
canRefundTime
==
null
||
LocalDateTime
.
now
().
isAfter
(
canRefundTime
)
)
{
return
ResponseDto
.
failure
(
"申请失败"
);
}
else
{
if
(
LocalDateTime
.
now
().
isAfter
(
canRefundTime
))
{
return
ResponseDto
.
failure
(
"申请失败"
);
}
}
//判断券
if
((!(
orderVo
.
getUcouponId
()
==
null
||
orderVo
.
getUcouponId
().
equals
(
""
))
||
!(
orderVo
.
getStoreCouponId
()
==
null
||
orderVo
.
getStoreCouponId
().
equals
(
""
)))
&&
param
.
getOrderSkuId
()
!=
null
)
{
// 3d. 用券订单仅支持整单退款
if
(
orderHasUsedCoupon
(
orderVo
)
&&
param
.
getOrderSkuId
()
!=
null
)
{
return
ResponseDto
.
failure
(
"用券仅支持整单退款"
);
}
//退款订单生成
GoblinBackOrder
backOrder
=
GoblinBackOrder
.
getNew
();
backOrder
.
setBackOrderId
(
IDGenerator
.
nextTimeId2
());
backOrder
.
setBackCode
(
IDGenerator
.
storeRefundCode
(
orderVo
.
getMasterOrderCode
()));
backOrder
.
setOrderId
(
param
.
getOrderId
());
backOrder
.
setOrderCode
(
orderVo
.
getOrderCode
());
backOrder
.
setStoreId
(
orderVo
.
getStoreId
());
backOrder
.
setLogisCompanyName
(
param
.
getCompany
());
backOrder
.
setMailNo
(
param
.
getMailNo
());
backOrder
.
setUserId
(
orderVo
.
getUserId
());
backOrder
.
setType
(
GoblinStatusConst
.
Type
.
BACK_TYPE_1
.
getValue
());
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_1
.
getValue
());
backOrder
.
setCreatedAt
(
now
);
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
//未发货
if
(
StringUtil
.
isNotBlank
(
param
.
getOrderSkuId
()))
{
return
ResponseDto
.
failure
(
"发货前仅支持整单退款"
);
}
backOrder
.
setBackPriceExpress
(
orderVo
.
getPriceExpress
()
==
null
?
BigDecimal
.
ZERO
:
orderVo
.
getPriceExpress
());
backOrder
.
setReason
(
param
.
getReason
());
backOrder
.
setPics
(
param
.
getPics
());
backOrder
.
setDescribes
(
param
.
getDescribes
());
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_0
.
getValue
());
backOrder
.
setAuditAt
(
now
);
backOrder
.
setSkuIdNums
(
Joiner
.
on
(
","
).
join
(
orderVo
.
getOrderSkuVoIds
()));
}
else
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_3
.
getValue
()
||
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_4
.
getValue
())
{
//已发货/已完成
if
(
StringUtil
.
isNotBlank
(
param
.
getOrderSkuId
()))
{
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
param
.
getOrderSkuId
());
if
(
orderSkuVo
==
null
||
!
orderVo
.
getOrderId
().
equals
(
orderSkuVo
.
getOrderId
()))
{
return
ResponseDto
.
failure
(
"不存在"
);
}
BigDecimal
applyingRefundPrice
=
mongoUtils
.
getRefundOrderSkuVoPriceBySkuId
(
orderSkuVo
.
getOrderSkuId
());
backOrder
.
setRealBackPrice
(
GoblinRefundHelper
.
remainRefundPrice
(
orderSkuVo
,
applyingRefundPrice
));
backOrder
.
setBackPriceExpress
(
BigDecimal
.
ZERO
);
}
else
{
backOrder
.
setBackPriceExpress
(
BigDecimal
.
ZERO
);
}
backOrder
.
setReason
(
param
.
getReason
());
backOrder
.
setPics
(
param
.
getPics
());
backOrder
.
setDescribes
(
param
.
getDescribes
());
backOrder
.
setType
(
param
.
getRefundType
()
==
null
?
GoblinStatusConst
.
Type
.
BACK_TYPE_1
.
getValue
()
:
param
.
getRefundType
());
backOrder
.
setSkuIdNums
(
param
.
getOrderSkuId
());
}
else
{
return
ResponseDto
.
failure
(
"不可申请"
);
// 3e. 发货前仅支持整单退款
if
(
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
()
&&
StringUtil
.
isNotBlank
(
param
.
getOrderSkuId
()))
{
return
ResponseDto
.
failure
(
"发货前仅支持整单退款"
);
}
// ---- 4. 构建退款单骨架(不含SKU明细和最终金额) ----
GoblinBackOrder
backOrder
=
buildBackOrderSkeleton
(
orderVo
,
param
,
now
);
// ---- 5. 构建退款单 VO ----
GoblinBackOrderVo
vo
=
GoblinBackOrderVo
.
getNew
();
BeanUtils
.
copyProperties
(
backOrder
,
vo
);
vo
.
setCreatedAt
(
nowStr
);
// ---- 6. 处理退款SKU列表 ----
List
<
GoblinBackOrderSkuVo
>
orderSkuVoList
=
ObjectUtil
.
goblinBackOrderSkuVoArrayList
();
BigDecimal
skuRefundPrice
=
BigDecimal
.
ZERO
;
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
//订单状态修改
// orderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_61.getValue());
orderStatus
.
add
(
new
Object
[]{
orderVo
.
getStatus
(),
orderVo
.
getZhengzaiStatus
(),
now
,
orderVo
.
getOrderId
(),
now
,
now
});
boolean
isUnshipped
=
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
();
boolean
hasSpecificSku
=
StringUtil
.
isNotBlank
(
param
.
getOrderSkuId
());
if
(
isUnshipped
)
{
// 发货前:仅支持整单退款,遍历所有SKU
orderStatusObjs
.
add
(
new
Object
[]{
orderVo
.
getStatus
(),
orderVo
.
getZhengzaiStatus
(),
now
,
orderVo
.
getOrderId
(),
now
,
now
});
for
(
String
orderSkuId
:
orderVo
.
getOrderSkuVoIds
())
{
//订单款式状态修改
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
orderSkuId
);
orderSkuVo
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_61
.
getValue
());
GoblinBackOrderSkuVo
backOrderSkuVo
=
GoblinBackOrderSkuVo
.
getNew
();
backOrderSkuVo
.
setOrderSkuId
(
orderSkuId
);
backOrderSkuVo
.
setSpuId
(
orderSkuVo
.
getSpuId
());
backOrderSkuVo
.
setSpuName
(
orderSkuVo
.
getSpuName
());
backOrderSkuVo
.
setSkuId
(
orderSkuVo
.
getSkuId
());
backOrderSkuVo
.
setSkuPic
(
orderSkuVo
.
getSkuImage
());
backOrderSkuVo
.
setSkuName
(
orderSkuVo
.
getSkuName
());
backOrderSkuVo
.
setSkuSpecs
(
orderSkuVo
.
getSkuSpecs
());
BigDecimal
applyingRefundPrice
=
mongoUtils
.
getRefundOrderSkuVoPriceBySkuId
(
orderSkuId
);
BigDecimal
refundPrice
=
GoblinRefundHelper
.
remainRefundPrice
(
orderSkuVo
,
applyingRefundPrice
);
BigDecimal
refundPrice
=
buildAndPersistRefundSku
(
orderSkuId
,
orderSkuVo
,
false
,
nowStr
,
now
,
orderSkuVoList
,
orderSkuStatusObjs
);
if
(
refundPrice
.
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
ResponseDto
.
failure
(
"退款价格超过商品可退价格"
);
}
skuRefundPrice
=
skuRefundPrice
.
add
(
refundPrice
);
backOrderSkuVo
.
setRefundPrice
(
refundPrice
);
backOrderSkuVo
.
setCreatedAt
(
nowStr
);
orderSkuVoList
.
add
(
backOrderSkuVo
);
backOrderLog
(
orderVo
,
orderSkuVo
,
now
);
//redis
redisUtils
.
setGoblinOrderSku
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
//mongo
mongoUtils
.
updateGoblinOrderSkuVo
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
orderSkuStatus
.
add
(
new
Object
[]{
orderSkuVo
.
getStatus
(),
now
,
orderSkuVo
.
getOrderSkuId
(),
now
,
now
});
}
}
else
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_3
.
getValue
()
||
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_4
.
getValue
())
{
if
(
StringUtil
.
isNotBlank
(
param
.
getOrderSkuId
()))
{
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
param
.
getOrderSkuId
());
if
(
orderSkuVo
==
null
||
!
orderVo
.
getOrderId
().
equals
(
orderSkuVo
.
getOrderId
()))
{
return
ResponseDto
.
failure
(
"不存在"
);
}
if
(
Objects
.
equals
(
orderSkuVo
.
getSkuType
(),
2
))
{
// 券类商品-校验发放的券是否已使用
// 券类商品默认一个商品对应一个券,下单只可购买一张
String
ucKey
=
CandyRedisConst
.
BASIC_USER_COUPON
.
concat
(
orderVo
.
getUserId
()
);
List
<
CandyUserCouponBasicDto
>
vos
=
(
List
<
CandyUserCouponBasicDto
>)
redisUtils
.
get
(
ucKey
);
int
idx
=
IntStream
.
range
(
0
,
vos
.
size
())
.
filter
(
i
->
vos
.
get
(
i
).
getUcouponId
().
equals
(
orderSkuVo
.
getOrderSkuId
())).
findFirst
().
orElse
(-
1
);
if
(-
1
!=
idx
)
{
CandyUserCouponBasicDto
basicDto
=
vos
.
get
(
idx
);
if
(
5
==
basicDto
.
getState
())
{
// 券状态为'5-已使用',则不可退款
return
ResponseDto
.
failure
(
"券已使用,不可申请"
);
}
basicDto
.
setState
(
2
);
// 置为'2-无效',防止用户在后台审核过程中使用券,造成券已使用,订单也退款
vos
.
set
(
idx
,
basicDto
);
redisUtils
.
redisUtil
.
set
(
ucKey
,
vos
);
updateCandyUserCouponObjs
.
add
(
new
Object
[]{
basicDto
.
getState
(),
orderVo
.
getUserId
(),
now
,
basicDto
.
getUcouponId
()}
);
}
else
{
log
.
warn
(
"券类商品订单申请退款,未找到对应券[orderSkuId={},uid={}]"
,
orderSkuVo
.
getOrderSkuId
(),
orderVo
.
getUserId
());
}
}
else
if
(
hasSpecificSku
)
{
// 发货后 + 指定SKU:仅退选中的单个商品
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
param
.
getOrderSkuId
());
if
(
orderSkuVo
==
null
||
!
orderVo
.
getOrderId
().
equals
(
orderSkuVo
.
getOrderId
()))
{
return
ResponseDto
.
failure
(
"不存在"
);
}
// 券类商品校验:已使用则拒绝,未使用则置为无效
String
couponError
=
validateAndDisableCouponForRefund
(
orderSkuVo
,
orderVo
.
getUserId
(),
now
,
updateCouponObjs
);
if
(
couponError
!=
null
)
{
return
ResponseDto
.
failure
(
couponError
);
}
BigDecimal
refundPrice
=
buildAndPersistRefundSku
(
param
.
getOrderSkuId
(),
orderSkuVo
,
true
,
nowStr
,
now
,
orderSkuVoList
,
orderSkuStatusObjs
);
if
(
refundPrice
.
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
ResponseDto
.
failure
(
"退款价格超过商品可退价格"
);
}
skuRefundPrice
=
skuRefundPrice
.
add
(
refundPrice
);
backOrderLog
(
orderVo
,
orderSkuVo
,
now
);
}
else
{
// 发货后 + 整单:遍历所有SKU
for
(
String
orderSkuId
:
orderVo
.
getOrderSkuVoIds
())
{
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
orderSkuId
);
String
couponError
=
validateAndDisableCouponForRefund
(
orderSkuVo
,
orderVo
.
getUserId
(),
now
,
updateCouponObjs
);
if
(
couponError
!=
null
)
{
return
ResponseDto
.
failure
(
couponError
);
}
//订单款式状态修改
orderSkuVo
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_61
.
getValue
());
GoblinBackOrderSkuVo
backOrderSkuVo
=
GoblinBackOrderSkuVo
.
getNew
();
backOrderSkuVo
.
setOrderSkuId
(
param
.
getOrderSkuId
());
backOrderSkuVo
.
setSpuId
(
orderSkuVo
.
getSpuId
());
backOrderSkuVo
.
setSpuName
(
orderSkuVo
.
getSpuName
());
backOrderSkuVo
.
setSkuId
(
orderSkuVo
.
getSkuId
());
backOrderSkuVo
.
setSkuPic
(
orderSkuVo
.
getSkuImage
());
backOrderSkuVo
.
setSkuName
(
orderSkuVo
.
getSkuName
());
BigDecimal
applyingRefundPrice
=
mongoUtils
.
getRefundOrderSkuVoPriceBySkuId
(
param
.
getOrderSkuId
());
BigDecimal
refundPrice
=
GoblinRefundHelper
.
remainRefundPrice
(
orderSkuVo
,
applyingRefundPrice
);
BigDecimal
refundPrice
=
buildAndPersistRefundSku
(
orderSkuId
,
orderSkuVo
,
true
,
nowStr
,
now
,
orderSkuVoList
,
orderSkuStatusObjs
);
if
(
refundPrice
.
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
ResponseDto
.
failure
(
"退款价格超过商品可退价格"
);
}
skuRefundPrice
=
skuRefundPrice
.
add
(
refundPrice
);
backOrderSkuVo
.
setRefundPrice
(
refundPrice
);
backOrderSkuVo
.
setSkuSpecs
(
orderSkuVo
.
getSkuSpecs
());
backOrderSkuVo
.
setCreatedAt
(
nowStr
);
backOrderSkuVo
.
setSkuType
(
orderSkuVo
.
getSkuType
());
orderSkuVoList
.
add
(
backOrderSkuVo
);
backOrderLog
(
orderVo
,
orderSkuVo
,
now
);
//redis
redisUtils
.
setGoblinOrderSku
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
//mongo
mongoUtils
.
updateGoblinOrderSkuVo
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
orderSkuStatus
.
add
(
new
Object
[]{
orderSkuVo
.
getStatus
(),
now
,
orderSkuVo
.
getOrderSkuId
(),
now
,
now
});
}
else
{
for
(
String
orderSkuId
:
orderVo
.
getOrderSkuVoIds
())
{
//订单款式状态修改
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
orderSkuId
);
if
(
Objects
.
equals
(
orderSkuVo
.
getSkuType
(),
2
))
{
// 券类商品-校验发放的券是否已使用
// 券类商品默认一个商品对应一个券,下单只可购买一张
String
ucKey
=
CandyRedisConst
.
BASIC_USER_COUPON
.
concat
(
orderVo
.
getUserId
());
List
<
CandyUserCouponBasicDto
>
vos
=
(
List
<
CandyUserCouponBasicDto
>)
redisUtils
.
get
(
ucKey
);
int
idx
=
IntStream
.
range
(
0
,
vos
.
size
()).
filter
(
i
->
vos
.
get
(
i
).
getUcouponId
().
equals
(
orderSkuVo
.
getOrderSkuId
())).
findFirst
().
orElse
(-
1
);
if
(-
1
!=
idx
)
{
CandyUserCouponBasicDto
basicDto
=
vos
.
get
(
idx
);
if
(
5
==
basicDto
.
getState
())
{
// 券状态为'5-已使用',则不可退款
return
ResponseDto
.
failure
(
"券已使用,不可申请"
);
}
basicDto
.
setState
(
2
);
// 置为'2-无效',防止用户在后台审核过程中使用券,造成券已使用,订单也退款
vos
.
set
(
idx
,
basicDto
);
redisUtils
.
redisUtil
.
set
(
ucKey
,
vos
);
updateCandyUserCouponObjs
.
add
(
new
Object
[]{
basicDto
.
getState
(),
orderVo
.
getUserId
(),
now
,
basicDto
.
getUcouponId
()});
}
else
{
log
.
warn
(
"券类商品订单申请退款,未找到对应券[orderSkuId={},uid={}]"
,
orderSkuVo
.
getOrderSkuId
(),
orderVo
.
getUserId
());
}
}
orderSkuVo
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_61
.
getValue
());
GoblinBackOrderSkuVo
backOrderSkuVo
=
GoblinBackOrderSkuVo
.
getNew
();
backOrderSkuVo
.
setOrderSkuId
(
orderSkuId
);
backOrderSkuVo
.
setSpuId
(
orderSkuVo
.
getSpuId
());
backOrderSkuVo
.
setSpuName
(
orderSkuVo
.
getSpuName
());
backOrderSkuVo
.
setSkuId
(
orderSkuVo
.
getSkuId
());
backOrderSkuVo
.
setSkuName
(
orderSkuVo
.
getSkuName
());
backOrderSkuVo
.
setSkuSpecs
(
orderSkuVo
.
getSkuSpecs
());
backOrderSkuVo
.
setSkuPic
(
orderSkuVo
.
getSkuImage
());
BigDecimal
applyingRefundPrice
=
mongoUtils
.
getRefundOrderSkuVoPriceBySkuId
(
orderSkuId
);
BigDecimal
refundPrice
=
GoblinRefundHelper
.
remainRefundPrice
(
orderSkuVo
,
applyingRefundPrice
);
if
(
refundPrice
.
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
ResponseDto
.
failure
(
"退款价格超过商品可退价格"
);
}
skuRefundPrice
=
skuRefundPrice
.
add
(
refundPrice
);
backOrderSkuVo
.
setRefundPrice
(
refundPrice
);
backOrderSkuVo
.
setCreatedAt
(
nowStr
);
backOrderSkuVo
.
setSkuType
(
orderSkuVo
.
getSkuType
());
orderSkuVoList
.
add
(
backOrderSkuVo
);
backOrderLog
(
orderVo
,
orderSkuVo
,
now
);
//redis
redisUtils
.
setGoblinOrderSku
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
//mongo
mongoUtils
.
updateGoblinOrderSkuVo
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
orderSkuStatus
.
add
(
new
Object
[]{
orderSkuVo
.
getStatus
(),
now
,
orderSkuVo
.
getOrderSkuId
(),
now
,
now
});
}
}
}
else
{
return
ResponseDto
.
failure
(
"不可申请"
);
}
// ---- 7. 最终金额与SKU汇总校验 ----
if
(
skuRefundPrice
.
compareTo
(
BigDecimal
.
ZERO
)
<=
0
)
{
return
ResponseDto
.
failure
(
"退款价格超过商品可退价格"
);
}
if
(
StringUtil
.
isBlank
(
backOrder
.
getSkuIdNums
()))
{
List
<
String
>
refundOrderSkuIds
=
new
LinkedList
<>();
for
(
GoblinBackOrderSkuVo
backOrderSkuVo
:
orderSkuVoList
)
{
refundOrderSkuIds
.
add
(
backOrderSkuVo
.
getOrderSkuId
());
}
backOrder
.
setSkuIdNums
(
Joiner
.
on
(
","
).
join
(
refundOrderSkuIds
));
}
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
backOrder
.
setRealBackPrice
(
GoblinRefundHelper
.
beforeShipRefundPrice
(
skuRefundPrice
,
backOrder
.
getBackPriceExpress
()));
}
else
{
backOrder
.
setRealBackPrice
(
skuRefundPrice
);
backOrder
.
setBackPriceExpress
(
BigDecimal
.
ZERO
);
}
vo
.
setRealBackPrice
(
backOrder
.
getRealBackPrice
());
vo
.
setBackPriceExpress
(
backOrder
.
getBackPriceExpress
());
vo
.
setStatus
(
backOrder
.
getStatus
());
vo
.
setAuditAt
(
backOrder
.
getAuditAt
()
==
null
?
null
:
nowStr
);
vo
.
setBackOrderSkuVos
(
orderSkuVoList
);
vo
.
setOperationType
(
GoblinStatusConst
.
Type
.
OPERATION_TYPE_1
.
getValue
());
//添加日志
fillSkuIdNumsIfBlank
(
backOrder
,
orderSkuVoList
);
setFinalRefundPrice
(
backOrder
,
orderVo
,
skuRefundPrice
);
syncBackOrderVoFields
(
vo
,
backOrder
,
orderSkuVoList
,
nowStr
);
// ---- 8. 操作日志 ----
GoblinBackOrderLog
backOrderLog
=
initBackLog
(
param
.
getOrderId
(),
uid
,
now
);
backOrderLog
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_LOG_STATUS_21
.
getValue
());
backOrderLog
.
setOperationType
(
GoblinStatusConst
.
Type
.
OPERATION_TYPE_1
.
getValue
());
backOrderLog
.
setMessage
(
"用户发起发起:"
+
JsonUtils
.
toJson
(
param
));
//redis
redisUtils
.
setBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
redisUtils
.
setGoblinOrder
(
orderVo
.
getOrderId
(),
orderVo
);
redisUtils
.
addBackOrderByOrderId
(
orderVo
.
getOrderId
(),
backOrder
.
getBackOrderId
());
//mongo
mongoUtils
.
insertGoblinBackOrderVo
(
vo
);
mongoUtils
.
updateGoblinStoreOrderVo
(
orderVo
.
getOrderId
(),
orderVo
);
//mysql
applyRefund
.
add
(
new
Object
[]{
// ---- 9. 持久化(Redis + Mongo + MySQL) ----
applyRefundObjs
.
add
(
new
Object
[]{
backOrder
.
getBackOrderId
(),
backOrder
.
getBackCode
(),
backOrder
.
getOrderId
(),
backOrder
.
getOrderCode
(),
backOrder
.
getStoreId
(),
backOrder
.
getUserId
(),
backOrder
.
getSkuIdNums
(),
backOrder
.
getType
(),
backOrder
.
getReason
(),
...
...
@@ -547,35 +398,16 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrder
.
getLogisCompanyName
(),
backOrder
.
getMailNo
(),
backOrder
.
getPics
(),
backOrder
.
getCreatedAt
(),
backOrder
.
getAuditAt
(),
backOrder
.
getErrorReason
()
});
//添加日志
refundLog
.
add
(
new
Object
[]{
refundLogObjs
.
add
(
new
Object
[]{
backOrderLog
.
getBackOrderLogId
(),
backOrderLog
.
getBackOrderId
(),
backOrderLog
.
getOperationType
(),
backOrderLog
.
getMessage
(),
backOrderLog
.
getOperationName
(),
backOrderLog
.
getStatus
(),
now
});
queueUtils
.
sendMsgByRedis
(
MQConst
.
GoblinQueue
.
GOBLIN_USER_ORDER_OPERA
.
getKey
(),
SqlMapping
.
gets
(
sqls
,
applyRefund
,
orderStatus
,
orderSkuStatus
,
refundLog
,
updateCandyUserCouponObjs
));
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
String
returnString
=
refundHelper
.
initRefund
(
orderVo
,
backOrder
.
getRealBackPrice
(),
backOrder
.
getBackCode
());
if
(!
refundHelper
.
isRefundSuccess
(
returnString
))
{
String
message
=
refundHelper
.
getRefundMessage
(
returnString
);
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_10
.
getValue
());
backOrder
.
setErrorReason
(
"失败原因:"
+
message
);
vo
.
setStatus
(
backOrder
.
getStatus
());
vo
.
setErrorReason
(
backOrder
.
getErrorReason
());
log
.
error
(
"REFUND DATA = "
+
returnString
);
redisUtils
.
setBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
mongoUtils
.
updateGoblinBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
queueUtils
.
sendMsgByRedis
(
MQConst
.
GoblinQueue
.
GOBLIN_USER_ORDER_OPERA
.
getKey
(),
SqlMapping
.
get
(
"goblin_order.store.applyRefund"
,
vo
.
getStatus
(),
vo
.
getReason
(),
vo
.
getAuditAt
(),
now
,
backOrder
.
getBackOrderId
(),
now
,
now
)
);
return
ResponseDto
.
failure
(
"退款失败:"
+
backOrder
.
getErrorReason
());
}
if
(
DragonConstant
.
REFUND_TYPE_MICROPAY_ALIPAY
.
equals
(
orderVo
.
getPaymentType
()))
{
refundHelper
.
alipayCallBack
(
orderVo
,
backOrder
.
getBackCode
());
}
persistRefundOrder
(
orderVo
,
backOrder
,
vo
,
sqls
,
applyRefundObjs
,
orderStatusObjs
,
orderSkuStatusObjs
,
refundLogObjs
,
updateCouponObjs
);
// ---- 10. 发货前自动调支付网关退款 ----
if
(
isUnshipped
)
{
return
executeAutoRefund
(
orderVo
,
backOrder
,
vo
,
now
);
}
return
ResponseDto
.
success
();
}
finally
{
...
...
@@ -583,6 +415,283 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
}
}
// ======================== 私有辅助方法 ========================
/**
* 判断订单是否使用了优惠券(用户券或店铺券)。
*/
private
boolean
orderHasUsedCoupon
(
GoblinStoreOrderVo
orderVo
)
{
boolean
hasUserCoupon
=
orderVo
.
getUcouponId
()
!=
null
&&
!
orderVo
.
getUcouponId
().
isEmpty
();
boolean
hasStoreCoupon
=
orderVo
.
getStoreCouponId
()
!=
null
&&
!
orderVo
.
getStoreCouponId
().
isEmpty
();
return
hasUserCoupon
||
hasStoreCoupon
;
}
/**
* 构建退款单骨架,填充与SKU无关的基础字段。
* <p>
* 发货前(status=2):状态=自动退款(0),含运费,必须整单。
* 发货后(status=3/4):状态=待审核(1),不含运费,可选整单或指定SKU。
*/
private
GoblinBackOrder
buildBackOrderSkeleton
(
GoblinStoreOrderVo
orderVo
,
GoblinAppOrderRefundParam
param
,
LocalDateTime
now
)
{
GoblinBackOrder
backOrder
=
GoblinBackOrder
.
getNew
();
backOrder
.
setBackOrderId
(
IDGenerator
.
nextTimeId2
());
backOrder
.
setBackCode
(
IDGenerator
.
storeRefundCode
(
orderVo
.
getMasterOrderCode
()));
backOrder
.
setOrderId
(
param
.
getOrderId
());
backOrder
.
setOrderCode
(
orderVo
.
getOrderCode
());
backOrder
.
setStoreId
(
orderVo
.
getStoreId
());
backOrder
.
setLogisCompanyName
(
param
.
getCompany
());
backOrder
.
setMailNo
(
param
.
getMailNo
());
backOrder
.
setUserId
(
orderVo
.
getUserId
());
backOrder
.
setType
(
GoblinStatusConst
.
Type
.
BACK_TYPE_1
.
getValue
());
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_1
.
getValue
());
backOrder
.
setCreatedAt
(
now
);
int
orderStatus
=
orderVo
.
getStatus
();
if
(
orderStatus
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
// 未发货:仅支持整单退,含运费,自动退款(整单校验已在主方法完成)
backOrder
.
setBackPriceExpress
(
orderVo
.
getPriceExpress
()
==
null
?
BigDecimal
.
ZERO
:
orderVo
.
getPriceExpress
());
backOrder
.
setReason
(
param
.
getReason
());
backOrder
.
setPics
(
param
.
getPics
());
backOrder
.
setDescribes
(
param
.
getDescribes
());
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_0
.
getValue
());
backOrder
.
setAuditAt
(
now
);
backOrder
.
setSkuIdNums
(
Joiner
.
on
(
","
).
join
(
orderVo
.
getOrderSkuVoIds
()));
}
else
{
// 已发货/已完成(status=3/4):不含运费,生成待审核退款单
backOrder
.
setBackPriceExpress
(
BigDecimal
.
ZERO
);
backOrder
.
setReason
(
param
.
getReason
());
backOrder
.
setPics
(
param
.
getPics
());
backOrder
.
setDescribes
(
param
.
getDescribes
());
backOrder
.
setType
(
param
.
getRefundType
()
==
null
?
GoblinStatusConst
.
Type
.
BACK_TYPE_1
.
getValue
()
:
param
.
getRefundType
());
backOrder
.
setSkuIdNums
(
param
.
getOrderSkuId
());
}
return
backOrder
;
}
/**
* 券类商品退款前的校验与状态处理:
* <ul>
* <li>非券类商品(skuType != 2):直接通过</li>
* <li>券状态=5(已使用):拒绝退款</li>
* <li>券状态其他:置为2(无效),防止用户在审核期间消费该券</li>
* </ul>
*
* @return 错误提示,null 表示校验通过
*/
private
String
validateAndDisableCouponForRefund
(
GoblinOrderSkuVo
orderSkuVo
,
String
userId
,
LocalDateTime
now
,
LinkedList
<
Object
[]>
updateCouponObjs
)
{
if
(!
Objects
.
equals
(
orderSkuVo
.
getSkuType
(),
2
))
{
return
null
;
// 非券类商品,无需校验
}
// 券类商品默认一个商品对应一个券,下单只可购买一张
String
ucKey
=
CandyRedisConst
.
BASIC_USER_COUPON
.
concat
(
userId
);
List
<
CandyUserCouponBasicDto
>
vos
=
(
List
<
CandyUserCouponBasicDto
>)
redisUtils
.
get
(
ucKey
);
if
(
vos
==
null
||
vos
.
isEmpty
())
{
log
.
warn
(
"券类商品订单申请退款,未找到用户券列表[orderSkuId={},uid={}]"
,
orderSkuVo
.
getOrderSkuId
(),
userId
);
return
null
;
}
int
idx
=
IntStream
.
range
(
0
,
vos
.
size
())
.
filter
(
i
->
vos
.
get
(
i
).
getUcouponId
().
equals
(
orderSkuVo
.
getOrderSkuId
()))
.
findFirst
().
orElse
(-
1
);
if
(-
1
!=
idx
)
{
CandyUserCouponBasicDto
basicDto
=
vos
.
get
(
idx
);
if
(
5
==
basicDto
.
getState
())
{
return
"券已使用,不可申请"
;
// 券已使用,不可退款
}
// 置为无效,防止用户在后台审核过程中使用券
basicDto
.
setState
(
2
);
vos
.
set
(
idx
,
basicDto
);
redisUtils
.
redisUtil
.
set
(
ucKey
,
vos
);
updateCouponObjs
.
add
(
new
Object
[]{
basicDto
.
getState
(),
userId
,
now
,
basicDto
.
getUcouponId
()});
}
else
{
log
.
warn
(
"券类商品订单申请退款,未找到对应券[orderSkuId={},uid={}]"
,
orderSkuVo
.
getOrderSkuId
(),
userId
);
}
return
null
;
}
/**
* 为单个SKU:计算可退金额、构建 BackOrderSkuVo、更新SKU状态到Redis/Mongo、生成SQL参数。
*
* @param orderSkuId SKU子订单ID
* @param orderSkuVo 对应的SKU VO(调用方已从Redis获取)
* @param setSkuType 是否设置skuType(发货后需要,发货前不需要)
* @return 该SKU的可退金额(remainRefundPrice 结果)
*/
private
BigDecimal
buildAndPersistRefundSku
(
String
orderSkuId
,
GoblinOrderSkuVo
orderSkuVo
,
boolean
setSkuType
,
String
nowStr
,
LocalDateTime
now
,
List
<
GoblinBackOrderSkuVo
>
orderSkuVoList
,
LinkedList
<
Object
[]>
orderSkuStatusObjs
)
{
// 计算可退金额 = skuPriceActual - priceRefund - 申请中的退款额
BigDecimal
applyingRefundPrice
=
mongoUtils
.
getRefundOrderSkuVoPriceBySkuId
(
orderSkuId
);
BigDecimal
refundPrice
=
GoblinRefundHelper
.
remainRefundPrice
(
orderSkuVo
,
applyingRefundPrice
);
// 更新SKU状态为"退款中"
orderSkuVo
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_61
.
getValue
());
// 构建 BackOrderSkuVo
GoblinBackOrderSkuVo
backOrderSkuVo
=
GoblinBackOrderSkuVo
.
getNew
();
backOrderSkuVo
.
setOrderSkuId
(
orderSkuId
);
backOrderSkuVo
.
setSpuId
(
orderSkuVo
.
getSpuId
());
backOrderSkuVo
.
setSpuName
(
orderSkuVo
.
getSpuName
());
backOrderSkuVo
.
setSkuId
(
orderSkuVo
.
getSkuId
());
backOrderSkuVo
.
setSkuPic
(
orderSkuVo
.
getSkuImage
());
backOrderSkuVo
.
setSkuName
(
orderSkuVo
.
getSkuName
());
backOrderSkuVo
.
setSkuSpecs
(
orderSkuVo
.
getSkuSpecs
());
backOrderSkuVo
.
setRefundPrice
(
refundPrice
);
backOrderSkuVo
.
setCreatedAt
(
nowStr
);
if
(
setSkuType
)
{
backOrderSkuVo
.
setSkuType
(
orderSkuVo
.
getSkuType
());
}
orderSkuVoList
.
add
(
backOrderSkuVo
);
// 持久化SKU状态:Redis + Mongo
redisUtils
.
setGoblinOrderSku
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
mongoUtils
.
updateGoblinOrderSkuVo
(
orderSkuVo
.
getOrderSkuId
(),
orderSkuVo
);
// 生成MySQL更新参数
orderSkuStatusObjs
.
add
(
new
Object
[]{
orderSkuVo
.
getStatus
(),
now
,
orderSkuVo
.
getOrderSkuId
(),
now
,
now
});
return
refundPrice
;
}
/**
* 如果 skuIdNums 为空(发货后整单退场景),从 orderSkuVoList 中收集填充。
*/
private
void
fillSkuIdNumsIfBlank
(
GoblinBackOrder
backOrder
,
List
<
GoblinBackOrderSkuVo
>
orderSkuVoList
)
{
if
(
StringUtil
.
isNotBlank
(
backOrder
.
getSkuIdNums
()))
{
return
;
}
List
<
String
>
refundOrderSkuIds
=
new
LinkedList
<>();
for
(
GoblinBackOrderSkuVo
vo
:
orderSkuVoList
)
{
refundOrderSkuIds
.
add
(
vo
.
getOrderSkuId
());
}
backOrder
.
setSkuIdNums
(
Joiner
.
on
(
","
).
join
(
refundOrderSkuIds
));
}
/**
* 计算并设置最终退款金额。
* 发货前:SKU总额 + 运费;发货后:仅SKU总额。
*/
private
void
setFinalRefundPrice
(
GoblinBackOrder
backOrder
,
GoblinStoreOrderVo
orderVo
,
BigDecimal
skuRefundPrice
)
{
if
(
orderVo
.
getStatus
()
==
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
())
{
backOrder
.
setRealBackPrice
(
GoblinRefundHelper
.
beforeShipRefundPrice
(
skuRefundPrice
,
backOrder
.
getBackPriceExpress
()));
}
else
{
backOrder
.
setRealBackPrice
(
skuRefundPrice
);
backOrder
.
setBackPriceExpress
(
BigDecimal
.
ZERO
);
}
}
/**
* 将 backOrder 中的最终字段同步到 vo 中。
*/
private
void
syncBackOrderVoFields
(
GoblinBackOrderVo
vo
,
GoblinBackOrder
backOrder
,
List
<
GoblinBackOrderSkuVo
>
orderSkuVoList
,
String
nowStr
)
{
vo
.
setRealBackPrice
(
backOrder
.
getRealBackPrice
());
vo
.
setBackPriceExpress
(
backOrder
.
getBackPriceExpress
());
vo
.
setStatus
(
backOrder
.
getStatus
());
vo
.
setAuditAt
(
backOrder
.
getAuditAt
()
==
null
?
null
:
nowStr
);
vo
.
setBackOrderSkuVos
(
orderSkuVoList
);
vo
.
setOperationType
(
GoblinStatusConst
.
Type
.
OPERATION_TYPE_1
.
getValue
());
}
/**
* 持久化退款单到 Redis + Mongo + MySQL(MQ异步)。
*/
private
void
persistRefundOrder
(
GoblinStoreOrderVo
orderVo
,
GoblinBackOrder
backOrder
,
GoblinBackOrderVo
vo
,
LinkedList
<
String
>
sqls
,
LinkedList
<
Object
[]>
applyRefundObjs
,
LinkedList
<
Object
[]>
orderStatusObjs
,
LinkedList
<
Object
[]>
orderSkuStatusObjs
,
LinkedList
<
Object
[]>
refundLogObjs
,
LinkedList
<
Object
[]>
updateCouponObjs
)
{
// Redis
redisUtils
.
setBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
redisUtils
.
setGoblinOrder
(
orderVo
.
getOrderId
(),
orderVo
);
redisUtils
.
addBackOrderByOrderId
(
orderVo
.
getOrderId
(),
backOrder
.
getBackOrderId
());
// Mongo
mongoUtils
.
insertGoblinBackOrderVo
(
vo
);
mongoUtils
.
updateGoblinStoreOrderVo
(
orderVo
.
getOrderId
(),
orderVo
);
// MySQL (MQ异步)
queueUtils
.
sendMsgByRedis
(
MQConst
.
GoblinQueue
.
GOBLIN_USER_ORDER_OPERA
.
getKey
(),
SqlMapping
.
gets
(
sqls
,
applyRefundObjs
,
orderStatusObjs
,
orderSkuStatusObjs
,
refundLogObjs
,
updateCouponObjs
));
}
/**
* 发货前自动退款:调用支付网关,失败则回滚状态。
*/
private
ResponseDto
<
Boolean
>
executeAutoRefund
(
GoblinStoreOrderVo
orderVo
,
GoblinBackOrder
backOrder
,
GoblinBackOrderVo
vo
,
LocalDateTime
now
)
{
String
returnString
;
try
{
returnString
=
refundHelper
.
initRefund
(
orderVo
,
backOrder
.
getRealBackPrice
(),
backOrder
.
getBackCode
());
}
catch
(
Exception
e
)
{
log
.
error
(
"REFUND EXCEPTION, orderId={}"
,
orderVo
.
getOrderId
(),
e
);
rollbackAutoRefund
(
orderVo
,
backOrder
,
vo
,
now
,
"退款异常:"
+
e
.
getMessage
());
return
ResponseDto
.
failure
(
"退款失败:退款异常:"
+
e
.
getMessage
());
}
if
(!
refundHelper
.
isRefundSuccess
(
returnString
))
{
// 退款失败,回滚退款单及SKU状态
String
message
=
refundHelper
.
getRefundMessage
(
returnString
);
log
.
error
(
"REFUND DATA = "
+
returnString
);
rollbackAutoRefund
(
orderVo
,
backOrder
,
vo
,
now
,
"失败原因:"
+
message
);
return
ResponseDto
.
failure
(
"退款失败:失败原因:"
+
message
);
}
// 支付宝micropay需主动查询结果
if
(
DragonConstant
.
REFUND_TYPE_MICROPAY_ALIPAY
.
equals
(
orderVo
.
getPaymentType
()))
{
refundHelper
.
alipayCallBack
(
orderVo
,
backOrder
.
getBackCode
());
}
return
ResponseDto
.
success
();
}
/**
* 发货前自动退款失败/异常时,回滚退款单和SKU状态。
*/
private
void
rollbackAutoRefund
(
GoblinStoreOrderVo
orderVo
,
GoblinBackOrder
backOrder
,
GoblinBackOrderVo
vo
,
LocalDateTime
now
,
String
errorReason
)
{
backOrder
.
setStatus
(
GoblinStatusConst
.
Status
.
ORDER_BACK_STATUS_10
.
getValue
());
backOrder
.
setErrorReason
(
errorReason
);
vo
.
setStatus
(
backOrder
.
getStatus
());
vo
.
setErrorReason
(
backOrder
.
getErrorReason
());
redisUtils
.
setBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
mongoUtils
.
updateGoblinBackOrderVo
(
backOrder
.
getBackOrderId
(),
vo
);
// 回滚SKU状态到订单原始状态
int
rollbackStatus
=
orderVo
.
getStatus
();
for
(
String
orderSkuId
:
orderVo
.
getOrderSkuVoIds
())
{
GoblinOrderSkuVo
orderSkuVo
=
redisUtils
.
getGoblinOrderSkuVo
(
orderSkuId
);
if
(
orderSkuVo
!=
null
)
{
orderSkuVo
.
setStatus
(
rollbackStatus
);
redisUtils
.
setGoblinOrderSku
(
orderSkuId
,
orderSkuVo
);
mongoUtils
.
updateGoblinOrderSkuVo
(
orderSkuId
,
orderSkuVo
);
}
}
queueUtils
.
sendMsgByRedis
(
MQConst
.
GoblinQueue
.
GOBLIN_USER_ORDER_OPERA
.
getKey
(),
SqlMapping
.
get
(
"goblin_order.store.applyRefund"
,
vo
.
getStatus
(),
vo
.
getReason
(),
vo
.
getAuditAt
(),
now
,
backOrder
.
getBackOrderId
(),
now
,
now
)
);
}
@Override
public
ResponseDto
<
Boolean
>
againRefund
(
GoblinAppOrderRefundParam
param
)
{
LinkedList
<
String
>
sqls
=
CollectionUtil
.
linkedListString
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment