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
e3e82a56
Commit
e3e82a56
authored
Jul 31, 2024
by
zhaobiyan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
兑换撤销接口
parent
879a2da6
Changes
31
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
584 additions
and
50 deletions
+584
-50
MemberScoreDetailExpireEvent.java
...pollo/core/event/export/MemberScoreDetailExpireEvent.java
+10
-0
MemberUserScoreApi.java
...der/yudao/module/member/api/score/MemberUserScoreApi.java
+3
-0
MemberUserScoreDetailUpdateReqDto.java
...mber/api/score/dto/MemberUserScoreDetailUpdateReqDto.java
+1
-0
MemberUserScoreOperateReqDTO.java
...le/member/api/score/dto/MemberUserScoreOperateReqDTO.java
+4
-0
ReleationScoreExpireInfoDTO.java
...ule/member/api/score/dto/ReleationScoreExpireInfoDTO.java
+12
-0
ErrorCodeConstants.java
...iocoder/yudao/module/member/enums/ErrorCodeConstants.java
+2
-1
MemberScoreDetailReleationStatueEnum.java
...le/member/enums/MemberScoreDetailReleationStatueEnum.java
+25
-0
ScoreSourceTypeEnum.java
...ocoder/yudao/module/member/enums/ScoreSourceTypeEnum.java
+13
-4
MemberUserScoreApiImpl.java
...yudao/module/member/api/score/MemberUserScoreApiImpl.java
+78
-12
MemberUserScoreExpireTask.java
...ember/controller/admin/job/MemberUserScoreExpireTask.java
+4
-3
MemberUserScoreDetailDO.java
...object/memberUserScoreDetail/MemberUserScoreDetailDO.java
+3
-2
MemberUserScoreDetailReleationDO.java
...coreDetailReleation/MemberUserScoreDetailReleationDO.java
+36
-0
MemberUserScoreDetailReleationMapper.java
...DetailReleation/MemberUserScoreDetailReleationMapper.java
+17
-0
ScoreDetailChangeDto.java
...iocoder/yudao/module/member/dto/ScoreDetailChangeDto.java
+11
-0
MemberUserScoreDetailExpireListener.java
.../member/listener/MemberUserScoreDetailExpireListener.java
+66
-0
MemberUserScoreServiceImpl.java
...r/service/memberUserScore/MemberUserScoreServiceImpl.java
+9
-0
MemberUserScoreDetailService.java
...e/memberUserScoreDetail/MemberUserScoreDetailService.java
+4
-1
MemberUserScoreDetailServiceImpl.java
...mberUserScoreDetail/MemberUserScoreDetailServiceImpl.java
+87
-16
MemberUserScoreDetailReleationService.java
...etailReleation/MemberUserScoreDetailReleationService.java
+20
-0
MemberUserScoreDetailReleationServiceImpl.java
...lReleation/MemberUserScoreDetailReleationServiceImpl.java
+69
-0
MemberUserScoreDetailReleationMapper.xml
...rces/mapper/user/MemberUserScoreDetailReleationMapper.xml
+5
-0
ErrorCodeConstants.java
...iocoder/yudao/module/reward/enums/ErrorCodeConstants.java
+1
-0
RedeemRewardApiImpl.java
...r/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
+9
-7
RedeemRewardController.java
...eward/controller/admin/redeem/RedeemRewardController.java
+12
-0
RewardRedeemDO.java
...o/module/reward/dal/dataobject/redeem/RewardRedeemDO.java
+1
-0
RewardRedeemService.java
...dao/module/reward/service/redeem/RewardRedeemService.java
+4
-0
RewardRedeemServiceImpl.java
...module/reward/service/redeem/RewardRedeemServiceImpl.java
+61
-1
RedeemCancelCheckRespVO.java
...udao/module/reward/vo/reward/RedeemCancelCheckRespVO.java
+12
-0
RewardRedeemMapper.xml
...ard-impl/src/main/resources/mapper/RewardRedeemMapper.xml
+1
-1
messages_en.properties
yudao-server/src/main/resources/i18n/messages_en.properties
+2
-1
messages_zh.properties
yudao-server/src/main/resources/i18n/messages_zh.properties
+2
-1
No files found.
yudao-framework/yudao-spring-boot-starter-config/src/main/java/cn/iocoder/yudao/framework/apollo/core/event/export/MemberScoreDetailExpireEvent.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
framework
.
apollo
.
core
.
event
.
export
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
MemberScoreDetailExpireEvent
{
private
List
<
Long
>
detailIds
;
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/score/MemberUserScoreApi.java
View file @
e3e82a56
...
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.member.api.score;
...
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.member.api.score;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreBatchOperateReqDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreBatchOperateReqDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateRespDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateRespDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.ReleationScoreExpireInfoDTO
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
java.util.List
;
import
java.util.List
;
...
@@ -12,4 +14,5 @@ public interface MemberUserScoreApi {
...
@@ -12,4 +14,5 @@ public interface MemberUserScoreApi {
List
<
MemberUserScoreOperateRespDTO
>
batchOperateScore
(
MemberUserScoreBatchOperateReqDTO
req
);
List
<
MemberUserScoreOperateRespDTO
>
batchOperateScore
(
MemberUserScoreBatchOperateReqDTO
req
);
List
<
ReleationScoreExpireInfoDTO
>
getScoreExpireInfo
(
String
releation
,
ScoreSourceTypeEnum
scoreSourceTypeEnum
);
}
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/score/dto/MemberUserScoreDetailUpdateReqDto.java
View file @
e3e82a56
...
@@ -14,4 +14,5 @@ public class MemberUserScoreDetailUpdateReqDto {
...
@@ -14,4 +14,5 @@ public class MemberUserScoreDetailUpdateReqDto {
private
ScoreSourceTypeEnum
sourceType
;
private
ScoreSourceTypeEnum
sourceType
;
private
Long
scoreLogId
;
private
Long
scoreLogId
;
private
Integer
expireDays
;
private
Integer
expireDays
;
private
String
releationId
;
}
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/score/dto/MemberUserScoreOperateReqDTO.java
View file @
e3e82a56
...
@@ -28,6 +28,10 @@ public class MemberUserScoreOperateReqDTO {
...
@@ -28,6 +28,10 @@ public class MemberUserScoreOperateReqDTO {
* 人工操作时必传,其他来源不需要传
* 人工操作时必传,其他来源不需要传
*/
*/
private
ScoreOperateTypeEnum
operateType
;
private
ScoreOperateTypeEnum
operateType
;
/**
* 若操作的积分后续存在回退逻辑时必传, 目前存在 礼品兑换后, 兑换取消,扣除积分的回退
*/
private
String
releationId
;
/**
/**
* 积分规则id
* 积分规则id
*/
*/
...
...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/score/dto/ReleationScoreExpireInfoDTO.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
api
.
score
.
dto
;
import
lombok.Data
;
import
java.util.Date
;
@Data
public
class
ReleationScoreExpireInfoDTO
{
private
Long
detailId
;
private
Date
expireDate
;
private
Integer
scoreCount
;
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
View file @
e3e82a56
...
@@ -44,5 +44,6 @@ public interface ErrorCodeConstants {
...
@@ -44,5 +44,6 @@ public interface ErrorCodeConstants {
ErrorCode
SCORE_COUNT_ERROR
=
new
ErrorCode
(
1004008002
,
"score.count.error"
);
ErrorCode
SCORE_COUNT_ERROR
=
new
ErrorCode
(
1004008002
,
"score.count.error"
);
ErrorCode
MEMBER_SCORE_NOT_ENOUGH
=
new
ErrorCode
(
1004008002
,
"member.score.not.enough"
);
ErrorCode
MEMBER_SCORE_NOT_ENOUGH
=
new
ErrorCode
(
1004008003
,
"member.score.not.enough"
);
ErrorCode
REVERSE_SOURCE_NO_RELEATION_ID
=
new
ErrorCode
(
1004008004
,
"reverse.source.no.releation.id"
);
}
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberScoreDetailReleationStatueEnum.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
enums
;
public
enum
MemberScoreDetailReleationStatueEnum
{
AVAILABLE
(
1
,
"有效"
),
NOT_AVAILABLE
(
2
,
"失效"
)
;
private
final
int
value
;
private
final
String
name
;
MemberScoreDetailReleationStatueEnum
(
int
value
,
String
name
)
{
this
.
value
=
value
;
this
.
name
=
name
;
}
public
int
getValue
()
{
return
value
;
}
public
String
getName
()
{
return
name
;
}
}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ScoreSourceTypeEnum.java
View file @
e3e82a56
...
@@ -5,11 +5,13 @@ import com.google.common.collect.Sets;
...
@@ -5,11 +5,13 @@ import com.google.common.collect.Sets;
import
java.util.Set
;
import
java.util.Set
;
public
enum
ScoreSourceTypeEnum
{
public
enum
ScoreSourceTypeEnum
{
MANUAL_OPERATE
(
1
,
"人工操作"
,
null
),
MANUAL_OPERATE
(
1
,
"人工操作"
,
null
,
null
),
EXCHANGE_REWARD
(
2
,
"兑换礼品"
,
ScoreOperateTypeEnum
.
REDUCE
),
EXCHANGE_REWARD
(
2
,
"兑换礼品"
,
ScoreOperateTypeEnum
.
REDUCE
,
null
),
SYSTEM_EXPIRED
(
3
,
"系统失效"
,
ScoreOperateTypeEnum
.
REDUCE
),
SYSTEM_EXPIRED
(
3
,
"系统失效"
,
ScoreOperateTypeEnum
.
REDUCE
,
null
),
EXCHANGE_REWARD_CANCEL
(
4
,
"兑换礼品撤销"
,
ScoreOperateTypeEnum
.
ADD
,
EXCHANGE_REWARD
),
;
;
private
final
int
value
;
private
final
int
value
;
...
@@ -18,16 +20,23 @@ public enum ScoreSourceTypeEnum {
...
@@ -18,16 +20,23 @@ public enum ScoreSourceTypeEnum {
private
final
ScoreOperateTypeEnum
operateType
;
private
final
ScoreOperateTypeEnum
operateType
;
ScoreSourceTypeEnum
(
int
value
,
String
name
,
ScoreOperateTypeEnum
operateType
)
{
private
final
ScoreSourceTypeEnum
reverseSource
;
ScoreSourceTypeEnum
(
int
value
,
String
name
,
ScoreOperateTypeEnum
operateType
,
ScoreSourceTypeEnum
reverseSource
)
{
this
.
value
=
value
;
this
.
value
=
value
;
this
.
name
=
name
;
this
.
name
=
name
;
this
.
operateType
=
operateType
;
this
.
operateType
=
operateType
;
this
.
reverseSource
=
reverseSource
;
}
}
public
int
getValue
()
{
public
int
getValue
()
{
return
value
;
return
value
;
}
}
public
ScoreSourceTypeEnum
getReverseSource
()
{
return
reverseSource
;
}
public
String
getName
()
{
public
String
getName
()
{
return
name
;
return
name
;
}
}
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/score/MemberUserScoreApiImpl.java
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
api
.
score
;
package
cn
.
iocoder
.
yudao
.
module
.
member
.
api
.
score
;
import
cn.iocoder.yudao.framework.
redis.helper.RedisDistributedLock
;
import
cn.iocoder.yudao.framework.
apollo.core.event.export.MemberScoreDetailExpireEvent
;
import
cn.iocoder.yudao.module.member.api.score.dto.*
;
import
cn.iocoder.yudao.module.member.api.score.dto.*
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScore.MemberUserScoreDO
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScore.MemberUserScoreDO
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.MemberUserScoreDetailDO
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetailReleation.MemberUserScoreDetailReleationDO
;
import
cn.iocoder.yudao.module.member.dto.ScoreDetailChangeDto
;
import
cn.iocoder.yudao.module.member.enums.MemberScoreDetailReleationStatueEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreOperateTypeEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreOperateTypeEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
cn.iocoder.yudao.module.member.service.memberUserScore.MemberUserScoreService
;
import
cn.iocoder.yudao.module.member.service.memberUserScore.MemberUserScoreService
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreDetail.MemberUserScoreDetailService
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreDetail.MemberUserScoreDetailService
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreDetailReleation.MemberUserScoreDetailReleationService
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreLog.MemberUserScoreLogService
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreLog.MemberUserScoreLogService
;
import
cn.iocoder.yudao.module.member.vo.memberUserScoreLog.MemberUserScoreLogCreateReq
;
import
cn.iocoder.yudao.module.member.vo.memberUserScoreLog.MemberUserScoreLogCreateReq
;
import
com.alibaba.excel.util.CollectionUtils
;
import
com.alibaba.excel.util.CollectionUtils
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.StringUtils
;
import
org.redisson.api.RLock
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.TimeUnit
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
...
@@ -36,7 +49,12 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
...
@@ -36,7 +49,12 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
@Resource
@Resource
private
MemberUserScoreService
memberUserScoreService
;
private
MemberUserScoreService
memberUserScoreService
;
@Resource
@Resource
private
RedisDistributedLock
redisDistributedLock
;
private
MemberUserScoreDetailReleationService
memberUserScoreDetailReleationService
;
@Resource
private
ApplicationContext
applicationContext
;
@Resource
private
RedissonClient
redissonClient
;
@Override
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
MemberUserScoreOperateRespDTO
operateScore
(
MemberUserScoreOperateReqDTO
req
)
{
public
MemberUserScoreOperateRespDTO
operateScore
(
MemberUserScoreOperateReqDTO
req
)
{
...
@@ -46,21 +64,43 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
...
@@ -46,21 +64,43 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
if
(
req
.
getScoreCount
()
<=
0
)
{
if
(
req
.
getScoreCount
()
<=
0
)
{
throw
exception
(
SCORE_COUNT_ERROR
);
throw
exception
(
SCORE_COUNT_ERROR
);
}
}
String
lockKey
=
"member:operate:socre:"
+
req
.
getMemberId
();
String
lockKey
=
"member:operate:score:"
+
req
.
getMemberId
();
boolean
lock
=
redisDistributedLock
.
lock
(
lockKey
,
5000
,
3
,
100
);
RLock
lock
=
redissonClient
.
getLock
(
lockKey
);
if
(!
lock
)
{
try
{
boolean
lockSuccess
=
lock
.
tryLock
(
2
,
2
,
TimeUnit
.
MINUTES
);
if
(!
lockSuccess
)
{
throw
exception
(
GET_LOCK_FAILED
);
throw
exception
(
GET_LOCK_FAILED
);
}
}
try
{
Long
logId
=
saveScoreLog
(
req
);
Long
logId
=
saveScoreLog
(
req
);
saveScoreDetail
(
req
,
logId
);
List
<
ScoreDetailChangeDto
>
detailInfos
=
saveScoreDetail
(
req
,
logId
);
saveScoreDetailReleation
(
req
,
detailInfos
);
updateUserScore
(
req
);
updateUserScore
(
req
);
publishDetailExpireEvent
(
req
,
detailInfos
);
}
catch
(
InterruptedException
e
)
{
throw
exception
(
GET_LOCK_FAILED
);
}
finally
{
}
finally
{
redisDistributedLock
.
releaseLock
(
lockKey
);
lock
.
unlock
(
);
}
}
return
MemberUserScoreOperateRespDTO
.
success
(
req
);
return
MemberUserScoreOperateRespDTO
.
success
(
req
);
}
}
private
void
publishDetailExpireEvent
(
MemberUserScoreOperateReqDTO
req
,
List
<
ScoreDetailChangeDto
>
detailInfos
)
{
if
(
req
.
getSourceType
().
getReverseSource
()
==
null
||
req
.
getOperateType
()
==
ScoreOperateTypeEnum
.
REDUCE
)
{
return
;
}
//判断回退流程,回退的积分是否过期.如果过期再走正常的过期扣积分流程
MemberScoreDetailExpireEvent
memberScoreDetailExpireEvent
=
new
MemberScoreDetailExpireEvent
();
memberScoreDetailExpireEvent
.
setDetailIds
(
detailInfos
.
stream
().
map
(
ScoreDetailChangeDto:
:
getDetailId
).
collect
(
Collectors
.
toList
()));
applicationContext
.
publishEvent
(
memberScoreDetailExpireEvent
);
}
private
void
saveScoreDetailReleation
(
MemberUserScoreOperateReqDTO
req
,
List
<
ScoreDetailChangeDto
>
detailInfos
)
{
if
(
StringUtils
.
isBlank
(
req
.
getReleationId
()))
{
return
;
}
memberUserScoreDetailReleationService
.
updateReleation
(
req
.
getReleationId
(),
req
.
getSourceType
(),
detailInfos
);
}
@Override
@Override
@Transactional
@Transactional
public
List
<
MemberUserScoreOperateRespDTO
>
batchOperateScore
(
MemberUserScoreBatchOperateReqDTO
req
)
{
public
List
<
MemberUserScoreOperateRespDTO
>
batchOperateScore
(
MemberUserScoreBatchOperateReqDTO
req
)
{
...
@@ -91,6 +131,31 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
...
@@ -91,6 +131,31 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
}
}
@Override
public
List
<
ReleationScoreExpireInfoDTO
>
getScoreExpireInfo
(
String
releationId
,
ScoreSourceTypeEnum
scoreSourceTypeEnum
)
{
if
(
StringUtils
.
isBlank
(
releationId
))
{
return
Collections
.
emptyList
();
}
LambdaQueryWrapper
<
MemberUserScoreDetailReleationDO
>
wrapper
=
Wrappers
.
lambdaQuery
();
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getReleationId
,
releationId
);
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getSourceType
,
scoreSourceTypeEnum
.
getValue
());
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getStatus
,
MemberScoreDetailReleationStatueEnum
.
AVAILABLE
.
getValue
());
List
<
MemberUserScoreDetailReleationDO
>
releationDOList
=
memberUserScoreDetailReleationService
.
list
(
wrapper
);
Set
<
Long
>
detailIds
=
releationDOList
.
stream
().
map
(
MemberUserScoreDetailReleationDO:
:
getDetailId
).
collect
(
Collectors
.
toSet
());
LambdaQueryWrapper
<
MemberUserScoreDetailDO
>
detailWrappers
=
Wrappers
.
lambdaQuery
();
detailWrappers
.
in
(
MemberUserScoreDetailDO:
:
getId
,
detailIds
);
Map
<
Long
,
MemberUserScoreDetailDO
>
detailIdInfoMap
=
scoreDetailService
.
list
(
detailWrappers
).
stream
()
.
collect
(
Collectors
.
toMap
(
MemberUserScoreDetailDO:
:
getId
,
Function
.
identity
(),
(
c1
,
c2
)
->
c1
));
return
releationDOList
.
stream
().
map
(
releation
->
{
ReleationScoreExpireInfoDTO
expireInfoDTO
=
new
ReleationScoreExpireInfoDTO
();
MemberUserScoreDetailDO
detailDO
=
detailIdInfoMap
.
getOrDefault
(
releation
.
getDetailId
(),
new
MemberUserScoreDetailDO
());
expireInfoDTO
.
setDetailId
(
detailDO
.
getId
());
expireInfoDTO
.
setExpireDate
(
detailDO
.
getExpireTime
());
expireInfoDTO
.
setScoreCount
(
releation
.
getScoreCount
());
return
expireInfoDTO
;
}).
collect
(
Collectors
.
toList
());
}
private
void
updateUserScore
(
MemberUserScoreOperateReqDTO
req
)
{
private
void
updateUserScore
(
MemberUserScoreOperateReqDTO
req
)
{
memberUserScoreService
.
updateUserScore
(
MemberUserScoreUpdateReqDTO
.
builder
()
memberUserScoreService
.
updateUserScore
(
MemberUserScoreUpdateReqDTO
.
builder
()
.
memberId
(
req
.
getMemberId
())
.
memberId
(
req
.
getMemberId
())
...
@@ -101,8 +166,8 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
...
@@ -101,8 +166,8 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
.
build
());
.
build
());
}
}
private
void
saveScoreDetail
(
MemberUserScoreOperateReqDTO
req
,
Long
scoreLogId
)
{
private
List
<
ScoreDetailChangeDto
>
saveScoreDetail
(
MemberUserScoreOperateReqDTO
req
,
Long
scoreLogId
)
{
scoreDetailService
.
updateScoreDetail
(
MemberUserScoreDetailUpdateReqDto
.
builder
()
return
scoreDetailService
.
updateScoreDetail
(
MemberUserScoreDetailUpdateReqDto
.
builder
()
.
memberId
(
req
.
getMemberId
())
.
memberId
(
req
.
getMemberId
())
.
scoreCount
(
req
.
getScoreCount
())
.
scoreCount
(
req
.
getScoreCount
())
.
operateType
(
req
.
getSourceType
()
==
ScoreSourceTypeEnum
.
MANUAL_OPERATE
?
.
operateType
(
req
.
getSourceType
()
==
ScoreSourceTypeEnum
.
MANUAL_OPERATE
?
...
@@ -110,6 +175,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
...
@@ -110,6 +175,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
.
sourceType
(
req
.
getSourceType
())
.
sourceType
(
req
.
getSourceType
())
.
scoreLogId
(
scoreLogId
)
.
scoreLogId
(
scoreLogId
)
.
expireDays
(
req
.
getExpireDays
())
.
expireDays
(
req
.
getExpireDays
())
.
releationId
(
req
.
getReleationId
())
.
build
());
.
build
());
}
}
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/job/MemberUserScoreExpireTask.java
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
controller
.
admin
.
job
;
package
cn
.
iocoder
.
yudao
.
module
.
member
.
controller
.
admin
.
job
;
import
cn.hutool.json.JSONArray
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.common.util.date.DateUtils
;
import
cn.iocoder.yudao.framework.quartz.core.handler.JobHandler
;
import
cn.iocoder.yudao.framework.quartz.core.handler.JobHandler
;
import
cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi
;
import
cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi
;
...
@@ -46,7 +47,7 @@ public class MemberUserScoreExpireTask implements JobHandler {
...
@@ -46,7 +47,7 @@ public class MemberUserScoreExpireTask implements JobHandler {
LambdaQueryWrapper
<
MemberUserScoreDetailDO
>
wrapper
=
Wrappers
.
lambdaQuery
();
LambdaQueryWrapper
<
MemberUserScoreDetailDO
>
wrapper
=
Wrappers
.
lambdaQuery
();
wrapper
.
in
(
MemberUserScoreDetailDO:
:
getStatus
,
Lists
.
newArrayList
(
MemberScoreStatueEnum
.
AVAILABLE
.
getValue
(),
wrapper
.
in
(
MemberUserScoreDetailDO:
:
getStatus
,
Lists
.
newArrayList
(
MemberScoreStatueEnum
.
AVAILABLE
.
getValue
(),
MemberScoreStatueEnum
.
PART_AVAILABLE
.
getValue
()));
MemberScoreStatueEnum
.
PART_AVAILABLE
.
getValue
()));
wrapper
.
eq
(
MemberUserScoreDetailDO:
:
getExpireTime
,
DateUtils
.
getNextNDayStart
(
new
Date
(),
0
));
wrapper
.
le
(
MemberUserScoreDetailDO:
:
getExpireTime
,
DateUtils
.
getNextNDayStart
(
new
Date
(),
0
));
wrapper
.
orderByAsc
(
MemberUserScoreDetailDO:
:
getCreateTime
);
wrapper
.
orderByAsc
(
MemberUserScoreDetailDO:
:
getCreateTime
);
List
<
MemberUserScoreDetailDO
>
todoList
=
scoreDetailService
.
list
(
wrapper
);
List
<
MemberUserScoreDetailDO
>
todoList
=
scoreDetailService
.
list
(
wrapper
);
log
.
info
(
"member user score expire task, to expire record count :{}"
,
todoList
.
size
());
log
.
info
(
"member user score expire task, to expire record count :{}"
,
todoList
.
size
());
...
@@ -56,9 +57,9 @@ public class MemberUserScoreExpireTask implements JobHandler {
...
@@ -56,9 +57,9 @@ public class MemberUserScoreExpireTask implements JobHandler {
for
(
MemberUserScoreDetailDO
memberUserScoreDetailDO
:
todoList
)
{
for
(
MemberUserScoreDetailDO
memberUserScoreDetailDO
:
todoList
)
{
try
{
try
{
log
.
info
(
"score expire, score detail id :{}"
,
memberUserScoreDetailDO
.
getId
());
log
.
info
(
"score expire, score detail id :{}"
,
memberUserScoreDetailDO
.
getId
());
List
logIds
=
(
List
)
memberUserScoreDetailDO
.
getExtParamByKey
(
MemberUserScoreDetailDO
.
MemberUserScoreDetailExtKey
.
LOG_IDS
);
JSONArray
logIds
=
memberUserScoreDetailDO
.
getExtParamByKey
(
MemberUserScoreDetailDO
.
MemberUserScoreDetailExtKey
.
LOG_IDS
);
Map
<
String
,
Object
>
extParam
=
new
HashMap
<>();
Map
<
String
,
Object
>
extParam
=
new
HashMap
<>();
extParam
.
put
(
"scoreLogIds"
,
logIds
);
extParam
.
put
(
"scoreLogIds"
,
logIds
.
toList
(
Long
.
class
)
);
memberUserScoreApi
.
operateScore
(
MemberUserScoreOperateReqDTO
.
builder
()
memberUserScoreApi
.
operateScore
(
MemberUserScoreOperateReqDTO
.
builder
()
.
memberId
(
memberUserScoreDetailDO
.
getMemberId
())
.
memberId
(
memberUserScoreDetailDO
.
getMemberId
())
.
scoreCount
(
memberUserScoreDetailDO
.
getRemainCount
())
.
scoreCount
(
memberUserScoreDetailDO
.
getRemainCount
())
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/memberUserScoreDetail/MemberUserScoreDetailDO.java
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
dal
.
dataobject
.
memberUserScoreDetail
;
package
cn
.
iocoder
.
yudao
.
module
.
member
.
dal
.
dataobject
.
memberUserScoreDetail
;
import
cn.hutool.json.JSONArray
;
import
cn.hutool.json.JSONObject
;
import
cn.hutool.json.JSONObject
;
import
cn.hutool.json.JSONUtil
;
import
cn.hutool.json.JSONUtil
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
...
@@ -55,8 +56,8 @@ public class MemberUserScoreDetailDO extends BaseDO {
...
@@ -55,8 +56,8 @@ public class MemberUserScoreDetailDO extends BaseDO {
}
}
public
Object
getExtParamByKey
(
MemberUserScoreDetailExtKey
key
)
{
public
JSONArray
getExtParamByKey
(
MemberUserScoreDetailExtKey
key
)
{
JSONObject
extParamJsonObject
=
JSONUtil
.
parseObj
(
extParam
);
JSONObject
extParamJsonObject
=
JSONUtil
.
parseObj
(
extParam
);
return
extParamJsonObject
.
get
(
key
.
getKey
(),
List
.
class
);
return
extParamJsonObject
.
get
(
key
.
getKey
(),
JSONArray
.
class
);
}
}
}
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/memberUserScoreDetailReleation/MemberUserScoreDetailReleationDO.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
dal
.
dataobject
.
memberUserScoreDetailReleation
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
import
java.util.Date
;
/**
* 会员积分 DO
*
* @author 系统管理员
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName
(
"member_user_score_detail_releation"
)
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
MemberUserScoreDetailReleationDO
extends
BaseDO
{
@TableId
private
Long
id
;
private
String
releationId
;
private
Integer
sourceType
;
private
Long
detailId
;
private
Integer
scoreCount
;
private
Integer
status
;
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/memberUserScoreDetailReleation/MemberUserScoreDetailReleationMapper.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
dal
.
mysql
.
memberUserScoreDetailReleation
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetailReleation.MemberUserScoreDetailReleationDO
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.Collection
;
/**
* 会员积分详情 Mapper
* @author 系统管理员
*/
@Mapper
public
interface
MemberUserScoreDetailReleationMapper
extends
AbstractMapper
<
MemberUserScoreDetailReleationDO
>
{
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dto/ScoreDetailChangeDto.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
dto
;
import
lombok.Builder
;
import
lombok.Data
;
@Data
@Builder
public
class
ScoreDetailChangeDto
{
private
Long
detailId
;
private
Integer
scoreCount
;
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/listener/MemberUserScoreDetailExpireListener.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
listener
;
import
cn.hutool.core.thread.ThreadUtil
;
import
cn.hutool.json.JSONArray
;
import
cn.hutool.json.JSONUtil
;
import
cn.iocoder.yudao.framework.apollo.core.event.export.MemberScoreDetailExpireEvent
;
import
cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.MemberUserScoreDetailDO
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
cn.iocoder.yudao.module.member.service.memberUserScoreDetail.MemberUserScoreDetailService
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.CollectionUtils
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.event.EventListener
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Component
@AllArgsConstructor
@Slf4j
public
class
MemberUserScoreDetailExpireListener
{
@Resource
private
MemberUserScoreDetailService
scoreDetailService
;
@Resource
private
MemberUserScoreApi
memberUserScoreApi
;
@Async
@EventListener
(
MemberScoreDetailExpireEvent
.
class
)
public
void
listen
(
MemberScoreDetailExpireEvent
event
)
{
log
.
info
(
"member user score expire listen,event:{}"
,
JSONUtil
.
toJsonStr
(
event
));
if
(
CollectionUtils
.
isEmpty
(
event
.
getDetailIds
()))
{
return
;
}
//暂停一会确保那边事务执行完成
ThreadUtil
.
safeSleep
(
3000L
);
LambdaQueryWrapper
<
MemberUserScoreDetailDO
>
wrapper
=
Wrappers
.
lambdaQuery
();
wrapper
.
in
(
MemberUserScoreDetailDO:
:
getId
,
event
.
getDetailIds
());
wrapper
.
le
(
MemberUserScoreDetailDO:
:
getExpireTime
,
new
Date
());
List
<
MemberUserScoreDetailDO
>
todoList
=
scoreDetailService
.
list
(
wrapper
);
todoList
.
forEach
(
detail
->
{
try
{
log
.
info
(
"score expire, score detail id :{}"
,
detail
.
getId
());
JSONArray
jsonArray
=
detail
.
getExtParamByKey
(
MemberUserScoreDetailDO
.
MemberUserScoreDetailExtKey
.
LOG_IDS
);
Map
<
String
,
Object
>
extParam
=
new
HashMap
<>();
extParam
.
put
(
"scoreLogIds"
,
jsonArray
.
toList
(
Long
.
class
));
memberUserScoreApi
.
operateScore
(
MemberUserScoreOperateReqDTO
.
builder
()
.
memberId
(
detail
.
getMemberId
())
.
scoreCount
(
detail
.
getRemainCount
())
.
sourceType
(
ScoreSourceTypeEnum
.
SYSTEM_EXPIRED
)
.
extParam
(
extParam
)
.
build
());
}
catch
(
Exception
e
)
{
log
.
error
(
"member user score expire exception, data:{}"
,
detail
,
e
);
}
});
log
.
info
(
"member user score expire listen finished"
);
}
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/memberUserScore/MemberUserScoreServiceImpl.java
View file @
e3e82a56
...
@@ -76,6 +76,15 @@ public class MemberUserScoreServiceImpl extends AbstractService<MemberUserScoreM
...
@@ -76,6 +76,15 @@ public class MemberUserScoreServiceImpl extends AbstractService<MemberUserScoreM
if
(
memberUserScoreDO
==
null
)
{
if
(
memberUserScoreDO
==
null
)
{
memberUserScoreDO
=
initMemberUserScore
(
query
.
getMemberId
());
memberUserScoreDO
=
initMemberUserScore
(
query
.
getMemberId
());
}
}
// 回退流程增加积分
if
(
query
.
getSourceType
().
getReverseSource
()
!=
null
&&
query
.
getOperateType
()
==
ScoreOperateTypeEnum
.
ADD
)
{
// 回退流程增加积分,不仅需要新增持有积分,还需要减少使用积分
memberUserScoreDO
.
setHoldScore
(
memberUserScoreDO
.
getHoldScore
()
+
query
.
getScoreCount
());
memberUserScoreDO
.
setUsedScore
(
memberUserScoreDO
.
getUsedScore
()
-
query
.
getScoreCount
());
this
.
saveOrUpdate
(
memberUserScoreDO
);
return
;
}
//正常流程 增加积分 减少积分
if
(
query
.
getOperateType
()
==
ScoreOperateTypeEnum
.
ADD
)
{
if
(
query
.
getOperateType
()
==
ScoreOperateTypeEnum
.
ADD
)
{
memberUserScoreDO
.
setHoldScore
(
memberUserScoreDO
.
getHoldScore
()
+
query
.
getScoreCount
());
memberUserScoreDO
.
setHoldScore
(
memberUserScoreDO
.
getHoldScore
()
+
query
.
getScoreCount
());
this
.
saveOrUpdate
(
memberUserScoreDO
);
this
.
saveOrUpdate
(
memberUserScoreDO
);
...
...
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/memberUserScoreDetail/MemberUserScoreDetailService.java
View file @
e3e82a56
...
@@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.member.service.memberUserScoreDetail;
...
@@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.member.service.memberUserScoreDetail;
import
cn.iocoder.yudao.framework.mybatis.core.service.IService
;
import
cn.iocoder.yudao.framework.mybatis.core.service.IService
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreDetailUpdateReqDto
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreDetailUpdateReqDto
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.MemberUserScoreDetailDO
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.MemberUserScoreDetailDO
;
import
cn.iocoder.yudao.module.member.dto.ScoreDetailChangeDto
;
import
java.util.List
;
/**
/**
* 会员积分日志 Service 接口
* 会员积分日志 Service 接口
...
@@ -11,5 +14,5 @@ import cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.Membe
...
@@ -11,5 +14,5 @@ import cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetail.Membe
*/
*/
public
interface
MemberUserScoreDetailService
extends
IService
<
MemberUserScoreDetailDO
>
{
public
interface
MemberUserScoreDetailService
extends
IService
<
MemberUserScoreDetailDO
>
{
void
updateScoreDetail
(
MemberUserScoreDetailUpdateReqDto
reqDto
);
List
<
ScoreDetailChangeDto
>
updateScoreDetail
(
MemberUserScoreDetailUpdateReqDto
reqDto
);
}
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/memberUserScoreDetail/MemberUserScoreDetailServiceImpl.java
View file @
e3e82a56
This diff is collapsed.
Click to expand it.
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/memberUserScoreDetailReleation/MemberUserScoreDetailReleationService.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
service
.
memberUserScoreDetailReleation
;
import
cn.iocoder.yudao.framework.mybatis.core.service.IService
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetailReleation.MemberUserScoreDetailReleationDO
;
import
cn.iocoder.yudao.module.member.dto.ScoreDetailChangeDto
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
java.util.List
;
/**
* 会员积分日志 Service 接口
*
* @author 系统管理员
*/
public
interface
MemberUserScoreDetailReleationService
extends
IService
<
MemberUserScoreDetailReleationDO
>
{
void
updateReleation
(
String
releationId
,
ScoreSourceTypeEnum
sourceType
,
List
<
ScoreDetailChangeDto
>
detailInfos
);
List
<
MemberUserScoreDetailReleationDO
>
listByReleationIdAndSource
(
String
releationId
,
int
value
);
}
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/memberUserScoreDetailReleation/MemberUserScoreDetailReleationServiceImpl.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
member
.
service
.
memberUserScoreDetailReleation
;
import
cn.iocoder.yudao.framework.mybatis.core.service.AbstractService
;
import
cn.iocoder.yudao.module.member.dal.dataobject.memberUserScoreDetailReleation.MemberUserScoreDetailReleationDO
;
import
cn.iocoder.yudao.module.member.dal.mysql.memberUserScoreDetailReleation.MemberUserScoreDetailReleationMapper
;
import
cn.iocoder.yudao.module.member.dto.ScoreDetailChangeDto
;
import
cn.iocoder.yudao.module.member.enums.MemberScoreDetailReleationStatueEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreOperateTypeEnum
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.validation.annotation.Validated
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.stream.Collectors
;
/**
* 会员积分详情 Service 实现类
*
* @author 系统管理员
*/
@Service
@Validated
public
class
MemberUserScoreDetailReleationServiceImpl
extends
AbstractService
<
MemberUserScoreDetailReleationMapper
,
MemberUserScoreDetailReleationDO
>
implements
MemberUserScoreDetailReleationService
{
@Override
public
void
updateReleation
(
String
releationId
,
ScoreSourceTypeEnum
sourceType
,
List
<
ScoreDetailChangeDto
>
detailInfos
)
{
if
(
StringUtils
.
isBlank
(
releationId
)
||
CollectionUtils
.
isEmpty
(
detailInfos
))
{
return
;
}
if
(
sourceType
.
getReverseSource
()
!=
null
)
{
//回退流程, 失效掉之前的关联关系
LambdaUpdateWrapper
<
MemberUserScoreDetailReleationDO
>
updateWrapper
=
Wrappers
.
lambdaUpdate
();
updateWrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getReleationId
,
releationId
);
updateWrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getSourceType
,
sourceType
.
getReverseSource
().
getValue
());
updateWrapper
.
in
(
MemberUserScoreDetailReleationDO:
:
getDetailId
,
detailInfos
.
stream
().
map
(
ScoreDetailChangeDto:
:
getDetailId
).
collect
(
Collectors
.
toList
()));
updateWrapper
.
set
(
MemberUserScoreDetailReleationDO:
:
getStatus
,
MemberScoreDetailReleationStatueEnum
.
NOT_AVAILABLE
.
getValue
());
this
.
update
(
updateWrapper
);
return
;
}
List
<
MemberUserScoreDetailReleationDO
>
dos
=
detailInfos
.
stream
().
map
(
scoreDetailChangeDto
->
{
MemberUserScoreDetailReleationDO
releationDO
=
new
MemberUserScoreDetailReleationDO
();
releationDO
.
setReleationId
(
releationId
);
releationDO
.
setSourceType
(
sourceType
.
getValue
());
releationDO
.
setDetailId
(
scoreDetailChangeDto
.
getDetailId
());
releationDO
.
setScoreCount
(
scoreDetailChangeDto
.
getScoreCount
());
releationDO
.
setStatus
(
MemberScoreDetailReleationStatueEnum
.
AVAILABLE
.
getValue
());
return
releationDO
;
}).
collect
(
Collectors
.
toList
());
this
.
saveOrUpdateBatch
(
dos
);
}
@Override
public
List
<
MemberUserScoreDetailReleationDO
>
listByReleationIdAndSource
(
String
releationId
,
int
sourceType
)
{
if
(
StringUtils
.
isBlank
(
releationId
))
{
return
Collections
.
emptyList
();
}
LambdaQueryWrapper
<
MemberUserScoreDetailReleationDO
>
wrapper
=
Wrappers
.
lambdaQuery
();
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getReleationId
,
releationId
);
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getSourceType
,
sourceType
);
wrapper
.
eq
(
MemberUserScoreDetailReleationDO:
:
getStatus
,
MemberScoreDetailReleationStatueEnum
.
AVAILABLE
.
getValue
());
return
this
.
list
(
wrapper
);
}
}
yudao-module-member/yudao-module-member-impl/src/main/resources/mapper/user/MemberUserScoreDetailReleationMapper.xml
0 → 100644
View file @
e3e82a56
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.yudao.module.member.dal.mysql.memberUserScoreDetailReleation.MemberUserScoreDetailReleationMapper"
>
</mapper>
yudao-module-reward/yudao-module-reward-api/src/main/java/cn/iocoder/yudao/module/reward/enums/ErrorCodeConstants.java
View file @
e3e82a56
...
@@ -29,5 +29,6 @@ public interface ErrorCodeConstants {
...
@@ -29,5 +29,6 @@ public interface ErrorCodeConstants {
ErrorCode
REWARD_REDEEM_BATCH_VERIFY_ERROR
=
new
ErrorCode
(
1001011021
,
"reward.redeem.batch.verify.error"
);
ErrorCode
REWARD_REDEEM_BATCH_VERIFY_ERROR
=
new
ErrorCode
(
1001011021
,
"reward.redeem.batch.verify.error"
);
ErrorCode
REWARD_REDEEM_VERIFY_BACK_STATUS
=
new
ErrorCode
(
1001011022
,
"reward.redeem.verify.back.status"
);
ErrorCode
REWARD_REDEEM_VERIFY_BACK_STATUS
=
new
ErrorCode
(
1001011022
,
"reward.redeem.verify.back.status"
);
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"
);
}
}
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/api/reward/RedeemRewardApiImpl.java
View file @
e3e82a56
...
@@ -79,12 +79,12 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -79,12 +79,12 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
if
(!
lock
)
{
if
(!
lock
)
{
throw
exception
(
GET_LOCK_FAILED
);
throw
exception
(
GET_LOCK_FAILED
);
}
}
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
// 添加兑换记录
// 添加兑换记录
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
);
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
,
rewardDO
);
// 更新会员积分
// 更新会员积分
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
}
finally
{
}
finally
{
...
@@ -111,14 +111,16 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -111,14 +111,16 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
.
memberId
(
redeemRewardReqVO
.
getMemberId
())
.
memberId
(
redeemRewardReqVO
.
getMemberId
())
.
sourceType
(
ScoreSourceTypeEnum
.
EXCHANGE_REWARD
)
.
sourceType
(
ScoreSourceTypeEnum
.
EXCHANGE_REWARD
)
.
scoreCount
(
redeemRewardReqVO
.
getRewardCount
()
*
rewardDO
.
getPointsRequire
())
.
scoreCount
(
redeemRewardReqVO
.
getRewardCount
()
*
rewardDO
.
getPointsRequire
())
.
releationId
(
String
.
valueOf
(
redeemId
))
.
extParam
(
extParam
)
.
extParam
(
extParam
)
.
build
());
.
build
());
}
}
private
Long
addRedeemRecord
(
RedeemRewardReqVO
redeemRewardReqVO
)
{
private
Long
addRedeemRecord
(
RedeemRewardReqVO
redeemRewardReqVO
,
RewardDO
rewardDO
)
{
RewardRedeemDO
rewardRedeemDO
=
BeanUtil
.
copyProperties
(
redeemRewardReqVO
,
RewardRedeemDO
.
class
);
RewardRedeemDO
rewardRedeemDO
=
BeanUtil
.
copyProperties
(
redeemRewardReqVO
,
RewardRedeemDO
.
class
);
rewardRedeemDO
.
setId
(
snowflakeGenerator
.
next
());
rewardRedeemDO
.
setId
(
snowflakeGenerator
.
next
());
rewardRedeemDO
.
setStatus
(
RewardRedeemStatusEnum
.
REDEEMING
.
getValue
());
rewardRedeemDO
.
setStatus
(
RewardRedeemStatusEnum
.
REDEEMING
.
getValue
());
rewardRedeemDO
.
setScoreCount
(
redeemRewardReqVO
.
getRewardCount
()*
rewardDO
.
getPointsRequire
());
rewardRedeemMapper
.
insert
(
rewardRedeemDO
);
rewardRedeemMapper
.
insert
(
rewardRedeemDO
);
return
rewardRedeemDO
.
getId
();
return
rewardRedeemDO
.
getId
();
}
}
...
@@ -164,12 +166,12 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
...
@@ -164,12 +166,12 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw
exception
(
GET_LOCK_FAILED
);
throw
exception
(
GET_LOCK_FAILED
);
}
}
for
(
RedeemRewardReqVO
redeemRewardReqVO
:
redeemRewardReqVOList
)
{
for
(
RedeemRewardReqVO
redeemRewardReqVO
:
redeemRewardReqVOList
)
{
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
// 添加兑换记录
// 添加兑换记录
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
);
Long
redeemId
=
addRedeemRecord
(
redeemRewardReqVO
,
rewardDO
);
// 更新会员积分
// 更新会员积分
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
updateMemberScore
(
redeemRewardReqVO
,
rewardDO
,
redeemId
);
// 更新礼品
redeemReward
(
rewardDO
,
redeemRewardReqVO
.
getRewardCount
());
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"redeem reward exception"
,
e
);
log
.
error
(
"redeem reward exception"
,
e
);
...
...
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/controller/admin/redeem/RedeemRewardController.java
View file @
e3e82a56
...
@@ -81,6 +81,18 @@ public class RedeemRewardController {
...
@@ -81,6 +81,18 @@ public class RedeemRewardController {
return
success
(
rewardRedeemService
.
export
(
reqVO
));
return
success
(
rewardRedeemService
.
export
(
reqVO
));
}
}
@PostMapping
(
"record/cancel/check"
)
@ApiOperation
(
"撤销检查"
)
public
CommonResult
<
RedeemCancelCheckRespVO
>
cancelCheck
(
@Valid
@RequestBody
RewardRedeemUpdateReqVO
reqVO
)
{
return
success
(
rewardRedeemService
.
cancelCheck
(
reqVO
));
}
@PostMapping
(
"record/cancel"
)
@ApiOperation
(
"撤销"
)
public
CommonResult
<
Boolean
>
cancel
(
@Valid
@RequestBody
RewardRedeemUpdateReqVO
reqVO
)
{
return
success
(
rewardRedeemService
.
cancel
(
reqVO
));
}
@PostMapping
(
"record/import/template"
)
@PostMapping
(
"record/import/template"
)
@ApiOperation
(
"导入模板下载"
)
@ApiOperation
(
"导入模板下载"
)
public
void
importTemplate
(
HttpServletResponse
response
)
throws
IOException
{
public
void
importTemplate
(
HttpServletResponse
response
)
throws
IOException
{
...
...
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/dal/dataobject/redeem/RewardRedeemDO.java
View file @
e3e82a56
...
@@ -33,6 +33,7 @@ public class RewardRedeemDO extends BaseDO {
...
@@ -33,6 +33,7 @@ public class RewardRedeemDO extends BaseDO {
* 兑换状态
* 兑换状态
*/
*/
private
Integer
status
;
private
Integer
status
;
private
Integer
scoreCount
;
/**
/**
* 兑换数量
* 兑换数量
*/
*/
...
...
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/service/redeem/RewardRedeemService.java
View file @
e3e82a56
...
@@ -33,4 +33,8 @@ public interface RewardRedeemService extends IService<RewardRedeemDO> {
...
@@ -33,4 +33,8 @@ public interface RewardRedeemService extends IService<RewardRedeemDO> {
Integer
exportCount
(
RewardRedeemPageReqVO
request
);
Integer
exportCount
(
RewardRedeemPageReqVO
request
);
RecordInfoImportRespVO
recordImport
(
List
<
RedeemInfoImportExcelVO
>
dataList
);
RecordInfoImportRespVO
recordImport
(
List
<
RedeemInfoImportExcelVO
>
dataList
);
Boolean
cancel
(
RewardRedeemUpdateReqVO
reqVO
);
RedeemCancelCheckRespVO
cancelCheck
(
RewardRedeemUpdateReqVO
reqVO
);
}
}
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/service/redeem/RewardRedeemServiceImpl.java
View file @
e3e82a56
...
@@ -12,6 +12,10 @@ import cn.iocoder.yudao.module.ecw.api.currency.CurrencyApi;
...
@@ -12,6 +12,10 @@ import cn.iocoder.yudao.module.ecw.api.currency.CurrencyApi;
import
cn.iocoder.yudao.module.ecw.api.currency.dto.CurrencyRespDTO
;
import
cn.iocoder.yudao.module.ecw.api.currency.dto.CurrencyRespDTO
;
import
cn.iocoder.yudao.module.ecw.api.express.ExpressApi
;
import
cn.iocoder.yudao.module.ecw.api.express.ExpressApi
;
import
cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO
;
import
cn.iocoder.yudao.module.ecw.api.express.dto.ExpressRespDTO
;
import
cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi
;
import
cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO
;
import
cn.iocoder.yudao.module.member.api.score.dto.ReleationScoreExpireInfoDTO
;
import
cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum
;
import
cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO
;
import
cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO
;
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.dto.RewardRedeemVerifyDTO
;
import
cn.iocoder.yudao.module.reward.dto.RewardRedeemVerifyDTO
;
...
@@ -29,6 +33,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
...
@@ -29,6 +33,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.*
;
import
java.util.*
;
import
java.util.function.Function
;
import
java.util.function.Function
;
...
@@ -53,13 +58,15 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
...
@@ -53,13 +58,15 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
private
final
FileMakeApi
fileMakeApi
;
private
final
FileMakeApi
fileMakeApi
;
private
final
ExpressApi
expressApi
;
private
final
ExpressApi
expressApi
;
private
final
CurrencyApi
currencyApi
;
private
final
CurrencyApi
currencyApi
;
private
final
MemberUserScoreApi
memberUserScoreApi
;
public
RewardRedeemServiceImpl
(
RewardRedeemMapper
rewardRedeemMapper
,
FileMakeApi
fileMakeApi
,
public
RewardRedeemServiceImpl
(
RewardRedeemMapper
rewardRedeemMapper
,
FileMakeApi
fileMakeApi
,
ExpressApi
expressApi
,
CurrencyApi
currencyApi
)
{
ExpressApi
expressApi
,
CurrencyApi
currencyApi
,
MemberUserScoreApi
memberUserScoreApi
)
{
this
.
rewardRedeemMapper
=
rewardRedeemMapper
;
this
.
rewardRedeemMapper
=
rewardRedeemMapper
;
this
.
fileMakeApi
=
fileMakeApi
;
this
.
fileMakeApi
=
fileMakeApi
;
this
.
expressApi
=
expressApi
;
this
.
expressApi
=
expressApi
;
this
.
currencyApi
=
currencyApi
;
this
.
currencyApi
=
currencyApi
;
this
.
memberUserScoreApi
=
memberUserScoreApi
;
}
}
@Override
@Override
...
@@ -237,6 +244,59 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
...
@@ -237,6 +244,59 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
return
RecordInfoImportRespVO
.
builder
().
build
();
return
RecordInfoImportRespVO
.
builder
().
build
();
}
}
@Override
@Transactional
public
Boolean
cancel
(
RewardRedeemUpdateReqVO
reqVO
)
{
//取消兑换 状态改为已取消 回退扣减的积分 ,如果存在已过期的积分,则直接过期
if
(
reqVO
.
getId
()
==
null
)
{
throw
exception
(
ErrorCodeConstants
.
REWARD_REDEEM_NOT_EXIST
);
}
RewardRedeemDO
rewardRedeemDO
=
this
.
getById
(
reqVO
.
getId
());
if
(
rewardRedeemDO
==
null
)
{
throw
exception
(
ErrorCodeConstants
.
REWARD_REDEEM_NOT_EXIST
);
}
if
(
rewardRedeemDO
.
getStatus
()
!=
RewardRedeemStatusEnum
.
REDEEMING
.
getValue
())
{
throw
exception
(
ErrorCodeConstants
.
REDEEM_CANCEL_STATUS_ERROR
);
}
LambdaUpdateWrapper
<
RewardRedeemDO
>
updateWrapper
=
Wrappers
.
lambdaUpdate
();
updateWrapper
.
eq
(
RewardRedeemDO:
:
getId
,
reqVO
.
getId
());
updateWrapper
.
eq
(
RewardRedeemDO:
:
getStatus
,
RewardRedeemStatusEnum
.
REDEEMING
.
getValue
());
updateWrapper
.
set
(
RewardRedeemDO:
:
getStatus
,
RewardRedeemStatusEnum
.
CANCELED
.
getValue
());
boolean
updateSuccess
=
this
.
update
(
null
,
updateWrapper
);
if
(!
updateSuccess
)
{
throw
exception
(
ErrorCodeConstants
.
REDEEM_CANCEL_STATUS_ERROR
);
}
Map
<
String
,
Object
>
extParam
=
new
HashMap
<>();
extParam
.
put
(
"redeemId"
,
reqVO
.
getId
());
memberUserScoreApi
.
operateScore
(
MemberUserScoreOperateReqDTO
.
builder
()
.
memberId
(
rewardRedeemDO
.
getMemberId
())
.
sourceType
(
ScoreSourceTypeEnum
.
EXCHANGE_REWARD_CANCEL
)
.
scoreCount
(
rewardRedeemDO
.
getScoreCount
())
.
extParam
(
extParam
)
.
releationId
(
String
.
valueOf
(
reqVO
.
getId
()))
.
build
());
return
true
;
}
@Override
public
RedeemCancelCheckRespVO
cancelCheck
(
RewardRedeemUpdateReqVO
reqVO
)
{
if
(
reqVO
.
getId
()
==
null
)
{
throw
exception
(
ErrorCodeConstants
.
REWARD_REDEEM_NOT_EXIST
);
}
RewardRedeemDO
rewardRedeemDO
=
this
.
getById
(
reqVO
.
getId
());
if
(
rewardRedeemDO
==
null
)
{
throw
exception
(
ErrorCodeConstants
.
REWARD_REDEEM_NOT_EXIST
);
}
if
(
rewardRedeemDO
.
getStatus
()
!=
RewardRedeemStatusEnum
.
REDEEMING
.
getValue
())
{
throw
exception
(
ErrorCodeConstants
.
REDEEM_CANCEL_STATUS_ERROR
);
}
List
<
ReleationScoreExpireInfoDTO
>
scoreExpireInfo
=
memberUserScoreApi
.
getScoreExpireInfo
(
String
.
valueOf
(
reqVO
.
getId
()),
ScoreSourceTypeEnum
.
EXCHANGE_REWARD
);
int
totalExpireScore
=
scoreExpireInfo
.
stream
().
filter
(
e
->
e
.
getExpireDate
()
!=
null
&&
e
.
getExpireDate
().
compareTo
(
new
Date
())
<
0
)
.
mapToInt
(
ReleationScoreExpireInfoDTO:
:
getScoreCount
).
sum
();
return
RedeemCancelCheckRespVO
.
builder
().
expireCount
(
totalExpireScore
).
build
();
}
private
Map
<
String
,
String
>
validate
(
List
<
RedeemInfoImportExcelVO
>
dataList
,
Map
<
String
,
CurrencyRespDTO
>
titleZhCurrencyMap
,
private
Map
<
String
,
String
>
validate
(
List
<
RedeemInfoImportExcelVO
>
dataList
,
Map
<
String
,
CurrencyRespDTO
>
titleZhCurrencyMap
,
Map
<
String
,
CurrencyRespDTO
>
titleEnCurrencyMap
,
Map
<
String
,
CurrencyRespDTO
>
titleEnCurrencyMap
,
Map
<
String
,
ExpressRespDTO
>
nameExpressMap
)
{
Map
<
String
,
ExpressRespDTO
>
nameExpressMap
)
{
...
...
yudao-module-reward/yudao-module-reward-impl/src/main/java/cn/iocoder/yudao/module/reward/vo/reward/RedeemCancelCheckRespVO.java
0 → 100644
View file @
e3e82a56
package
cn
.
iocoder
.
yudao
.
module
.
reward
.
vo
.
reward
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Builder
;
import
lombok.Data
;
@Data
@Builder
public
class
RedeemCancelCheckRespVO
{
@ExcelProperty
(
"过期积分数量"
)
private
int
expireCount
;
}
yudao-module-reward/yudao-module-reward-impl/src/main/resources/mapper/RewardRedeemMapper.xml
View file @
e3e82a56
...
@@ -102,7 +102,7 @@
...
@@ -102,7 +102,7 @@
er.title_fr as rewardTitleFr,
er.title_fr as rewardTitleFr,
en.title_zh as nodeTitleZh,
en.title_zh as nodeTitleZh,
en.title_en as nodeTitleEn,
en.title_en as nodeTitleEn,
er
.points_require*err.reward
_count as totalCount,
er
r.score
_count as totalCount,
suc.username as creatorName,
suc.username as creatorName,
suu.username as updaterName,
suu.username as updaterName,
cc.title_zh as currencyTitleZh,
cc.title_zh as currencyTitleZh,
...
...
yudao-server/src/main/resources/i18n/messages_en.properties
View file @
e3e82a56
...
@@ -1021,3 +1021,4 @@ dict.unknown.error = Not in dict {0}: {1}
...
@@ -1021,3 +1021,4 @@ dict.unknown.error = Not in dict {0}: {1}
express.not.exist
=
express not exist
express.not.exist
=
express not exist
currency.not.exist
=
currency not exist
currency.not.exist
=
currency not exist
date.format.error
=
date format error, for example : 2024-01-01 12:11:11
date.format.error
=
date format error, for example : 2024-01-01 12:11:11
redeem.cancel.status.error
=
record status must be redeeming
\ No newline at end of file
yudao-server/src/main/resources/i18n/messages_zh.properties
View file @
e3e82a56
...
@@ -1025,3 +1025,4 @@ dict.unknown.error = \u4E0D\u5728{0}\u5B57\u5178\u4E2D: {1}
...
@@ -1025,3 +1025,4 @@ dict.unknown.error = \u4E0D\u5728{0}\u5B57\u5178\u4E2D: {1}
express.not.exist
=
\u
5FEB
\u9012\u
516C
\u
53F8
\u
4E0D
\u
5B58
\u5728
express.not.exist
=
\u
5FEB
\u9012\u
516C
\u
53F8
\u
4E0D
\u
5B58
\u5728
currency.not.exist
=
\u
5E01
\u
79CD
\u
4E0D
\u
5B58
\u5728
currency.not.exist
=
\u
5E01
\u
79CD
\u
4E0D
\u
5B58
\u5728
date.format.error
=
\u
65E5
\u
671F
\u
683C
\u
5F0F
\u
4E0D
\u
6B63
\u
786E,
\u
6B63
\u
786E
\u
683C
\u
5F0F
\u
53C2
\u8003
: 2024-01-01 12:11:11
date.format.error
=
\u
65E5
\u
671F
\u
683C
\u
5F0F
\u
4E0D
\u
6B63
\u
786E,
\u
6B63
\u
786E
\u
683C
\u
5F0F
\u
53C2
\u8003
: 2024-01-01 12:11:11
redeem.cancel.status.error
=
\u5151\u6362\u
4E2D
\u
72B6
\u6001\u7684\u
8BB0
\u
5F55
\u
624D
\u
80FD
\u
64A4
\u9500
\ No newline at end of file
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