记得上下班打卡 | 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
633e0966
Commit
633e0966
authored
May 18, 2026
by
wangyifan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
草莓护照v1.1- 整体重构获取home页汇总数据;优化查询效率
parent
9607bee7
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
609 additions
and
360 deletions
+609
-360
AdamCaomeiPassportBadgeShelfItemVo.java
...rvice/adam/dto/vo/AdamCaomeiPassportBadgeShelfItemVo.java
+1
-1
AdamCaomeiPassportHomeVo.java
...quidnet/service/adam/dto/vo/AdamCaomeiPassportHomeVo.java
+4
-1
IAdamCaomeiPassportUserService.java
.../service/adam/service/IAdamCaomeiPassportUserService.java
+2
-7
AdamCaomeiPassportUserController.java
...ice/adam/controller/AdamCaomeiPassportUserController.java
+1
-8
CaomeiBadgeApplyStatus.java
...t/service/adam/service/caomei/CaomeiBadgeApplyStatus.java
+55
-0
CaomeiBadgeEligibilityService.java
...ce/adam/service/caomei/CaomeiBadgeEligibilityService.java
+300
-0
CaomeiBadgeGrantService.java
.../service/adam/service/caomei/CaomeiBadgeGrantService.java
+156
-0
AdamCaomeiBadgeUserServiceImpl.java
...ice/adam/service/impl/AdamCaomeiBadgeUserServiceImpl.java
+12
-90
AdamCaomeiPassportUserServiceImpl.java
.../adam/service/impl/AdamCaomeiPassportUserServiceImpl.java
+78
-253
No files found.
liquidnet-bus-api/liquidnet-service-adam-api/src/main/java/com/liquidnet/service/adam/dto/vo/AdamCaomeiPassportBadgeShelfItemVo.java
View file @
633e0966
...
@@ -27,7 +27,7 @@ public class AdamCaomeiPassportBadgeShelfItemVo {
...
@@ -27,7 +27,7 @@ public class AdamCaomeiPassportBadgeShelfItemVo {
@ApiModelProperty
(
"分享文案"
)
@ApiModelProperty
(
"分享文案"
)
private
String
shareText
;
private
String
shareText
;
@ApiModelProperty
(
"类型 1护照 2演出 3特殊(不含 4 签证页,签证页见
签证卡片接口
)"
)
@ApiModelProperty
(
"类型 1护照 2演出 3特殊(不含 4 签证页,签证页见
home.visaBadges
)"
)
private
Integer
type
;
private
Integer
type
;
@ApiModelProperty
(
"关联演出ID(演出纪念徽章、签证页)"
)
@ApiModelProperty
(
"关联演出ID(演出纪念徽章、签证页)"
)
...
...
liquidnet-bus-api/liquidnet-service-adam-api/src/main/java/com/liquidnet/service/adam/dto/vo/AdamCaomeiPassportHomeVo.java
View file @
633e0966
...
@@ -13,9 +13,12 @@ public class AdamCaomeiPassportHomeVo {
...
@@ -13,9 +13,12 @@ public class AdamCaomeiPassportHomeVo {
@ApiModelProperty
(
"个人信息卡片"
)
@ApiModelProperty
(
"个人信息卡片"
)
private
AdamCaomeiPassportUserCardVo
userCard
;
private
AdamCaomeiPassportUserCardVo
userCard
;
@ApiModelProperty
(
"已认领徽章(用于网格墙;不含 type=4 签证页
,签证页见签证卡片列表接口
)"
)
@ApiModelProperty
(
"已认领徽章(用于网格墙;不含 type=4 签证页)"
)
private
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
claimedBadges
;
private
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
claimedBadges
;
@ApiModelProperty
(
"签证页卡片(type=4;home 内静默发放后返回,含 performanceName)"
)
private
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
visaBadges
;
@ApiModelProperty
(
"全部上架徽章货架(不含 type=4 签证页;演出类含 performanceName)"
)
@ApiModelProperty
(
"全部上架徽章货架(不含 type=4 签证页;演出类含 performanceName)"
)
private
List
<
AdamCaomeiPassportBadgeShelfItemVo
>
allBadges
;
private
List
<
AdamCaomeiPassportBadgeShelfItemVo
>
allBadges
;
}
}
liquidnet-bus-api/liquidnet-service-adam-api/src/main/java/com/liquidnet/service/adam/service/IAdamCaomeiPassportUserService.java
View file @
633e0966
...
@@ -17,16 +17,11 @@ public interface IAdamCaomeiPassportUserService {
...
@@ -17,16 +17,11 @@ public interface IAdamCaomeiPassportUserService {
ResponseDto
<
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>>
bindPassport
(
String
passportNo
);
ResponseDto
<
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>>
bindPassport
(
String
passportNo
);
/**
/**
* 护照首页:个人信息、实名状态、已认领墙、上架徽章货架;末尾自动发放满足条件的 type=4 签证页(响应中不含签证页)
* 护照首页:个人信息、实名状态、已认领墙、签证页(type=4)、上架徽章货架;
* 末尾自动发放满足条件的 type=4 签证页,并在 {@link AdamCaomeiPassportHomeVo#getVisaBadges()} 返回。
*/
*/
ResponseDto
<
AdamCaomeiPassportHomeVo
>
getPassportHome
();
ResponseDto
<
AdamCaomeiPassportHomeVo
>
getPassportHome
();
/**
* 签证页卡片列表(type=4):仅从用户已获徽章缓存/库中筛选 type=4。
* 需用户先访问护照首页 {@link #getPassportHome()} 触发静默发放后,本接口才有数据。
*/
ResponseDto
<
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>>
listVisaCards
();
/**
/**
* 校验当前登录用户是否已绑定护照
* 校验当前登录用户是否已绑定护照
*/
*/
...
...
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/controller/AdamCaomeiPassportUserController.java
View file @
633e0966
...
@@ -36,20 +36,13 @@ public class AdamCaomeiPassportUserController {
...
@@ -36,20 +36,13 @@ public class AdamCaomeiPassportUserController {
}
}
@ApiOperationSupport
(
order
=
2
)
@ApiOperationSupport
(
order
=
2
)
@ApiOperation
(
"护照首页聚合数据"
)
@ApiOperation
(
"护照首页聚合数据
(含签证页 type=4 字段 visaBadges,访问时自动静默发放)
"
)
@GetMapping
(
"home"
)
@GetMapping
(
"home"
)
public
ResponseDto
<
AdamCaomeiPassportHomeVo
>
home
()
{
public
ResponseDto
<
AdamCaomeiPassportHomeVo
>
home
()
{
return
adamCaomeiPassportUserService
.
getPassportHome
();
return
adamCaomeiPassportUserService
.
getPassportHome
();
}
}
@ApiOperationSupport
(
order
=
3
)
@ApiOperationSupport
(
order
=
3
)
@ApiOperation
(
"签证页卡片列表:仅从用户已获徽章中筛选 type=4;须先访问护照首页 home 完成静默发放后再查看"
)
@GetMapping
(
"visa/list"
)
public
ResponseDto
<
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>>
visaList
()
{
return
adamCaomeiPassportUserService
.
listVisaCards
();
}
@ApiOperationSupport
(
order
=
4
)
@ApiOperation
(
"校验当前用户是否已绑定护照"
)
@ApiOperation
(
"校验当前用户是否已绑定护照"
)
@GetMapping
(
"/check"
)
@GetMapping
(
"/check"
)
public
ResponseDto
<
Boolean
>
checkBound
()
{
public
ResponseDto
<
Boolean
>
checkBound
()
{
...
...
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/caomei/CaomeiBadgeApplyStatus.java
0 → 100644
View file @
633e0966
package
com
.
liquidnet
.
service
.
adam
.
service
.
caomei
;
import
java.util.Collections
;
import
java.util.Set
;
/**
* 用户补签审核状态快照(按「徽章 ID」与「场次 performanceId」两个维度聚合)。
* <p>
* 由 {@link CaomeiBadgeEligibilityService#loadApplyBadgeStatus} 从 DB 补签表加载,
* 供护照首页货架({@code claimable} / {@code applyPending})与演出徽章认领前置判断共用,
* 避免 home 展示与 POST claim 规则不一致。
*/
public
final
class
CaomeiBadgeApplyStatus
{
/** 审核已通过(auditStatus=1)的补签申请对应的 badgeId */
private
final
Set
<
String
>
passedApplyBadgeIds
;
/** 待审核(auditStatus=0)的补签申请对应的 badgeId */
private
final
Set
<
String
>
pendingApplyBadgeIds
;
/** 审核已通过补签所关联的场次 ID(含从 badge 配置兜底解析的 performanceId) */
private
final
Set
<
String
>
passedApplyPerformanceIds
;
/** 待审核补签所关联的场次 ID */
private
final
Set
<
String
>
pendingApplyPerformanceIds
;
/**
* @param passedApplyBadgeIds 已通过补签的徽章 ID 集合,可为 null(视为空集)
* @param pendingApplyBadgeIds 待审核补签的徽章 ID 集合,可为 null
* @param passedApplyPerformanceIds 已通过补签的场次 ID 集合,可为 null
* @param pendingApplyPerformanceIds 待审核补签的场次 ID 集合,可为 null
*/
public
CaomeiBadgeApplyStatus
(
Set
<
String
>
passedApplyBadgeIds
,
Set
<
String
>
pendingApplyBadgeIds
,
Set
<
String
>
passedApplyPerformanceIds
,
Set
<
String
>
pendingApplyPerformanceIds
)
{
this
.
passedApplyBadgeIds
=
passedApplyBadgeIds
==
null
?
Collections
.
emptySet
()
:
passedApplyBadgeIds
;
this
.
pendingApplyBadgeIds
=
pendingApplyBadgeIds
==
null
?
Collections
.
emptySet
()
:
pendingApplyBadgeIds
;
this
.
passedApplyPerformanceIds
=
passedApplyPerformanceIds
==
null
?
Collections
.
emptySet
()
:
passedApplyPerformanceIds
;
this
.
pendingApplyPerformanceIds
=
pendingApplyPerformanceIds
==
null
?
Collections
.
emptySet
()
:
pendingApplyPerformanceIds
;
}
public
Set
<
String
>
getPassedApplyBadgeIds
()
{
return
passedApplyBadgeIds
;
}
public
Set
<
String
>
getPendingApplyBadgeIds
()
{
return
pendingApplyBadgeIds
;
}
public
Set
<
String
>
getPassedApplyPerformanceIds
()
{
return
passedApplyPerformanceIds
;
}
public
Set
<
String
>
getPendingApplyPerformanceIds
()
{
return
pendingApplyPerformanceIds
;
}
}
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/caomei/CaomeiBadgeEligibilityService.java
0 → 100644
View file @
633e0966
package
com
.
liquidnet
.
service
.
adam
.
service
.
caomei
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.liquidnet.service.adam.dto.vo.AdamRealInfoVo
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadgeApplyRecord
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiBadgeApplyRecordMapper
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiBadgeMapper
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
lombok.Getter
;
import
lombok.Setter
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
* 草莓徽章「领取资格」判断:护照首页货架展示(是否可点领取、是否补签待审)
* 与 {@code POST caomei/badge/claim} 演出徽章校验共用同一套规则。
* <p>
* 不负责写 Redis/MQ;发放见 {@link CaomeiBadgeGrantService}。
*/
@Service
public
class
CaomeiBadgeEligibilityService
{
/** 徽章类型:签证页(仅 home 静默发放,不可 claim) */
private
static
final
int
BADGE_TYPE_VISA
=
4
;
@Autowired
private
AdamCaomeiBadgeApplyRecordMapper
badgeApplyRecordMapper
;
@Autowired
private
AdamCaomeiBadgeMapper
adamCaomeiBadgeMapper
;
@Autowired
private
AdamRdmService
adamRdmService
;
/**
* 加载用户补签状态,用于 home 货架 {@code allBadges} 的 claimable / applyPending。
* <p>
* 只查 auditStatus 为 0(待审)、1(通过)的记录;驳回(2) 不参与。
* 补签记录若未填 performanceId,会用 {@code published} 里 badgeId→performanceId 兜底,
* 以便按「场次」聚合待审/通过状态。
*
* @param uid 当前用户 ID
* @param published 已上架徽章全量列表(来自 published Redis),用于 performanceId 兜底
*/
public
CaomeiBadgeApplyStatus
loadApplyBadgeStatus
(
String
uid
,
List
<
AdamCaomeiBadge
>
published
)
{
// 徽章ID 演出ID Map
Map
<
String
,
String
>
badgeIdToPerformanceId
=
new
HashMap
<>();
if
(
published
!=
null
)
{
for
(
AdamCaomeiBadge
b
:
published
)
{
if
(
b
!=
null
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
()))
{
badgeIdToPerformanceId
.
put
(
b
.
getBadgeId
(),
StringUtils
.
trimToEmpty
(
b
.
getPerformanceId
()));
}
}
}
// 查询用户提交的补签申请(0 待审核、1 已通过)
List
<
AdamCaomeiBadgeApplyRecord
>
applyRecords
=
badgeApplyRecordMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadgeApplyRecord
.
class
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getUserId
,
uid
)
.
in
(
AdamCaomeiBadgeApplyRecord:
:
getAuditStatus
,
0
,
1
)
);
Set
<
String
>
passedApplyBadgeIds
=
new
HashSet
<>();
// 补签通过的徽章ID
Set
<
String
>
pendingApplyBadgeIds
=
new
HashSet
<>();
// 补签中的徽章ID
Set
<
String
>
passedApplyPerformanceIds
=
new
HashSet
<>();
// 补签通过的演出ID
Set
<
String
>
pendingApplyPerformanceIds
=
new
HashSet
<>();
// 补签中的演出ID
if
(
applyRecords
!=
null
)
{
for
(
AdamCaomeiBadgeApplyRecord
r
:
applyRecords
)
{
if
(
r
==
null
||
StringUtils
.
isBlank
(
r
.
getBadgeId
())
||
r
.
getAuditStatus
()
==
null
)
{
continue
;
}
String
perf
=
StringUtils
.
trimToEmpty
(
r
.
getPerformanceId
());
if
(
StringUtils
.
isBlank
(
perf
))
{
perf
=
StringUtils
.
trimToEmpty
(
badgeIdToPerformanceId
.
get
(
r
.
getBadgeId
()));
}
if
(
r
.
getAuditStatus
()
==
1
)
{
passedApplyBadgeIds
.
add
(
r
.
getBadgeId
());
if
(
StringUtils
.
isNotBlank
(
perf
))
{
passedApplyPerformanceIds
.
add
(
perf
);
}
}
else
if
(
r
.
getAuditStatus
()
==
0
)
{
pendingApplyBadgeIds
.
add
(
r
.
getBadgeId
());
if
(
StringUtils
.
isNotBlank
(
perf
))
{
pendingApplyPerformanceIds
.
add
(
perf
);
}
}
}
}
return
new
CaomeiBadgeApplyStatus
(
passedApplyBadgeIds
,
pendingApplyBadgeIds
,
passedApplyPerformanceIds
,
pendingApplyPerformanceIds
);
}
/**
* 为本次 claim 请求中的 type=2 徽章构建校验上下文(实名、购票场次、补签通过、同场 badge 映射)。
* <p>
* 须在 {@link #canClaimPerformanceBadge} / {@link #resolveClaimSourceForType2} 之前调用一次。
*
* @param uid 用户 ID
* @param type2BadgesInRequest 本次请求要认领的徽章列表(可含 type=1,内部只取 type=2 的 performanceId)
* @return {@code realNameOk=false} 表示未实名,不可领任何 type=2
*/
public
Type2ClaimContext
buildType2ClaimContext
(
String
uid
,
List
<
AdamCaomeiBadge
>
type2BadgesInRequest
)
{
AdamRealInfoVo
real
=
adamRdmService
.
getRealInfoVoByUidPlain
(
uid
);
if
(
real
==
null
||
real
.
getState
()
==
null
||
real
.
getState
()
!=
1
||
StringUtils
.
isBlank
(
real
.
getIdCard
()))
{
return
Type2ClaimContext
.
notEligible
();
}
List
<
String
>
paidPerformanceIds
=
adamRdmService
.
getPaidPerformanceIdsByIdCard
(
real
.
getIdCard
());
Set
<
String
>
paidPerformanceSet
=
paidPerformanceIds
==
null
?
Collections
.
emptySet
()
:
new
HashSet
<>(
paidPerformanceIds
);
List
<
AdamCaomeiBadgeApplyRecord
>
passedApplyRecords
=
badgeApplyRecordMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadgeApplyRecord
.
class
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getUserId
,
uid
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getAuditStatus
,
1
)
);
Set
<
String
>
passedApplyBadgeIds
=
new
HashSet
<>();
Set
<
String
>
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
());
}
}
}
Map
<
String
,
Set
<
String
>>
perfAllBadgeIds
=
Collections
.
emptyMap
();
if
(
type2BadgesInRequest
!=
null
&&
!
type2BadgesInRequest
.
isEmpty
())
{
Set
<
String
>
targetPerfIds
=
type2BadgesInRequest
.
stream
()
.
filter
(
b
->
b
!=
null
&&
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
==
null
?
Collections
.
emptyMap
()
:
perfBadges
.
stream
()
.
filter
(
b
->
StringUtils
.
isNotBlank
(
b
.
getPerformanceId
())
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
()))
.
collect
(
Collectors
.
groupingBy
(
AdamCaomeiBadge:
:
getPerformanceId
,
Collectors
.
mapping
(
AdamCaomeiBadge:
:
getBadgeId
,
Collectors
.
toSet
())));
}
}
return
new
Type2ClaimContext
(
true
,
paidPerformanceSet
,
passedApplyBadgeIds
,
passedApplyPerformanceIds
,
perfAllBadgeIds
);
}
/**
* 判断单枚 type=2 演出纪念徽章是否允许认领。
* <p>
* 满足其一即可:身份证下有该场次购票;该场次补签已通过;同场次任一 type=2 徽章补签已通过。
*
* @param badge 待认领配置(须 type=2)
* @param ctx {@link #buildType2ClaimContext} 的返回值
*/
public
boolean
canClaimPerformanceBadge
(
AdamCaomeiBadge
badge
,
Type2ClaimContext
ctx
)
{
if
(
badge
==
null
||
ctx
==
null
||
!
ctx
.
isRealNameOk
())
{
return
false
;
}
String
perfId
=
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
());
boolean
hasPaidRecord
=
StringUtils
.
isNotBlank
(
perfId
)
&&
ctx
.
getPaidPerformanceSet
().
contains
(
perfId
);
if
(
hasPaidRecord
)
{
return
true
;
}
if
(
StringUtils
.
isBlank
(
perfId
))
{
return
false
;
}
if
(
ctx
.
getPassedApplyPerformanceIds
().
contains
(
perfId
))
{
return
true
;
}
Set
<
String
>
badgeIdSet
=
ctx
.
getPerfAllBadgeIds
().
getOrDefault
(
perfId
,
Collections
.
emptySet
());
return
badgeIdSet
.
stream
().
anyMatch
(
id
->
ctx
.
getPassedApplyBadgeIds
().
contains
(
id
));
}
/**
* 解析 type=2 认领落库时的 source:有购票记录为 2,否则视为补签通过为 3。
*
* @param badge 当前认领的 type=2 徽章
* @param ctx 已构建的 Type2 上下文
*/
public
int
resolveClaimSourceForType2
(
AdamCaomeiBadge
badge
,
Type2ClaimContext
ctx
)
{
String
perfId
=
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
());
boolean
hasPaid
=
StringUtils
.
isNotBlank
(
perfId
)
&&
ctx
.
getPaidPerformanceSet
().
contains
(
perfId
);
return
hasPaid
?
2
:
3
;
}
/**
* 计算首页货架单枚徽章的交互状态(未领取时是否显示可领、是否补签待审)。
* <p>
* type=1:已绑护照即可 claimable(用于后上架补领);type=2:购票或补签通过;
* type=3/4:不可自助领取(4 由 home 静默发,不在货架展示)。
*
* @param badge 货架上的徽章配置
* @param claimed 用户是否已在 user 缓存/库中拥有该 badgeId
* @param paidPerformanceIds 实名身份证下的已购场次 ID 列表(home 已查)
* @param applyStatus {@link #loadApplyBadgeStatus} 结果
*/
public
ShelfInteractState
resolveShelfInteract
(
AdamCaomeiBadge
badge
,
boolean
claimed
,
List
<
String
>
paidPerformanceIds
,
CaomeiBadgeApplyStatus
applyStatus
)
{
ShelfInteractState
state
=
new
ShelfInteractState
();
if
(
claimed
)
{
state
.
setClaimable
(
false
);
state
.
setApplyPending
(
false
);
return
state
;
}
int
type
=
badge
.
getType
()
==
null
?
0
:
badge
.
getType
();
String
perfId
=
StringUtils
.
defaultString
(
badge
.
getPerformanceId
());
if
(
type
==
1
)
{
state
.
setClaimable
(
true
);
}
else
if
(
type
==
2
)
{
boolean
canClaimByPaid
=
paidPerformanceIds
!=
null
&&
paidPerformanceIds
.
contains
(
badge
.
getPerformanceId
());
boolean
canClaimByApplyThisBadge
=
applyStatus
.
getPassedApplyBadgeIds
().
contains
(
badge
.
getBadgeId
());
boolean
canClaimByApplyThisPerf
=
StringUtils
.
isNotBlank
(
perfId
)
&&
applyStatus
.
getPassedApplyPerformanceIds
().
contains
(
perfId
);
state
.
setClaimable
(
canClaimByPaid
||
canClaimByApplyThisBadge
||
canClaimByApplyThisPerf
);
boolean
pendingThisBadge
=
applyStatus
.
getPendingApplyBadgeIds
().
contains
(
badge
.
getBadgeId
());
boolean
pendingThisPerf
=
StringUtils
.
isNotBlank
(
perfId
)
&&
applyStatus
.
getPendingApplyPerformanceIds
().
contains
(
perfId
);
state
.
setApplyPending
(
pendingThisBadge
||
pendingThisPerf
);
}
else
{
state
.
setClaimable
(
false
);
}
return
state
;
}
/** 是否签证页 type=4(用于 home 响应拆分 claimedBadges / visaBadges) */
public
static
boolean
isVisaBadgeType
(
Integer
type
)
{
return
type
!=
null
&&
type
==
BADGE_TYPE_VISA
;
}
/**
* type=2 批量认领时的只读上下文,避免 claim 循环内重复查实名/购票/补签。
*/
@Getter
public
static
final
class
Type2ClaimContext
{
/** 是否已实名(state=1 且有身份证号) */
private
final
boolean
realNameOk
;
/** 身份证下已支付订单关联的场次 ID */
private
final
Set
<
String
>
paidPerformanceSet
;
/** 补签审核通过的 badgeId */
private
final
Set
<
String
>
passedApplyBadgeIds
;
/** 补签审核通过的 performanceId */
private
final
Set
<
String
>
passedApplyPerformanceIds
;
/**
* 场次 → 该场次下所有 type=2 的 badgeId 集合;
* 用于「同场次任一徽章补签通过则本场次均可领」规则。
*/
private
final
Map
<
String
,
Set
<
String
>>
perfAllBadgeIds
;
private
Type2ClaimContext
(
boolean
realNameOk
,
Set
<
String
>
paidPerformanceSet
,
Set
<
String
>
passedApplyBadgeIds
,
Set
<
String
>
passedApplyPerformanceIds
,
Map
<
String
,
Set
<
String
>>
perfAllBadgeIds
)
{
this
.
realNameOk
=
realNameOk
;
this
.
paidPerformanceSet
=
paidPerformanceSet
;
this
.
passedApplyBadgeIds
=
passedApplyBadgeIds
;
this
.
passedApplyPerformanceIds
=
passedApplyPerformanceIds
;
this
.
perfAllBadgeIds
=
perfAllBadgeIds
;
}
/** 未实名时的空上下文,{@link #canClaimPerformanceBadge} 将全部返回 false */
static
Type2ClaimContext
notEligible
()
{
return
new
Type2ClaimContext
(
false
,
Collections
.
emptySet
(),
Collections
.
emptySet
(),
Collections
.
emptySet
(),
Collections
.
emptyMap
());
}
}
/**
* 首页货架项的前端交互标记(对应 {@link com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportBadgeShelfItemVo})。
*/
@Getter
@Setter
public
static
final
class
ShelfInteractState
{
/** 未领取时是否展示为可点击认领 */
private
boolean
claimable
;
/** 是否展示补签审核中(仅 type=2 有意义) */
private
boolean
applyPending
;
}
}
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/caomei/CaomeiBadgeGrantService.java
0 → 100644
View file @
633e0966
package
com
.
liquidnet
.
service
.
adam
.
service
.
caomei
;
import
com.liquidnet.commons.lang.util.DateUtil
;
import
com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
com.liquidnet.service.adam.util.QueueUtils
;
import
com.liquidnet.service.base.SqlMapping
;
import
com.liquidnet.service.base.constant.MQConst
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
* 草莓徽章「发放」统一入口:写入用户徽章 Redis({@code INFO_CAOMEI_BADGE_USER + uid}),
* 并通过 MQ 异步 INSERT {@code adam_caomei_user_badge}。
* <p>
* 调用方:绑护照发 type=1、用户 claim、home 静默发 type=4 签证页。
* <p>
* {@code source} 与库表一致:1-绑定护照,2-购票自动,3-补签通过,4-现场管理员(本服务未使用 4)。
*/
@Slf4j
@Service
public
class
CaomeiBadgeGrantService
{
@Autowired
private
AdamRdmService
adamRdmService
;
@Autowired
private
QueueUtils
queueUtils
;
/**
* 将运营配置的徽章实体转为用户已获列表中的缓存 DTO(尚未写 Redis)。
*
* @param badge 上架徽章配置(含 badgeId、名称、type、performanceId 等)
* @param source 获得途径,见类说明
* @param claimedAt 获得时间,null 时使用当前时间
*/
public
AdamCaomeiPassportUserBadgeDto
toUserBadgeDto
(
AdamCaomeiBadge
badge
,
int
source
,
Date
claimedAt
)
{
AdamCaomeiPassportUserBadgeDto
dto
=
new
AdamCaomeiPassportUserBadgeDto
();
dto
.
setBadgeId
(
badge
.
getBadgeId
());
dto
.
setBadgeName
(
StringUtils
.
defaultString
(
badge
.
getName
()));
dto
.
setSubTitle
(
StringUtils
.
defaultString
(
badge
.
getSubTitle
()));
dto
.
setIcon
(
StringUtils
.
defaultString
(
badge
.
getIcon
()));
dto
.
setShareText
(
StringUtils
.
defaultString
(
badge
.
getShareText
()));
dto
.
setType
(
badge
.
getType
());
dto
.
setPerformanceId
(
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
()));
dto
.
setClaimedAt
(
claimedAt
!=
null
?
claimedAt
:
DateUtil
.
now
());
dto
.
setSource
(
source
);
return
dto
;
}
/**
* 批量发放:对比用户当前已拥有 badgeId,仅对「尚未拥有」的徽章追加缓存并落库。
* <p>
* 适用于:绑护照一次性发多个 type=1、home 末尾静默发多个 type=4。
*
* @param uid 当前用户 ID
* @param badges 待发放的配置列表(通常来自 published 缓存筛选)
* @param source 获得途径
* @param grantAt 统一获得时间(批量场景 bind/签证 使用同一时间戳),null 则取当前时间
* @return 本次实际写入 Redis 的 DTO;空列表表示全部已拥有、未发生发放
*/
public
List
<
AdamCaomeiPassportUserBadgeDto
>
grantBadgesIfAbsent
(
String
uid
,
List
<
AdamCaomeiBadge
>
badges
,
int
source
,
Date
grantAt
)
{
if
(
StringUtils
.
isBlank
(
uid
)
||
CollectionUtils
.
isEmpty
(
badges
))
{
return
new
ArrayList
<>();
}
Date
at
=
grantAt
!=
null
?
grantAt
:
DateUtil
.
now
();
List
<
AdamCaomeiPassportUserBadgeDto
>
cacheList
=
copyUserBadgeCache
(
uid
);
Set
<
String
>
existedBadgeIds
=
cacheList
.
stream
()
.
map
(
AdamCaomeiPassportUserBadgeDto:
:
getBadgeId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toSet
());
List
<
AdamCaomeiPassportUserBadgeDto
>
appendVos
=
badges
.
stream
()
.
filter
(
b
->
b
!=
null
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
()))
.
filter
(
b
->
!
existedBadgeIds
.
contains
(
b
.
getBadgeId
()))
.
map
(
b
->
toUserBadgeDto
(
b
,
source
,
at
))
.
collect
(
Collectors
.
toList
());
if
(
appendVos
.
isEmpty
())
{
return
appendVos
;
}
adamRdmService
.
addUserCaomeiBadgeDtosByUid
(
uid
,
cacheList
,
appendVos
);
sendUserBadgeInsertMq
(
uid
,
appendVos
,
source
,
at
);
return
appendVos
;
}
/**
* 单条发放:用于 POST claim 循环内逐枚写入。
* <p>
* 调用方须已做「未领取」校验;本方法不再查重。
*
* @param uid 用户 ID
* @param badge 单枚上架徽章配置
* @param source 获得途径(type=2 时由 Eligibility 解析为 2 或 3)
* @param mutableCacheList 当前请求内持有的用户徽章列表副本,发放后会 append 并写回 Redis
*/
public
void
grantOne
(
String
uid
,
AdamCaomeiBadge
badge
,
int
source
,
List
<
AdamCaomeiPassportUserBadgeDto
>
mutableCacheList
)
{
if
(
badge
==
null
||
StringUtils
.
isBlank
(
badge
.
getBadgeId
()))
{
return
;
}
Date
now
=
new
Date
();
AdamCaomeiPassportUserBadgeDto
dto
=
toUserBadgeDto
(
badge
,
source
,
now
);
adamRdmService
.
addUserCaomeiBadgeDtoByUid
(
uid
,
mutableCacheList
,
dto
);
queueUtils
.
sendMsgByRedis
(
MQConst
.
AdamQueue
.
SQL_UCENTER
.
getKey
(),
SqlMapping
.
get
(
"adam_caomei_user_badge.add"
,
uid
,
badge
.
getBadgeId
(),
source
,
now
)
);
}
/** 读取用户徽章 Redis,返回可修改副本(miss 时可能为空列表) */
private
List
<
AdamCaomeiPassportUserBadgeDto
>
copyUserBadgeCache
(
String
uid
)
{
List
<
AdamCaomeiPassportUserBadgeDto
>
cache
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
if
(
cache
==
null
)
{
return
new
ArrayList
<>();
}
return
new
ArrayList
<>(
cache
);
}
/** 批量 MQ:仅对 appendVos 中的 badgeId 发送 INSERT,与 Redis 追加范围一致 */
private
void
sendUserBadgeInsertMq
(
String
uid
,
List
<
AdamCaomeiPassportUserBadgeDto
>
appendVos
,
int
source
,
Date
grantAt
)
{
LinkedList
<
Object
[]>
paramsList
=
new
LinkedList
<>();
for
(
AdamCaomeiPassportUserBadgeDto
dto
:
appendVos
)
{
if
(
dto
==
null
||
StringUtils
.
isBlank
(
dto
.
getBadgeId
()))
{
continue
;
}
paramsList
.
add
(
new
Object
[]{
uid
,
dto
.
getBadgeId
(),
source
,
grantAt
});
}
if
(
paramsList
.
isEmpty
())
{
return
;
}
queueUtils
.
sendMsgByRedis
(
MQConst
.
AdamQueue
.
SQL_UCENTER
.
getKey
(),
SqlMapping
.
get
(
"adam_caomei_user_badge.add"
,
paramsList
)
);
}
}
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/impl/AdamCaomeiBadgeUserServiceImpl.java
View file @
633e0966
...
@@ -7,7 +7,6 @@ import com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto;
...
@@ -7,7 +7,6 @@ import com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto;
import
com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyParam
;
import
com.liquidnet.service.adam.dto.param.AdamCaomeiBadgeApplyParam
;
import
com.liquidnet.service.adam.dto.AdamCaomeiBadgeApplyRecordUserDto
;
import
com.liquidnet.service.adam.dto.AdamCaomeiBadgeApplyRecordUserDto
;
import
com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyRecordUserVo
;
import
com.liquidnet.service.adam.dto.vo.AdamCaomeiBadgeApplyRecordUserVo
;
import
com.liquidnet.service.adam.dto.vo.AdamRealInfoVo
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadgeApplyRecord
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadgeApplyRecord
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.entity.AdamCaomeiPassport
;
import
com.liquidnet.service.adam.entity.AdamCaomeiPassport
;
...
@@ -16,6 +15,8 @@ import com.liquidnet.service.adam.mapper.AdamCaomeiBadgeMapper;
...
@@ -16,6 +15,8 @@ import com.liquidnet.service.adam.mapper.AdamCaomeiBadgeMapper;
import
com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
com.liquidnet.service.adam.service.IAdamCaomeiBadgeUserService
;
import
com.liquidnet.service.adam.service.IAdamCaomeiBadgeUserService
;
import
com.liquidnet.service.adam.service.caomei.CaomeiBadgeEligibilityService
;
import
com.liquidnet.service.adam.service.caomei.CaomeiBadgeGrantService
;
import
com.liquidnet.service.adam.util.QueueUtils
;
import
com.liquidnet.service.adam.util.QueueUtils
;
import
com.liquidnet.service.base.ErrorMapping
;
import
com.liquidnet.service.base.ErrorMapping
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.base.ResponseDto
;
...
@@ -29,12 +30,10 @@ import org.springframework.transaction.annotation.Transactional;
...
@@ -29,12 +30,10 @@ import org.springframework.transaction.annotation.Transactional;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.HashSet
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
@Slf4j
@Slf4j
...
@@ -50,6 +49,10 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
...
@@ -50,6 +49,10 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
@Autowired
@Autowired
private
AdamRdmService
adamRdmService
;
private
AdamRdmService
adamRdmService
;
@Autowired
@Autowired
private
CaomeiBadgeGrantService
caomeiBadgeGrantService
;
@Autowired
private
CaomeiBadgeEligibilityService
caomeiBadgeEligibilityService
;
@Autowired
private
QueueUtils
queueUtils
;
private
QueueUtils
queueUtils
;
@Override
@Override
...
@@ -133,56 +136,13 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
...
@@ -133,56 +136,13 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
}
}
}
}
Set
<
String
>
paidPerformanceSet
=
Collections
.
emptySet
();
CaomeiBadgeEligibilityService
.
Type2ClaimContext
type2Ctx
=
null
;
Set
<
String
>
passedApplyBadgeIds
=
Collections
.
emptySet
();
Set
<
String
>
passedApplyPerformanceIds
=
Collections
.
emptySet
();
Map
<
String
,
Set
<
String
>>
perfAllBadgeIds
=
Collections
.
emptyMap
();
if
(
hasType2
)
{
if
(
hasType2
)
{
AdamRealInfoVo
real
=
adamRdmService
.
getRealInfoVoByUidPlain
(
uid
);
type2Ctx
=
caomeiBadgeEligibilityService
.
buildType2ClaimContext
(
uid
,
orderedBadges
);
if
(
real
==
null
||
real
.
getState
()
==
null
||
real
.
getState
()
!=
1
||
StringUtils
.
isBlank
(
real
.
getIdCard
()
))
{
if
(
!
type2Ctx
.
isRealNameOk
(
))
{
log
.
error
(
"[claimBadges] 认领演出徽章需先实名, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
log
.
error
(
"[claimBadges] 认领演出徽章需先实名, uid: {}, badgeIds: {}"
,
uid
,
requestBadgeIds
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10610"
));
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10610"
));
}
}
List
<
String
>
paidPerformanceIds
=
adamRdmService
.
getPaidPerformanceIdsByIdCard
(
real
.
getIdCard
());
paidPerformanceSet
=
paidPerformanceIds
==
null
?
Collections
.
emptySet
()
:
new
HashSet
<>(
paidPerformanceIds
);
List
<
AdamCaomeiBadgeApplyRecord
>
passedApplyRecords
=
badgeApplyRecordMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadgeApplyRecord
.
class
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getUserId
,
uid
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getAuditStatus
,
1
)
);
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
<>();
List
<
String
>
claimedBadgeIds
=
new
ArrayList
<>();
...
@@ -190,25 +150,14 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
...
@@ -190,25 +150,14 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
int
type
=
badge
.
getType
()
==
null
?
0
:
badge
.
getType
();
int
type
=
badge
.
getType
()
==
null
?
0
:
badge
.
getType
();
int
source
=
1
;
int
source
=
1
;
if
(
type
==
2
)
{
if
(
type
==
2
)
{
String
perfId
=
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
());
if
(!
caomeiBadgeEligibilityService
.
canClaimPerformanceBadge
(
badge
,
type2Ctx
))
{
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
(
"[claimBadges] 无购票记录且无通过补签,无法认领, uid: {}, badgeId: {}"
,
uid
,
badge
.
getBadgeId
());
log
.
error
(
"[claimBadges] 无购票记录且无通过补签,无法认领, uid: {}, badgeId: {}"
,
uid
,
badge
.
getBadgeId
());
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10611"
));
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10611"
));
}
}
source
=
hasPaidRecord
?
2
:
3
;
source
=
caomeiBadgeEligibilityService
.
resolveClaimSourceForType2
(
badge
,
type2Ctx
)
;
}
}
grantUserBadgeRedisThenMq
(
uid
,
badge
,
source
,
badgeVos
);
caomeiBadgeGrantService
.
grantOne
(
uid
,
badge
,
source
,
badgeVos
);
claimedBadgeIds
.
add
(
badge
.
getBadgeId
());
claimedBadgeIds
.
add
(
badge
.
getBadgeId
());
}
}
...
@@ -216,33 +165,6 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
...
@@ -216,33 +165,6 @@ public class AdamCaomeiBadgeUserServiceImpl implements IAdamCaomeiBadgeUserServi
return
ResponseDto
.
success
(
claimedBadgeIds
);
return
ResponseDto
.
success
(
claimedBadgeIds
);
}
}
/**
* Redis 追加用户徽章展示 DTO,再发 MQ 异步执行 sqlmap 中的 INSERT。
*/
private
void
grantUserBadgeRedisThenMq
(
String
uid
,
AdamCaomeiBadge
badge
,
int
source
,
List
<
AdamCaomeiPassportUserBadgeDto
>
badgeVos
)
{
Date
now
=
new
Date
();
AdamCaomeiPassportUserBadgeDto
dto
=
new
AdamCaomeiPassportUserBadgeDto
();
dto
.
setBadgeId
(
badge
.
getBadgeId
());
dto
.
setBadgeName
(
StringUtils
.
defaultString
(
badge
.
getName
()));
dto
.
setIcon
(
StringUtils
.
defaultString
(
badge
.
getIcon
()));
dto
.
setShareText
(
StringUtils
.
defaultString
(
badge
.
getShareText
()));
dto
.
setType
(
badge
.
getType
());
dto
.
setClaimedAt
(
now
);
dto
.
setSource
(
source
);
dto
.
setSubTitle
(
badge
.
getSubTitle
());
dto
.
setPerformanceId
(
StringUtils
.
defaultString
(
badge
.
getPerformanceId
()));
adamRdmService
.
addUserCaomeiBadgeDtoByUid
(
uid
,
badgeVos
,
dto
);
long
t
=
System
.
currentTimeMillis
();
queueUtils
.
sendMsgByRedis
(
MQConst
.
AdamQueue
.
SQL_UCENTER
.
getKey
(),
SqlMapping
.
get
(
"adam_caomei_user_badge.add"
,
uid
,
badge
.
getBadgeId
(),
source
,
now
)
);
log
.
debug
(
"[claimBadge] MQ耗时:{}ms, uid: {}, badgeId: {}"
,
System
.
currentTimeMillis
()
-
t
,
uid
,
badge
.
getBadgeId
());
}
@Override
@Override
public
ResponseDto
<
List
<
AdamCaomeiBadgeApplyRecordUserVo
>>
getApplyRecords
(
String
uid
)
{
public
ResponseDto
<
List
<
AdamCaomeiBadgeApplyRecordUserVo
>>
getApplyRecords
(
String
uid
)
{
if
(
StringUtils
.
isBlank
(
uid
))
{
if
(
StringUtils
.
isBlank
(
uid
))
{
...
...
liquidnet-bus-service/liquidnet-service-adam/liquidnet-service-adam-impl/src/main/java/com/liquidnet/service/adam/service/impl/AdamCaomeiPassportUserServiceImpl.java
View file @
633e0966
...
@@ -6,17 +6,15 @@ import com.liquidnet.commons.lang.util.DateUtil;
...
@@ -6,17 +6,15 @@ import com.liquidnet.commons.lang.util.DateUtil;
import
com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto
;
import
com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto
;
import
com.liquidnet.service.adam.dto.vo.*
;
import
com.liquidnet.service.adam.dto.vo.*
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadge
;
import
com.liquidnet.service.adam.entity.AdamCaomeiBadgeApplyRecord
;
import
com.liquidnet.service.adam.entity.AdamCaomeiPassport
;
import
com.liquidnet.service.adam.entity.AdamCaomeiPassport
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiBadgeApplyRecordMapper
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper
;
import
com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
com.liquidnet.service.adam.service.AdamRdmService
;
import
com.liquidnet.service.adam.service.IAdamCaomeiPassportUserService
;
import
com.liquidnet.service.adam.service.IAdamCaomeiPassportUserService
;
import
com.liquidnet.service.adam.util.QueueUtils
;
import
com.liquidnet.service.adam.service.caomei.CaomeiBadgeApplyStatus
;
import
com.liquidnet.service.adam.service.caomei.CaomeiBadgeEligibilityService
;
import
com.liquidnet.service.adam.service.caomei.CaomeiBadgeGrantService
;
import
com.liquidnet.service.base.ErrorMapping
;
import
com.liquidnet.service.base.ErrorMapping
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.base.SqlMapping
;
import
com.liquidnet.service.base.constant.MQConst
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
@@ -40,11 +38,11 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -40,11 +38,11 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
@Autowired
@Autowired
private
AdamCaomeiPassportMapper
adamCaomeiPassportMapper
;
private
AdamCaomeiPassportMapper
adamCaomeiPassportMapper
;
@Autowired
@Autowired
private
AdamCaomeiBadgeApplyRecordMapper
badgeApplyRecordMapper
;
@Autowired
private
AdamRdmService
adamRdmService
;
private
AdamRdmService
adamRdmService
;
@Autowired
@Autowired
private
QueueUtils
queueUtils
;
private
CaomeiBadgeGrantService
caomeiBadgeGrantService
;
@Autowired
private
CaomeiBadgeEligibilityService
caomeiBadgeEligibilityService
;
@Override
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
...
@@ -101,49 +99,9 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -101,49 +99,9 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
return
ResponseDto
.
success
();
return
ResponseDto
.
success
();
}
}
List
<
String
>
badgeIds
=
passportTypeBadges
.
stream
()
.
map
(
AdamCaomeiBadge:
:
getBadgeId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toList
());
Date
grantAt
=
DateUtil
.
now
();
Date
grantAt
=
DateUtil
.
now
();
List
<
AdamCaomeiPassportUserBadgeDto
>
appendVos
=
caomeiBadgeGrantService
.
grantBadgesIfAbsent
(
// 兼容 claimBadge 的写法:把本次发放的护照徽章同时写入用户徽章缓存列表
uid
,
passportTypeBadges
,
1
,
grantAt
);
List
<
AdamCaomeiPassportUserBadgeDto
>
cacheBadgeVos
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
if
(
cacheBadgeVos
==
null
)
{
cacheBadgeVos
=
new
ArrayList
<>();
}
else
{
cacheBadgeVos
=
new
ArrayList
<>(
cacheBadgeVos
);
}
Set
<
String
>
existedBadgeIds
=
cacheBadgeVos
.
stream
()
.
map
(
AdamCaomeiPassportUserBadgeDto:
:
getBadgeId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toSet
());
List
<
AdamCaomeiPassportUserBadgeDto
>
appendVos
=
passportTypeBadges
.
stream
()
.
filter
(
b
->
b
!=
null
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
())
&&
!
existedBadgeIds
.
contains
(
b
.
getBadgeId
()))
.
map
(
b
->
{
AdamCaomeiPassportUserBadgeDto
dto
=
new
AdamCaomeiPassportUserBadgeDto
();
dto
.
setBadgeId
(
b
.
getBadgeId
());
dto
.
setBadgeName
(
StringUtils
.
defaultString
(
b
.
getName
()));
dto
.
setIcon
(
StringUtils
.
defaultString
(
b
.
getIcon
()));
dto
.
setShareText
(
StringUtils
.
defaultString
(
b
.
getShareText
()));
dto
.
setType
(
b
.
getType
());
dto
.
setClaimedAt
(
grantAt
);
dto
.
setSource
(
1
);
dto
.
setSubTitle
(
b
.
getSubTitle
());
return
dto
;
})
.
collect
(
Collectors
.
toList
());
adamRdmService
.
addUserCaomeiBadgeDtosByUid
(
uid
,
cacheBadgeVos
,
appendVos
);
LinkedList
<
Object
[]>
paramsList
=
new
LinkedList
<>();
for
(
String
badgeId
:
badgeIds
)
{
paramsList
.
add
(
new
Object
[]{
uid
,
badgeId
,
1
,
grantAt
});
}
queueUtils
.
sendMsgByRedis
(
MQConst
.
AdamQueue
.
SQL_UCENTER
.
getKey
(),
SqlMapping
.
get
(
"adam_caomei_user_badge.add"
,
paramsList
)
);
// 5. 返回本次绑定场景下的护照类型徽章列表(用于前端弹窗)
// 5. 返回本次绑定场景下的护照类型徽章列表(用于前端弹窗)
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
grantedBadges
=
appendVos
.
stream
().
map
(
b
->
{
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
grantedBadges
=
appendVos
.
stream
().
map
(
b
->
{
...
@@ -207,7 +165,7 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -207,7 +165,7 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
if
(
published
==
null
)
{
if
(
published
==
null
)
{
published
=
new
ArrayList
<>();
published
=
new
ArrayList
<>();
}
}
ApplyBadgeStatus
applyBadgeStatus
=
loadApplyBadgeStatus
(
uid
,
published
);
CaomeiBadgeApplyStatus
applyBadgeStatus
=
caomeiBadgeEligibilityService
.
loadApplyBadgeStatus
(
uid
,
published
);
// 用户已获得记录(含 type=4;展示层再过滤)
// 用户已获得记录(含 type=4;展示层再过滤)
List
<
AdamCaomeiPassportUserBadgeDto
>
rows
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
List
<
AdamCaomeiPassportUserBadgeDto
>
rows
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
...
@@ -217,12 +175,13 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -217,12 +175,13 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
rows
=
new
ArrayList
<>(
rows
);
rows
=
new
ArrayList
<>(
rows
);
}
}
// 末尾:实名且已购对应场次时,静默发放 type=4 签证页(写用户徽章 Redis + MQ 落库)
// 末尾:已购或补签通过对应场次时,静默发放 type=4 签证页(写用户徽章 Redis + MQ 落库)
boolean
visaGranted
=
syncVisaPageBadgesIfEligible
(
uid
,
published
,
rows
,
paidPerformanceIds
);
List
<
AdamCaomeiPassportUserBadgeDto
>
visaGranted
=
syncVisaPageBadgesIfEligible
(
if
(
visaGranted
)
{
uid
,
published
,
paidPerformanceIds
,
applyBadgeStatus
);
List
<
AdamCaomeiPassportUserBadgeDto
>
refreshed
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
if
(!
visaGranted
.
isEmpty
())
{
rows
=
refreshed
==
null
?
new
ArrayList
<>()
:
new
ArrayList
<>(
refreshed
);
rows
.
addAll
(
visaGranted
);
log
.
info
(
"[getPassportHome] 本次静默发放签证页后刷新用户徽章缓存, uid: {}"
,
uid
);
log
.
info
(
"[getPassportHome] 本次静默发放签证页, uid: {}, badgeIds: {}"
,
uid
,
visaGranted
.
stream
().
map
(
AdamCaomeiPassportUserBadgeDto:
:
getBadgeId
).
collect
(
Collectors
.
toList
()));
}
}
// 首页货架:排除 type=4
// 首页货架:排除 type=4
...
@@ -231,12 +190,17 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -231,12 +190,17 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
Map
<
String
,
String
>
performanceTitleById
=
adamRdmService
.
getPerformanceTitleMapByIds
(
Map
<
String
,
String
>
performanceTitleById
=
adamRdmService
.
getPerformanceTitleMapByIds
(
collectPerformanceIdsForTitleLookup
(
rows
,
shelfPublished
));
collectPerformanceIdsForTitleLookup
(
rows
,
shelfPublished
));
// 首页徽章墙:排除 type=4
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
userBadgeVos
=
toClaimedBadgeVos
(
rows
,
performanceTitleById
);
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
claimed
=
toClaimedBadgeVos
(
rows
,
performanceTitleById
).
stream
()
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
visaBadges
=
userBadgeVos
.
stream
()
.
filter
(
v
->
isVisaBadgeType
(
v
.
getType
()))
.
collect
(
Collectors
.
toList
());
home
.
setVisaBadges
(
visaBadges
);
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
claimed
=
userBadgeVos
.
stream
()
.
filter
(
v
->
!
isVisaBadgeType
(
v
.
getType
()))
.
filter
(
v
->
!
isVisaBadgeType
(
v
.
getType
()))
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
home
.
setClaimedBadges
(
claimed
);
home
.
setClaimedBadges
(
claimed
);
log
.
info
(
"[getPassportHome] 用户已认领的徽章数量(不含签证页), uid: {}, 数量: {}"
,
uid
,
claimed
.
size
());
log
.
info
(
"[getPassportHome] 用户已认领徽章(不含签证页) {}, 签证页 {}, uid: {}"
,
claimed
.
size
(),
visaBadges
.
size
(),
uid
);
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
=
toClaimedBadgeMap
(
rows
);
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
=
toClaimedBadgeMap
(
rows
);
...
@@ -255,37 +219,6 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -255,37 +219,6 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
return
ResponseDto
.
success
(
home
);
return
ResponseDto
.
success
(
home
);
}
}
@Override
public
ResponseDto
<
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>>
listVisaCards
()
{
String
uid
=
CurrentUtil
.
getCurrentUid
();
AdamCaomeiPassport
bound
=
findBoundPassportForUser
(
uid
);
if
(
bound
==
null
)
{
log
.
error
(
"[listVisaCards] 用户未绑定护照, uid: {}"
,
uid
);
return
ResponseDto
.
failure
(
ErrorMapping
.
get
(
"10604"
));
}
// 仅读用户已获徽章列表(Redis 缓存 miss 时回源 DB);须先访问 home 触发 type=4 静默发放后才有数据
List
<
AdamCaomeiPassportUserBadgeDto
>
rows
=
adamRdmService
.
getUserCaomeiBadgesByUid
(
uid
);
if
(
rows
==
null
)
{
rows
=
Collections
.
emptyList
();
}
List
<
AdamCaomeiPassportUserBadgeDto
>
visaRows
=
rows
.
stream
()
.
filter
(
r
->
r
!=
null
&&
isVisaBadgeType
(
r
.
getType
()))
.
collect
(
Collectors
.
toList
());
if
(
visaRows
.
isEmpty
())
{
return
ResponseDto
.
success
(
Collections
.
emptyList
());
}
Map
<
String
,
String
>
performanceTitleById
=
adamRdmService
.
getPerformanceTitleMapByIds
(
visaRows
.
stream
()
.
map
(
AdamCaomeiPassportUserBadgeDto:
:
getPerformanceId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toList
())
);
return
ResponseDto
.
success
(
toClaimedBadgeVos
(
visaRows
,
performanceTitleById
));
}
@Override
@Override
public
ResponseDto
<
Boolean
>
checkPassportBound
()
{
public
ResponseDto
<
Boolean
>
checkPassportBound
()
{
String
uid
=
CurrentUtil
.
getCurrentUid
();
String
uid
=
CurrentUtil
.
getCurrentUid
();
...
@@ -310,52 +243,6 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -310,52 +243,6 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
return
card
;
return
card
;
}
}
private
ApplyBadgeStatus
loadApplyBadgeStatus
(
String
uid
,
List
<
AdamCaomeiBadge
>
published
)
{
Map
<
String
,
String
>
badgeIdToPerformanceId
=
new
HashMap
<>();
if
(
published
!=
null
)
{
for
(
AdamCaomeiBadge
b
:
published
)
{
if
(
b
!=
null
&&
StringUtils
.
isNotBlank
(
b
.
getBadgeId
()))
{
badgeIdToPerformanceId
.
put
(
b
.
getBadgeId
(),
StringUtils
.
trimToEmpty
(
b
.
getPerformanceId
()));
}
}
}
List
<
AdamCaomeiBadgeApplyRecord
>
applyRecords
=
badgeApplyRecordMapper
.
selectList
(
Wrappers
.
lambdaQuery
(
AdamCaomeiBadgeApplyRecord
.
class
)
.
eq
(
AdamCaomeiBadgeApplyRecord:
:
getUserId
,
uid
)
.
in
(
AdamCaomeiBadgeApplyRecord:
:
getAuditStatus
,
0
,
1
)
);
Set
<
String
>
passedApplyBadgeIds
=
new
HashSet
<>();
Set
<
String
>
pendingApplyBadgeIds
=
new
HashSet
<>();
Set
<
String
>
passedApplyPerformanceIds
=
new
HashSet
<>();
Set
<
String
>
pendingApplyPerformanceIds
=
new
HashSet
<>();
for
(
AdamCaomeiBadgeApplyRecord
r
:
applyRecords
)
{
if
(
r
==
null
||
StringUtils
.
isBlank
(
r
.
getBadgeId
())
||
r
.
getAuditStatus
()
==
null
)
{
continue
;
}
String
perf
=
StringUtils
.
trimToEmpty
(
r
.
getPerformanceId
());
if
(
StringUtils
.
isBlank
(
perf
))
{
perf
=
StringUtils
.
trimToEmpty
(
badgeIdToPerformanceId
.
get
(
r
.
getBadgeId
()));
}
if
(
r
.
getAuditStatus
()
==
1
)
{
passedApplyBadgeIds
.
add
(
r
.
getBadgeId
());
if
(
StringUtils
.
isNotBlank
(
perf
))
{
passedApplyPerformanceIds
.
add
(
perf
);
}
}
else
if
(
r
.
getAuditStatus
()
==
0
)
{
pendingApplyBadgeIds
.
add
(
r
.
getBadgeId
());
if
(
StringUtils
.
isNotBlank
(
perf
))
{
pendingApplyPerformanceIds
.
add
(
perf
);
}
}
}
return
new
ApplyBadgeStatus
(
passedApplyBadgeIds
,
pendingApplyBadgeIds
,
passedApplyPerformanceIds
,
pendingApplyPerformanceIds
);
}
private
static
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
toClaimedBadgeVos
(
List
<
AdamCaomeiPassportUserBadgeDto
>
rows
,
private
static
List
<
AdamCaomeiPassportUserClaimedBadgeVo
>
toClaimedBadgeVos
(
List
<
AdamCaomeiPassportUserBadgeDto
>
rows
,
Map
<
String
,
String
>
performanceTitleById
)
{
Map
<
String
,
String
>
performanceTitleById
)
{
return
rows
.
stream
().
map
(
r
->
{
return
rows
.
stream
().
map
(
r
->
{
...
@@ -409,64 +296,60 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -409,64 +296,60 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
}
}
/**
/**
* home 末尾:对已上架 type=4、用户已购对应场次且尚未获得的签证页执行静默发放。
* home 末尾:对已上架 type=4、用户在该场次已购票或补签审核通过、且尚未获得的签证页执行静默发放。
* <p>
* 购票:source=2;仅补签通过(无购票记录):source=3,与演出纪念徽章认领一致。
*
*
* @return 是否本次有发放(用于刷新用户徽章缓存后再组装首页响应)
* @param applyBadgeStatus {@link CaomeiBadgeEligibilityService#loadApplyBadgeStatus},取已通过补签的场次 ID
* @return 本次实际新增的 user 缓存 DTO(供 home 本地 merge,避免二次读 Redis)
*/
*/
private
boolean
syncVisaPageBadgesIfEligible
(
String
uid
,
private
List
<
AdamCaomeiPassportUserBadgeDto
>
syncVisaPageBadgesIfEligible
(
String
uid
,
List
<
AdamCaomeiBadge
>
published
,
List
<
AdamCaomeiBadge
>
published
,
List
<
AdamCaomeiPassportUserBadgeDto
>
badgeVo
s
,
List
<
String
>
paidPerformanceId
s
,
List
<
String
>
paidPerformanceId
s
)
{
CaomeiBadgeApplyStatus
applyBadgeStatu
s
)
{
if
(
StringUtils
.
isBlank
(
uid
)
||
published
==
null
||
published
.
isEmpty
())
{
if
(
StringUtils
.
isBlank
(
uid
)
||
published
==
null
||
published
.
isEmpty
())
{
return
false
;
return
Collections
.
emptyList
()
;
}
}
if
(
paidPerformanceIds
==
null
||
paidPerformanceIds
.
isEmpty
())
{
return
false
;
Set
<
String
>
paidSet
=
paidPerformanceIds
==
null
?
Collections
.
emptySet
()
:
paidPerformanceIds
.
stream
().
filter
(
StringUtils:
:
isNotBlank
).
map
(
String:
:
trim
).
collect
(
Collectors
.
toSet
());
Set
<
String
>
passedApplyPerfSet
=
applyBadgeStatus
==
null
?
Collections
.
emptySet
()
:
applyBadgeStatus
.
getPassedApplyPerformanceIds
();
if
(
paidSet
.
isEmpty
()
&&
passedApplyPerfSet
.
isEmpty
())
{
return
Collections
.
emptyList
();
}
}
Set
<
String
>
paidSet
=
new
HashSet
<>(
paidPerformanceIds
);
Set
<
String
>
claimedBadgeIds
=
badgeVos
.
stream
()
.
map
(
AdamCaomeiPassportUserBadgeDto:
:
getBadgeId
)
.
filter
(
StringUtils:
:
isNotBlank
)
.
collect
(
Collectors
.
toSet
());
List
<
AdamCaomeiBadge
>
toGrant
=
published
.
stream
()
// 筛选所有 type=4的徽章
List
<
AdamCaomeiBadge
>
visaPublished
=
published
.
stream
()
.
filter
(
b
->
b
!=
null
&&
isVisaBadgeType
(
b
.
getType
()))
.
filter
(
b
->
b
!=
null
&&
isVisaBadgeType
(
b
.
getType
()))
.
filter
(
b
->
StringUtils
.
isNotBlank
(
b
.
getPerformanceId
()))
.
filter
(
b
->
StringUtils
.
isNotBlank
(
b
.
getPerformanceId
()))
.
filter
(
b
->
paidSet
.
contains
(
StringUtils
.
trimToEmpty
(
b
.
getPerformanceId
())))
.
filter
(
b
->
StringUtils
.
isNotBlank
(
b
.
getBadgeId
())
&&
!
claimedBadgeIds
.
contains
(
b
.
getBadgeId
()))
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
if
(
toGrant
.
isEmpty
())
{
if
(
visaPublished
.
isEmpty
())
{
return
false
;
return
Collections
.
emptyList
()
;
}
}
List
<
AdamCaomeiBadge
>
grantByPaid
=
visaPublished
.
stream
()
.
filter
(
b
->
paidSet
.
contains
(
StringUtils
.
trimToEmpty
(
b
.
getPerformanceId
())))
.
collect
(
Collectors
.
toList
());
List
<
AdamCaomeiBadge
>
grantByApplyOnly
=
visaPublished
.
stream
()
.
filter
(
b
->
{
String
perfId
=
StringUtils
.
trimToEmpty
(
b
.
getPerformanceId
());
return
!
paidSet
.
contains
(
perfId
)
&&
passedApplyPerfSet
.
contains
(
perfId
);
})
.
collect
(
Collectors
.
toList
());
Date
grantAt
=
DateUtil
.
now
();
Date
grantAt
=
DateUtil
.
now
();
List
<
AdamCaomeiPassportUserBadgeDto
>
appendVos
=
new
ArrayList
<>(
toGrant
.
size
());
List
<
AdamCaomeiPassportUserBadgeDto
>
granted
=
new
ArrayList
<>();
for
(
AdamCaomeiBadge
badge
:
toGrant
)
{
if
(!
grantByPaid
.
isEmpty
())
{
AdamCaomeiPassportUserBadgeDto
dto
=
new
AdamCaomeiPassportUserBadgeDto
();
granted
.
addAll
(
caomeiBadgeGrantService
.
grantBadgesIfAbsent
(
dto
.
setBadgeId
(
badge
.
getBadgeId
());
uid
,
grantByPaid
,
USER_BADGE_SOURCE_PAID_AUTO
,
grantAt
));
dto
.
setBadgeName
(
StringUtils
.
defaultString
(
badge
.
getName
()));
}
dto
.
setSubTitle
(
StringUtils
.
defaultString
(
badge
.
getSubTitle
()));
if
(!
grantByApplyOnly
.
isEmpty
())
{
dto
.
setIcon
(
StringUtils
.
defaultString
(
badge
.
getIcon
()));
granted
.
addAll
(
caomeiBadgeGrantService
.
grantBadgesIfAbsent
(
uid
,
grantByApplyOnly
,
3
,
grantAt
));
dto
.
setShareText
(
StringUtils
.
defaultString
(
badge
.
getShareText
()));
}
dto
.
setType
(
badge
.
getType
());
return
granted
;
dto
.
setPerformanceId
(
StringUtils
.
trimToEmpty
(
badge
.
getPerformanceId
()));
dto
.
setClaimedAt
(
grantAt
);
dto
.
setSource
(
USER_BADGE_SOURCE_PAID_AUTO
);
appendVos
.
add
(
dto
);
}
adamRdmService
.
addUserCaomeiBadgeDtosByUid
(
uid
,
badgeVos
,
appendVos
);
LinkedList
<
Object
[]>
paramsList
=
new
LinkedList
<>();
for
(
AdamCaomeiBadge
badge
:
toGrant
)
{
paramsList
.
add
(
new
Object
[]{
uid
,
badge
.
getBadgeId
(),
USER_BADGE_SOURCE_PAID_AUTO
,
grantAt
});
}
queueUtils
.
sendMsgByRedis
(
MQConst
.
AdamQueue
.
SQL_UCENTER
.
getKey
(),
SqlMapping
.
get
(
"adam_caomei_user_badge.add"
,
paramsList
)
);
log
.
info
(
"[syncVisaPageBadgesIfEligible] 静默发放签证页, uid: {}, badgeIds: {}"
,
uid
,
toGrant
.
stream
().
map
(
AdamCaomeiBadge:
:
getBadgeId
).
collect
(
Collectors
.
toList
()));
return
true
;
}
}
/** type=2 演出纪念、type=4 签证页需展示关联场次 */
/** type=2 演出纪念、type=4 签证页需展示关联场次 */
...
@@ -485,10 +368,10 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -485,10 +368,10 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
return
type
!=
null
&&
type
==
BADGE_TYPE_VISA
;
return
type
!=
null
&&
type
==
BADGE_TYPE_VISA
;
}
}
private
static
List
<
AdamCaomeiPassportBadgeShelfItemVo
>
toShelfItems
(
List
<
AdamCaomeiBadge
>
published
,
private
List
<
AdamCaomeiPassportBadgeShelfItemVo
>
toShelfItems
(
List
<
AdamCaomeiBadge
>
published
,
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
,
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
,
List
<
String
>
paidPerformanceIds
,
List
<
String
>
paidPerformanceIds
,
ApplyBadge
Status
applyBadgeStatus
,
CaomeiBadgeApply
Status
applyBadgeStatus
,
Map
<
String
,
String
>
performanceTitleById
)
{
Map
<
String
,
String
>
performanceTitleById
)
{
return
published
.
stream
()
return
published
.
stream
()
.
map
(
b
->
toShelfItem
(
b
,
claimedMap
,
paidPerformanceIds
,
applyBadgeStatus
,
performanceTitleById
))
.
map
(
b
->
toShelfItem
(
b
,
claimedMap
,
paidPerformanceIds
,
applyBadgeStatus
,
performanceTitleById
))
...
@@ -503,10 +386,10 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -503,10 +386,10 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
* @param performanceTitleById 演出 ID → 演出名称(仅 type=2 使用)
* @param performanceTitleById 演出 ID → 演出名称(仅 type=2 使用)
* @return
* @return
*/
*/
private
static
AdamCaomeiPassportBadgeShelfItemVo
toShelfItem
(
AdamCaomeiBadge
b
,
private
AdamCaomeiPassportBadgeShelfItemVo
toShelfItem
(
AdamCaomeiBadge
b
,
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
,
Map
<
String
,
AdamCaomeiPassportUserBadgeDto
>
claimedMap
,
List
<
String
>
paidPerformanceIds
,
List
<
String
>
paidPerformanceIds
,
ApplyBadge
Status
applyBadgeStatus
,
CaomeiBadgeApply
Status
applyBadgeStatus
,
Map
<
String
,
String
>
performanceTitleById
)
{
Map
<
String
,
String
>
performanceTitleById
)
{
AdamCaomeiPassportBadgeShelfItemVo
v
=
new
AdamCaomeiPassportBadgeShelfItemVo
();
AdamCaomeiPassportBadgeShelfItemVo
v
=
new
AdamCaomeiPassportBadgeShelfItemVo
();
v
.
setBadgeId
(
b
.
getBadgeId
());
v
.
setBadgeId
(
b
.
getBadgeId
());
...
@@ -522,41 +405,15 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -522,41 +405,15 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
String
title
=
performanceTitleById
!=
null
?
performanceTitleById
.
get
(
perfId
)
:
null
;
String
title
=
performanceTitleById
!=
null
?
performanceTitleById
.
get
(
perfId
)
:
null
;
v
.
setPerformanceName
(
StringUtils
.
isNotBlank
(
title
)
?
title
:
perfId
);
v
.
setPerformanceName
(
StringUtils
.
isNotBlank
(
title
)
?
title
:
perfId
);
}
}
v
.
setApplyPending
(
false
);
// 判断当前徽章是否已认领
AdamCaomeiPassportUserBadgeDto
got
=
claimedMap
.
get
(
b
.
getBadgeId
());
AdamCaomeiPassportUserBadgeDto
got
=
claimedMap
.
get
(
b
.
getBadgeId
());
boolean
claimed
=
got
!=
null
;
boolean
claimed
=
got
!=
null
;
v
.
setClaimed
(
claimed
);
v
.
setClaimed
(
claimed
);
v
.
setClaimedAt
(
got
!=
null
?
got
.
getClaimedAt
()
:
null
);
v
.
setClaimedAt
(
got
!=
null
?
got
.
getClaimedAt
()
:
null
);
// 针对未认领的徽章,根据类型判断是否可认领 (claimable)
CaomeiBadgeEligibilityService
.
ShelfInteractState
interact
=
if
(!
claimed
)
{
caomeiBadgeEligibilityService
.
resolveShelfInteract
(
b
,
claimed
,
paidPerformanceIds
,
applyBadgeStatus
);
if
(
type
==
1
)
{
v
.
setClaimable
(
interact
.
isClaimable
());
// 护照纪念徽章:只要绑定了护照,就可认领(通常是绑定时漏发或后来新上架的)
v
.
setApplyPending
(
interact
.
isApplyPending
());
v
.
setClaimable
(
true
);
}
else
if
(
type
==
2
)
{
// 演出纪念徽章:有购票记录,或本场次任一补签审核通过,则本场次关联徽章均可认领
boolean
canClaimByPaid
=
paidPerformanceIds
!=
null
&&
paidPerformanceIds
.
contains
(
b
.
getPerformanceId
());
boolean
canClaimByApplyThisBadge
=
applyBadgeStatus
.
getPassedApplyBadgeIds
().
contains
(
b
.
getBadgeId
());
boolean
canClaimByApplyThisPerf
=
StringUtils
.
isNotBlank
(
perfId
)
&&
applyBadgeStatus
.
getPassedApplyPerformanceIds
().
contains
(
perfId
);
v
.
setClaimable
(
canClaimByPaid
||
canClaimByApplyThisBadge
||
canClaimByApplyThisPerf
);
boolean
pendingThisBadge
=
applyBadgeStatus
.
getPendingApplyBadgeIds
().
contains
(
b
.
getBadgeId
());
boolean
pendingThisPerf
=
StringUtils
.
isNotBlank
(
perfId
)
&&
applyBadgeStatus
.
getPendingApplyPerformanceIds
().
contains
(
perfId
);
v
.
setApplyPending
(
pendingThisBadge
||
pendingThisPerf
);
}
else
if
(
type
==
3
)
{
// 特殊徽章:不可自助领取,需要提示用户
v
.
setClaimable
(
false
);
}
else
if
(
type
==
BADGE_TYPE_VISA
)
{
// 签证页不在首页货架展示;若配置误入货架列表,不可点击认领(由 home 静默发放)
v
.
setClaimable
(
false
);
}
}
else
{
// 已认领的徽章,可认领状态置为 false
v
.
setClaimable
(
false
);
}
return
v
;
return
v
;
}
}
...
@@ -572,36 +429,4 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
...
@@ -572,36 +429,4 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
);
);
}
}
private
static
final
class
ApplyBadgeStatus
{
private
final
Set
<
String
>
passedApplyBadgeIds
;
private
final
Set
<
String
>
pendingApplyBadgeIds
;
private
final
Set
<
String
>
passedApplyPerformanceIds
;
private
final
Set
<
String
>
pendingApplyPerformanceIds
;
private
ApplyBadgeStatus
(
Set
<
String
>
passedApplyBadgeIds
,
Set
<
String
>
pendingApplyBadgeIds
,
Set
<
String
>
passedApplyPerformanceIds
,
Set
<
String
>
pendingApplyPerformanceIds
)
{
this
.
passedApplyBadgeIds
=
passedApplyBadgeIds
;
this
.
pendingApplyBadgeIds
=
pendingApplyBadgeIds
;
this
.
passedApplyPerformanceIds
=
passedApplyPerformanceIds
;
this
.
pendingApplyPerformanceIds
=
pendingApplyPerformanceIds
;
}
Set
<
String
>
getPassedApplyBadgeIds
()
{
return
passedApplyBadgeIds
;
}
Set
<
String
>
getPendingApplyBadgeIds
()
{
return
pendingApplyBadgeIds
;
}
Set
<
String
>
getPassedApplyPerformanceIds
()
{
return
passedApplyPerformanceIds
;
}
Set
<
String
>
getPendingApplyPerformanceIds
()
{
return
pendingApplyPerformanceIds
;
}
}
}
}
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