Commit 10561abf 10561abf37d707350efe4a302a762b13290bfb29 by xianghan

1.优化

1 parent 3b8ac7e5
...@@ -23,6 +23,9 @@ import java.time.LocalDateTime; ...@@ -23,6 +23,9 @@ import java.time.LocalDateTime;
23 @Table(name="m_coupon_history") 23 @Table(name="m_coupon_history")
24 public class CouponHistory implements Serializable { 24 public class CouponHistory implements Serializable {
25 25
26 @Transient
27 private String memberCode;
28
26 /** 主键 */ 29 /** 主键 */
27 @Id 30 @Id
28 @GeneratedValue(strategy = GenerationType.IDENTITY) 31 @GeneratedValue(strategy = GenerationType.IDENTITY)
......
...@@ -23,6 +23,9 @@ import java.sql.Timestamp; ...@@ -23,6 +23,9 @@ import java.sql.Timestamp;
23 @Table(name="uc_exp_detail") 23 @Table(name="uc_exp_detail")
24 public class ExpDetail implements Serializable { 24 public class ExpDetail implements Serializable {
25 25
26 @Transient
27 private String memberCode;
28
26 /** 主键 */ 29 /** 主键 */
27 @Id 30 @Id
28 @GeneratedValue(strategy = GenerationType.IDENTITY) 31 @GeneratedValue(strategy = GenerationType.IDENTITY)
......
...@@ -72,4 +72,10 @@ public interface MemberService { ...@@ -72,4 +72,10 @@ public interface MemberService {
72 * @param member 会员 72 * @param member 会员
73 */ 73 */
74 MemberDTO checkMember(Member member); 74 MemberDTO checkMember(Member member);
75
76 /**
77 *
78 * @param resources
79 */
80 MemberDTO doUpdateMemberExpAndLevel(Member resources);
75 } 81 }
......
...@@ -105,6 +105,12 @@ public class MemberServiceImpl implements MemberService { ...@@ -105,6 +105,12 @@ public class MemberServiceImpl implements MemberService {
105 } 105 }
106 106
107 @Override 107 @Override
108 public MemberDTO doUpdateMemberExpAndLevel(Member resources) {
109 MemberDTO memberDTO = this.update(resources);
110 return memberDTO;
111 }
112
113 @Override
108 @Transactional(rollbackFor = Exception.class) 114 @Transactional(rollbackFor = Exception.class)
109 public MemberDTO create(Member resources) { 115 public MemberDTO create(Member resources) {
110 116
......
1 package com.topdraw.business.process.service; 1 package com.topdraw.business.process.service;
2 2
3 import com.topdraw.business.process.domian.TempCoupon;
4
5 import java.util.List;
6
7 /** 3 /**
8 * @description 权益操作接口 4 * @description 权益操作接口
9 * @author XiangHan 5 * @author XiangHan
...@@ -12,15 +8,4 @@ import java.util.List; ...@@ -12,15 +8,4 @@ import java.util.List;
12 8
13 public interface CouponOperationService { 9 public interface CouponOperationService {
14 10
15 /**
16 * 基于已完成的任务发放优惠券
17 * @param tempCouponList
18 */
19 void grantCouponThroughTempCoupon(List<TempCoupon> tempCouponList);
20
21 /**
22 * 系统手动发放优惠券
23 * @param tempCouponList
24 */
25 void grantCouponByManual(List<TempCoupon> tempCouponList);
26 } 11 }
......
...@@ -11,20 +11,5 @@ import java.util.List; ...@@ -11,20 +11,5 @@ import java.util.List;
11 */ 11 */
12 public interface ExpOperationService { 12 public interface ExpOperationService {
13 13
14 /**
15 * 任务完成后自动发放成长值
16 * @param tempExpList
17 */
18 void grantPointsThroughTempExp(List<TempExp> tempExpList);
19
20 /**
21 * 系统手动发放优惠券
22 * @param memberId
23 * @param userId
24 * @param tempExpList
25 */
26 void grantExpByManual(Long memberId, Long userId, List<TempExp> tempExpList);
27
28 void grantExpByManual(List<TempExp> tempExpList);
29 14
30 } 15 }
......
...@@ -11,38 +11,4 @@ import java.util.List; ...@@ -11,38 +11,4 @@ import java.util.List;
11 */ 11 */
12 public interface PointsOperationService { 12 public interface PointsOperationService {
13 13
14 /**
15 * 手动发放积分
16 * @param memberId 会员id
17 * @param tempPoints 积分详情
18 */
19 void grantPointsByManual(Long memberId , TempPoints tempPoints);
20
21 /**
22 *
23 * @param tempPoints
24 */
25 void grantPointsByManualByTempPoints(TempPoints tempPoints);
26
27
28 /**
29 * 积分扣减
30 * @param tempPoints 积分对象
31 */
32 boolean customPoints(TempPoints tempPoints);
33
34
35 /**
36 * 积分发放,基于已获得的权益
37 * @param tempPointsList 已获得的权益
38 */
39 void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList);
40
41
42 /**
43 * 清理过期并计算可用总积分
44 * @param memberId
45 * @return
46 */
47 Long cleanInvalidPointsAndCalculateCurrentPoints(Long memberId);
48 } 14 }
......
1 package com.topdraw.business.process.service;
2
3 import com.topdraw.business.module.rights.history.domain.RightsHistory;
4 import com.topdraw.business.process.domian.RightType;
5
6 import java.util.List;
7 import java.util.Map;
8
9 /**
10 * @description 权益操作接口
11 * @author XiangHan
12 * @date 2021.10.22
13 */
14 public interface RightsOperationService {
15
16 /**
17 * 系统手动发放权益
18 * @param rightsHistories
19 */
20 void grantRightsByManual(List<RightsHistory> rightsHistories);
21
22 /**
23 * 任务完成自动发放权益
24 * @param tempRightsMap
25 */
26 void grantRights(Map<RightType, Object> tempRightsMap);
27 }
...@@ -6,193 +6,33 @@ import com.topdraw.business.module.coupon.service.CouponService; ...@@ -6,193 +6,33 @@ import com.topdraw.business.module.coupon.service.CouponService;
6 import com.topdraw.business.module.member.domain.Member; 6 import com.topdraw.business.module.member.domain.Member;
7 import com.topdraw.business.module.member.service.MemberService; 7 import com.topdraw.business.module.member.service.MemberService;
8 import com.topdraw.business.module.member.service.dto.MemberDTO; 8 import com.topdraw.business.module.member.service.dto.MemberDTO;
9 import com.topdraw.business.process.domian.TempCoupon;
10 import com.topdraw.business.process.service.CouponOperationService; 9 import com.topdraw.business.process.service.CouponOperationService;
11 import com.topdraw.business.process.service.RightsOperationService;
12 import com.topdraw.business.process.service.member.MemberOperationService; 10 import com.topdraw.business.process.service.member.MemberOperationService;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.springframework.beans.BeanUtils;
16 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
18 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
19 13
20 import java.time.LocalDateTime;
21 import java.util.List;
22 import java.util.Objects;
23
24
25 @Service 14 @Service
26 public class CouponOperationServiceImpl implements CouponOperationService { 15 public class CouponOperationServiceImpl implements CouponOperationService {
27 16
28 private static final Logger LOG = LoggerFactory.getLogger(CouponOperationServiceImpl.class);
29
30 @Autowired
31 CouponService couponService;
32 @Autowired
33 CouponHistoryService couponHistoryService;
34 @Autowired
35 MemberOperationService memberOperationService;
36 @Autowired 17 @Autowired
37 RightsOperationService rightsOperationService; 18 private CouponHistoryService couponHistoryService;
38 @Autowired 19 @Autowired
39 MemberService memberService; 20 private MemberOperationService memberOperationService;
40 @Autowired 21 @Autowired
41 ThreadPoolTaskExecutor threadPoolTaskExecutor; 22 private MemberService memberService;
42
43 // 过期阀值(默认一个月)
44 private static final Integer EXPIRE_FACTOR_DAY = 30;
45
46 @Override
47 public void grantCouponThroughTempCoupon(List<TempCoupon> tempCouponList) {
48 // 优惠券领取、使用历史记录表
49 for (TempCoupon tempCoupon : tempCouponList) {
50 this.refresh(tempCoupon);
51 }
52 }
53
54 /**
55 * 手动发放优惠券
56 * @param tempCouponList
57 */
58 @Override
59 public void grantCouponByManual(List<TempCoupon> tempCouponList) {
60 // 优惠券领取、使用历史记录表
61 for (TempCoupon tempCoupon : tempCouponList) {
62 this.refresh(tempCoupon);
63 }
64 }
65
66
67 /**
68 * 优惠券领取历史记录表
69 *
70 * @param tempCoupon 领取的优惠券
71 */
72 private void refresh(TempCoupon tempCoupon) {
73 // 1.更新会员优惠券数量
74 this.refreshMemberCoupon(tempCoupon);
75 // 2.保存优惠券领取、使用历史记录表
76 this.doInsertCouponHistory(tempCoupon);
77 }
78
79
80 /**
81 * 更新会员优惠券信息
82 * @param tempCoupon 账号id
83 */
84 private void refreshMemberCoupon(TempCoupon tempCoupon) {
85 // Long userId = tempCoupon.getUserId();
86 Long memberId = tempCoupon.getMemberId();
87 Integer rightsAmount = tempCoupon.getRightsAmount();
88 try {
89 // 1.历史总优惠券数量
90 Long historyCouponCount = this.getTotalHistoryCoupon(memberId);
91 // 1.当前总优惠券数量
92 Long totalCouponCount = this.getTotalCoupon(historyCouponCount,rightsAmount);
93 // 2.获取已过期的优惠券数量
94 Long expireCouponCount = this.getTotalExpireCoupon(memberId);
95 // 3.即将过期的优惠券数量
96 Long expireSoonCouponCount = this.getTotalExpireSoonCoupon(memberId,EXPIRE_FACTOR_DAY);
97 // 4.当前优惠券数量 = 总优惠券-已过期的优惠券
98 Long currentCoupon = this.getCurrentCoupon(totalCouponCount,expireCouponCount);
99 // 5.更新用户信息(优惠券数量、即将过期的优惠券数量)
100 this.doUpdateMemberInfo(memberId,currentCoupon,expireSoonCouponCount);
101 } catch (Exception e) {
102 e.printStackTrace();
103 throw e;
104 }
105 }
106
107 private Long getTotalCoupon(Long historyCouponCount, Integer rightsAmount) {
108 return (Objects.nonNull(historyCouponCount) ? historyCouponCount: 0L) + (Objects.nonNull(rightsAmount) ? rightsAmount: 0L);
109 }
110
111
112 /**
113 * 更新当前用户优惠券信息
114 * @param memberId
115 * @param currentCoupon
116 * @param expireSoonCouponCount
117 */
118 private void doUpdateMemberInfo(Long memberId, Long currentCoupon, Long expireSoonCouponCount) {
119 MemberDTO memberDTO = this.findMemberByMemberId(memberId);
120 23
121 Member member = new Member(); 24 public void asyncMemberCoupon(Member member) {
122 BeanUtils.copyProperties(memberDTO,member); 25 String memberCode = member.getCode();
123 26 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
124 member.setCouponAmount(currentCoupon); 27 member.setId(memberDTO.getId());
125 member.setDueCouponAmount(expireSoonCouponCount);
126 member.setUpdateTime(LocalDateTime.now());
127 this.memberOperationService.doUpdateMember(member); 28 this.memberOperationService.doUpdateMember(member);
128 } 29 }
129 30
130 private MemberDTO findMemberByMemberId(Long memberId) { 31 public void asyncCouponHistory(CouponHistory couponHistory) {
131 MemberDTO memberDTO = this.memberService.findById(memberId); 32 String memberCode = couponHistory.getMemberCode();
132 return memberDTO; 33 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
133 } 34 couponHistory.setUserId(memberDTO.getId());
134
135 35
136
137 /**
138 * 当前优惠券数量 = 总优惠券-已过期的优惠券
139 * @param totalCouponCount 总数
140 * @param expireCouponCount 已过期总数
141 * @return
142 */
143 private Long getCurrentCoupon(Long totalCouponCount, Long expireCouponCount) {
144 return (Objects.nonNull(totalCouponCount)?totalCouponCount:0L)-(Objects.nonNull(expireCouponCount)?expireCouponCount:0L);
145 }
146
147
148 /**
149 * 即将过期的优惠券数量
150 * @param expireFactor
151 * @return
152 */
153 private Long getTotalExpireSoonCoupon(Long userId, Integer expireFactor) {
154 LocalDateTime expireTime = LocalDateTime.now().plusDays(expireFactor);
155 return this.couponHistoryService.countByUserIdAndExpireTimeBetween(userId,LocalDateTime.now(),expireTime);
156 }
157
158
159 /**
160 * 获取已过期的优惠券数量
161 * @param userId
162 * @return
163 */
164 private Long getTotalExpireCoupon(Long userId) {
165 return this.couponHistoryService.countByUserIdAndExpireTimeBefore(userId,LocalDateTime.now());
166 }
167
168
169 /**
170 * 获取用户领取的总优惠券
171 * @param userId
172 * @return
173 */
174 private Long getTotalHistoryCoupon(Long userId) {
175 return this.couponHistoryService.countByUserId(userId);
176 }
177
178
179 /**
180 * 优惠券领取、使用历史记录表
181 * @param tempCoupon 优惠券
182 */
183 private void doInsertCouponHistory(TempCoupon tempCoupon) {
184 CouponHistory couponHistory = new CouponHistory();
185 BeanUtils.copyProperties(tempCoupon,couponHistory);
186 couponHistory.setId(null);
187 couponHistory.setCouponId(tempCoupon.getId());
188 couponHistory.setUserId(tempCoupon.getMemberId());
189 couponHistory.setCouponCode(tempCoupon.getCode());
190 couponHistory.setUserNickname(tempCoupon.getUserNickname());
191 couponHistory.setOrderDetailId(tempCoupon.getOrderId());
192 couponHistory.setReceiveTime(LocalDateTime.now());
193 couponHistory.setUseStatus(Objects.nonNull(couponHistory.getUseStatus()) ? couponHistory.getUseStatus():0);
194 this.couponHistoryService.create(couponHistory); 36 this.couponHistoryService.create(couponHistory);
195 } 37 }
196
197
198 } 38 }
......
...@@ -4,25 +4,13 @@ import com.topdraw.business.module.exp.detail.domain.ExpDetail; ...@@ -4,25 +4,13 @@ import com.topdraw.business.module.exp.detail.domain.ExpDetail;
4 import com.topdraw.business.module.exp.detail.service.ExpDetailService; 4 import com.topdraw.business.module.exp.detail.service.ExpDetailService;
5 import com.topdraw.business.module.member.domain.Member; 5 import com.topdraw.business.module.member.domain.Member;
6 import com.topdraw.business.module.member.level.service.MemberLevelService; 6 import com.topdraw.business.module.member.level.service.MemberLevelService;
7 import com.topdraw.business.module.member.level.service.dto.MemberLevelDTO;
8 import com.topdraw.business.module.member.service.MemberService; 7 import com.topdraw.business.module.member.service.MemberService;
9 import com.topdraw.business.module.member.service.dto.MemberDTO; 8 import com.topdraw.business.module.member.service.dto.MemberDTO;
10 import com.topdraw.business.process.domian.TempExp;
11 import com.topdraw.business.process.service.ExpOperationService; 9 import com.topdraw.business.process.service.ExpOperationService;
12 import com.topdraw.business.process.service.member.MemberOperationService; 10 import com.topdraw.business.process.service.member.MemberOperationService;
13 import com.topdraw.util.IdWorker;
14 import com.topdraw.utils.StringUtils;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.BeanUtils;
18 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 12 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
20 import org.springframework.stereotype.Service; 13 import org.springframework.stereotype.Service;
21 import org.springframework.util.CollectionUtils;
22
23 import java.time.LocalDateTime;
24 import java.util.List;
25 import java.util.Objects;
26 14
27 /** 15 /**
28 * 16 *
...@@ -30,180 +18,30 @@ import java.util.Objects; ...@@ -30,180 +18,30 @@ import java.util.Objects;
30 @Service 18 @Service
31 public class ExpOperationServiceImpl implements ExpOperationService { 19 public class ExpOperationServiceImpl implements ExpOperationService {
32 20
33 private static final Logger LOG = LoggerFactory.getLogger(ExpOperationServiceImpl.class);
34
35 @Autowired 21 @Autowired
36 ExpDetailService expDetailService; 22 private ExpDetailService expDetailService;
37 @Autowired 23 @Autowired
38 MemberOperationService memberOperationService; 24 private MemberOperationService memberOperationService;
39 @Autowired 25 @Autowired
40 MemberLevelService memberLevelService; 26 private MemberLevelService memberLevelService;
41 @Autowired 27 @Autowired
42 MemberService memberService; 28 private MemberService memberService;
43 @Autowired 29 @Autowired
44 ThreadPoolTaskExecutor threadPoolTaskExecutor; 30 ThreadPoolTaskExecutor threadPoolTaskExecutor;
45 31
46 @Override 32 public void asyncMemberExpAndLevel(Member member) {
47 public void grantPointsThroughTempExp(List<TempExp> tempExpList) { 33 String code = member.getCode();
48 34 MemberDTO memberDTO = this.memberService.findByCode(code);
49 for (TempExp tempExp : tempExpList) { 35 member.setId(memberDTO.getId());
50 this.refresh(tempExp);
51 }
52
53 }
54
55 @Override
56 public void grantExpByManual(Long memberId, Long userId, List<TempExp> tempExpList) {
57 for (TempExp tempExp : tempExpList) {
58 this.refresh(tempExp);
59 }
60 }
61 36
62 @Override 37 this.memberService.doUpdateMemberExpAndLevel(member);
63 public void grantExpByManual(List<TempExp> tempExpList) {
64 for (TempExp tempExp : tempExpList) {
65 this.refresh(tempExp);
66 } 38 }
67 }
68
69
70 /**
71 *
72 * @param tempExp
73 */
74 private void refresh(TempExp tempExp) {
75 String memberCode = tempExp.getMemberCode();
76 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
77 Long id = memberDTO.getId();
78 tempExp.setId(id);
79 try {
80 // 原始积分
81 long originExp = this.getExpByMemberId(tempExp);
82 // 总积分
83 long totalExp = this.calculateTotalExp(originExp, tempExp);
84 // 1.添加成长值记录
85 // this.threadPoolTaskExecutor.execute(() -> this.doInsertExpDetail(tempExp, originExp, totalExp));
86 // 2.更新成长值与等级
87 this.refreshMemberExpAndLevel(tempExp,totalExp);
88 39
89 this.doInsertExpDetail(tempExp, originExp, totalExp); 40 public void asyncExpDetail(ExpDetail expDetail) {
41 String code = expDetail.getMemberCode();
42 MemberDTO memberDTO = this.memberService.findByCode(code);
43 expDetail.setMemberId(memberDTO.getId());
90 44
91 } catch (Exception e) {
92 e.printStackTrace();
93 throw e;
94 }
95 }
96
97 private long calculateTotalExp(long originalExp, TempExp tempExp) {
98 Long rewardExp = tempExp.getRewardExp();
99 return rewardExp + originalExp;
100 }
101
102 private long getExpByMemberId(TempExp tempExp) {
103 Long memberId = tempExp.getMemberId();
104 MemberDTO memberDTO = this.memberOperationService.findById(memberId);
105 if (Objects.nonNull(memberDTO)) {
106 Long exp = memberDTO.getExp();
107 return Objects.isNull(exp) ? 0L : exp;
108 }
109 return 0L;
110 }
111
112
113 /**
114 * 更新成长值与等级
115 *
116 * @param tempExp 成长值列表
117 */
118 private void refreshMemberExpAndLevel(TempExp tempExp, long totalExp) {
119
120 Long memberId = tempExp.getMemberId();
121 // 1.获取当前成长值
122 MemberDTO memberDTO = this.getMemberInfoByMemberId(memberId);
123 // 2.获取下一级需要的成长值
124 MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberDTO.getLevel() + 1, 1);
125 // 4.成长值比较,判断是否升级
126 Integer level = this.compareExp(totalExp, memberLevelDTO,memberDTO);
127 // 5.更新用户信息
128 this.updateMemberInfo(level, totalExp, memberId);
129 }
130
131 /**
132 *
133 * @param level
134 * @param totalExp 总积分
135 * @param memberId 会员id
136 */
137 private void updateMemberInfo(Integer level,Long totalExp,Long memberId) {
138 MemberDTO memberDTO = this.findMemberByMemberId(memberId);
139
140 Member member = new Member();
141 BeanUtils.copyProperties(memberDTO,member);
142
143 member.setExp(totalExp);
144 member.setLevel(level);
145 member.setUpdateTime(LocalDateTime.now());
146 this.memberOperationService.doUpdateMember(member);
147 }
148
149 private MemberDTO findMemberByMemberId(Long memberId) {
150 MemberDTO memberDTO = this.memberService.findById(memberId);
151 return memberDTO;
152 }
153
154 private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO, MemberDTO memberDTO) {
155 if (Objects.nonNull(memberLevelDTO)) {
156 Long nextLevelExp = memberLevelDTO.getExpValue();
157 if (Objects.nonNull(nextLevelExp) && nextLevelExp > 0)
158 if(newExp - nextLevelExp >= 0){
159 return memberLevelDTO.getLevel();
160 }
161 }
162 return memberDTO.getLevel();
163 }
164
165 private MemberLevelDTO getNextLevelExp(Integer i, Integer status) {
166 List<MemberLevelDTO> memberLevelDTOList = this.memberLevelService.findLevelAndStatus(i,status);
167 if (!CollectionUtils.isEmpty(memberLevelDTOList)) {
168 return memberLevelDTOList.get(0);
169 }
170 return null;
171 }
172
173
174 /**
175 * 获取当前会员的成长值
176 * @param memberId 会员id
177 * @return Long 当前会员成长值
178 */
179 private MemberDTO getMemberInfoByMemberId(Long memberId) {
180 MemberDTO memberDTO = this.memberOperationService.findById(memberId);
181 return memberDTO;
182 }
183
184 /**
185 * 添加成长值记录
186 *
187 * @param tempExp 成长值列表
188 */
189 private void doInsertExpDetail(TempExp tempExp, long originalExp, long totalExp) {
190 // 获得的积分
191 Long rewardExp = tempExp.getRewardExp();
192
193 ExpDetail expDetail = new ExpDetail();
194 BeanUtils.copyProperties(tempExp,expDetail);
195
196 expDetail.setCode(String.valueOf(IdWorker.generator()));
197 // 原始积分
198 expDetail.setOriginalExp(originalExp);
199 // 总积分
200 expDetail.setResultExp(totalExp);
201 // 获得的积分
202 expDetail.setExp(rewardExp);
203 if (StringUtils.isEmpty(expDetail.getDescription())) {
204 expDetail.setDescription("#");
205 }
206 this.expDetailService.create(expDetail); 45 this.expDetailService.create(expDetail);
207 } 46 }
208
209 } 47 }
......
...@@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Propagation; ...@@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Propagation;
26 import org.springframework.transaction.annotation.Transactional; 26 import org.springframework.transaction.annotation.Transactional;
27 import org.springframework.util.CollectionUtils; 27 import org.springframework.util.CollectionUtils;
28 28
29 import javax.validation.constraints.NotNull;
29 import java.time.LocalDateTime; 30 import java.time.LocalDateTime;
30 import java.util.*; 31 import java.util.*;
31 import java.util.stream.Collectors; 32 import java.util.stream.Collectors;
...@@ -39,532 +40,32 @@ import java.util.stream.Collectors; ...@@ -39,532 +40,32 @@ import java.util.stream.Collectors;
39 public class PointsOperationServiceImpl implements PointsOperationService { 40 public class PointsOperationServiceImpl implements PointsOperationService {
40 41
41 @Autowired 42 @Autowired
42 PointsService pointsService; 43 private PointsDetailService pointsDetailService;
43 @Autowired 44 @Autowired
44 PointsDetailService pointsDetailService; 45 private PointsAvailableService pointsAvailableService;
45 @Autowired 46 @Autowired
46 PointsAvailableService pointsAvailableService; 47 private MemberService memberService;
47 @Autowired
48 PointsDetailHistoryService pointsDetailHistoryService;
49 @Autowired
50 MemberOperationService memberOperationService;
51 @Autowired
52 MemberService memberService;
53
54 // 过期阈值 30天
55 private static final Integer EXPIRE_FACTOR = 30;
56
57 private static final String DELETE_AVAILABLE_POINTS = "delete";
58 private static final String INSERT_AVAILABLE_POINTS = "insert";
59 @Autowired 48 @Autowired
60 ThreadPoolTaskExecutor threadPoolTaskExecutor; 49 ThreadPoolTaskExecutor threadPoolTaskExecutor;
61 50
62 @Override 51 public void asyncMemberPoint(Member member) {
63 @Transactional(rollbackFor = Exception.class) 52 String code = member.getCode();
64 public void grantPointsByManual(Long memberId,TempPoints tempPoints){ 53 MemberDTO memberDTO = this.memberService.findByCode(code);
65 if (Objects.nonNull(tempPoints) && Objects.nonNull(tempPoints.getPoints())) { 54 member.setId(memberDTO.getId());
66 this.refresh(tempPoints); 55 this.memberService.doUpdateMemberPoints(member);
67 }
68 } 56 }
69 57
70 @Override 58 public void asyncPointsAvailable(PointsAvailable pointsAvailable) {
71 @Transactional(rollbackFor = Exception.class) 59 String memberCode = pointsAvailable.getMemberCode();
72 public void grantPointsByManualByTempPoints(TempPoints tempPoints) {
73 if (Objects.nonNull(tempPoints) && Objects.nonNull(tempPoints.getPoints())) {
74 String memberCode = tempPoints.getMemberCode();
75 MemberDTO memberDTO = this.memberService.findByCode(memberCode); 60 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
76 if (Objects.nonNull(memberDTO)) { 61 pointsAvailable.setMemberId(memberDTO.getId());
77 Long memberId = memberDTO.getId();
78 tempPoints.setMemberId(memberId);
79 this.refresh(tempPoints);
80 }
81 }
82 }
83
84
85 /**
86 * 积分消耗
87 * @param tempPoints 任务对象
88 * @return true: 满足 false:不满足
89 */
90 @Override
91 @Transactional(rollbackFor = Exception.class)
92 public boolean customPoints(TempPoints tempPoints) {
93
94 String memberCode = tempPoints.getMemberCode();
95
96 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
97
98 if (Objects.nonNull(memberDTO)) {
99
100 Long memberId = memberDTO.getId();
101 tempPoints.setMemberId(memberId);
102 try {
103 //1.删除过期的积分
104 this.cleanInvalidAvailablePointsByMemberId(memberId);
105 // 1.判断可用积分是否够用
106 boolean b = this.checkAvailablePoints(tempPoints);
107 log.info("customPoints-->>> 当前可用总积分大于待兑换的积分--->>" + b);
108 if (b) {
109 // 2.可用积分表,按照过期时间进行升序排列
110 List<PointsAvailableDTO> pointsAvailableDTOS = this.findByMemberIdOrderByExpireTime(tempPoints);
111 // 3.当前可用总积分
112 long currentPoints = this.findAvailablePointsByMemberId(memberId);
113 // 2.优先使用即将过期的积分,累加到超过需兑换积分时,需要进行拆分
114 Map<String, List<PointsAvailableDTO>> customAvailablePointsMap = this.customAvailablePoints(tempPoints, pointsAvailableDTOS);
115 // 3.添加积分明细
116 this.doInsertTrPointsDetailByAvailablePointsMap(tempPoints, customAvailablePointsMap, currentPoints);
117 // 4.更新可用积分表,超过的删除,剩余的新增
118 long totalPoints = this.doFreshTrPointsAvailableByAvailablePointsMap(customAvailablePointsMap, currentPoints);
119 // 5.即将过期的积分
120 long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
121 // 6.更新会员积分信息
122 this.freshMemberCurrentPoints(memberId, totalPoints,soonExpirePoints,tempPoints);
123
124 return true;
125 }
126 }catch (Exception e) {
127 e.printStackTrace();
128 throw e;
129 }
130
131 }
132
133 return false;
134 }
135
136 /**
137 * 更新可用积分表
138 * @param customAvailablePointsMap
139 */
140 private long doFreshTrPointsAvailableByAvailablePointsMap(
141 Map<String, List<PointsAvailableDTO>> customAvailablePointsMap,long currentPoints) {
142
143 long totalCustomAvailablePoints = 0L;
144 if (customAvailablePointsMap != null) {
145 // 需要删除的
146 List<PointsAvailableDTO> pointsAvailableDTOS1 = customAvailablePointsMap.get(DELETE_AVAILABLE_POINTS);
147 if (!CollectionUtils.isEmpty(pointsAvailableDTOS1)) {
148 for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS1) {
149 totalCustomAvailablePoints = (totalCustomAvailablePoints+pointsAvailableDTO.getPoints());
150 this.pointsAvailableService.delete(pointsAvailableDTO.getId());
151 }
152 }
153
154 // 需要添加的
155 List<PointsAvailableDTO> pointsAvailableDTOS2 = customAvailablePointsMap.get(INSERT_AVAILABLE_POINTS);
156 if (!CollectionUtils.isEmpty(pointsAvailableDTOS2)) {
157 PointsAvailableDTO pointsAvailableDTO = pointsAvailableDTOS2.get(0);
158 PointsAvailable pointsAvailable = new PointsAvailable();
159 BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailable);
160 pointsAvailable.setId(null);
161 pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
162 this.pointsAvailableService.create4Custom(pointsAvailable); 62 this.pointsAvailableService.create4Custom(pointsAvailable);
163 } 63 }
164 }
165
166 return currentPoints - totalCustomAvailablePoints;
167 }
168
169 /**
170 * 优先使用即将过期的积分,注意拆分
171 * @param customAvailablePointsMap
172 */
173 private void doInsertTrPointsDetailByAvailablePointsMap(TempPoints tempPoints,
174 Map<String, List<PointsAvailableDTO>> customAvailablePointsMap,
175 long currentPoints) {
176 // 兑换的积分
177 Long points = tempPoints.getPoints();
178
179 List<PointsAvailableDTO> pointsAvailableDTOS = customAvailablePointsMap.get(DELETE_AVAILABLE_POINTS);
180
181 if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
182 PointsAvailableDTO pointsAvailableDTO = pointsAvailableDTOS.get(0);
183 Long memberId = pointsAvailableDTO.getMemberId();
184
185 TempPoints tempPoints1 = new TempPoints();
186 BeanUtils.copyProperties(pointsAvailableDTO,tempPoints1);
187 BeanUtils.copyProperties(tempPoints,tempPoints1);
188 tempPoints1.setPoints(-(Math.abs(points)));
189 Long totalPoints = this.calculateTotalPoints(tempPoints1, currentPoints);
190 this.doInsertTrPointsDetail(memberId,tempPoints1,currentPoints,totalPoints);
191 }
192 }
193
194 /**
195 * 消耗过期的积分
196 * @param tempPoints 需要消耗的积分
197 * @param pointsAvailableDTOS 可用积分列表
198 * @return List<PointsAvailableDTO> 已消耗的可用积分列表
199 */
200 private Map<String,List<PointsAvailableDTO>> customAvailablePoints(TempPoints tempPoints, List<PointsAvailableDTO> pointsAvailableDTOS) {
201 // 兑换的积分
202 Long points = tempPoints.getPoints();
203 Long points1_ = 0L;
204 List<PointsAvailableDTO> pointsAvailableDTOS1 = new ArrayList<>();
205 List<PointsAvailableDTO> pointsAvailableDTOS2 = new ArrayList<>();
206 Map<String,List<PointsAvailableDTO>> map = new HashMap<>();
207
208 for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
209 Long points1 = pointsAvailableDTO.getPoints();
210 points1_ = (points1_ + points1);
211
212 // 不够
213 if (points1_ < points) {
214 pointsAvailableDTOS1.add(pointsAvailableDTO);
215 continue;
216 }
217
218 // 刚好
219 if (points1_ == points) {
220 pointsAvailableDTOS1.add(pointsAvailableDTO);
221 break;
222 }
223 64
224 // 超了,拆分 65 public void asyncPointsDetail(PointsDetail pointsDetail) {
225 if (points1_ > points) { 66 String memberCode = pointsDetail.getMemberCode();
226 67 MemberDTO memberDTO = this.memberService.findByCode(memberCode);
227 // 超过的 68 pointsDetail.setMemberId(memberDTO.getId());
228 long beyond = points1_ - points;
229 // 新增
230 PointsAvailableDTO pointsAvailableDTO2 = new PointsAvailableDTO();
231 BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailableDTO2);
232 pointsAvailableDTO2.setPoints(beyond);
233 pointsAvailableDTOS2.add(pointsAvailableDTO2);
234
235 // 剩余的
236 long suit = points1 - beyond;
237 // 扣除
238 PointsAvailableDTO pointsAvailableDTO1 = new PointsAvailableDTO();
239 BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailableDTO1);
240 pointsAvailableDTO1.setPoints(suit);
241 pointsAvailableDTOS1.add(pointsAvailableDTO1);
242
243 break;
244 }
245
246 }
247
248 map.put(DELETE_AVAILABLE_POINTS,pointsAvailableDTOS1);
249 map.put(INSERT_AVAILABLE_POINTS,pointsAvailableDTOS2);
250
251 return map;
252 }
253
254 /**
255 * 可用积分表,按照过期时间进行升序排列
256 * @param tempPoints
257 * @return
258 */
259 private List<PointsAvailableDTO> findByMemberIdOrderByExpireTime(TempPoints tempPoints) {
260 return this.pointsAvailableService.findByMemberIdOrderByExpireTime(tempPoints.getMemberId());
261 }
262
263 /**
264 * 检查当前用户可用积分是否足够
265 * @param tempPoints
266 * @return true : 满足 false: 不满足
267 */
268 private boolean checkAvailablePoints(TempPoints tempPoints) {
269 Long memberId = tempPoints.getMemberId();
270 // 可用积分
271 long currentPoints = this.findAvailablePointsByMemberId(memberId);
272 long points1 = tempPoints.getPoints();
273 if (currentPoints > 0 && points1 > 0 && (currentPoints - Math.abs(points1) >= 0)) {
274 return true;
275 }
276 return false;
277 }
278
279 /**
280 * 积分发放,基于已获得的权益
281 *
282 * @param tempPointsList 已获得的权益
283 */
284 @Override
285 @Transactional(rollbackFor = Exception.class)
286 public void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList){
287 log.info("------->>grantPointsThroughTempRightsList start1");
288 for (TempPoints tempPoints : tempPointsList){
289 log.info("------->>grantPointsThroughTempRightsList start");
290 this.refresh(tempPoints);
291 }
292 }
293
294 /**
295 * 清理过期积分
296 * @param memberId
297 */
298 private void cleanInvalidAvailablePointsByMemberId(Long memberId) {
299 List<PointsAvailableDTO> pointsAvailableDTOS =
300 pointsAvailableService.findByMemberIdAndExpireTimeBefore(memberId,LocalDateTime.now());
301 if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
302 //1.获取原始积分
303 for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
304 // 添加积分明细 uc_points_detail
305 this.doCreatePointsDetail(pointsAvailableDTO);
306 // 删除已过期的积分
307 this.doDeleteInvalidAvailablePoints(pointsAvailableDTO);
308 }
309
310 }
311 }
312
313 @Override
314 public Long cleanInvalidPointsAndCalculateCurrentPoints(Long memberId) {
315
316 // 清理当前用户的过期积分
317 this.cleanInvalidAvailablePointsByMemberId(memberId);
318 // 获取当前用户的可用总积分
319 long currentPoints = this.findAvailablePointsByMemberId(memberId);
320 // 即将过期的积分
321 long soonExpirePoints = this.getSoonExpirePoints(memberId, null);
322 // 更新会员信息
323 this.doUpdateMemberPoints(memberId,currentPoints,soonExpirePoints);
324
325 return currentPoints;
326 }
327
328 /**
329 * 获取可用总积分
330 * @param memberId
331 * @return
332 */
333 private long findAvailablePointsByMemberId(Long memberId){
334 return this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
335 }
336
337 /**
338 * 修改会员信息
339 * @param memberId
340 * @param currentPoints
341 */
342 private void doUpdateMemberPoints(Long memberId, long currentPoints,long soonExpirePoints) {
343 Member member = new Member();
344 member.setId(memberId);
345 member.setPoints(currentPoints);
346 member.setDuePoints(soonExpirePoints);
347 this.memberOperationService.doUpdateMemberPoints(member);
348 }
349
350 /**
351 *
352 * @param pointsAvailableDTOS
353 */
354 private void doDeleteBatchInvalidAvailablePoints(List<PointsAvailableDTO> pointsAvailableDTOS) {
355 List<Long> collect = pointsAvailableDTOS.stream().map(pointsAvailableDTO -> pointsAvailableDTO.getId()).collect(Collectors.toList());
356 this.pointsAvailableService.deleteBatchByIds(collect);
357 }
358
359 /**
360 *
361 * @param pointsAvailableDTO
362 */
363 private void doDeleteInvalidAvailablePoints(PointsAvailableDTO pointsAvailableDTO) {
364 this.pointsAvailableService.delete(pointsAvailableDTO.getId());
365 }
366
367 /**
368 * 可用积分
369 * @param pointsAvailableDTO
370 */
371 private void doCreatePointsDetail(PointsAvailableDTO pointsAvailableDTO) {
372
373 Long memberId = pointsAvailableDTO.getMemberId();
374 // 原始积分
375 long availablePoints = this.pointsAvailableService.findTotalPointsByMemberId(memberId);//this.findAvailablePointsByMemberId(memberId);
376 // 过期积分
377 long l = pointsAvailableDTO.getPoints();
378 // 结果积分
379 long resultPoints = availablePoints - l;
380
381 PointsDetail pointsDetail = new PointsDetail();
382 BeanUtils.copyProperties(pointsAvailableDTO,pointsDetail);
383 pointsDetail.setId(null);
384 pointsDetail.setPoints(-Math.abs(l));
385 pointsDetail.setCode(String.valueOf(IdWorker.generator()));
386 pointsDetail.setOriginalPoints(availablePoints);
387 pointsDetail.setResultPoints(resultPoints);
388 pointsDetail.setDescription("过期积分");
389 pointsDetail.setEvtType(99);
390 pointsDetail.setCreateTime(TimestampUtil.now());
391 pointsDetail.setUpdateTime(TimestampUtil.now());
392 this.doInsertPointsDetail(pointsDetail);
393 }
394
395 /**
396 * 模板方法,提供更新积分的总体流程
397 *
398 * @param tempPoints 积分
399 */
400 private void refresh(TempPoints tempPoints) {
401 Long memberId = tempPoints.getMemberId();
402 log.info("----------->> points refresh start");
403 log.info("----------->> rLock --->> start" );
404 try {
405 log.info("----------->> refresh findAvailablePointsByMemberId start");
406 // 1.可用总积分
407 Long currentPoints = this.findAvailablePointsByMemberId(memberId);
408 log.info("----------->> refresh findAvailablePointsByMemberId currentPoints " + currentPoints);
409
410 // 2.计算总积分
411 Long totalPoints = this.calculateTotalPoints(tempPoints, currentPoints);
412 log.info("----------->> refresh findAvailablePointsByMemberId totalPoints " + totalPoints);
413
414 // 3.添加积分明细,并计算总积分
415 this.doInsertTrPointsDetail(memberId, tempPoints, currentPoints, totalPoints);
416 log.info(Thread.currentThread().getName() + "----------->> refresh doInsertTrPointsDetail end ");
417
418 // 4.添加可用积分
419 log.info("----------->> refresh doInsertTrPointsAvailable start ");
420 this.doInsertTrPointsAvailable(tempPoints);
421 log.info("----------->> refresh doInsertTrPointsAvailable end ");
422
423 // 即将过期的积分
424 long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
425
426 // 6.更新会员的总积分
427 log.info("----------->> refresh freshMemberCurrentPoints start ");
428 this.freshMemberCurrentPoints(memberId, totalPoints,soonExpirePoints,tempPoints);
429 log.info("----------->> refresh freshMemberCurrentPoints end ");
430
431 } catch (Exception e) {
432 e.printStackTrace();
433 throw e;
434 }
435 }
436
437 /**
438 * 获取总积分
439 * @param tempPoints
440 * @param currentPoints
441 * @return
442 */
443 private Long calculateTotalPoints(TempPoints tempPoints, Long currentPoints) {
444 // 获取的积分
445 Long rewardPoints = tempPoints.getPoints();
446 // 总积分
447 Long totalPoints = currentPoints + rewardPoints;
448 return totalPoints;
449 }
450
451 /**
452 * 获取即将过期的积分
453 * @param memberId
454 * @return
455 */
456 private long getSoonExpirePoints(Long memberId,TempPoints tempPoints) {
457 // 计算即将过期的天数
458 Integer factor = this.calculateExpireFactor(tempPoints);
459 if (Objects.isNull(factor)) {
460 factor = EXPIRE_FACTOR;
461 }
462
463 Long soonExpireTime = this.pointsAvailableService.findSoonExpireTime(memberId, factor);
464 return Objects.nonNull(soonExpireTime) ? soonExpireTime : 0L;
465 }
466
467 /**
468 * 如果过期时间和过期天数同时存在,则以过期时间为准
469 * @param tempPoints
470 * @return
471 */
472 private Integer calculateExpireFactor(TempPoints tempPoints) {
473 // TODO 计算过期的相对时间
474 return null;
475 }
476
477 /**
478 * 更新会员总积分
479 * @param memberId 会员Id
480 * @param currentPoints 当前总积分
481 */
482 private void freshMemberCurrentPoints(Long memberId, Long currentPoints,long duePoints,TempPoints tempPoints) {
483 Member member = new Member();
484 member.setId(memberId);
485 member.setPoints(Objects.nonNull(currentPoints)?currentPoints:0);
486 member.setDuePoints(duePoints);
487 member.setUpdateTime(LocalDateTime.now());
488 member.setCode(tempPoints.getMemberCode());
489 try {
490 this.memberOperationService.doUpdateMemberPoints(member);
491 } catch (Exception e){
492 throw e;
493 }
494 }
495
496 /**
497 * 计算当前总积分
498 * @param memberId 会员id
499 * @return
500 */
501 private Long findAvailablePointsByMemberId(long memberId){
502 Long availablePoints = this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
503 return Objects.nonNull(availablePoints) ? availablePoints : 0L;
504 }
505
506 /**
507 * 更新可用积分表
508 * @param tempPoints
509 */
510 private void doInsertTrPointsAvailable(TempPoints tempPoints){
511
512 PointsAvailable pointsAvailable = new PointsAvailable();
513 BeanUtils.copyProperties(tempPoints,pointsAvailable);
514 String description = pointsAvailable.getDescription();
515 pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
516 pointsAvailable.setDescription(StringUtils.isEmpty(description)?"#":description);
517 LocalDateTime timestamp = tempPoints.getExpireTime();
518 if (Objects.nonNull(timestamp)) {
519 pointsAvailable.setExpireTime(timestamp);
520 }
521
522 // 添加可用积分记录
523 this.doInsertTrPointsAvailable(pointsAvailable);
524
525 }
526
527 /**
528 * 添加可用积分记录
529 * @param pointsAvailable 可用积分
530 */
531 private void doInsertTrPointsAvailable(PointsAvailable pointsAvailable) {
532 this.pointsAvailableService.create(pointsAvailable);
533 }
534
535 /**
536 * 添加积分明细
537 * @param memberId 会员Id
538 * @param tempPoints 积分
539 * @return Integer 总积分
540 */
541 private void doInsertTrPointsDetail(Long memberId, TempPoints tempPoints,Long currentPoints,Long totalPoints){
542
543 PointsDetail pointsDetail = new PointsDetail();
544 BeanUtils.copyProperties(tempPoints,pointsDetail);
545 pointsDetail.setId(null);
546 pointsDetail.setMemberId(memberId);
547 pointsDetail.setCode(String.valueOf(IdWorker.generator()));
548 pointsDetail.setPoints(tempPoints.getPoints());
549 pointsDetail.setOriginalPoints(currentPoints);
550 pointsDetail.setResultPoints(totalPoints);
551 pointsDetail.setCreateTime(null);
552 pointsDetail.setUpdateTime(null);
553 String description = pointsDetail.getDescription();
554 if (StringUtils.isEmpty(description)) {
555 pointsDetail.setDescription("#");
556 }
557
558 // 保存积分流水
559 this.doInsertPointsDetail(pointsDetail);
560
561 }
562
563 /**
564 *
565 * @param pointsDetail
566 */
567 private void doInsertPointsDetail(PointsDetail pointsDetail){
568 this.pointsDetailService.create4Custom(pointsDetail); 69 this.pointsDetailService.create4Custom(pointsDetail);
569 } 70 }
570 } 71 }
......
1 package com.topdraw.business.process.service.impl;
2
3 import cn.hutool.core.date.LocalDateTimeUtil;
4 import com.topdraw.business.module.coupon.service.CouponService;
5 import com.topdraw.business.module.coupon.service.dto.CouponDTO;
6 import com.topdraw.business.module.rights.history.domain.RightsHistory;
7 import com.topdraw.business.module.rights.history.service.RightsHistoryService;
8 import com.topdraw.business.module.rights.service.RightsService;
9 import com.topdraw.business.module.rights.service.dto.RightsDTO;
10 import com.topdraw.business.process.domian.*;
11 import com.topdraw.business.process.service.CouponOperationService;
12 import com.topdraw.business.process.service.ExpOperationService;
13 import com.topdraw.business.process.service.PointsOperationService;
14 import com.topdraw.business.process.service.RightsOperationService;
15 import com.topdraw.util.TimestampUtil;
16 import lombok.extern.slf4j.Slf4j;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.stereotype.Service;
21 import org.springframework.util.CollectionUtils;
22 import org.springframework.util.StringUtils;
23
24 import java.time.LocalDateTime;
25 import java.util.*;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.Executors;
28
29 /**
30 * 权益处理
31 *
32 * @author XiangHan
33 * @date 2021.10.23
34 */
35 @Service
36 @Slf4j
37 public class RightsOperationServiceImpl implements RightsOperationService {
38
39 @Autowired
40 RightsHistoryService rightsHistoryService;
41 @Autowired
42 CouponOperationService couponOperationService;
43 @Autowired
44 RightsService rightsService;
45 @Autowired
46 ExpOperationService expOperationService;
47 @Autowired
48 PointsOperationService pointsOperationService;
49 @Autowired
50 CouponService couponService;
51
52 // @Autowired
53 // ThreadPoolTaskExecutor threadPoolTaskExecutor;
54
55 private ExecutorService threadPoolTaskExecutor = Executors.newFixedThreadPool(10);
56
57 /**
58 * 系统手动发放
59 * 实现步骤:
60 * 1.当前权益只有实体券
61 * @param rightsList
62 */
63 @Override
64 public void grantRightsByManual(List<RightsHistory> rightsList) {
65 // 1.权益区分
66 Map<RightType,Object> tempRightsMap = this.distinguishRight(rightsList);
67 // 2.权益下发
68 this.refresh(tempRightsMap);
69 // 3.保存权益历史
70 this.doInsertTrRightHistory(rightsList);
71 }
72
73 /**
74 * 权益发放
75 * @param tempRightsMap 权益类型
76 */
77 @Override
78 public void grantRights(Map<RightType, Object> tempRightsMap) {
79
80 // this.threadPoolTaskExecutor.execute(()-> {
81 // 2.创建权益历史对象
82 List<RightsHistory> rightsList = this.getRightHistory(tempRightsMap);
83 // 3.保存权益历史
84 this.doInsertTrRightHistory(rightsList);
85 // });
86
87 // 1.权益下发
88 this.refresh(tempRightsMap);
89 }
90
91 /**
92 *
93 * @param tempRightsMap
94 * @return
95 */
96 private List<RightsHistory> getRightHistory(Map<RightType, Object> tempRightsMap) {
97 List<TempRights> values = (List<TempRights>)tempRightsMap.get(RightType.RIGHTS);
98 List<RightsHistory> rightsHistoryList = new ArrayList<>();
99
100 values.forEach(value -> {
101 RightsHistory rightsHistory = new RightsHistory();
102 rightsHistory.setSendTime(TimestampUtil.now());
103 rightsHistory.setRightsId(value.getId());
104 rightsHistory.setMemberId(value.getMemberId());
105 rightsHistory.setExpireTime(value.getExpireTime());
106 String memberCode = value.getMemberCode();
107 rightsHistory.setMemberCode(memberCode);
108 rightsHistoryList.add(rightsHistory);
109 });
110
111 return rightsHistoryList;
112 }
113
114 /**
115 * 成长值发放,基于已获得的权益
116 * @param tempExpList 权益列表
117 */
118 private void grantExp(List<TempExp> tempExpList) {
119 if (!CollectionUtils.isEmpty(tempExpList))
120 this.expOperationService.grantPointsThroughTempExp(tempExpList);
121 }
122
123 /**
124 * 发放积分,基于已获得的权益
125 *
126 * @param tempPointsList 权益列表
127 */
128 private void grantPoint(List<TempPoints> tempPointsList) {
129 if (!CollectionUtils.isEmpty(tempPointsList))
130 this.pointsOperationService.grantPointsThroughTempRightsList(tempPointsList);
131 }
132
133 /**
134 * 发放优惠券,基于已获得的权益
135 *
136 * @param tempCouponList 优惠券
137 */
138 private void grantCoupon(List<TempCoupon> tempCouponList) {
139 // 发放优惠券
140 if (!CollectionUtils.isEmpty(tempCouponList))
141 this.couponOperationService.grantCouponThroughTempCoupon(tempCouponList);
142 }
143
144 /**
145 * 权益发放
146 * @param tempRightsMap
147 */
148 private void refresh(Map<RightType, Object> tempRightsMap) {
149 /*FutureTask<Map<Long,Long>> futureTask1 = new FutureTask(()->{
150 log.info(Thread.currentThread().getName() + "=========>> start");
151 // 积分
152 this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
153 log.info(Thread.currentThread().getName() + "=========>>grantPoint end");
154 // 成长值
155 // this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
156 // 优惠券
157 // this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
158 return null;
159 });
160 FutureTask<Map<Long,Long>> futureTask2 = new FutureTask(()->{
161 // 积分
162 // this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
163 // 成长值
164 this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
165 // 优惠券
166 // this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
167 return null;
168 });
169 FutureTask<Map<Long,Long>> futureTask3 = new FutureTask(()->{
170 // 积分
171 // this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
172 // 成长值
173 // this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
174 // 优惠券
175 this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
176 return null;
177 });
178 this.threadPoolTaskExecutor.execute(futureTask1);
179 this.threadPoolTaskExecutor.execute(futureTask2);
180 this.threadPoolTaskExecutor.execute(futureTask3);*/
181 /*this.threadPoolTaskExecutor.execute(() -> {
182 // 积分
183 this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
184 // 成长值
185 this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
186 // 优惠券
187 this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
188 });*/
189
190
191 /*this.threadPoolTaskExecutor.execute(() -> {
192 log.info(Thread.currentThread().getName() + "=========>> start");
193 // 积分
194 this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
195 log.info(Thread.currentThread().getName() + "=========>> end");
196 });*/
197
198 List<TempPoints> tempPointsList = (List<TempPoints>) tempRightsMap.get(RightType.POINTS);
199 if (!CollectionUtils.isEmpty(tempPointsList)) {
200 // 积分
201 this.grantPoint(tempPointsList);
202 }
203
204 List<TempExp> tempExpList = (List<TempExp>) tempRightsMap.get(RightType.EXP);
205 if (!CollectionUtils.isEmpty(tempExpList)) {
206 // 成长值
207 this.grantExp(tempExpList);
208 }
209
210 List<TempCoupon> tempCouponList = (List<TempCoupon>) tempRightsMap.get(RightType.COUPON);
211 if (!CollectionUtils.isEmpty(tempCouponList)) {
212 // 优惠券
213 this.grantCoupon(tempCouponList);
214 }
215
216 }
217
218 /**
219 * 区分权益
220 * @param rightsList
221 * @return
222 */
223 private Map<RightType, Object> distinguishRight(List<RightsHistory> rightsList) {
224
225 Map<RightType,Object> map = new HashMap<>();
226
227 // 优惠券
228 List<TempCoupon> tempCouponList = new ArrayList<>();
229
230 for (RightsHistory right : rightsList) {
231 Long rightId = right.getRightsId();
232 Long memberId = right.getMemberId();
233 Long userId = right.getUserId();
234 // 权益类型
235 RightsDTO rightsDTO = this.getRights(rightId);
236 // 权益的实体类型 1:积分;2成长值;3优惠券
237 String type = rightsDTO.getEntityType();
238 Long expireTime = rightsDTO.getExpireTime();
239
240 switch (type) {
241 // 优惠券
242 case "1":
243 Long entityId = rightsDTO.getEntityId();
244 CouponDTO couponDTO = this.findCouponById(entityId);
245 if (Objects.nonNull(couponDTO)) {
246 TempCoupon tempCoupon = new TempCoupon();
247 tempCoupon.setId(couponDTO.getId());
248 tempCoupon.setMemberId(memberId);
249 tempCoupon.setUserId(userId);
250 tempCoupon.setRightsAmount(1);
251 tempCoupon.setRightsSendStrategy(0);
252 tempCoupon.setCode(couponDTO.getCode());
253 if (Objects.nonNull(expireTime))
254 tempCoupon.setExpireTime(LocalDateTimeUtil.of(expireTime));
255 tempCouponList.add(tempCoupon);
256 }
257 break;
258 // 观影券
259 case "2":
260 break;
261 // 活动参与机会
262 case "3":
263 break;
264
265 default:
266 break;
267 }
268 }
269
270 // 优惠券
271 if (!CollectionUtils.isEmpty(tempCouponList))
272 map.put(RightType.COUPON,tempCouponList);
273 return map;
274 }
275
276 /**
277 * 获取优惠券信息
278 * @param id
279 * @return
280 */
281 private CouponDTO findCouponById(Long id) {
282 CouponDTO couponDTO = this.couponService.findById(id);
283 return couponDTO;
284 }
285
286 /**
287 * 权益详情
288 * @param rightsId
289 * @return
290 */
291 private RightsDTO getRights(Long rightsId) {
292 RightsDTO rightsDTO = this.rightsService.findById(rightsId);
293 return rightsDTO;
294 }
295
296
297 /**
298 * 添加权益领取记录
299 * @param rightsHistories
300 */
301 private void doInsertTrRightHistory(List<RightsHistory> rightsHistories) {
302 if (!CollectionUtils.isEmpty(rightsHistories)) {
303
304 for (RightsHistory rightsHistory : rightsHistories) {
305 Long operatorId = rightsHistory.getOperatorId();
306 String operatorName = rightsHistory.getOperatorName();
307 rightsHistory.setSendTime(TimestampUtil.now());
308 rightsHistory.setOperatorId(Objects.nonNull(operatorId)?operatorId:0);
309 rightsHistory.setOperatorName(!StringUtils.isEmpty(operatorName)?operatorName:"系统发放");
310 this.rightsHistoryService.create(rightsHistory);
311 }
312
313 }
314
315 }
316
317 }
...@@ -138,7 +138,8 @@ public class RabbitMqConfig { ...@@ -138,7 +138,8 @@ public class RabbitMqConfig {
138 138
139 public static final String UC_DIRECT_MANAGEMENT = "uc.direct.management"; 139 public static final String UC_DIRECT_MANAGEMENT = "uc.direct.management";
140 // uc-service-management 2 uc-consumer-iptv 140 // uc-service-management 2 uc-consumer-iptv
141 public static final String ENGINE_TO_SERVICE_DIRECT = "uc.engine.service.direct"; 141 // public static final String ENGINE_TO_SERVICE_DIRECT = "uc.engine.service.direct";
142 public static final String ENGINE_TO_SERVICE_DIRECT = "uc.engine.service.direct.local";
142 143
143 @Bean 144 @Bean
144 public Queue managementDirect() { 145 public Queue managementDirect() {
...@@ -184,18 +185,18 @@ public class RabbitMqConfig { ...@@ -184,18 +185,18 @@ public class RabbitMqConfig {
184 185
185 186
186 /**************************************************数据基座*************************************************************/ 187 /**************************************************数据基座*************************************************************/
187 public static final String UC_EVENTBUS = "uc.eventbus"; 188 public static final String UC_EVENTBUS_EXCHANGE = "uc.eventbus.local";
188 public static final String UC_EVENTBUS_KEY = "uc.eventbus.*.topic"; 189 public static final String UC_EVENTBUS_KEY = "uc.eventbus.*.topic";
189 public static final String UC_EVENTBUS_TOPIC = "uc.eventbus"; 190 public static final String UC_EVENTBUS_QUEUE = "uc.eventbus.local";
190 191
191 @Bean 192 @Bean
192 public Queue eventBusQueue() { 193 public Queue eventBusQueue() {
193 return new Queue(UC_EVENTBUS_TOPIC); 194 return new Queue(UC_EVENTBUS_QUEUE);
194 } 195 }
195 196
196 @Bean 197 @Bean
197 TopicExchange eventBusExchange() { 198 TopicExchange eventBusExchange() {
198 return ExchangeBuilder.topicExchange(UC_EVENTBUS) 199 return ExchangeBuilder.topicExchange(UC_EVENTBUS_EXCHANGE)
199 .durable(true).build(); 200 .durable(true).build();
200 } 201 }
201 202
......
...@@ -2,34 +2,35 @@ package com.topdraw.mq.consumer; ...@@ -2,34 +2,35 @@ package com.topdraw.mq.consumer;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.fasterxml.jackson.annotation.JsonFormat; 5 import com.topdraw.business.module.member.service.MemberService;
6 import com.topdraw.business.module.member.service.dto.MemberDTO; 6 import com.topdraw.business.module.member.service.dto.MemberDTO;
7 import com.topdraw.business.module.user.iptv.service.UserTvService; 7 import com.topdraw.business.module.user.iptv.service.UserTvService;
8 import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO; 8 import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
9 import com.topdraw.config.RabbitMqConfig; 9 import com.topdraw.config.RabbitMqConfig;
10 import com.topdraw.exception.BadRequestException;
11 import com.topdraw.exception.EntityNotFoundException;
10 import com.topdraw.mq.domain.DataSyncMsg; 12 import com.topdraw.mq.domain.DataSyncMsg;
11 import com.topdraw.resttemplate.RestTemplateClient; 13 import com.topdraw.resttemplate.RestTemplateClient;
12 import com.topdraw.util.JSONUtil; 14 import com.topdraw.util.JSONUtil;
13 import lombok.Data; 15 import lombok.Data;
14 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
15 import org.apache.commons.lang3.StringUtils; 17 import org.apache.commons.lang3.StringUtils;
16 import org.springframework.amqp.core.ExchangeTypes;
17 import org.springframework.amqp.rabbit.annotation.*; 18 import org.springframework.amqp.rabbit.annotation.*;
18 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
20 import org.springframework.util.Assert;
21 21
22 import java.sql.Timestamp;
23 import java.util.Objects; 22 import java.util.Objects;
24 23
25 @Component 24 @Component
26 @Slf4j 25 @Slf4j
27 public class UcEventBusIptv2IptvConsumer { 26 public class UcEventBusIptv2ManagementUcEngine {
28 27
29 @Autowired 28 @Autowired
30 RestTemplateClient restTemplateClient; 29 private RestTemplateClient restTemplateClient;
31 @Autowired 30 @Autowired
32 private UserTvService userTvService; 31 private UserTvService userTvService;
32 @Autowired
33 private MemberService memberService;
33 34
34 /** 35 /**
35 * 事件 36 * 事件
...@@ -39,7 +40,7 @@ public class UcEventBusIptv2IptvConsumer { ...@@ -39,7 +40,7 @@ public class UcEventBusIptv2IptvConsumer {
39 * @date 2021/9/7 11:26 上午 40 * @date 2021/9/7 11:26 上午
40 */ 41 */
41 @RabbitHandler 42 @RabbitHandler
42 @RabbitListener(queues = RabbitMqConfig.UC_EVENTBUS_TOPIC, 43 @RabbitListener(queues = RabbitMqConfig.UC_EVENTBUS_QUEUE,
43 containerFactory = "managementRabbitListenerContainerFactory") 44 containerFactory = "managementRabbitListenerContainerFactory")
44 public void ucEventConsumer(String content) { 45 public void ucEventConsumer(String content) {
45 log.info(" receive dataSync msg , content is : {} ", content); 46 log.info(" receive dataSync msg , content is : {} ", content);
...@@ -53,18 +54,6 @@ public class UcEventBusIptv2IptvConsumer { ...@@ -53,18 +54,6 @@ public class UcEventBusIptv2IptvConsumer {
53 * @param content 54 * @param content
54 * @return 55 * @return
55 */ 56 */
56 /*{
57 "evt": "play”, // 表示播放
58 "deviceType": 1, // 1代表大屏
59 "time": "2022-04-01 00:10:09”,
60 "msgData": {
61 "platformAccount": "itv094430@“, // 大屏用户账号
62 "playDuration": 60, // 播放时长,单位分钟
63 "mediaId": 3433, // 节目id,此次是累计计算,可不传
64 "mediaCode": "media_123”, // 节目标识,同上
65 "mediaName": "白宫陷落” // 节目名称,同上
66 }
67 }*/
68 private DataSyncMsg parseContent(String content) { 57 private DataSyncMsg parseContent(String content) {
69 58
70 CommonMsg commonMsg = JSONUtil.parseMsg2Object(content, CommonMsg.class); 59 CommonMsg commonMsg = JSONUtil.parseMsg2Object(content, CommonMsg.class);
...@@ -91,22 +80,35 @@ public class UcEventBusIptv2IptvConsumer { ...@@ -91,22 +80,35 @@ public class UcEventBusIptv2IptvConsumer {
91 DataSyncMsg.MsgData msgData1 = new DataSyncMsg.MsgData(); 80 DataSyncMsg.MsgData msgData1 = new DataSyncMsg.MsgData();
92 81
93 if (StringUtils.isNotBlank(platformAccount)) { 82 if (StringUtils.isNotBlank(platformAccount)) {
94 MemberDTO memberDTO = this.userTvService.findMemberByPlatformAccount(platformAccount); 83 UserTvDTO userTvDTO = this.userTvService.findByPlatformAccount(platformAccount);
95 Long memberId = memberDTO.getId(); 84 String priorityMemberCode = userTvDTO.getPriorityMemberCode();
96 String memberCode = memberDTO.getCode(); 85 String memberCode = "";
86 if (StringUtils.isNotBlank(priorityMemberCode)) {
87 memberCode = priorityMemberCode;
88 } else {
89 memberCode = this.memberService.findById(userTvDTO.getMemberId()).getCode();
90 }
91
92 if (StringUtils.isBlank(memberCode))
93 throw new EntityNotFoundException(MemberDTO.class, "memberCode", "memberCode is null");
94
97 msgData1.setMemberCode(memberCode); 95 msgData1.setMemberCode(memberCode);
98 } 96 }
99 97
100 msgData1.setEvent(8); 98 msgData1.setEvent(8);
101 msgData1.setDeviceType(deviceType); 99 msgData1.setDeviceType(deviceType);
102 msgData1.setMediaId(mediaId); 100 msgData1.setMediaId(mediaId);
103 JSONObject jsonObject = new JSONObject(); 101
104 jsonObject.put("mediaId", mediaId); 102 JSONObject param = new JSONObject();
105 jsonObject.put("mediaName", mediaName); 103 param.put("playDuration", playDuration);
106 jsonObject.put("playDuration", playDuration); 104 msgData1.setParam(JSON.toJSONString(param));
107 jsonObject.put("mediaCode", mediaCode); 105 JSONObject description = new JSONObject();
108 jsonObject.put("time", time); 106 description.put("mediaId", mediaId);
109 msgData1.setDescription(JSON.toJSONString(jsonObject)); 107 description.put("mediaName", mediaName);
108 description.put("playDuration", playDuration);
109 description.put("mediaCode", mediaCode);
110 description.put("time", time);
111 msgData1.setDescription(JSON.toJSONString(description));
110 112
111 dataSyncMsg.setMsg(msgData1); 113 dataSyncMsg.setMsg(msgData1);
112 return dataSyncMsg; 114 return dataSyncMsg;
......