记得上下班打卡 | 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
8d25b760
Commit
8d25b760
authored
Jul 15, 2026
by
Administrator
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'jxl-sqb-refund' into 'master'
Jxl sqb refund See merge request
!437
parents
10f46998
2ce1f84b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
48 additions
and
30 deletions
+48
-30
IGoblinSqbService.java
...m/liquidnet/service/goblin/service/IGoblinSqbService.java
+2
-2
GoblinSqbOrderMapper.java
...liquidnet/service/goblin/mapper/GoblinSqbOrderMapper.java
+2
-1
GoblinSqbOrderMapper.xml
....liquidnet.service.goblin.mapper/GoblinSqbOrderMapper.xml
+10
-3
GoblinTaskHandler.java
...dnet/service/executor/main/handler/GoblinTaskHandler.java
+1
-1
GoblinSqbJobController.java
...rvice/goblin/controller/Inner/GoblinSqbJobController.java
+2
-2
GoblinSqbServiceImpl.java
...net/service/goblin/service/impl/GoblinSqbServiceImpl.java
+31
-21
No files found.
liquidnet-bus-api/liquidnet-service-goblin-api/src/main/java/com/liquidnet/service/goblin/service/IGoblinSqbService.java
View file @
8d25b760
...
@@ -38,8 +38,8 @@ public interface IGoblinSqbService {
...
@@ -38,8 +38,8 @@ public interface IGoblinSqbService {
ResponseDto
<
Boolean
>
syncCouponStatus
(
String
userId
,
String
orderId
);
ResponseDto
<
Boolean
>
syncCouponStatus
(
String
userId
,
String
orderId
);
/**
/**
*
演出结束
自动退款(定时任务调用)
* 自动退款(定时任务调用)
* SQL 已联表过滤:收钱吧扩展单、
主单已支付(2)、演出已结束、扩展未核销;循环内仅
调 refund。
* SQL 已联表过滤:收钱吧扩展单、
未核销,且(主单已支付(2)+演出已结束)或(退款中(61)+超 8 小时);循环内
调 refund。
*
*
* @param performancesId 演出ID,传 null 或空则不按演出缩小(全库符合条件候选,慎用)
* @param performancesId 演出ID,传 null 或空则不按演出缩小(全库符合条件候选,慎用)
* @return 处理结果摘要(成功/失败笔数)
* @return 处理结果摘要(成功/失败笔数)
...
...
liquidnet-bus-do/liquidnet-service-goblin-do/src/main/java/com/liquidnet/service/goblin/mapper/GoblinSqbOrderMapper.java
View file @
8d25b760
...
@@ -17,7 +17,8 @@ import java.util.List;
...
@@ -17,7 +17,8 @@ import java.util.List;
public
interface
GoblinSqbOrderMapper
extends
BaseMapper
<
GoblinSqbOrder
>
{
public
interface
GoblinSqbOrderMapper
extends
BaseMapper
<
GoblinSqbOrder
>
{
/**
/**
* 联表过滤:主单已支付(2)、演出已结束、扩展未核销;可选按演出 id 缩小范围
* 联表过滤候选:未核销 + 有演出关联,且满足其一:
* 主单已支付(2)+演出已结束,或主单退款中(61)+进入退款中已超 8 小时;可选按演出 id 缩小范围
*/
*/
List
<
GoblinSqbOrder
>
selectAutoRefundCandidates
(
@Param
(
"performancesId"
)
String
performancesId
);
List
<
GoblinSqbOrder
>
selectAutoRefundCandidates
(
@Param
(
"performancesId"
)
String
performancesId
);
}
}
liquidnet-bus-do/liquidnet-service-goblin-do/src/main/resources/com.liquidnet.service.goblin.mapper/GoblinSqbOrderMapper.xml
View file @
8d25b760
...
@@ -2,17 +2,24 @@
...
@@ -2,17 +2,24 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.liquidnet.service.goblin.mapper.GoblinSqbOrderMapper"
>
<mapper
namespace=
"com.liquidnet.service.goblin.mapper.GoblinSqbOrderMapper"
>
<!-- 收钱吧扩展单 + 主单已支付 + 演出已结束 + 未核销(定时自动退候选) -->
<!-- 定时自动退候选:未核销 + 有演出关联,且满足其一:
1) 主单已支付(2) + 演出已结束
2) 主单退款中(61) + 进入退款中已超 8 小时(卡单重试,不要求演出结束) -->
<select
id=
"selectAutoRefundCandidates"
resultType=
"com.liquidnet.service.goblin.entity.GoblinSqbOrder"
>
<select
id=
"selectAutoRefundCandidates"
resultType=
"com.liquidnet.service.goblin.entity.GoblinSqbOrder"
>
SELECT so.*
SELECT so.*
FROM goblin_sqb_order so
FROM goblin_sqb_order so
INNER JOIN goblin_store_order o ON o.order_id = so.order_id
INNER JOIN goblin_store_order o ON o.order_id = so.order_id
INNER JOIN kylin_performances kp ON kp.performances_id = so.performances_id
INNER JOIN kylin_performances kp ON kp.performances_id = so.performances_id
WHERE (so.coupon_used_status = 0 OR so.coupon_used_status IS NULL)
WHERE (so.coupon_used_status = 0 OR so.coupon_used_status IS NULL)
AND o.status = 2
AND kp.time_end
<
NOW()
AND so.performances_id IS NOT NULL
AND so.performances_id IS NOT NULL
AND so.performances_id != ''
AND so.performances_id != ''
AND (
(o.status = 2 AND kp.time_end
<
NOW())
OR (
o.status = 61
AND o.updated_at
<
= DATE_SUB(NOW(), INTERVAL 8 HOUR)
)
)
<if
test=
"performancesId != null and performancesId != ''"
>
<if
test=
"performancesId != null and performancesId != ''"
>
AND so.performances_id = #{performancesId}
AND so.performances_id = #{performancesId}
</if>
</if>
...
...
liquidnet-bus-service/liquidnet-service-executor-all/liquidnet-service-executor-main/src/main/java/com/liquidnet/service/executor/main/handler/GoblinTaskHandler.java
View file @
8d25b760
...
@@ -70,7 +70,7 @@ public class GoblinTaskHandler {
...
@@ -70,7 +70,7 @@ public class GoblinTaskHandler {
}
}
/**
/**
* 演出结束自动退款
* 演出结束自动退款
/ 退款中超8小时卡单重试
* xxl-job 配置:JobHandler = sev-goblin:sqbAutoRefund;参数为演出ID、或 performancesId=xxx;空则走 goblin 全库候选(慎用)
* xxl-job 配置:JobHandler = sev-goblin:sqbAutoRefund;参数为演出ID、或 performancesId=xxx;空则走 goblin 全库候选(慎用)
*/
*/
@XxlJob
(
value
=
"sev-goblin:sqbAutoRefund"
)
@XxlJob
(
value
=
"sev-goblin:sqbAutoRefund"
)
...
...
liquidnet-bus-service/liquidnet-service-goblin/liquidnet-service-goblin-impl/src/main/java/com/liquidnet/service/goblin/controller/Inner/GoblinSqbJobController.java
View file @
8d25b760
...
@@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
...
@@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
* - JobHandler:sev-goblin:sqbAutoRefund(接口走 rsc/** 免登录,与 NFT job 一致)
* - JobHandler:sev-goblin:sqbAutoRefund(接口走 rsc/** 免登录,与 NFT job 一致)
* - CRON:按演出结束时间触发(如演出结束后 5 分钟:0 5 * * * ?,具体由运维根据演出时间动态配置)
* - CRON:按演出结束时间触发(如演出结束后 5 分钟:0 5 * * * ?,具体由运维根据演出时间动态配置)
* - 执行器:liquidnet-service-executor
* - 执行器:liquidnet-service-executor
* - 任务参数:演出ID 或 performancesId=xxx;留空则处理全库
「演出已结束 + 主单已支付 + 扩展未核销」候选(
慎用)
* - 任务参数:演出ID 或 performancesId=xxx;留空则处理全库
候选(演出结束已支付 / 退款中超8小时,
慎用)
* - 路由策略:第一个
* - 路由策略:第一个
*/
*/
@Slf4j
@Slf4j
...
@@ -32,7 +32,7 @@ public class GoblinSqbJobController {
...
@@ -32,7 +32,7 @@ public class GoblinSqbJobController {
private
IGoblinSqbService
goblinSqbService
;
private
IGoblinSqbService
goblinSqbService
;
@PostMapping
(
"/autoRefund"
)
@PostMapping
(
"/autoRefund"
)
@ApiOperation
(
"
演出结束自动退款
"
)
@ApiOperation
(
"
收钱吧自动退款(演出结束已支付 / 退款中超8小时卡单重试)
"
)
public
ResponseDto
<
String
>
autoRefund
(
@RequestParam
(
value
=
"performancesId"
,
required
=
false
)
String
performancesId
)
{
public
ResponseDto
<
String
>
autoRefund
(
@RequestParam
(
value
=
"performancesId"
,
required
=
false
)
String
performancesId
)
{
log
.
info
(
"[收钱吧自动退款] 收到任务,performancesId={}"
,
performancesId
);
log
.
info
(
"[收钱吧自动退款] 收到任务,performancesId={}"
,
performancesId
);
return
goblinSqbService
.
autoRefundByPerformance
(
performancesId
);
return
goblinSqbService
.
autoRefundByPerformance
(
performancesId
);
...
...
liquidnet-bus-service/liquidnet-service-goblin/liquidnet-service-goblin-impl/src/main/java/com/liquidnet/service/goblin/service/impl/GoblinSqbServiceImpl.java
View file @
8d25b760
...
@@ -134,7 +134,8 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
...
@@ -134,7 +134,8 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
if
(
Integer
.
valueOf
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_6
.
getValue
()).
equals
(
storeSt
))
{
if
(
Integer
.
valueOf
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_6
.
getValue
()).
equals
(
storeSt
))
{
return
ResponseDto
.
failure
(
"订单已退款,不可重复退款"
);
return
ResponseDto
.
failure
(
"订单已退款,不可重复退款"
);
}
}
if
(!
Integer
.
valueOf
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
()).
equals
(
storeSt
))
{
boolean
isRetry
=
Integer
.
valueOf
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_61
.
getValue
()).
equals
(
storeSt
);
if
(!
isRetry
&&
!
Integer
.
valueOf
(
GoblinStatusConst
.
Status
.
ORDER_STATUS_2
.
getValue
()).
equals
(
storeSt
))
{
return
ResponseDto
.
failure
(
"订单状态不可退款"
);
return
ResponseDto
.
failure
(
"订单状态不可退款"
);
}
}
List
<
String
>
orderSkuVoIds
=
storeOrderVo
.
getOrderSkuVoIds
();
List
<
String
>
orderSkuVoIds
=
storeOrderVo
.
getOrderSkuVoIds
();
...
@@ -160,11 +161,13 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
...
@@ -160,11 +161,13 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
return
ResponseDto
.
failure
(
"券码已核销,不可退款"
);
return
ResponseDto
.
failure
(
"券码已核销,不可退款"
);
}
}
// 更新状态为退款中
// 首次申请:置退款中;卡单重试(已是61):不改主单状态,避免刷新 updated_at
String
now
=
LocalDateTime
.
now
().
format
(
DTF
);
if
(!
isRetry
)
{
orderVo
.
setUpdatedAt
(
now
);
String
now
=
LocalDateTime
.
now
().
format
(
DTF
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
orderVo
.
setUpdatedAt
(
now
);
syncOrderStatus
(
orderId
,
4
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
syncOrderStatus
(
orderId
,
4
);
}
List
<
GoblinOrderSkuVo
>
orderSkuVos
=
new
ArrayList
<>();
List
<
GoblinOrderSkuVo
>
orderSkuVos
=
new
ArrayList
<>();
for
(
String
skuVoId
:
storeOrderVo
.
getOrderSkuVoIds
())
{
for
(
String
skuVoId
:
storeOrderVo
.
getOrderSkuVoIds
())
{
...
@@ -183,32 +186,39 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
...
@@ -183,32 +186,39 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
reason
,
reason
,
buildRequestId
(
IDGenerator
.
nextSnowId
())
buildRequestId
(
IDGenerator
.
nextSnowId
())
);
);
log
.
info
(
"[收钱吧-退款] 收钱吧退款响应: {}, orderId: {}
."
,
JsonUtils
.
toJson
(
refundData
),
orderId
);
log
.
info
(
"[收钱吧-退款] 收钱吧退款响应: {}, orderId: {}
, isRetry={}."
,
JsonUtils
.
toJson
(
refundData
),
orderId
,
isRetry
);
if
(
refundData
==
null
)
{
if
(
refundData
==
null
)
{
// 退款失败,回滚状态
if
(!
isRetry
)
{
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
// 首次申请失败:回滚为已支付
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
syncOrderStatus
(
orderId
,
1
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
syncOrderStatus
(
orderId
,
1
);
}
else
{
log
.
warn
(
"[收钱吧-退款] 卡单重试失败,保持退款中,orderId={}"
,
orderId
);
}
return
ResponseDto
.
failure
(
"退款失败,请稍后重试"
);
return
ResponseDto
.
failure
(
"退款失败,请稍后重试"
);
}
}
//
退款成功
//
调收钱吧成功:写退款号;库存只在退款回调 targetState=20 时回(避免申请成功+回调各回一次)
orderVo
.
setRefundSn
(
refundData
.
getTicketsSn
());
orderVo
.
setRefundSn
(
refundData
.
getTicketsSn
());
orderVo
.
setRefundSignature
(
refundData
.
getTicketSignature
());
orderVo
.
setRefundSignature
(
refundData
.
getTicketSignature
());
orderVo
.
setRefundReason
(
reason
);
orderVo
.
setRefundReason
(
reason
);
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
goblinRedisUtils
.
incrSkuStock
(
null
,
orderVo
.
getSkuId
(),
orderVo
.
getQuantity
());
// syncOrderStatus(orderId, 3);
// syncOrderStatus(orderId, 3);
log
.
info
(
"[收钱吧-退款] 调用收钱吧退款成功,orderId={}
"
,
orderId
);
log
.
info
(
"[收钱吧-退款] 调用收钱吧退款成功,orderId={}
, isRetry={}"
,
orderId
,
isRetry
);
return
ResponseDto
.
success
(
Boolean
.
TRUE
);
return
ResponseDto
.
success
(
Boolean
.
TRUE
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"[收钱吧退款] 退款异常,orderId={},回滚主单为已支付"
,
orderId
,
e
);
if
(!
isRetry
)
{
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
log
.
error
(
"[收钱吧退款] 退款异常,orderId={},回滚主单为已支付"
,
orderId
,
e
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
orderVo
.
setUpdatedAt
(
LocalDateTime
.
now
().
format
(
DTF
));
syncOrderStatus
(
orderId
,
1
);
goblinSqbRedisUtils
.
setSqbOrder
(
orderId
,
orderVo
);
syncOrderStatus
(
orderId
,
1
);
}
else
{
log
.
error
(
"[收钱吧退款] 卡单重试异常,保持退款中,orderId={}"
,
orderId
,
e
);
}
return
ResponseDto
.
failure
(
"退款失败:"
+
e
.
getMessage
());
return
ResponseDto
.
failure
(
"退款失败:"
+
e
.
getMessage
());
}
}
}
}
...
@@ -272,14 +282,14 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
...
@@ -272,14 +282,14 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
pid
=
null
;
pid
=
null
;
}
}
if
(
pid
==
null
)
{
if
(
pid
==
null
)
{
log
.
warn
(
"[收钱吧自动退款] performancesId 为空,将处理库内所有
「演出已结束 + 主单已支付 + 扩展未核销」候选单
"
);
log
.
warn
(
"[收钱吧自动退款] performancesId 为空,将处理库内所有
符合条件候选单(演出结束已支付 / 退款中超8小时)
"
);
}
else
{
}
else
{
log
.
info
(
"[收钱吧自动退款] 开始 performancesId={}"
,
pid
);
log
.
info
(
"[收钱吧自动退款] 开始 performancesId={}"
,
pid
);
}
}
List
<
GoblinSqbOrder
>
orders
=
goblinSqbOrderMapper
.
selectAutoRefundCandidates
(
pid
);
List
<
GoblinSqbOrder
>
orders
=
goblinSqbOrderMapper
.
selectAutoRefundCandidates
(
pid
);
if
(
CollectionUtils
.
isEmpty
(
orders
))
{
if
(
CollectionUtils
.
isEmpty
(
orders
))
{
String
scope
=
pid
!=
null
?
(
"演出 "
+
pid
)
:
"全库
(演出已结束)
"
;
String
scope
=
pid
!=
null
?
(
"演出 "
+
pid
)
:
"全库"
;
String
summary
=
scope
+
" 无待自动退款的收钱吧扩展单"
;
String
summary
=
scope
+
" 无待自动退款的收钱吧扩展单"
;
log
.
info
(
"[收钱吧自动退款] {}"
,
summary
);
log
.
info
(
"[收钱吧自动退款] {}"
,
summary
);
return
ResponseDto
.
success
(
summary
);
return
ResponseDto
.
success
(
summary
);
...
@@ -311,7 +321,7 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
...
@@ -311,7 +321,7 @@ public class GoblinSqbServiceImpl implements IGoblinSqbService {
}
}
}
}
String
scopeLabel
=
pid
!=
null
?
(
"演出 "
+
pid
)
:
"全库
(演出已结束)
"
;
String
scopeLabel
=
pid
!=
null
?
(
"演出 "
+
pid
)
:
"全库"
;
String
summary
=
String
.
format
(
"%s 自动退款完成:成功 %d 笔,失败 %d 笔"
,
scopeLabel
,
successCount
,
failCount
);
String
summary
=
String
.
format
(
"%s 自动退款完成:成功 %d 笔,失败 %d 笔"
,
scopeLabel
,
successCount
,
failCount
);
log
.
info
(
"[收钱吧自动退款] {}"
,
summary
);
log
.
info
(
"[收钱吧自动退款] {}"
,
summary
);
return
ResponseDto
.
success
(
summary
);
return
ResponseDto
.
success
(
summary
);
...
...
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