Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
张云鹏
/
uc-engine
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
837e43b6
...
837e43b69d13f2cfd7c2b908a5706890d20a114f
authored
2021-11-14 01:27:41 +0800
by
xianghan@topdraw.cn
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
处理并发情况下的数据安全问题
1 parent
b90c4861
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
179 additions
and
161 deletions
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/domain/Member.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/level/service/impl/MemberLevelServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/service/dto/MemberDTO.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/service/impl/MemberServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/task/service/impl/TaskServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/task/template/service/impl/TaskTemplateServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/process/domian/TempRights.java
member-service-impl/src/main/java/com/topdraw/business/process/service/PointsOperationService.java
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/CouponOperationServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/ExpOperationServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/PointsOperationServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/RightsOperationServiceImpl.java
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/TaskOperationServiceImpl.java
member-service-impl/src/main/java/com/topdraw/util/TimestampUtil.java
member-service-impl/src/main/resources/config/application.yml
member-service-impl/src/test/java/com/topdraw/test/business/basicdata/member/MemberServiceTest.java
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/ExpOperationControllerTest.java
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/PointsOperationControllerTest.java
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/RightOperationControllerTest.java
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/domain/Member.java
View file @
837e43b
...
...
@@ -121,7 +121,7 @@ public class Member implements Serializable {
// 是否在黑名单 1:是;0否
@Column
(
name
=
"black_status"
)
private
Integer
blackStatus
;
private
Long
blackStatus
;
public
void
copy
(
Member
source
){
BeanUtil
.
copyProperties
(
source
,
this
,
CopyOptions
.
create
().
setIgnoreNullValue
(
true
));
...
...
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/level/service/impl/MemberLevelServiceImpl.java
View file @
837e43b
...
...
@@ -9,6 +9,7 @@ import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import
com.topdraw.business.basicdata.member.level.service.dto.MemberLevelQueryCriteria
;
import
com.topdraw.business.basicdata.member.level.service.mapper.MemberLevelMapper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -89,6 +90,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
:
new
MemberLevelDTO
();
}
@Cacheable
(
cacheNames
=
"uc-member_level"
,
key
=
"#level"
)
@Override
public
List
<
MemberLevelDTO
>
findLevelAndStatus
(
Integer
level
,
Integer
status
)
{
return
MemberLevelMapper
.
toDto
(
MemberLevelRepository
.
findByLevelAndStatus
(
level
,
status
));
...
...
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/service/dto/MemberDTO.java
View file @
837e43b
...
...
@@ -83,5 +83,5 @@ public class MemberDTO implements Serializable {
private
Timestamp
updateTime
;
// 是否在黑名单 1:是;0否
private
Integer
blackStatus
;
private
Long
blackStatus
;
}
...
...
member-service-impl/src/main/java/com/topdraw/business/basicdata/member/service/impl/MemberServiceImpl.java
View file @
837e43b
...
...
@@ -19,13 +19,18 @@ import org.redisson.api.RLock;
import
org.redisson.api.RedissonClient
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.dao.EmptyResultDataAccessException
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.PlatformTransactionManager
;
import
org.springframework.transaction.TransactionDefinition
;
import
org.springframework.transaction.TransactionStatus
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.support.DefaultTransactionDefinition
;
import
org.springframework.util.Assert
;
import
java.util.List
;
...
...
@@ -38,6 +43,7 @@ import java.util.Objects;
*/
@Service
@Transactional
(
propagation
=
Propagation
.
SUPPORTS
,
readOnly
=
true
,
rollbackFor
=
Exception
.
class
)
//@CacheConfig(cacheNames = "uc-member-info")
public
class
MemberServiceImpl
implements
MemberService
{
@Autowired
...
...
@@ -61,12 +67,12 @@ public class MemberServiceImpl implements MemberService {
return
memberMapper
.
toDto
(
memberRepository
.
findAll
((
root
,
criteriaQuery
,
criteriaBuilder
)
->
QueryHelp
.
getPredicate
(
root
,
criteria
,
criteriaBuilder
)));
}
// @Cacheable(cacheNames = "",key = "")
@Override
public
MemberDTO
findById
(
Long
id
)
{
Member
member
=
memberRepository
.
findById
(
id
).
orElseGet
(
Member:
:
new
);
ValidationUtil
.
isNull
(
member
.
getId
(),
"Member"
,
"id"
,
id
);
return
memberMapper
.
toDto
(
member
);
}
@Override
...
...
@@ -99,6 +105,9 @@ public class MemberServiceImpl implements MemberService {
return
member
;
}
@Autowired
PlatformTransactionManager
platformTransactionManager
;
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@AsyncMqSend
()
...
...
@@ -106,18 +115,31 @@ public class MemberServiceImpl implements MemberService {
RLock
rLock
=
this
.
redissonClient
.
getLock
(
"updateMember"
+
resources
.
getId
().
toString
());
try
{
RedissonUtil
.
lock
(
rLock
);
String
name
=
Thread
.
currentThread
().
getName
();
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> start ===>> "
);
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> 【resources】 ===>> "
+
resources
);
Member
member
=
memberRepository
.
findById
(
resources
.
getId
()).
orElseGet
(
Member:
:
new
);
ValidationUtil
.
isNull
(
member
.
getId
(),
"Member"
,
"id"
,
resources
.
getId
());
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> 【member-search】 ===>> "
+
member
);
member
.
copy
(
resources
);
memberRepository
.
save
(
member
);
this
.
save
(
member
);
// platformTransactionManager.commit(transaction);
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> 【exp】 ===>> "
+
member
.
getExp
());
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> 【point】 ===>> "
+
member
.
getPoints
());
System
.
out
.
println
(
"=============>>>>【name】 ===== >> "
+
name
+
" =======>> 【member】 ===>> "
+
member
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
throw
e
;
}
finally
{
RedissonUtil
.
unlock
(
rLock
);
}
}
@Transactional
(
propagation
=
Propagation
.
REQUIRES_NEW
)
public
void
save
(
Member
member
){
memberRepository
.
save
(
member
);
}
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@AsyncMqSend
()
...
...
member-service-impl/src/main/java/com/topdraw/business/basicdata/task/service/impl/TaskServiceImpl.java
View file @
837e43b
...
...
@@ -9,6 +9,7 @@ import com.topdraw.business.basicdata.task.service.dto.TaskDTO;
import
com.topdraw.business.basicdata.task.service.dto.TaskQueryCriteria
;
import
com.topdraw.business.basicdata.task.service.mapper.TaskMapper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -79,6 +80,7 @@ public class TaskServiceImpl implements TaskService {
TaskRepository
.
delete
(
Task
);
}
@Cacheable
(
cacheNames
=
"uc-admin_taskList"
,
key
=
"#taskTemplateId"
)
@Override
public
List
<
Task
>
findByTemplateId
(
Long
taskTemplateId
)
{
return
Objects
.
nonNull
(
taskTemplateId
)
?
this
.
TaskRepository
.
findByTaskTemplateId
(
taskTemplateId
)
:
null
;
...
...
member-service-impl/src/main/java/com/topdraw/business/basicdata/task/template/service/impl/TaskTemplateServiceImpl.java
View file @
837e43b
...
...
@@ -87,14 +87,16 @@ public class TaskTemplateServiceImpl implements TaskTemplateService {
:
new
TaskTemplateDTO
();
}
// @Cacheable(cacheNames = "uc.taskTemplate" , key = "event")
@Override
public
TaskTemplate
findByEvent
(
String
event
)
{
return
StringUtils
.
isNotEmpty
(
event
)
?
this
.
TaskTemplateRepository
.
findByEvent
(
event
)
:
null
;
}
@Cacheable
(
cacheNames
=
"uc-admin_taskTemplate"
,
key
=
"#event"
)
@Override
public
TaskTemplate
findByType
(
Integer
event
)
{
System
.
out
.
println
(
"查询数据库了!!"
);
return
Objects
.
nonNull
(
event
)
?
this
.
TaskTemplateRepository
.
findByType
(
event
)
:
null
;
}
}
...
...
member-service-impl/src/main/java/com/topdraw/business/process/domian/TempRights.java
View file @
837e43b
...
...
@@ -20,6 +20,14 @@ public class TempRights {
@Transient
protected
Long
id
;
/** 编号 */
@Transient
protected
String
code
;
/** 权益名称 */
@Transient
protected
String
name
;
/** 会员ID */
@Transient
@NotNull
(
message
=
""
)
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/PointsOperationService.java
View file @
837e43b
...
...
@@ -5,6 +5,7 @@ import com.topdraw.business.basicdata.task.domain.Task;
import
com.topdraw.business.process.domian.TempPoints
;
import
java.util.List
;
import
java.util.Map
;
/**
* @description 积分操作接口
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/CouponOperationServiceImpl.java
View file @
837e43b
...
...
@@ -19,10 +19,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.sql.Timestamp
;
import
java.time.LocalDateTime
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.locks.ReentrantLock
;
...
...
@@ -41,11 +45,11 @@ public class CouponOperationServiceImpl implements CouponOperationService {
RightsOperationService
rightsOperationService
;
@Autowired
RedissonClient
redissonClient
;
@
Autowired
@
Resource
(
name
=
"executorTask"
)
ThreadPoolTaskExecutor
threadPoolTaskExecutor
;
// 过期阀值(默认一个月)
private
static
final
Integer
EXPIRE_FACTOR_
MONTH
=
1
;
private
static
final
Integer
EXPIRE_FACTOR_
DAY
=
30
;
...
...
@@ -80,10 +84,10 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param tempCoupon 领取的优惠券
*/
private
void
refresh
(
TempCoupon
tempCoupon
)
{
// 1.保存优惠券领取、使用历史记录表
this
.
threadPoolTaskExecutor
.
execute
(()->
this
.
doInsertCouponHistory
(
tempCoupon
));
// 2.更新会员优惠券数量
// 1.更新会员优惠券数量
this
.
refreshMemberCoupon
(
tempCoupon
);
// 2.保存优惠券领取、使用历史记录表
this
.
doInsertCouponHistory
(
tempCoupon
);
}
...
...
@@ -92,17 +96,20 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param tempCoupon 账号id
*/
private
void
refreshMemberCoupon
(
TempCoupon
tempCoupon
)
{
Long
userId
=
tempCoupon
.
getUserId
();
//
Long userId = tempCoupon.getUserId();
Long
memberId
=
tempCoupon
.
getMemberId
();
RLock
rLock
=
this
.
redissonClient
.
getLock
(
"refreshMemberCoupon:"
+
memberId
.
toString
());
Integer
rightsAmount
=
tempCoupon
.
getRightsAmount
();
// RLock rLock = this.redissonClient.getLock("refreshMemberCoupon:" + memberId.toString());
try
{
RedissonUtil
.
lock
(
rLock
);
// 1.获取用户领取的总优惠券
Long
totalCouponCount
=
this
.
getTotalCoupon
(
userId
);
// RedissonUtil.lock(rLock);
// 1.历史总优惠券数量
Long
historyCouponCount
=
this
.
getTotalHistoryCoupon
(
memberId
);
// 1.当前总优惠券数量
Long
totalCouponCount
=
this
.
getTotalCoupon
(
historyCouponCount
,
rightsAmount
);
// 2.获取已过期的优惠券数量
Long
expireCouponCount
=
this
.
getTotalExpireCoupon
(
us
erId
);
Long
expireCouponCount
=
this
.
getTotalExpireCoupon
(
memb
erId
);
// 3.即将过期的优惠券数量
Long
expireSoonCouponCount
=
this
.
getTotalExpireSoonCoupon
(
userId
,
EXPIRE_FACTOR_MONTH
);
Long
expireSoonCouponCount
=
this
.
getTotalExpireSoonCoupon
(
memberId
,
EXPIRE_FACTOR_DAY
);
// 4.当前优惠券数量 = 总优惠券-已过期的优惠券
Long
currentCoupon
=
this
.
getCurrentCoupon
(
totalCouponCount
,
expireCouponCount
);
// 5.更新用户信息(优惠券数量、即将过期的优惠券数量)
...
...
@@ -111,10 +118,14 @@ public class CouponOperationServiceImpl implements CouponOperationService {
e
.
printStackTrace
();
throw
e
;
}
finally
{
RedissonUtil
.
unlock
(
rLock
);
//
RedissonUtil.unlock(rLock);
}
}
private
Long
getTotalCoupon
(
Long
historyCouponCount
,
Integer
rightsAmount
)
{
return
(
Objects
.
nonNull
(
historyCouponCount
)
?
historyCouponCount:
0L
)
+
(
Objects
.
nonNull
(
rightsAmount
)
?
rightsAmount:
0L
);
}
/**
* 更新当前用户优惠券信息
...
...
@@ -149,28 +160,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @return
*/
private
Long
getTotalExpireSoonCoupon
(
Long
userId
,
Integer
expireFactor
)
{
LocalDateTime
localDateTime
=
LocalDateTime
.
now
();
String
s
=
EXPIRE_FACTOR_MONTH
.
toString
();
String
[]
s1
=
s
.
split
(
"_"
);
String
s2
=
s1
[
s1
.
length
-
1
];
switch
(
s2
)
{
case
"YEAR"
:
localDateTime
.
plusYears
(
expireFactor
);
break
;
case
"MONTH"
:
localDateTime
.
plusMonths
(
expireFactor
);
break
;
case
"DAY"
:
localDateTime
.
plusDays
(
expireFactor
);
break
;
case
"HOUR"
:
localDateTime
.
plusHours
(
expireFactor
);
break
;
default
:
break
;
}
Timestamp
expireTime
=
TimestampUtil
.
now
(
localDateTime
);
Timestamp
expireTime
=
TimestampUtil
.
localDateTime2Timestamp1
(
LocalDateTime
.
now
().
plusDays
(
expireFactor
));
return
this
.
couponHistoryService
.
countByUserIdAndExpireTimeBetween
(
userId
,
TimestampUtil
.
now
(),
expireTime
);
}
...
...
@@ -190,7 +180,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param userId
* @return
*/
private
Long
getTotalCoupon
(
Long
userId
)
{
private
Long
getTotal
History
Coupon
(
Long
userId
)
{
return
this
.
couponHistoryService
.
countByUserId
(
userId
);
}
...
...
@@ -204,10 +194,12 @@ public class CouponOperationServiceImpl implements CouponOperationService {
BeanUtils
.
copyProperties
(
tempCoupon
,
couponHistory
);
couponHistory
.
setId
(
null
);
couponHistory
.
setCouponId
(
tempCoupon
.
getId
());
couponHistory
.
setUserId
(
tempCoupon
.
get
Us
erId
());
couponHistory
.
setUserId
(
tempCoupon
.
get
Memb
erId
());
couponHistory
.
setCouponCode
(
tempCoupon
.
getCode
());
couponHistory
.
setUserNickname
(
tempCoupon
.
getUserNickname
());
couponHistory
.
setOrderDetailId
(
tempCoupon
.
getOrderId
());
couponHistory
.
setReceiveTime
(
TimestampUtil
.
now
());
couponHistory
.
setUseStatus
(
Objects
.
nonNull
(
couponHistory
.
getUseStatus
())
?
couponHistory
.
getUseStatus
():
0
);
this
.
couponHistoryService
.
create
(
couponHistory
);
}
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/ExpOperationServiceImpl.java
View file @
837e43b
...
...
@@ -75,19 +75,18 @@ public class ExpOperationServiceImpl implements ExpOperationService {
* @param tempExp
*/
private
void
refresh
(
TempExp
tempExp
)
{
RLock
lock
=
this
.
redissonClient
.
getLock
(
"
refresh_
exp:"
+
tempExp
.
getMemberId
());
RLock
lock
=
this
.
redissonClient
.
getLock
(
"
uc-refresh-
exp:"
+
tempExp
.
getMemberId
());
try
{
RedissonUtil
.
lock
(
lock
);
// 原始积分
long
originExp
=
this
.
getExpByMemberId
(
tempExp
);
// 总积分
long
totalExp
=
this
.
calculateTotalExp
(
originExp
,
tempExp
);
// 1.添加成长值记录
this
.
threadPoolTaskExecutor
.
execute
(()
->
this
.
doInsertExpDetail
(
tempExp
,
originExp
,
totalExp
));
// this.doInsertExpDetail(tempExp, originExp, totalExp);
// 2.更新成长值与等级
this
.
refreshMemberExpAndLevel
(
tempExp
);
this
.
refreshMemberExpAndLevel
(
tempExp
,
totalExp
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
...
...
@@ -98,7 +97,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
private
long
calculateTotalExp
(
long
originalExp
,
TempExp
tempExp
)
{
Long
rewardExp
=
tempExp
.
getRewardExp
();
return
(
Objects
.
nonNull
(
rewardExp
)
?
rewardExp
:
0L
)
+
(
Objects
.
nonNull
(
originalExp
)
?
originalExp
:
0L
)
;
return
rewardExp
+
originalExp
;
}
private
long
getExpByMemberId
(
TempExp
tempExp
)
{
...
...
@@ -114,57 +113,53 @@ public class ExpOperationServiceImpl implements ExpOperationService {
*
* @param tempExp 成长值列表
*/
private
void
refreshMemberExpAndLevel
(
TempExp
tempExp
)
{
private
void
refreshMemberExpAndLevel
(
TempExp
tempExp
,
long
totalExp
)
{
Long
memberId
=
tempExp
.
getMemberId
();
RLock
rLock
=
this
.
redissonClient
.
getLock
(
"refreshMemberExpAndLevel
"
+
memberId
.
toString
());
// RLock rLock = this.redissonClient.getLock("refresh
" + memberId.toString());
try
{
RedissonUtil
.
lock
(
rLock
);
//
RedissonUtil.lock(rLock);
// 1.获取当前成长值
MemberDTO
memberDTO
=
this
.
getMemberInfoByMemberId
(
memberId
);
// 2.获取下一级需要的成长值
MemberLevelDTO
memberLevelDTO
=
this
.
getNextLevelExp
(
memberDTO
.
getLevel
()
+
1
,
1
);
// 3.成长值累加
Long
newExp
=
memberDTO
.
getExp
()
+
tempExp
.
getRewardExp
();
// 4.成长值比较,判断是否升级
long
i
=
this
.
compareExp
(
newExp
,
memberLevel
DTO
);
Integer
level
=
this
.
compareExp
(
totalExp
,
memberLevelDTO
,
member
DTO
);
// 5.更新用户信息
this
.
updateMemberInfo
(
i
,
newExp
,
memberLevelDTO
,
memberId
);
this
.
updateMemberInfo
(
level
,
totalExp
,
memberId
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
}
finally
{
RedissonUtil
.
unlock
(
rLock
);
//
RedissonUtil.unlock(rLock);
}
}
/**
*
* @param i
* @param newExp 总积分
* @param memberLevelDTO 下一级
* @param level
* @param totalExp 总积分
* @param memberId 会员id
*/
private
void
updateMemberInfo
(
long
i
,
Long
newExp
,
MemberLevelDTO
memberLevelDTO
,
Long
memberId
)
{
private
void
updateMemberInfo
(
Integer
level
,
Long
totalExp
,
Long
memberId
)
{
Member
member
=
new
Member
();
member
.
setId
(
memberId
);
member
.
setExp
(
newExp
);
if
(
i
>
0
)
{
Integer
level
=
memberLevelDTO
.
getLevel
();
member
.
setLevel
(
level
);
}
member
.
setExp
(
totalExp
);
member
.
setLevel
(
level
);
member
.
setUpdateTime
(
TimestampUtil
.
now
());
this
.
memberOperationService
.
doUpdateMemberInfo
(
member
);
}
private
long
compareExp
(
long
newExp
,
MemberLevelDTO
memberLevel
DTO
)
{
private
Integer
compareExp
(
long
newExp
,
MemberLevelDTO
memberLevelDTO
,
MemberDTO
member
DTO
)
{
if
(
Objects
.
nonNull
(
memberLevelDTO
))
{
Long
nextLevelExp
=
memberLevelDTO
.
getExpValue
();
if
(
Objects
.
nonNull
(
nextLevelExp
)
&&
nextLevelExp
>
0
)
return
newExp
-
nextLevelExp
;
if
(
newExp
-
nextLevelExp
>=
0
){
return
memberLevelDTO
.
getLevel
();
}
}
return
-
1
;
return
memberDTO
.
getLevel
()
;
}
private
MemberLevelDTO
getNextLevelExp
(
Integer
i
,
Integer
status
)
{
...
...
@@ -200,7 +195,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
expDetail
.
setCode
(
String
.
valueOf
(
IdWorker
.
generator
()));
// 原始积分
expDetail
.
setOriginalExp
(
Objects
.
nonNull
(
originalExp
)
?
originalExp
:
0L
);
expDetail
.
setOriginalExp
(
originalExp
);
// 总积分
expDetail
.
setResultExp
(
totalExp
);
// 获得的积分
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/PointsOperationServiceImpl.java
View file @
837e43b
...
...
@@ -344,19 +344,24 @@ public class PointsOperationServiceImpl implements PointsOperationService {
*/
private
void
refresh
(
TempPoints
tempPoints
)
{
Long
memberId
=
tempPoints
.
getMemberId
();
RLock
rLock
=
this
.
redissonClient
.
getLock
(
"
refresh_point
:"
+
memberId
.
toString
());
RLock
rLock
=
this
.
redissonClient
.
getLock
(
"
uc-refresh-points
:"
+
memberId
.
toString
());
try
{
RedissonUtil
.
lock
(
rLock
);
// 1.可用总积分
long
currentPoints
=
this
.
findAvailablePointsByMemberId
(
memberId
);
// 2.计算总积分
long
totalPoints
=
this
.
calculateTotalPoints
(
tempPoints
,
currentPoints
);
// 2.添加积分明细,并计算总积分
// 3.添加积分明细,并计算总积分
this
.
threadPoolTaskExecutor
.
execute
(()->
this
.
doInsertTrPointsDetail
(
memberId
,
tempPoints
,
currentPoints
,
totalPoints
));
// 4.更新会员的总积分
this
.
freshMemberCurrentPoints
(
memberId
,
totalPoints
);
//
5
.添加可用积分
// this.doInsertTrPointsDetail(memberId, tempPoints, currentPoints,totalPoints);
//
4
.添加可用积分
this
.
doInsertTrPointsAvailable
(
tempPoints
);
// 6.更新会员的总积分
this
.
freshMemberCurrentPoints
(
memberId
,
totalPoints
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
...
...
@@ -468,21 +473,13 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param tempPoints 积分
* @return Integer 总积分
*/
private
void
doInsertTrPointsDetail
(
Long
memberId
,
TempPoints
tempPoints
,
long
totalPoints
,
long
current
Points
){
private
void
doInsertTrPointsDetail
(
Long
memberId
,
TempPoints
tempPoints
,
long
currentPoints
,
long
total
Points
){
PointsDetail
pointsDetail
=
new
PointsDetail
();
BeanUtils
.
copyProperties
(
tempPoints
,
pointsDetail
);
/* // 获取的积分
long rewardPoints = tempPoints.getPoints();
// 原始积分
long originalPoints = currentPoints;
// 总积分
long totalPoints = originalPoints + rewardPoints;*/
pointsDetail
.
setMemberId
(
memberId
);
pointsDetail
.
setCode
(
String
.
valueOf
(
IdWorker
.
generator
()));
pointsDetail
.
setPoints
(
tempPoints
.
getPoints
());
pointsDetail
.
setOriginalPoints
(
currentPoints
);
pointsDetail
.
setResultPoints
(
totalPoints
);
String
description
=
pointsDetail
.
getDescription
();
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/RightsOperationServiceImpl.java
View file @
837e43b
...
...
@@ -17,10 +17,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.StringUtils
;
import
javax.annotation.Resource
;
import
java.sql.Timestamp
;
import
java.util.*
;
import
java.util.concurrent.Future
;
/**
* 权益处理
...
...
@@ -144,24 +146,14 @@ public class RightsOperationServiceImpl implements RightsOperationService {
*/
private
void
refresh
(
Map
<
RightType
,
Object
>
tempRightsMap
)
{
this
.
threadPoolTaskExecutor
.
execute
(()->{
// 积分
this
.
grantPoint
((
List
<
TempPoints
>)
tempRightsMap
.
get
(
RightType
.
POINTS
));
this
.
threadPoolTaskExecutor
.
submit
(()
->
{
// 积分
this
.
grantPoint
((
List
<
TempPoints
>)
tempRightsMap
.
get
(
RightType
.
POINTS
));
// 成长值
this
.
grantExp
((
List
<
TempExp
>)
tempRightsMap
.
get
(
RightType
.
EXP
));
// 优惠券
this
.
grantCoupon
((
List
<
TempCoupon
>)
tempRightsMap
.
get
(
RightType
.
COUPON
));
});
this
.
threadPoolTaskExecutor
.
execute
(()->{
// 成长值
this
.
grantExp
((
List
<
TempExp
>)
tempRightsMap
.
get
(
RightType
.
EXP
));
});
this
.
threadPoolTaskExecutor
.
execute
(()->{
// 优惠券
this
.
grantCoupon
((
List
<
TempCoupon
>)
tempRightsMap
.
get
(
RightType
.
COUPON
));
});
/*this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));*/
}
/**
...
...
@@ -260,8 +252,11 @@ public class RightsOperationServiceImpl implements RightsOperationService {
if
(!
CollectionUtils
.
isEmpty
(
rightsHistories
))
{
for
(
RightsHistory
rightsHistory
:
rightsHistories
)
{
Long
operatorId
=
rightsHistory
.
getOperatorId
();
String
operatorName
=
rightsHistory
.
getOperatorName
();
rightsHistory
.
setSendTime
(
TimestampUtil
.
now
());
rightsHistory
.
setOperatorId
(
Objects
.
nonNull
(
operatorId
)?
operatorId:
0
);
rightsHistory
.
setOperatorName
(!
StringUtils
.
isEmpty
(
operatorName
)?
operatorName:
"系统发放"
);
this
.
rightsHistoryService
.
create
(
rightsHistory
);
}
...
...
member-service-impl/src/main/java/com/topdraw/business/process/service/impl/TaskOperationServiceImpl.java
View file @
837e43b
...
...
@@ -24,22 +24,17 @@ import com.topdraw.util.*;
import
lombok.extern.slf4j.Slf4j
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.cache.annotation.EnableCaching
;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.StringUtils
;
import
javax.annotation.Resource
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.sql.Timestamp
;
import
java.time.LocalDate
;
import
java.util.*
;
import
java.util.concurrent.locks.ReentrantLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
java.util.stream.Collectors
;
...
...
@@ -56,21 +51,19 @@ public class TaskOperationServiceImpl implements TaskOperationService {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
PointsOperationServiceImpl
.
class
);
@Autowired
private
TaskService
taskService
;
TaskService
taskService
;
@Autowired
private
MemberService
memberService
;
MemberService
memberService
;
@Autowired
private
RightsService
rightsService
;
RightsService
rightsService
;
@Autowired
private
TaskTemplateService
taskTemplateService
;
TaskTemplateService
taskTemplateService
;
@Autowired
private
RightsOperationService
rightsOperationService
;
RightsOperationService
rightsOperationService
;
@Autowired
private
TrTaskProgressService
trTaskProgressService
;
TrTaskProgressService
trTaskProgressService
;
@Autowired
private
PermanentRightsService
permanentRightsService
;
private
ReentrantReadWriteLock
reentrantReadWriteLock
=
new
ReentrantReadWriteLock
();
PermanentRightsService
permanentRightsService
;
private
static
final
Integer
TASK_FINISH_STATUS
=
1
;
private
static
final
Integer
TASK_UNFINISH_STATUS
=
2
;
...
...
@@ -87,10 +80,10 @@ public class TaskOperationServiceImpl implements TaskOperationService {
long
l
=
System
.
currentTimeMillis
();
// 验证会员信息
boolean
b
=
this
.
validatedMember
(
memberId
);
if
(
b
)
{
/*
boolean b = this.validatedMember(memberId);
if (
!
b) {
throw new BadRequestException("【member status exception!!】");
}
}
*/
// 1.通过任务标识获取任务模板,通过模板参数获取具体的模板
TaskTemplate
taskTemplate
=
this
.
getTaskTemplate
(
event
);
...
...
@@ -101,10 +94,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
if
(
checkResult
)
{
// 5.权益区分(积分、权益、成长值)
Map
<
RightType
,
Object
>
tempRightsMap
=
this
.
distinguishRight
(
memberId
,
taskList
,
msgData
);
// 6.权益发放
this
.
grantRight
(
tempRightsMap
);
}
long
r
=
System
.
currentTimeMillis
();
...
...
@@ -120,12 +111,13 @@ public class TaskOperationServiceImpl implements TaskOperationService {
private
boolean
validatedMember
(
Long
memberId
)
{
log
.
info
(
"validatedMember -->>【memberId】 -->> "
+
memberId
);
MemberDTO
memberDTO
=
this
.
memberService
.
findById
(
memberId
);
Integer
blackStatus
=
memberDTO
.
getBlackStatus
();
if
(
Objects
.
nonNull
(
blackStatus
)
&&
blackStatus
==
1
)
{
log
.
error
(
"validatedMember -->> 会员已被加入黑名单 【blackStatus】 -->> "
+
blackStatus
);
Long
blackStatus
=
memberDTO
.
getBlackStatus
();
// TODO 检查balckStatus无法获取的原因
if
(
Objects
.
isNull
(
blackStatus
)
||
blackStatus
==
1
)
{
log
.
error
(
"validatedMember -->> 会员不存在或者已被加入黑名单 【blackStatus】 -->> "
+
blackStatus
);
return
false
;
}
return
Objects
.
nonNull
(
memberDTO
)
?
true
:
fals
e
;
return
tru
e
;
}
/**
...
...
@@ -133,6 +125,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* @param memberId 会员id
* @return PermanentRightsDTO 永久权益
*/
@Deprecated
private
PermanentRightsDTO
getPermanentRights
(
Long
memberId
)
{
PermanentRightsDTO
permanentRights
=
null
;
MemberDTO
memberDTO
=
this
.
memberService
.
findById
(
memberId
);
...
...
@@ -149,6 +142,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* @param taskTemplate 任务模板
* @return Map<String, Object> 模板参数解析结果
*/
@Deprecated
private
Map
<
String
,
Object
>
parseTaskTemplateParam
(
TaskTemplate
taskTemplate
)
{
if
(
Objects
.
nonNull
(
taskTemplate
))
{
String
params
=
taskTemplate
.
getParams
();
...
...
@@ -166,19 +160,11 @@ public class TaskOperationServiceImpl implements TaskOperationService {
*/
private
void
doRefreshTrTaskProcess
(
TrTaskProgress
resources
)
{
Long
id
=
resources
.
getId
();
ReentrantReadWriteLock
.
WriteLock
writeLock
=
this
.
reentrantReadWriteLock
.
writeLock
();
try
{
writeLock
.
lock
();
if
(
Objects
.
nonNull
(
id
))
{
resources
.
setUpdateTime
(
TimestampUtil
.
now
());
this
.
trTaskProgressService
.
update
(
resources
);
}
else
{
this
.
trTaskProgressService
.
create
(
resources
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
writeLock
.
unlock
();
if
(
Objects
.
nonNull
(
id
))
{
resources
.
setUpdateTime
(
TimestampUtil
.
now
());
this
.
trTaskProgressService
.
update
(
resources
);
}
else
{
this
.
trTaskProgressService
.
create
(
resources
);
}
}
...
...
@@ -326,16 +312,15 @@ public class TaskOperationServiceImpl implements TaskOperationService {
/**
* 创建权益
* @param memberId
* @param rightsId
* @param rightsAmount
* @param expireTime
* @return
*/
private
TempRights
tmpRightsBuild
(
Long
memberId
,
Long
rightsId
,
Integer
rightsAmount
,
Long
expireTime
){
private
TempRights
tmpRightsBuild
(
Long
memberId
,
Integer
rightsAmount
,
RightsDTO
rightsDTO
){
TempRights
tempRights
=
new
TempRights
();
BeanUtils
.
copyProperties
(
rightsDTO
,
tempRights
);
tempRights
.
setMemberId
(
memberId
);
tempRights
.
setRightsAmount
(
rightsAmount
);
tempRights
.
setId
(
rightsId
);
Long
expireTime
=
rightsDTO
.
getExpireTime
(
);
if
(
Objects
.
nonNull
(
expireTime
))
tempRights
.
setExpireTime
(
TimestampUtil
.
long2Timestamp
(
expireTime
));
return
tempRights
;
...
...
@@ -344,17 +329,17 @@ public class TaskOperationServiceImpl implements TaskOperationService {
/**
* 优惠券
* @param memberId
* @param rightsId
* @param rightsAmount
* @param rightsSendStrategy
* @return
*/
private
TempCoupon
tempCouponBuild
(
Long
memberId
,
Long
rightsId
,
Integer
rightsAmount
,
Integer
rightsSendStrategy
){
private
TempCoupon
tempCouponBuild
(
Long
memberId
,
Integer
rightsAmount
,
Integer
rightsSendStrategy
,
TempRights
tempRights
,
String
nickname
){
TempCoupon
tempCoupon
=
new
TempCoupon
();
BeanUtils
.
copyProperties
(
tempRights
,
tempCoupon
);
tempCoupon
.
setMemberId
(
memberId
);
tempCoupon
.
setId
(
rightsId
);
tempCoupon
.
setRightsAmount
(
rightsAmount
);
tempCoupon
.
setRightsSendStrategy
(
Objects
.
isNull
(
rightsSendStrategy
)
?
0
:
rightsSendStrategy
);
tempCoupon
.
setUserNickname
(
nickname
);
return
tempCoupon
;
}
...
...
@@ -369,6 +354,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
List
<
TempCoupon
>
tempCouponList
=
new
ArrayList
<>();
// 权益列表,用以保存权益记录
List
<
TempRights
>
rightsList
=
new
ArrayList
<>();
// 会员信息
MemberDTO
memberDTO
=
this
.
findMemberById
(
memberId
);
// 权益1
Long
rights1Id
=
task
.
getRightsId
();
...
...
@@ -378,7 +365,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益1发放的策略
Integer
rightsSendStrategy
=
task
.
getRightsSendStrategy
();
// 权益分类
this
.
getTempRightType
(
member
Id
,
rights1Id
,
rights1Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
this
.
getTempRightType
(
member
DTO
,
rights1Id
,
rights1Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
}
// 权益2
...
...
@@ -388,7 +375,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益2发放的策略
Integer
rightsSendStrategy
=
task
.
getRightsSendStrategy
();
// 权权益分类
this
.
getTempRightType
(
member
Id
,
rights2Id
,
rights2Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
this
.
getTempRightType
(
member
DTO
,
rights2Id
,
rights2Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
}
// 权益3
...
...
@@ -398,7 +385,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益3发放的策略
Integer
rightsSendStrategy
=
task
.
getRightsSendStrategy
();
// 权益分类
this
.
getTempRightType
(
member
Id
,
rights3Id
,
rights3Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
this
.
getTempRightType
(
member
DTO
,
rights3Id
,
rights3Amount
,
rightsSendStrategy
,
tempCouponList
,
rightsList
);
}
// 优惠券
map
.
put
(
RightType
.
COUPON
,
tempCouponList
);
...
...
@@ -406,26 +393,36 @@ public class TaskOperationServiceImpl implements TaskOperationService {
return
map
;
}
/**
*
权益分类
*
会员对象
* @param memberId
* @return
*/
private
MemberDTO
findMemberById
(
Long
memberId
)
{
return
this
.
memberService
.
findById
(
memberId
);
}
/**
* 权益分类
* @param memberDTO
* @param rightsId
* @param rightsAmount
* @param rightsSendStrategy
* @param tempCouponList
* @param rightsList
*/
private
void
getTempRightType
(
Long
memberId
,
Long
rightsId
,
Integer
rightsAmount
,
Integer
rightsSendStrategy
,
List
<
TempCoupon
>
tempCouponList
,
private
void
getTempRightType
(
MemberDTO
memberDTO
,
Long
rightsId
,
Integer
rightsAmount
,
Integer
rightsSendStrategy
,
List
<
TempCoupon
>
tempCouponList
,
List
<
TempRights
>
rightsList
)
{
Long
memberId
=
memberDTO
.
getId
();
String
nickname
=
memberDTO
.
getNickname
();
// 权益详情
RightsDTO
rightsDTO
=
this
.
getRight
(
rightsId
);
if
(
Objects
.
nonNull
(
rightsDTO
)){
// 用以保存权益历史
Long
expireTime
=
rightsDTO
.
getExpireTime
();
TempRights
tempRights
=
this
.
tmpRightsBuild
(
memberId
,
rightsId
,
rightsAmount
,
expireTime
);
TempRights
tempRights
=
this
.
tmpRightsBuild
(
memberId
,
rightsAmount
,
rightsDTO
);
rightsList
.
add
(
tempRights
);
// 权益类型
...
...
@@ -433,7 +430,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
switch
(
type
)
{
case
"1"
:
// 优惠券
TempCoupon
tempCoupon
=
this
.
tempCouponBuild
(
memberId
,
rights
Id
,
rightsAmount
,
rightsSendStrategy
);
TempCoupon
tempCoupon
=
this
.
tempCouponBuild
(
memberId
,
rights
Amount
,
rightsSendStrategy
,
tempRights
,
nickname
);
tempCouponList
.
add
(
tempCoupon
);
break
;
default
:
...
...
member-service-impl/src/main/java/com/topdraw/util/TimestampUtil.java
View file @
837e43b
...
...
@@ -21,6 +21,10 @@ public class TimestampUtil {
return
epochSecond
;
}
public
static
Timestamp
localDateTime2Timestamp1
(
LocalDateTime
localDateTime
){
long
epochSecond
=
localDateTime
.
atZone
(
ZoneOffset
.
systemDefault
()).
toEpochSecond
();
return
long2Timestamp
(
epochSecond
);
}
public
static
Timestamp
long2Timestamp
(
long
timestamp
){
Timestamp
timestamp1
=
Timestamp
.
from
(
Instant
.
ofEpochSecond
(
timestamp
));
return
timestamp1
;
...
...
member-service-impl/src/main/resources/config/application.yml
View file @
837e43b
...
...
@@ -10,6 +10,8 @@ spring:
active
:
dev
jackson
:
time-zone
:
GMT+8
cache
:
type
:
simple
data
:
redis
:
repositories
:
...
...
member-service-impl/src/test/java/com/topdraw/test/business/basicdata/member/MemberServiceTest.java
View file @
837e43b
...
...
@@ -13,7 +13,7 @@ public class MemberServiceTest extends BaseTest {
@Test
public
void
findById
(){
Long
memberId
=
1
L
;
Long
memberId
=
3
L
;
MemberDTO
memberDTO
=
this
.
memberService
.
findById
(
memberId
);
LOG
.
info
(
"=====>>>"
+
memberDTO
);
...
...
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/ExpOperationControllerTest.java
View file @
837e43b
...
...
@@ -21,12 +21,11 @@ public class ExpOperationControllerTest extends BaseTest {
@Test
public
void
grantExpByManual
(){
Long
memberId
=
2
L
;
Long
memberId
=
3
L
;
Long
userId
=
2L
;
TempExp
tempExp
=
new
TempExp
();
tempExp
.
setMemberId
(
memberId
);
tempExp
.
setRewardExp
(
10L
);
tempExp
.
setMemberId
(
2L
);
tempExp
.
setRightsSendStrategy
(
0
);
tempExp
.
setAccountId
(
userId
);
tempExp
.
setExpireTime
(
Timestamp
.
valueOf
(
"2021-10-28 09:00:00"
));
...
...
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/PointsOperationControllerTest.java
View file @
837e43b
...
...
@@ -58,14 +58,14 @@ public class PointsOperationControllerTest extends BaseTest {
tempPoints
.
setMemberId
(
3L
);
tempPoints
.
setRightsSendStrategy
(
0
);
tempPoints
.
setAccountId
(
2L
);
tempPoints
.
setExpireTime
(
Timestamp
.
valueOf
(
"2021-1
0
-27 09:00:00"
));
tempPoints
.
setExpireTime
(
Timestamp
.
valueOf
(
"2021-1
1
-27 09:00:00"
));
tempPoints
.
setDeviceType
(
2
);
tempPoints
.
setAppCode
(
"WEI_XIN_GOLD_PANDA"
);
tempPoints
.
setOrderId
(
null
);
tempPoints
.
setMediaId
(
null
);
tempPoints
.
setActivityId
(
null
);
tempPoints
.
setItemId
(
null
);
tempPoints
.
setDescription
(
"
#
"
);
tempPoints
.
setDescription
(
"
系统发放
"
);
tempPoints
.
setEvtType
(
1
);
String
s
=
JSON
.
toJSONString
(
tempPoints
);
ResultInfo
byId
=
this
.
pointsOperationController
.
grantPointsByManual
(
tempPoints
);
...
...
member-service-impl/src/test/java/com/topdraw/test/business/process/rest/RightOperationControllerTest.java
View file @
837e43b
...
...
@@ -18,7 +18,7 @@ public class RightOperationControllerTest extends BaseTest {
public
void
grantRightsByManual
(){
RightsHistory
rightsHistory
=
new
RightsHistory
();
rightsHistory
.
setRightsId
(
1L
);
rightsHistory
.
setMemberId
(
5
L
);
rightsHistory
.
setMemberId
(
3
L
);
rightsHistory
.
setOperatorId
(
3L
);
rightsHistory
.
setOperatorName
(
"鲁二龙"
);
rightsHistory
.
setExpireTime
(
TimestampUtil
.
now
());
...
...
Please
register
or
sign in
to post a comment