Commit 837e43b6 837e43b69d13f2cfd7c2b908a5706890d20a114f by xianghan@topdraw.cn

处理并发情况下的数据安全问题

1 parent b90c4861
Showing 19 changed files with 169 additions and 151 deletions
......@@ -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));
......
......@@ -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));
......
......@@ -83,5 +83,5 @@ public class MemberDTO implements Serializable {
private Timestamp updateTime;
// 是否在黑名单 1:是;0否
private Integer blackStatus;
private Long blackStatus;
}
......
......@@ -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,10 +115,18 @@ 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;
......@@ -118,6 +135,11 @@ public class MemberServiceImpl implements MemberService {
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Member member){
memberRepository.save(member);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
......
......@@ -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;
......
......@@ -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;
}
}
......
......@@ -20,6 +20,14 @@ public class TempRights {
@Transient
protected Long id;
/** 编号 */
@Transient
protected String code;
/** 权益名称 */
@Transient
protected String name;
/** 会员ID */
@Transient
@NotNull(message = "")
......
......@@ -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 积分操作接口
......
......@@ -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(userId);
Long expireCouponCount = this.getTotalExpireCoupon(memberId);
// 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,8 +118,12 @@ 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 getTotalHistoryCoupon(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.getUserId());
couponHistory.setUserId(tempCoupon.getMemberId());
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);
}
......
......@@ -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, memberLevelDTO);
Integer level = this.compareExp(totalExp, memberLevelDTO,memberDTO);
// 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.setExp(totalExp);
member.setLevel(level);
}
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberInfo(member);
}
private long compareExp(long newExp, MemberLevelDTO memberLevelDTO) {
private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO,MemberDTO memberDTO) {
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);
// 获得的积分
......
......@@ -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 currentPoints){
private void doInsertTrPointsDetail(Long memberId, TempPoints tempPoints,long currentPoints,long totalPoints){
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();
......
......@@ -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.threadPoolTaskExecutor.submit(() -> {
// 积分
this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
});
this.threadPoolTaskExecutor.execute(()->{
this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
// 成长值
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
});
this.threadPoolTaskExecutor.execute(()->{
this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
// 优惠券
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));
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);
}
......
......@@ -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:false;
return true;
}
/**
......@@ -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,20 +160,12 @@ 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();
}
}
/**
......@@ -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(memberId,rights1Id,rights1Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,rights1Id,rights1Amount,rightsSendStrategy,tempCouponList,rightsList);
}
// 权益2
......@@ -388,7 +375,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益2发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
// 权权益分类
this.getTempRightType(memberId,rights2Id,rights2Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,rights2Id,rights2Amount,rightsSendStrategy,tempCouponList,rightsList);
}
// 权益3
......@@ -398,7 +385,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益3发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
// 权益分类
this.getTempRightType(memberId,rights3Id,rights3Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,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,rightsId,rightsAmount,rightsSendStrategy);
TempCoupon tempCoupon = this.tempCouponBuild(memberId,rightsAmount,rightsSendStrategy,tempRights,nickname);
tempCouponList.add(tempCoupon);
break;
default:
......
......@@ -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;
......
......@@ -10,6 +10,8 @@ spring:
active: dev
jackson:
time-zone: GMT+8
cache:
type: simple
data:
redis:
repositories:
......
......@@ -13,7 +13,7 @@ public class MemberServiceTest extends BaseTest {
@Test
public void findById(){
Long memberId = 1L;
Long memberId = 3L;
MemberDTO memberDTO = this.memberService.findById(memberId);
LOG.info("=====>>>" + memberDTO);
......
......@@ -21,12 +21,11 @@ public class ExpOperationControllerTest extends BaseTest {
@Test
public void grantExpByManual(){
Long memberId = 2L;
Long memberId = 3L;
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"));
......
......@@ -58,14 +58,14 @@ public class PointsOperationControllerTest extends BaseTest {
tempPoints.setMemberId(3L);
tempPoints.setRightsSendStrategy(0);
tempPoints.setAccountId(2L);
tempPoints.setExpireTime(Timestamp.valueOf("2021-10-27 09:00:00"));
tempPoints.setExpireTime(Timestamp.valueOf("2021-11-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);
......
......@@ -18,7 +18,7 @@ public class RightOperationControllerTest extends BaseTest {
public void grantRightsByManual(){
RightsHistory rightsHistory = new RightsHistory();
rightsHistory.setRightsId(1L);
rightsHistory.setMemberId(5L);
rightsHistory.setMemberId(3L);
rightsHistory.setOperatorId(3L);
rightsHistory.setOperatorName("鲁二龙");
rightsHistory.setExpireTime(TimestampUtil.now());
......