Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jiedao-api-boot-master
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
lanbaoming
jiedao-api-boot-master
Commits
eef3c4ae
Commit
eef3c4ae
authored
Aug 15, 2024
by
zhangfeng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
礼品兑换完善校验
parent
bc3631f0
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
63 additions
and
30 deletions
+63
-30
RedeemRewardReqVO.java
...yudao/module/reward/api/reward/dto/RedeemRewardReqVO.java
+4
-0
ErrorCodeConstants.java
...iocoder/yudao/module/reward/enums/ErrorCodeConstants.java
+1
-0
RedeemRewardApiImpl.java
...r/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
+56
-30
messages_en.properties
yudao-server/src/main/resources/i18n/messages_en.properties
+1
-0
messages_zh.properties
yudao-server/src/main/resources/i18n/messages_zh.properties
+1
-0
No files found.
yudao-module-reward/yudao-module-reward-api/src/main/java/cn/iocoder/yudao/module/reward/api/reward/dto/RedeemRewardReqVO.java
View file @
eef3c4ae
...
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
...
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import
lombok.Data
;
import
lombok.Data
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
javax.validation.constraints.NotNull
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.util.Date
;
import
java.util.Date
;
...
@@ -20,12 +21,15 @@ public class RedeemRewardReqVO {
...
@@ -20,12 +21,15 @@ public class RedeemRewardReqVO {
private
Long
rewardId
;
private
Long
rewardId
;
@ApiModelProperty
(
value
=
"兑换数量"
,
required
=
true
)
@ApiModelProperty
(
value
=
"兑换数量"
,
required
=
true
)
@NotNull
(
message
=
"兑换数量不能为空"
)
private
Integer
rewardCount
;
private
Integer
rewardCount
;
@ApiModelProperty
(
value
=
"兑换方式,同领取方式(1上门领取,2包邮到家,3邮寄到付)"
,
required
=
true
)
@ApiModelProperty
(
value
=
"兑换方式,同领取方式(1上门领取,2包邮到家,3邮寄到付)"
,
required
=
true
)
@NotNull
(
message
=
"兑换方式不能为空"
)
private
Integer
redeemType
;
private
Integer
redeemType
;
@ApiModelProperty
(
value
=
"兑换入口(后台,app,web)"
,
required
=
true
)
@ApiModelProperty
(
value
=
"兑换入口(后台,app,web)"
,
required
=
true
)
@NotNull
(
message
=
"兑换入口不能为空"
)
private
Integer
entrance
;
private
Integer
entrance
;
@ApiModelProperty
(
value
=
"费用数字(两位小数)"
)
@ApiModelProperty
(
value
=
"费用数字(两位小数)"
)
...
...
yudao-module-reward/yudao-module-reward-api/src/main/java/cn/iocoder/yudao/module/reward/enums/ErrorCodeConstants.java
View file @
eef3c4ae
...
@@ -29,5 +29,6 @@ public interface ErrorCodeConstants {
...
@@ -29,5 +29,6 @@ public interface ErrorCodeConstants {
ErrorCode
REDEEM_IMPORT_MAX_COUNT
=
new
ErrorCode
(
1001011023
,
"redeem.import.max.count"
);
ErrorCode
REDEEM_IMPORT_MAX_COUNT
=
new
ErrorCode
(
1001011023
,
"redeem.import.max.count"
);
ErrorCode
REDEEM_CANCEL_STATUS_ERROR
=
new
ErrorCode
(
1001011024
,
"redeem.cancel.status.error"
);
ErrorCode
REDEEM_CANCEL_STATUS_ERROR
=
new
ErrorCode
(
1001011024
,
"redeem.cancel.status.error"
);
ErrorCode
REWARD_NODE_AND_POINTS_LIST_ERROR
=
new
ErrorCode
(
1001011025
,
"reward.node.and.points.list.error"
);
ErrorCode
REWARD_NODE_AND_POINTS_LIST_ERROR
=
new
ErrorCode
(
1001011025
,
"reward.node.and.points.list.error"
);
ErrorCode
REWARD_REDEEM_RECIPIENT_ERROR
=
new
ErrorCode
(
1001011026
,
"reward.redeem.recipient.error"
);
}
}
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
View file @
eef3c4ae
...
@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO;
...
@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO;
import
cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO
;
import
cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO
;
import
cn.iocoder.yudao.module.reward.dal.mysql.redeem.RewardRedeemMapper
;
import
cn.iocoder.yudao.module.reward.dal.mysql.redeem.RewardRedeemMapper
;
import
cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper
;
import
cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper
;
import
cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum
;
import
cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum
;
import
cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum
;
import
cn.iocoder.yudao.module.reward.enums.RewardStatusEnum
;
import
cn.iocoder.yudao.module.reward.enums.RewardStatusEnum
;
import
cn.iocoder.yudao.module.reward.service.reward.RewardService
;
import
cn.iocoder.yudao.module.reward.service.reward.RewardService
;
...
@@ -26,6 +27,7 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
...
@@ -26,6 +27,7 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RedissonClient
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -70,19 +72,47 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -70,19 +72,47 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
@Override
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
Boolean
redeemReward
(
RedeemRewardReqVO
redeemRewardReqVO
)
{
public
Boolean
redeemReward
(
RedeemRewardReqVO
redeemRewardReqVO
)
{
UserRespDTO
memberUser
=
memberUserApi
.
getUser
(
redeemRewardReqVO
.
getMemberId
());
if
(
memberUser
==
null
)
{
throw
exception
(
USER_NOT_EXISTS
);
}
// 验证短信验证码
if
(
redeemRewardReqVO
.
getEntrance
()
!=
PlatformTypeEnum
.
BACKEND
.
getValue
()
&&
redeemRewardReqVO
instanceof
AppRedeemRewardReqVO
)
{
if
(
redeemRewardReqVO
.
getEntrance
()
!=
PlatformTypeEnum
.
BACKEND
.
getValue
()
&&
redeemRewardReqVO
instanceof
AppRedeemRewardReqVO
)
{
AppRedeemRewardReqVO
appRedeemRewardReqVO
=
(
AppRedeemRewardReqVO
)
redeemRewardReqVO
;
AppRedeemRewardReqVO
appRedeemRewardReqVO
=
(
AppRedeemRewardReqVO
)
redeemRewardReqVO
;
SmsCodeUseReqDTO
smsCodeUseReqDTO
=
new
SmsCodeUseReqDTO
();
SmsCodeUseReqDTO
smsCodeUseReqDTO
=
new
SmsCodeUseReqDTO
();
UserRespDTO
memberUserApiUser
=
memberUserApi
.
getUser
(
redeemRewardReqVO
.
getMemberId
());
smsCodeUseReqDTO
.
setMobile
(
memberUser
.
getMobile
());
if
(
memberUserApiUser
==
null
)
{
throw
exception
(
USER_NOT_EXISTS
);
}
smsCodeUseReqDTO
.
setMobile
(
memberUserApiUser
.
getMobile
());
smsCodeUseReqDTO
.
setCode
(
appRedeemRewardReqVO
.
getCode
());
smsCodeUseReqDTO
.
setCode
(
appRedeemRewardReqVO
.
getCode
());
smsCodeUseReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeUseReqDTO
.
setUsedIp
(
getClientIP
());
smsCodeUseReqDTO
.
setScene
(
SmsSceneEnum
.
MEMBER_REDEEM_REWARD
.
getScene
());
smsCodeUseReqDTO
.
setScene
(
SmsSceneEnum
.
MEMBER_REDEEM_REWARD
.
getScene
());
smsCodeApi
.
useSmsCode
(
smsCodeUseReqDTO
);
smsCodeApi
.
useSmsCode
(
smsCodeUseReqDTO
);
}
}
// 校验收货人信息
verifyRecipientInfo
(
redeemRewardReqVO
,
memberUser
);
// 校验礼品
RewardDO
rewardDO
=
getAndVerifyRewardDO
(
redeemRewardReqVO
);
// 校验会员
verifyMemberUser
(
redeemRewardReqVO
,
rewardDO
,
memberUser
.
getHoldScore
());
String
lockKey
=
"reward:redeem:lock:"
+
redeemRewardReqVO
.
getRewardId
();
RLock
lock
=
redissonClient
.
getLock
(
lockKey
);
try
{
if
(!
lock
.
tryLock
(
2
,
10
,
TimeUnit
.
SECONDS
))
{
throw
exception
(
GET_LOCK_FAILED
);
}
// 添加兑换记录
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
,
rewardDO
);
// 更新会员积分
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
}
catch
(
InterruptedException
e
)
{
throw
exception
(
GET_LOCK_FAILED
);
}
finally
{
lock
.
unlock
();
}
return
true
;
}
private
RewardDO
getAndVerifyRewardDO
(
RedeemRewardReqVO
redeemRewardReqVO
)
{
// 查询礼品
// 查询礼品
RewardDO
rewardDO
=
rewardMapper
.
selectById
(
redeemRewardReqVO
.
getRewardId
());
RewardDO
rewardDO
=
rewardMapper
.
selectById
(
redeemRewardReqVO
.
getRewardId
());
if
(
rewardDO
==
null
)
{
if
(
rewardDO
==
null
)
{
...
@@ -102,25 +132,22 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -102,25 +132,22 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
if
(!
Arrays
.
asList
(
split
).
contains
(
String
.
valueOf
(
redeemRewardReqVO
.
getRedeemType
())))
{
if
(!
Arrays
.
asList
(
split
).
contains
(
String
.
valueOf
(
redeemRewardReqVO
.
getRedeemType
())))
{
throw
exception
(
REWARD_PICK_METHOD_NOT_ALLOW
);
throw
exception
(
REWARD_PICK_METHOD_NOT_ALLOW
);
}
}
verifyMemberUser
(
redeemRewardReqVO
,
rewardDO
);
return
rewardDO
;
String
lockKey
=
"reward:redeem:lock:"
+
redeemRewardReqVO
.
getRewardId
();
}
RLock
lock
=
redissonClient
.
getLock
(
lockKey
);
try
{
private
void
verifyRecipientInfo
(
RedeemRewardReqVO
redeemRewardReqVO
,
UserRespDTO
memberUser
)
{
if
(!
lock
.
tryLock
(
2
,
10
,
TimeUnit
.
SECONDS
))
{
if
(
redeemRewardReqVO
.
getRedeemType
()
==
RewardPickMethedEnum
.
SELF_PICKUP
.
getValue
())
{
throw
exception
(
GET_LOCK_FAILED
);
if
(
StringUtils
.
isBlank
(
redeemRewardReqVO
.
getRecipientName
()))
{
redeemRewardReqVO
.
setRecipientName
(
memberUser
.
getNickname
());
}
if
(
StringUtils
.
isBlank
(
redeemRewardReqVO
.
getRecipientPhoneNum
()))
{
redeemRewardReqVO
.
setRecipientPhoneNum
(
memberUser
.
getMobile
());
}
}
else
{
if
(
StringUtils
.
isAnyBlank
(
redeemRewardReqVO
.
getRecipientName
(),
redeemRewardReqVO
.
getRecipientPhoneNum
(),
redeemRewardReqVO
.
getRecipientAddress
()))
{
throw
exception
(
REWARD_REDEEM_RECIPIENT_ERROR
);
}
}
// 添加兑换记录
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
,
rewardDO
);
// 更新会员积分
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
}
catch
(
InterruptedException
e
)
{
throw
exception
(
GET_LOCK_FAILED
);
}
finally
{
lock
.
unlock
();
}
}
return
true
;
}
}
private
void
redeemReward
(
RewardDO
reward
,
Integer
rewardCount
)
{
private
void
redeemReward
(
RewardDO
reward
,
Integer
rewardCount
)
{
...
@@ -172,6 +199,11 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -172,6 +199,11 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
}
}
int
totalCount
=
0
;
int
totalCount
=
0
;
for
(
RedeemRewardReqVO
redeemRewardReqVO
:
redeemRewardReqVOList
)
{
for
(
RedeemRewardReqVO
redeemRewardReqVO
:
redeemRewardReqVOList
)
{
UserRespDTO
memberUser
=
memberUserApi
.
getUser
(
redeemRewardReqVO
.
getMemberId
());
if
(
memberUser
==
null
)
{
throw
exception
(
USER_NOT_EXISTS
);
}
verifyRecipientInfo
(
redeemRewardReqVO
,
memberUser
);
// 每个兑换VO校验一遍
// 每个兑换VO校验一遍
// 兑换方式不匹配,后台不校验
// 兑换方式不匹配,后台不校验
if
(
redeemRewardReqVO
.
getEntrance
()
!=
PlatformTypeEnum
.
BACKEND
.
getValue
())
{
if
(
redeemRewardReqVO
.
getEntrance
()
!=
PlatformTypeEnum
.
BACKEND
.
getValue
())
{
...
@@ -181,7 +213,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -181,7 +213,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw
exception
(
REWARD_PICK_METHOD_NOT_ALLOW
);
throw
exception
(
REWARD_PICK_METHOD_NOT_ALLOW
);
}
}
}
}
verifyMemberUser
(
redeemRewardReqVO
,
rewardDO
);
verifyMemberUser
(
redeemRewardReqVO
,
rewardDO
,
memberUser
.
getHoldScore
()
);
// 记录兑换总数
// 记录兑换总数
totalCount
+=
redeemRewardReqVO
.
getRewardCount
();
totalCount
+=
redeemRewardReqVO
.
getRewardCount
();
// 判断兑换总数是否大于礼物数量
// 判断兑换总数是否大于礼物数量
...
@@ -243,13 +275,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -243,13 +275,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
smsCodeApi
.
sendSmsCode
(
smsCodeSendReqDTO
);
smsCodeApi
.
sendSmsCode
(
smsCodeSendReqDTO
);
}
}
private
void
verifyMemberUser
(
RedeemRewardReqVO
redeemRewardReqVO
,
RewardDO
rewardDO
)
{
private
void
verifyMemberUser
(
RedeemRewardReqVO
redeemRewardReqVO
,
RewardDO
rewardDO
,
Integer
holdScore
)
{
// 查询会员积分
UserRespDTO
memberUser
=
memberUserApi
.
getUser
(
redeemRewardReqVO
.
getMemberId
());
if
(
memberUser
==
null
)
{
throw
exception
(
USER_NOT_EXISTS
);
}
Integer
holdScore
=
memberUser
.
getHoldScore
();
// 会员积分不够
// 会员积分不够
if
(
holdScore
<
rewardDO
.
getPointsRequire
()
*
redeemRewardReqVO
.
getRewardCount
())
{
if
(
holdScore
<
rewardDO
.
getPointsRequire
()
*
redeemRewardReqVO
.
getRewardCount
())
{
throw
exception
(
REWARD_SCORE_NOT_ENOUGH
,
"userId:"
+
redeemRewardReqVO
.
getMemberId
()
+
",holdScore:"
+
holdScore
,
"requireScore:"
+
rewardDO
.
getPointsRequire
()
*
redeemRewardReqVO
.
getRewardCount
());
throw
exception
(
REWARD_SCORE_NOT_ENOUGH
,
"userId:"
+
redeemRewardReqVO
.
getMemberId
()
+
",holdScore:"
+
holdScore
,
"requireScore:"
+
rewardDO
.
getPointsRequire
()
*
redeemRewardReqVO
.
getRewardCount
());
...
...
yudao-server/src/main/resources/i18n/messages_en.properties
View file @
eef3c4ae
...
@@ -1025,6 +1025,7 @@ reward.count.not.enough = reward count not enough
...
@@ -1025,6 +1025,7 @@ reward.count.not.enough = reward count not enough
reward.redeem.count.not.allow
=
bulk redemption is limited to a maximum of 10 pieces at a time
reward.redeem.count.not.allow
=
bulk redemption is limited to a maximum of 10 pieces at a time
reward.redeem.allow.count.error
=
the number of redemptions allowed by the individual has been exceeded:{}
reward.redeem.allow.count.error
=
the number of redemptions allowed by the individual has been exceeded:{}
reward.node.and.points.list.error
=
reward node and points create error
reward.node.and.points.list.error
=
reward node and points create error
reward.redeem.recipient.error
=
recipient info information is incomplete
redeem.import.max.count
=
allow maximum number of imports is {}
redeem.import.max.count
=
allow maximum number of imports is {}
dict.unknown.error
=
Not in dict {0}: {1}
dict.unknown.error
=
Not in dict {0}: {1}
...
...
yudao-server/src/main/resources/i18n/messages_zh.properties
View file @
eef3c4ae
...
@@ -1023,6 +1023,7 @@ reward.count.not.enough = \u793C\u54C1\u6570\u91CF\u4E0D\u8DB3
...
@@ -1023,6 +1023,7 @@ reward.count.not.enough = \u793C\u54C1\u6570\u91CF\u4E0D\u8DB3
reward.redeem.count.not.allow
=
\u6279\u
91CF
\u5151\u6362\u
6BCF
\u
6B21
\u6700\u
591A
\u5341\u6761
reward.redeem.count.not.allow
=
\u6279\u
91CF
\u5151\u6362\u
6BCF
\u
6B21
\u6700\u
591A
\u5341\u6761
reward.redeem.allow.count.error
=
\u
5DF2
\u
8D85
\u
51FA
\u
4E2A
\u
4EBA
\u5141\u
8BB8
\u5151\u6362\u
6B21
\u6570\u
FF1A{}
reward.redeem.allow.count.error
=
\u
5DF2
\u
8D85
\u
51FA
\u
4E2A
\u
4EBA
\u5141\u
8BB8
\u5151\u6362\u
6B21
\u6570\u
FF1A{}
reward.node.and.points.list.error
=
\u
521B
\u
5EFA
\u
793C
\u
54C1
\u
7F51
\u
70B9
\u6216\u6240\u9700\u
79EF
\u5206\u9519\u
8BEF
reward.node.and.points.list.error
=
\u
521B
\u
5EFA
\u
793C
\u
54C1
\u
7F51
\u
70B9
\u6216\u6240\u9700\u
79EF
\u5206\u9519\u
8BEF
reward.redeem.recipient.error
=
\u
793C
\u
54C1
\u6536\u
8D27
\u
4EBA
\u
4FE1
\u
606F
\u
4E0D
\u5168
get.lock.failed
=
\u
670D
\u
52A1
\u
7E41
\u
5FD9
\u
FF0C
\u
8BF7
\u
7A0D
\u
540E
\u
91CD
\u
8BD5
get.lock.failed
=
\u
670D
\u
52A1
\u
7E41
\u
5FD9
\u
FF0C
\u
8BF7
\u
7A0D
\u
540E
\u
91CD
\u
8BD5
reward.redeem.not.exist
=
\u
793C
\u
54C1
\u5151\u6362\u
8BB0
\u
5F55
\u
4E0D
\u
5B58
\u5728
reward.redeem.not.exist
=
\u
793C
\u
54C1
\u5151\u6362\u
8BB0
\u
5F55
\u
4E0D
\u
5B58
\u5728
...
...
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