记得上下班打卡 | 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
c43bc066
Commit
c43bc066
authored
Apr 28, 2026
by
wangyifan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
草莓护照- 支持批量领取徽章
parent
5779f1da
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
137 additions
and
54 deletions
+137
-54
AdamCaomeiBadgeClaimParam.java
...net/service/adam/dto/param/AdamCaomeiBadgeClaimParam.java
+5
-3
IAdamCaomeiBadgeUserService.java
...net/service/adam/service/IAdamCaomeiBadgeUserService.java
+1
-1
AdamCaomeiBadgeMapper.java
.../liquidnet/service/adam/mapper/AdamCaomeiBadgeMapper.java
+12
-0
AdamCaomeiBadgeUserController.java
...ervice/adam/controller/AdamCaomeiBadgeUserController.java
+2
-2
AdamCaomeiBadgeUserServiceImpl.java
...ice/adam/service/impl/AdamCaomeiBadgeUserServiceImpl.java
+117
-48
No files found.
liquidnet-bus-api/liquidnet-service-adam-api/src/main/java/com/liquidnet/service/adam/dto/param/AdamCaomeiBadgeClaimParam.java
View file @
c43bc066
...
...
@@ -5,12 +5,14 @@ import io.swagger.annotations.ApiModelProperty;
import
lombok.Data
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.NotEmpty
;
import
java.util.List
;
@Data
@ApiModel
(
"草莓徽章-认领参数"
)
public
class
AdamCaomeiBadgeClaimParam
{
@Not
Blank
(
message
=
"徽章ID
不能为空"
)
@ApiModelProperty
(
value
=
"徽章ID"
,
required
=
true
)
private
String
badgeId
;
@Not
Empty
(
message
=
"徽章ID列表
不能为空"
)
@ApiModelProperty
(
value
=
"徽章ID
列表
"
,
required
=
true
)
private
List
<
@NotBlank
(
message
=
"徽章ID不能为空"
)
String
>
badgeIds
;
}
liquidnet-bus-api/liquidnet-service-adam-api/src/main/java/com/liquidnet/service/adam/service/IAdamCaomeiBadgeUserService.java
View file @
c43bc066
...
...
@@ -14,7 +14,7 @@ public interface IAdamCaomeiBadgeUserService {
/**
* 认领徽章
*/
ResponseDto
<
String
>
claimBadge
(
String
badgeId
,
String
uid
);
ResponseDto
<
List
<
String
>>
claimBadges
(
List
<
String
>
badgeIds
,
String
uid
);
/**
* 补签申请记录列表(用户端)
...
...
liquidnet-bus-do/liquidnet-service-adam-do/src/main/java/com/liquidnet/service/adam/mapper/AdamCaomeiBadgeMapper.java
View file @
c43bc066
...
...
@@ -87,6 +87,18 @@ public interface AdamCaomeiBadgeMapper extends BaseMapper<AdamCaomeiBadge> {
@Select
(
"select count(1) from adam_caomei_user_badge where user_id = #{userId} and badge_id = #{badgeId}"
)
int
checkUserBadgeExists
(
@Param
(
"userId"
)
String
userId
,
@Param
(
"badgeId"
)
String
badgeId
);
@Select
({
"<script>"
,
"select badge_id from adam_caomei_user_badge"
,
"where user_id = #{userId} and badge_id in"
,
"<foreach collection='badgeIds' item='badgeId' open='(' separator=',' close=')'>"
,
"#{badgeId}"
,
"</foreach>"
,
"</script>"
})
List
<
String
>
selectClaimedBadgeIdsByUserAndBadgeIds
(
@Param
(
"userId"
)
String
userId
,
@Param
(
"badgeIds"
)
List
<
String
>
badgeIds
);
@Insert
({
"insert into adam_caomei_user_badge (user_id, badge_id, source, created_at) "
,
"values (#{userId}, #{badgeId}, #{source}, now())"
...
...
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/controller/AdamCaomeiBadgeUserController.java
View file @
c43bc066
...
...
@@ -36,9 +36,9 @@ public class AdamCaomeiBadgeUserController {
@ApiOperationSupport
(
order
=
1
)
@ApiOperation
(
"认领徽章"
)
@PostMapping
(
"claim"
)
public
ResponseDto
<
String
>
claim
(
@Valid
@RequestBody
AdamCaomeiBadgeClaimParam
param
)
{
public
ResponseDto
<
List
<
String
>
>
claim
(
@Valid
@RequestBody
AdamCaomeiBadgeClaimParam
param
)
{
String
uid
=
CurrentUtil
.
getCurrentUid
();
return
adamCaomeiBadgeUserService
.
claimBadge
(
param
.
getBadgeId
(),
uid
);
return
adamCaomeiBadgeUserService
.
claimBadge
s
(
param
.
getBadgeIds
(),
uid
);
}
@ApiOperationSupport
(
order
=
2
)
...
...
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/impl/AdamCaomeiBadgeUserServiceImpl.java
View file @
c43bc066
...
...
@@ -30,8 +30,11 @@ import org.springframework.transaction.annotation.Transactional;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.HashSet
;
import
java.util.stream.Collectors
;
@Slf4j
...
...
@@ -51,21 +54,36 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
ResponseDto
<
String
>
claimBadge
(
String
badgeId
,
String
uid
)
{
public
ResponseDto
<
List
<
String
>>
claimBadges
(
List
<
String
>
badgeIds
,
String
uid
)
{
if
(
StringUtils
.
isBlank
(
uid
))
{
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10001"
));
}
if
(
badgeIds
==
null
||
badgeIds
.
isEmpty
())
{
return
ResponseDto
.
failure
(
"徽章ID列表不能为空"
);
}
List
<
String
>
requestBadgeIds
=
badgeIds
.
stream
()
.
filter
(
StringUtils:
:
isNotBlank
)
.
map
(
StringUtils:
:
trim
)
.
collect
(
Collectors
.
collectingAndThen
(
Collectors
.
toCollection
(
LinkedHashSet:
:
new
),
ArrayList:
:
new
));
if
(
requestBadgeIds
.
isEmpty
())
{
return
ResponseDto
.
failure
(
"徽章ID列表不能为空"
);
}
// 1
. 查询徽章配置
AdamCaomeiBadge
badge
=
adamCaomeiBadgeMapper
.
selectOne
(
// 1
) 批量查询徽章配置(一次查询)
List
<
AdamCaomeiBadge
>
badges
=
adamCaomeiBadgeMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadge
.
class
)
.
eq
(
AdamCaomeiBadge:
:
getBadgeId
,
badgeId
)
.
in
(
AdamCaomeiBadge:
:
getBadgeId
,
requestBadgeIds
)
.
eq
(
AdamCaomeiBadge:
:
getDisplayStatus
,
1
)
);
if
(
badge
==
null
)
{
log
.
error
(
"[claimBadge
] 徽章不存在或未上架, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
if
(
badge
s
==
null
||
badges
.
size
()
!=
requestBadgeIds
.
size
()
)
{
log
.
error
(
"[claimBadge
s] 存在徽章不存在或未上架, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10607"
));
}
Map
<
String
,
AdamCaomeiBadge
>
badgeMap
=
badges
.
stream
()
.
collect
(
Collectors
.
toMap
(
AdamCaomeiBadge:
:
getBadgeId
,
b
->
b
));
List
<
AdamCaomeiBadge
>
orderedBadges
=
requestBadgeIds
.
stream
()
.
map
(
badgeMap:
:
get
)
.
collect
(
Collectors
.
toList
());
// 2. 与收货地址 add 一致:先取 Redis(或回源)用户徽章列表,再判重;DB 再兜一层防缓存未命中或其它写入路径
List
<
AdamCaomeiPassportUserBadgeDto
>
badgeVos
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
...
...
@@ -74,19 +92,35 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
}
else
{
badgeVos
=
new
ArrayList
<>(
badgeVos
);
}
if
(
badgeVos
.
stream
().
anyMatch
(
b
->
badgeId
.
equals
(
b
.
getBadgeId
())))
{
log
.
info
(
"[claimBadge] 用户已领取过该徽章(Redis列表), uid: {}, badgeId: {}"
,
uid
,
badgeId
);
Set
<
String
>
claimedInCache
=
badgeVos
.
stream
()
.
map
(
AdamCaomeiPassportUserBadgeDto:
:
getBadgeId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toSet
());
if
(
requestBadgeIds
.
stream
().
anyMatch
(
claimedInCache:
:
contains
))
{
log
.
info
(
"[claimBadges] 用户已领取过徽章(Redis列表), uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10608"
));
}
int
count
=
adamCaomeiBadgeMapper
.
checkUserBadgeExists
(
uid
,
badgeId
);
if
(
c
ount
>
0
)
{
log
.
info
(
"[claimBadge
] 用户已领取过该徽章, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
List
<
String
>
claimedInDb
=
adamCaomeiBadgeMapper
.
selectClaimedBadgeIdsByUserAndBadgeIds
(
uid
,
requestBadgeIds
);
if
(
c
laimedInDb
!=
null
&&
!
claimedInDb
.
isEmpty
()
)
{
log
.
info
(
"[claimBadge
s] 用户已领取过徽章(DB), uid: {}, badgeIds: {}"
,
uid
,
claimedInDb
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10608"
));
}
int
type
=
badge
.
getType
()
==
null
?
0
:
badge
.
getType
();
boolean
hasType1
=
orderedBadges
.
stream
().
anyMatch
(
b
->
b
.
getType
()
!=
null
&&
b
.
getType
()
==
1
);
boolean
hasType2
=
orderedBadges
.
stream
().
anyMatch
(
b
->
b
.
getType
()
!=
null
&&
b
.
getType
()
==
2
);
boolean
hasType3
=
orderedBadges
.
stream
().
anyMatch
(
b
->
b
.
getType
()
!=
null
&&
b
.
getType
()
==
3
);
boolean
hasUnknownType
=
orderedBadges
.
stream
().
anyMatch
(
b
->
b
.
getType
()
==
null
||
(
b
.
getType
()
!=
1
&&
b
.
getType
()
!=
2
&&
b
.
getType
()
!=
3
));
if
(
hasType3
)
{
log
.
error
(
"[claimBadges] 含特殊徽章不可自助领取, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10612"
));
}
if
(
hasUnknownType
)
{
log
.
error
(
"[claimBadges] 含未知徽章类型, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10613"
));
}
if
(
type
==
1
)
{
if
(
hasType
1
)
{
AdamCaomeiPassport
bound
=
adamCaomeiPassportMapper
.
selectOne
(
Wrappers
.
lambdaQuery
(
AdamCaomeiPassport
.
class
)
.
eq
(
AdamCaomeiPassport:
:
getUserId
,
uid
)
...
...
@@ -94,57 +128,92 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
.
last
(
"limit 1"
)
);
if
(
bound
==
null
)
{
log
.
error
(
"[claimBadge
] 认领护照纪念徽章需先绑定护照, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
log
.
error
(
"[claimBadge
s] 认领护照纪念徽章需先绑定护照, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10609"
));
}
}
// 发放徽章 (source: 1-绑定护照自动发放/护照徽章认领):先写 Redis,再 MQ 落库
grantUserBadgeRedisThenMq
(
uid
,
badge
,
1
,
badgeVos
);
log
.
info
(
"[claimBadge] 护照纪念徽章认领成功, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
return
ResponseDto
.
success
(
badgeId
);
}
else
if
(
type
==
2
)
{
Set
<
String
>
paidPerformanceSet
=
Collections
.
emptySet
();
Set
<
String
>
passedApplyBadgeIds
=
Collections
.
emptySet
();
Set
<
String
>
passedApplyPerformanceIds
=
Collections
.
emptySet
();
Map
<
String
,
Set
<
String
>>
perfAllBadgeIds
=
Collections
.
emptyMap
();
if
(
hasType2
)
{
AdamRealInfoVo
real
=
adamRdmService
.
getRealInfoVoByUidPlain
(
uid
);
if
(
real
==
null
||
real
.
getState
()
==
null
||
real
.
getState
()
!=
1
||
StringUtils
.
isBlank
(
real
.
getIdCard
()))
{
log
.
error
(
"[claimBadge
] 认领演出徽章需先实名, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
log
.
error
(
"[claimBadge
s] 认领演出徽章需先实名, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10610"
));
}
List
<
String
>
paidPerformanceIds
=
adamRdmService
.
getPaidPerformanceIdsByIdCard
(
real
.
getIdCard
());
paidPerformanceSet
=
paidPerformanceIds
==
null
?
Collections
.
emptySet
()
:
new
HashSet
<>(
paidPerformanceIds
);
String
idCard
=
real
.
getIdCard
();
List
<
String
>
paidPerformanceIds
=
adamRdmService
.
getPaidPerformanceIdsByIdCard
(
idCard
);
boolean
hasPaidRecord
=
paidPerformanceIds
!=
null
&&
paidPerformanceIds
.
contains
(
badge
.
getPerformanceId
());
String
perfId
=
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
());
boolean
hasPassedApply
;
if
(
StringUtils
.
isNotBlank
(
perfId
))
{
hasPassedApply
=
countApplyForUserPerformanceAudit
(
uid
,
perfId
,
1
)
>
0
;
}
else
{
Integer
passedApplyCount
=
badgeApplyRecordMapper
.
selectCount
(
List
<
AdamCaomeiBadgeApplyRecord
>
passedApplyRecords
=
badgeApplyRecordMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadgeApplyRecord
.
class
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getUserId
,
uid
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getBadgeId
,
badgeId
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getAuditStatus
,
1
)
);
hasPassedApply
=
passedApplyCount
!=
null
&&
passedApplyCount
>
0
;
passedApplyBadgeIds
=
new
HashSet
<>();
passedApplyPerformanceIds
=
new
HashSet
<>();
if
(
passedApplyRecords
!=
null
)
{
for
(
AdamCaomeiBadgeApplyRecord
r
:
passedApplyRecords
)
{
if
(
r
==
null
)
{
continue
;
}
if
(
StringUtils
.
isNotBlank
(
r
.
getBadgeId
()))
{
passedApplyBadgeIds
.
add
(
r
.
getBadgeId
());
}
if
(
StringUtils
.
isNotBlank
(
r
.
getPerformanceId
()))
{
passedApplyPerformanceIds
.
add
(
r
.
getPerformanceId
());
}
}
}
Set
<
String
>
targetPerfIds
=
orderedBadges
.
stream
()
.
filter
(
b
->
b
.
getType
()
!=
null
&&
b
.
getType
()
==
2
)
.
map
(
AdamCaomeiBadge:
:
getPerformanceId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toSet
());
if
(!
targetPerfIds
.
isEmpty
())
{
List
<
AdamCaomeiBadge
>
perfBadges
=
adamCaomeiBadgeMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadge
.
class
)
.
eq
(
AdamCaomeiBadge:
:
getType
,
2
)
.
in
(
AdamCaomeiBadge:
:
getPerformanceId
,
targetPerfIds
)
);
perfAllBadgeIds
=
perfBadges
.
stream
()
.
filter
(
b
->
StringUtils
.
isNotBlank
(
b
.
getPerformanceId
())
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
()))
.
collect
(
Collectors
.
groupingBy
(
AdamCaomeiBadge:
:
getPerformanceId
,
Collectors
.
mapping
(
AdamCaomeiBadge:
:
getBadgeId
,
Collectors
.
toSet
())));
}
}
List
<
String
>
claimedBadgeIds
=
new
ArrayList
<>();
for
(
AdamCaomeiBadge
badge
:
orderedBadges
)
{
int
type
=
badge
.
getType
()
==
null
?
0
:
badge
.
getType
();
int
source
=
1
;
if
(
type
==
2
)
{
String
perfId
=
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
());
boolean
hasPaidRecord
=
StringUtils
.
isNotBlank
(
perfId
)
&&
paidPerformanceSet
.
contains
(
perfId
);
boolean
hasPassedApply
=
false
;
if
(
StringUtils
.
isNotBlank
(
perfId
))
{
if
(
passedApplyPerformanceIds
.
contains
(
perfId
))
{
hasPassedApply
=
true
;
}
else
{
Set
<
String
>
badgeIdSet
=
perfAllBadgeIds
.
getOrDefault
(
perfId
,
Collections
.
emptySet
());
hasPassedApply
=
badgeIdSet
.
stream
().
anyMatch
(
passedApplyBadgeIds:
:
contains
);
}
}
if
(!
hasPaidRecord
&&
!
hasPassedApply
)
{
log
.
error
(
"[claimBadge] 无购票记录且无通过的补签申请,无法认领, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
log
.
error
(
"[claimBadges] 无购票记录且无通过补签,无法认领, uid: {}, badgeId: {}"
,
uid
,
badge
.
getBadgeId
()
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10611"
));
}
source
=
hasPaidRecord
?
2
:
3
;
}
int
source
=
hasPaidRecord
?
2
:
3
;
grantUserBadgeRedisThenMq
(
uid
,
badge
,
source
,
badgeVos
);
log
.
info
(
"[claimBadge] 演出纪念徽章认领成功, uid: {}, badgeId: {}, 发放数量: {}"
,
uid
,
badgeId
,
1
);
return
ResponseDto
.
success
(
badgeId
);
}
else
if
(
type
==
3
)
{
log
.
error
(
"[claimBadge] 特殊徽章不可自助领取, uid: {}, badgeId: {}"
,
uid
,
badgeId
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10612"
));
claimedBadgeIds
.
add
(
badge
.
getBadgeId
());
}
log
.
error
(
"[claimBadge] 未知的徽章类型, uid: {}, badgeId: {}, type: {}"
,
uid
,
badgeId
,
type
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10613"
)
);
log
.
info
(
"[claimBadges] 批量认领成功, uid: {}, badgeIds: {}"
,
uid
,
claimedBadgeIds
);
return
ResponseDto
.
success
(
claimedBadgeIds
);
}
/**
...
...
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