Commit 6e65ab83 6e65ab83cdce522d9b156f72d3a72f6f0cc3c3fd by xianghan

1.优化任务处理执行

2.为任务处理添加缓存
1 parent 2ce05838
Showing 29 changed files with 306 additions and 492 deletions
......@@ -3,6 +3,9 @@ package com.topdraw.business.module.exp.detail.repository;
import com.topdraw.business.module.exp.detail.domain.ExpDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.Optional;
......@@ -13,4 +16,15 @@ import java.util.Optional;
public interface ExpDetailRepository extends JpaRepository<ExpDetail, Long>, JpaSpecificationExecutor<ExpDetail> {
Optional<ExpDetail> findFirstByCode(String code);
@Modifying
@Query(value = "INSERT INTO `uc_exp_detail`(`code`, `member_id`, `account_id`, `original_exp`, `result_exp`, `exp`, " +
"`device_type`, `evt_type`, `order_id`, `media_id`, `activity_id`, `description`, `app_code`, `create_time`, `update_time`)\n" +
" VALUES (:#{#resources.code}, :#{#resources.memberId}, :#{#resources.accountId}, :#{#resources.originalExp}, " +
" :#{#resources.resultExp}, :#{#resources.exp}, :#{#resources.deviceType}, :#{#resources.evtType}, " +
" :#{#resources.orderId}, :#{#resources.mediaId}, :#{#resources.activityId}, '#', NULL, now(), now())", nativeQuery = true)
void insertIntoExpDetail(@Param("resources") ExpDetail expDetail);
}
......
......@@ -44,7 +44,7 @@ public class ExpDetailServiceImpl implements ExpDetailService {
@Transactional(rollbackFor = Exception.class)
public void create(ExpDetail resources) {
ExpDetail expDetail = ExpDetailBuilder.build(resources);
this.expDetailRepository.save(expDetail);
this.expDetailRepository.insertIntoExpDetail(expDetail);
}
@Override
......
......@@ -15,5 +15,5 @@ public interface MemberLevelRepository extends JpaRepository<MemberLevel, Long>,
Optional<MemberLevel> findFirstByCode(String code);
List<MemberLevel> findByLevelAndStatus(Integer level, Integer status);
Optional<MemberLevel> findByLevelAndStatus(Integer level, Integer status);
}
......
......@@ -25,12 +25,9 @@ public interface MemberLevelService {
MemberLevelDTO getByCode(String code);
/**
* 通过等级和状态检索
*
* @param i
* @param status
* @return
*/
List<MemberLevelDTO> findLevelAndStatus(Integer i, Integer status);
MemberLevelDTO findByLevel(int i);
}
......
......@@ -31,6 +31,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
private MemberLevelMapper memberLevelMapper;
@Override
@Transactional(readOnly = true)
public MemberLevelDTO findById(Long id) {
MemberLevel MemberLevel = this.memberLevelRepository.findById(id).orElseGet(MemberLevel::new);
ValidationUtil.isNull(MemberLevel.getId(),"MemberLevel","id",id);
......@@ -38,15 +39,18 @@ public class MemberLevelServiceImpl implements MemberLevelService {
}
@Override
@Transactional(readOnly = true)
public MemberLevelDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? this.memberLevelMapper.toDto(this.memberLevelRepository.findFirstByCode(code).orElseGet(MemberLevel::new))
: new MemberLevelDTO();
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberLevelByLevel, key = "#level", unless = "#result.size() == 0")
public List<MemberLevelDTO> findLevelAndStatus(Integer level, Integer status) {
return this.memberLevelMapper.toDto(this.memberLevelRepository.findByLevelAndStatus(level, status));
@Transactional(readOnly = true)
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberLevelByLevel, key = "#level", unless = "#result.id == null")
public MemberLevelDTO findByLevel(int level) {
MemberLevel memberLevel = this.memberLevelRepository.findByLevelAndStatus(level, 1).orElseGet(MemberLevel::new);
return this.memberLevelMapper.toDto(memberLevel);
}
}
......
......@@ -30,20 +30,16 @@ public interface MemberRepository extends JpaRepository<Member, Long>, JpaSpecif
void updateUserIptvIdById(Long id, Long userIptvId, LocalDateTime now);
@Modifying
@Query(value = "UPDATE `uc_member` SET `exp` = :#{#resources.exp}, " +
"`level` = :#{#resources.level} , `update_time`= now() " +
@Query(value = "UPDATE `uc_member` SET `exp` = :#{#resources.exp}, `level` = :#{#resources.level} , `update_time`= now() " +
" WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer updateExpAndLevel(@Param("resources") Member member);
@Modifying
@Query(value = "UPDATE `uc_member` SET `points` = :#{#resources.points}, " +
"`due_points` = :#{#resources.duePoints} , `update_time`= now() " +
" WHERE `id` = :#{#resources.id}", nativeQuery = true)
@Query(value = "UPDATE `uc_member` SET `points` = :#{#resources.points}, `update_time`= now() WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer updatePointAndDuePoint(@Param("resources") Member resources);
@Modifying
@Query(value = "UPDATE `uc_member` SET `coupon_amount` = :#{#resources.couponAmount}, " +
"`due_coupon_amount` = :#{#resources.dueCouponAmount} , `update_time`= now() " +
@Query(value = "UPDATE `uc_member` SET `coupon_amount` = :#{#resources.couponAmount}, `due_coupon_amount` = :#{#resources.dueCouponAmount} , `update_time`= now() " +
" WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer doUpdateMemberCoupon(@Param("resources") Member member);
......@@ -52,20 +48,20 @@ public interface MemberRepository extends JpaRepository<Member, Long>, JpaSpecif
Optional<Member> findByPlatformAccount(String platformAccount);
@Modifying
@Query(value = "UPDATE `uc_member` SET `vip` = :#{#resources.vip}, " +
"`vip_expire_time` = :#{#resources.vipExpireTime} , `update_time`= now() " +
@Query(value = "UPDATE `uc_member` SET `vip` = :#{#resources.vip}, `vip_expire_time` = :#{#resources.vipExpireTime} , `update_time`= now() " +
" WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer updateMemberVipAndVipExpireTime(@Param("resources") Member member);
@Modifying
@Query(value = "UPDATE `uc_member` SET `user_iptv_id` = :#{#resources.userIptvId}, `update_time` = now() , " +
" `bind_iptv_platform_type`= :#{#resources.bindIptvPlatformType}, " +
@Query(value = "UPDATE `uc_member` SET `user_iptv_id` = :#{#resources.userIptvId}, `update_time` = now() , `bind_iptv_platform_type`= :#{#resources.bindIptvPlatformType}, " +
" `bind_iptv_time`=:#{#resources.bindIptvTime} WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer updateMemberUserIptvIdAndBindIptvPlatformAndBindIptvTime(@Param("resources") Member member);
@Modifying
@Query(value = "UPDATE `uc_member` SET `avatar_url` = :#{#resources.avatarUrl}, `update_time` = now() , " +
" `nickname`= :#{#resources.nickname}, " +
@Query(value = "UPDATE `uc_member` SET `avatar_url` = :#{#resources.avatarUrl}, `update_time` = now() , `nickname`= :#{#resources.nickname}, " +
" `gender`=:#{#resources.gender} WHERE `id` = :#{#resources.id}", nativeQuery = true)
Integer updateMemberAvatarUrlAndNicknameAndGender(@Param("resources") Member resource);
@Query(value = "SELECT IFNULL(`exp`,0) AS exp FROM uc_member WHERE `id` = ?1 ", nativeQuery = true)
Long findExpByMemberId(Long memberId);
}
......
......@@ -65,7 +65,7 @@ public interface MemberService {
* 修改会员积分
* @param member 会员
*/
MemberDTO doUpdateMemberPoints(Member member);
Integer doUpdateMemberPoints(Member member);
/**
* 查询绑定了大屏会员列表
......@@ -92,14 +92,14 @@ public interface MemberService {
* @param resources
* @return
*/
MemberDTO doUpdateMemberExpAndLevel(Member resources);
Integer doUpdateMemberExpAndLevel(Member resources);
/**
*
* @param member
* @return
*/
MemberDTO doUpdateMemberCoupon(Member member);
Integer doUpdateMemberCoupon(Member member);
/**
*
......@@ -127,4 +127,12 @@ public interface MemberService {
* @param member
*/
MemberDTO doUpdateMemberAvatarUrlAndNicknameAndGender(Member member);
/**
*
* @param memberId
* @return
*/
Long findExpByMemberId(Long memberId);
}
......
package com.topdraw.business.module.member.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.domain.MemberBuilder;
import com.topdraw.business.module.member.domain.MemberSimple;
......@@ -16,6 +18,7 @@ import com.topdraw.business.module.member.service.mapper.MemberSimpleMapper;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.exception.BadRequestException;
import com.topdraw.exception.GlobeExceptionMsg;
import com.topdraw.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
......@@ -48,6 +51,9 @@ public class MemberServiceImpl implements MemberService {
@Autowired
private MemberSimpleMapper memberSimpleMapper;
@Autowired
private RedisUtils redisUtils;
@Override
@Transactional(readOnly = true)
public String findCodeById(Long id) {
......@@ -57,7 +63,7 @@ public class MemberServiceImpl implements MemberService {
@Override
@Transactional(readOnly = true)
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberById, key = "#id")
// @Cacheable(cacheNames = RedisKeyConstants.cacheMemberById, key = "#id")
public MemberDTO findById(Long id) {
Member member = this.memberRepository.findById(id).orElseGet(Member::new);
return this.memberMapper.toDto(member);
......@@ -66,9 +72,19 @@ public class MemberServiceImpl implements MemberService {
@Override
@Transactional(readOnly = true)
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberSimpleById, key = "#id", unless = "#result.id == null")
public MemberSimpleDTO findSimpleById(Long id) {
return this.memberSimpleMapper.toDto(this.memberSimpleRepository.findSimpleById(id).orElseGet(MemberSimple::new));
Object memberSimpleRedis = this.redisUtils.get(RedisKeyConstants.cacheMemberSimpleById + "::" + id);
if (Objects.nonNull(memberSimpleRedis)) {
return JSONObject.parseObject(JSON.toJSONString(memberSimpleRedis), MemberSimpleDTO.class);
}
MemberSimple memberSimple = this.memberSimpleRepository.findSimpleById(id).orElseGet(MemberSimple::new);
if (Objects.nonNull(memberSimple.getId())) {
MemberSimpleDTO memberSimpleDTO = new MemberSimpleDTO();
BeanUtils.copyProperties(memberSimple, memberSimpleDTO);
this.redisUtils.set(RedisKeyConstants.cacheMemberSimpleById + "::" + id, memberSimpleDTO);
}
return this.memberSimpleMapper.toDto(memberSimple);
}
@Override
......@@ -80,7 +96,7 @@ public class MemberServiceImpl implements MemberService {
@Override
@Transactional(readOnly = true)
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberSimpleById, key = "#id", unless = "#result.id == null")
@Cacheable(cacheNames = RedisKeyConstants.cacheMemberSimpleByCode, key = "#code", unless = "#result.id == null")
public MemberSimpleDTO findSimpleByCode(String code) {
return this.memberSimpleMapper.toDto(this.memberSimpleRepository.findSimpleByCode(code).orElseGet(MemberSimple::new));
}
......@@ -118,46 +134,15 @@ public class MemberServiceImpl implements MemberService {
@Override
@Transactional(rollbackFor = Exception.class)
@CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#resource.code")
public MemberDTO doUpdateMemberExpAndLevel(Member resource) {
try {
// this.redisUtils.doLock(RedisKeyConstants.updateCacheMemberById + resource.getId());
Integer count = this.memberRepository.updateExpAndLevel(resource);
if (Objects.nonNull(count) && count > 0) {
Member member = this.memberRepository.findById(resource.getId()).orElseGet(Member::new);
return this.memberMapper.toDto(member);
}
} catch (Exception e) {
log.info("修改会员优惠券,"+e.getMessage());
} finally {
// this.redisUtils.doUnLock(RedisKeyConstants.updateCacheMemberById + resource.getId());
}
return this.memberMapper.toDto(resource);
public Integer doUpdateMemberExpAndLevel(Member resource) {
return this.memberRepository.updateExpAndLevel(resource);
}
@Override
@Transactional(rollbackFor = Exception.class)
@CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#resource.code")
public MemberDTO doUpdateMemberCoupon(Member resource) {
log.info("修改会员优惠券 =>> {}", resource);
try {
// this.redisUtils.doLock(RedisKeyConstants.updateCacheMemberById + resource.getId());
Integer count = this.memberRepository.doUpdateMemberCoupon(resource);
if (Objects.nonNull(count) && count > 0) {
Member member = this.memberRepository.findById(resource.getId()).orElseGet(Member::new);
return this.memberMapper.toDto(member);
}
} catch (Exception e) {
log.info("修改会员优惠券,"+e.getMessage());
} finally {
// this.redisUtils.doUnLock(RedisKeyConstants.updateCacheMemberById + resource.getId());
}
return this.memberMapper.toDto(resource);
// @CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#resource.code")
public Integer doUpdateMemberCoupon(Member resource) {
return this.memberRepository.doUpdateMemberCoupon(resource);
}
@Override
......@@ -237,6 +222,12 @@ public class MemberServiceImpl implements MemberService {
return this.memberMapper.toDto(resource);
}
@Override
@Transactional(readOnly = true)
public Long findExpByMemberId(Long memberId) {
return this.memberRepository.findExpByMemberId(memberId);
}
@Override
@Transactional(rollbackFor = Exception.class)
......@@ -286,24 +277,8 @@ public class MemberServiceImpl implements MemberService {
@Override
@Transactional(rollbackFor = Exception.class)
@CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#resources.code")
public MemberDTO doUpdateMemberPoints(Member resources) {
try {
// this.redisUtils.doLock(RedisKeyConstants.updateCacheMemberById + resources.getId());
Integer count = this.memberRepository.updatePointAndDuePoint(resources);
if (Objects.nonNull(count) && count > 0) {
Member member = this.memberRepository.findById(resources.getId()).orElseGet(Member::new);
return this.memberMapper.toDto(member);
}
} catch (Exception e) {
log.info(e.getMessage());
} finally {
// this.redisUtils.doUnLock(RedisKeyConstants.updateCacheMemberById + resources.getId());
}
return this.memberMapper.toDto(resources);
public Integer doUpdateMemberPoints(Member resources) {
return this.memberRepository.updatePointAndDuePoint(resources);
}
}
......
......@@ -88,6 +88,10 @@ public class PointsDetail implements Serializable {
@Column(name = "item_id")
private Long itemId;
// 状态:0:异常;1:正常
@Column(name = "status")
private Long status;
// 创建时间
@CreatedDate
@Column(name = "create_time")
......
......@@ -3,6 +3,9 @@ package com.topdraw.business.module.points.detail.repository;
import com.topdraw.business.module.points.detail.domain.PointsDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
......@@ -16,4 +19,14 @@ public interface PointsDetailRepository extends JpaRepository<PointsDetail, Long
Optional<PointsDetail> findFirstByCode(String code);
List<PointsDetail> findByMemberId(Long memberId);
@Modifying
@Query(value = "INSERT INTO `uc_points_detail`(`code`, `app_code`, `member_id`, `account_id`, `original_points`, `result_points`, " +
" `points`, `device_type`, `evt_type`, `order_id`, `media_id`, `activity_id`, `item_id`, `status`, `description`, `create_time`, `update_time`)" +
" VALUES (:#{#resources.code}, :#{#resources.appCode}, :#{#resources.memberId}, :#{#resources.accountId}," +
" :#{#resources.originalPoints}, :#{#resources.resultPoints}, :#{#resources.points}, :#{#resources.deviceType}," +
" :#{#resources.evtType}, :#{#resources.orderId}, :#{#resources.mediaId}, :#{#resources.activityId}, " +
" :#{#resources.itemId}, :#{#resources.status}, :#{#resources.description}, now(), now())", nativeQuery = true)
Integer insertPointsDetail(@Param("resources") PointsDetail pointsDetail);
}
......
......@@ -46,13 +46,6 @@ public interface PointsDetailService {
PointsDetailDTO getByCode(String code);
/**
*
* @param memberId
* @return
*/
List<PointsDetailDTO> loadListExpirePointsByMemberId(Long memberId);
/**
* 已过期的积分
* @param memberId
* @return
......@@ -63,5 +56,5 @@ public interface PointsDetailService {
*
* @param pointsDetail
*/
void create4Custom(PointsDetail pointsDetail);
void insertPointsDetail(PointsDetail pointsDetail);
}
......
......@@ -54,6 +54,9 @@ public class PointsDetailDTO implements Serializable {
// 积分变化描述,用于管理侧显示
private String description;
// 状态:0:异常;1:正常
private Long status;
// 商品id
private Long itemId;
......
......@@ -31,6 +31,7 @@ public class PointsDetailServiceImpl implements PointsDetailService {
private PointsDetailMapper pointsDetailMapper;
@Override
@Transactional(readOnly = true)
public PointsDetailDTO findById(Long id) {
PointsDetail pointsDetail = this.pointsDetailRepository.findById(id).orElseGet(PointsDetail::new);
ValidationUtil.isNull(pointsDetail.getId(),"PointsDetail","id",id);
......@@ -40,8 +41,7 @@ public class PointsDetailServiceImpl implements PointsDetailService {
@Override
@Transactional(rollbackFor = Exception.class)
public PointsDetailDTO create(PointsDetail resources) {
PointsDetail pointsDetail = this.pointsDetailRepository.save(resources);
return this.pointsDetailMapper.toDto(pointsDetail);
return this.pointsDetailMapper.toDto(this.pointsDetailRepository.save(resources));
}
@Override
......@@ -65,17 +65,14 @@ public class PointsDetailServiceImpl implements PointsDetailService {
@Override
@Transactional(readOnly = true)
public PointsDetailDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? this.pointsDetailMapper.toDto(this.pointsDetailRepository.findFirstByCode(code).orElseGet(PointsDetail::new))
: new PointsDetailDTO();
}
@Override
public List<PointsDetailDTO> loadListExpirePointsByMemberId(Long memberId) {
return null;
}
@Override
@Transactional(readOnly = true)
public List<PointsDetailDTO> findByMemberId(Long memberId) {
return Objects.nonNull(memberId)?
this.pointsDetailMapper.toDto(this.pointsDetailRepository.findByMemberId(memberId))
......@@ -83,7 +80,8 @@ public class PointsDetailServiceImpl implements PointsDetailService {
}
@Override
public void create4Custom(PointsDetail pointsDetail) {
this.pointsDetailRepository.save(pointsDetail);
@Transactional(rollbackFor = Exception.class)
public void insertPointsDetail(PointsDetail pointsDetail) {
this.pointsDetailRepository.insertPointsDetail(pointsDetail);
}
}
......
......@@ -96,11 +96,14 @@ public class TrTaskProgressServiceImpl implements TrTaskProgressService {
if (Objects.isNull(taskId)) {
continue;
}
finishTasks.put(Long.valueOf(taskId.toString()), Integer.valueOf(map.get("finishCount").toString()));
finishTasks.put(taskId, Integer.valueOf(map.get("finishCount").toString()));
}
if (finishTasks.size() > 0) {
// 总记录一直存储
this.redisUtils.hmset(RedisKeyConstants.cacheTotalFinishTaskCount + "::" + memberId, finishTasks);
}
return finishTasks;
}
}
......@@ -113,7 +116,6 @@ public class TrTaskProgressServiceImpl implements TrTaskProgressService {
Map<Object, Object> hmget = this.redisUtils.hmget(RedisKeyConstants.cacheTodayFinishTaskCount + "::" + memberId + ":" + todayStart);
if (Objects.isNull(hmget)) {
List<Map<String, Object>> maps = this.trTaskProgressRepository.countFinishTaskGroupByMemberIdAndToday(memberId, todayStart);
if (!CollectionUtils.isEmpty(maps)){
Map<Object, Object> finishTasks = new HashMap<>();
......@@ -123,16 +125,20 @@ public class TrTaskProgressServiceImpl implements TrTaskProgressService {
continue;
}
finishTasks.put(Long.valueOf(taskId.toString()), Integer.valueOf(map.get("finishCount").toString()));
finishTasks.put(taskId, Integer.valueOf(map.get("finishCount").toString()));
}
if (finishTasks.size() > 0) {
// 单天的记录只存储一天
this.redisUtils.hmset(RedisKeyConstants.cacheTodayFinishTaskCount + "::" + memberId + ":" + LocalDate.now(), finishTasks, 24*60*60);
}
return finishTasks;
}
}
return hmget;
}
......
package com.topdraw.business.module.task.service.impl;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.topdraw.business.module.task.domain.Task;
import com.topdraw.business.module.task.repository.TaskRepository;
import com.topdraw.business.module.task.service.TaskService;
......@@ -10,6 +11,7 @@ import com.topdraw.config.RedisKeyConstants;
import com.topdraw.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
......@@ -77,10 +79,25 @@ public class TaskServiceImpl implements TaskService {
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.cacheTaskByEventAndMemberLevelAndVip, key = "#event+':'+#level+':'+#vip",
unless = "#result.size() == 0")
@Transactional(readOnly = true)
public List<Task> findByEventAndMemberLevelAndVip(Integer event, Integer level, Integer vip) {
List<Task> tasks = this.taskRepository.findByEvent(event, level, vip);
return Objects.nonNull(event) ? tasks : new ArrayList<>();
try {
boolean b = this.redisUtils.hasKey(RedisKeyConstants.cacheTaskByEventAndMemberLevelAndVip + "::" + event + ":" + level + ":" + vip);
if (b) {
List<Object> tasksObjs = redisUtils.lGet(RedisKeyConstants.cacheTaskByEventAndMemberLevelAndVip + "::" + event + ":" + level + ":" + vip, 0, -1);
return JSONArray.parseArray(tasksObjs.get(0).toString(), Task.class);
}
List<Task> tasks = this.taskRepository.findByEvent(event, level, vip);
if (!CollectionUtils.isEmpty(tasks)) {
this.redisUtils.lSet(RedisKeyConstants.cacheTaskByEventAndMemberLevelAndVip + "::" + event + ":" + level + ":" + vip, tasks, 45 * 60);
}
return tasks;
} catch (Exception e) {
log.error(e.getMessage());
}
return new ArrayList<>();
}
}
......
......@@ -45,6 +45,10 @@ public class UserTvSimple extends AsyncMqModule implements Serializable {
@Column(name = "priority_member_code")
private String priorityMemberCode;
/** 绑定的小屏账户会员编码 */
@Column(name = "platform_account")
private String platformAccount;
public void copy(UserTvSimple source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(false));
}
......
......@@ -12,7 +12,6 @@ import org.springframework.data.jpa.repository.Query;
*/
public interface UserTvSimpleRepository extends JpaRepository<UserTvSimple, Long>, JpaSpecificationExecutor<UserTvSimple> {
@Query(value = "SELECT `id`, `vis_user_id` , `member_id` , " +
" `priority_member_code` FROM `uc_user_tv` WHERE `platform_account` = ?1", nativeQuery = true)
@Query(value = "SELECT `id`, `vis_user_id` , `member_id` , `platform_account`, `priority_member_code` FROM `uc_user_tv` WHERE `platform_account` = ?1", nativeQuery = true)
UserTvSimple findSimpleByPlatformAccount(String platformAccount);
}
......
package com.topdraw.business.module.user.iptv.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.module.member.service.MemberService;
......@@ -209,12 +210,12 @@ public class UserTvServiceImpl implements UserTvService {
UserTvSimple userTvSimple = this.userTvSimpleRepository.findSimpleByPlatformAccount(platformAccount);
if (Objects.nonNull(userTvSimple)) {
HashMap hashMap = JSONObject.parseObject(userTvSimple.toString(), HashMap.class);
this.redisUtils.set(RedisKeyConstants.cacheVisUserByPlatformAccount + "::" + platformAccount, hashMap);
JSONObject userTvSimpleJSON = JSONObject.parseObject(JSON.toJSONString(userTvSimple), JSONObject.class);
this.redisUtils.set(RedisKeyConstants.cacheVisUserByPlatformAccount + "::" + platformAccount, userTvSimpleJSON);
return this.userTvSimpleMapper.toDto(userTvSimple);
}
return null;
return this.userTvSimpleMapper.toDto(userTvSimple);
}
@Override
......
......@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
......@@ -45,8 +46,7 @@ public class ExpOperationController {
log.error("发放成长值失败,参数错误,成长值为空或者小于0 ==>> {}", rewardExp);
return ResultInfo.failure("发放成长值失败,参数错误,成长值为空或者小于0");
}
List<TempExp> tempExpList = Arrays.asList(tempExp);
this.expOperationService.grantExpByManual(tempExpList);
this.expOperationService.grantExpByManual(Collections.singletonList(tempExp));
return ResultInfo.success();
}
......
......@@ -18,14 +18,6 @@ public interface ExpOperationService {
void grantExpThroughTempExp( List<TempExp> tempExpList);
/**
* 系统手动发放优惠券
* @param memberId
* @param userId
* @param tempExpList
*/
void grantExpByManual(Long memberId,Long userId ,List<TempExp> tempExpList);
/**
*
* @param tempExpList
*/
......
......@@ -101,17 +101,18 @@ public class CouponOperationServiceImpl implements CouponOperationService {
try {
this.redisUtils.doLock(RedisKeyConstants.updateCacheCouponByMemberId + memberId.toString());
// 1.历史总优惠券数量
Long historyCouponCount = this.getTotalHistoryCoupon(memberId);
Long historyCouponCount = this.couponHistoryService.countByUserId(memberId);
// 1.当前总优惠券数量
Long totalCouponCount = this.getTotalCoupon(historyCouponCount, rightsAmount);
Long totalCouponCount = (Objects.nonNull(historyCouponCount) ? historyCouponCount: 0L) + (Objects.nonNull(rightsAmount) ? rightsAmount: 0L);
// 2.获取已过期的优惠券数量
Long expireCouponCount = this.getTotalExpireCoupon(memberId);
Long expireCouponCount = this.couponHistoryService.countByUserIdAndExpireTimeBefore(memberId, LocalDateTime.now());
// 3.即将过期的优惠券数量
Long expireSoonCouponCount = this.getTotalExpireSoonCoupon(memberId, EXPIRE_FACTOR_DAY);
Long expireSoonCouponCount = this.couponHistoryService.countByUserIdAndExpireTimeBetween(memberId, LocalDateTime.now(),LocalDateTime.now().plusDays(EXPIRE_FACTOR_DAY));
// 4.当前优惠券数量 = 总优惠券-已过期的优惠券
Long currentCoupon = this.getCurrentCoupon(totalCouponCount, expireCouponCount);
Long currentCoupon = (Objects.nonNull(totalCouponCount)?totalCouponCount:0L)-(Objects.nonNull(expireCouponCount)?expireCouponCount:0L);
// 5.更新用户信息(优惠券数量、即将过期的优惠券数量)
this.doUpdateMemberInfo(memberId,currentCoupon,expireSoonCouponCount);
} catch (Exception e) {
log.error(e.getMessage());
} finally {
......@@ -119,11 +120,6 @@ public class CouponOperationServiceImpl implements CouponOperationService {
}
}
private Long getTotalCoupon(Long historyCouponCount, Integer rightsAmount) {
return (Objects.nonNull(historyCouponCount) ? historyCouponCount: 0L) + (Objects.nonNull(rightsAmount) ? rightsAmount: 0L);
}
/**
* 更新当前用户优惠券信息
* @param memberId
......@@ -141,9 +137,10 @@ public class CouponOperationServiceImpl implements CouponOperationService {
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberCoupon(member);
/*this.threadPoolTaskExecutor.submit(() -> {
// ((CouponOperationServiceImpl) AopContext.currentProxy()).asyncMemberCoupon(member);
this.threadPoolTaskExecutor.submit(() -> {
((CouponOperationServiceImpl) AopContext.currentProxy()).asyncMemberCoupon(member);
});*/
});
}
private MemberDTO findMemberByMemberId(Long memberId) {
......@@ -171,27 +168,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
*/
private Long getTotalExpireSoonCoupon(Long userId, Integer expireFactor) {
LocalDateTime expireTime = LocalDateTime.now().plusDays(expireFactor);
return this.couponHistoryService.countByUserIdAndExpireTimeBetween(userId,LocalDateTime.now(),expireTime);
}
/**
* 获取已过期的优惠券数量
* @param userId
* @return
*/
private Long getTotalExpireCoupon(Long userId) {
return this.couponHistoryService.countByUserIdAndExpireTimeBefore(userId, LocalDateTime.now());
}
/**
* 获取用户领取的总优惠券
* @param userId
* @return
*/
private Long getTotalHistoryCoupon(Long userId) {
return this.couponHistoryService.countByUserId(userId);
return this.couponHistoryService.countByUserIdAndExpireTimeBetween(userId,LocalDateTime.now(),LocalDateTime.now().plusDays(expireFactor));
}
......
......@@ -7,12 +7,11 @@ import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.level.service.MemberLevelService;
import com.topdraw.business.module.member.level.service.dto.MemberLevelDTO;
import com.topdraw.business.module.member.service.MemberService;
import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import com.topdraw.business.process.service.ExpOperationService;
import com.topdraw.business.process.service.member.MemberOperationService;
import com.topdraw.business.process.domian.TempExp;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.RedisUtils;
import com.topdraw.utils.StringUtils;
......@@ -22,10 +21,10 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
*
......@@ -56,126 +55,88 @@ public class ExpOperationServiceImpl implements ExpOperationService {
@Override
public void grantExpThroughTempExp(List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
this.refresh(tempExpList);
}
@Override
public void grantExpByManual(Long memberId, Long userId, List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
}
@Override
public void grantExpByManual(List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
this.refresh(tempExpList);
}
/**
*
* @param tempExp
* @param tempExps
*/
private void refresh(TempExp tempExp) {
private void refresh(List<TempExp> tempExps) {
TempExp _tempExp = tempExps.get(0);
try {
this.redisUtils.doLock(RedisKeyConstants.updateCacheExpByMemberId + tempExp.getMemberId());
this.redisUtils.doLock(RedisKeyConstants.updateCacheExpByMemberId + _tempExp.getMemberId());
// 原始经验值
long l = System.currentTimeMillis();
long originExp = this.getExpByMemberId(tempExp);
long l1 = System.currentTimeMillis();
log.info("----获取会员当前原始经验值 ==>> {}, 总耗时 -->> {}", originExp, (l1-l));
// 总经验值
// TODO
long totalExp = this.calculateTotalExp(originExp, tempExp);
log.info("----计算总经验值 ==>> {}", totalExp);
long originExp = this.memberService.findExpByMemberId(_tempExp.getMemberId());
log.info("----获取会员当前原始经验值 ==>> {}", originExp);
long totalExp = originExp;
for (TempExp exp : tempExps) {
// 总经验值
totalExp = this.doInsertExpDetail(exp, totalExp, (exp.getRewardExp()+totalExp));
log.info("----保存经验值历史 -->>{}", totalExp);
}
// 2.更新成长值与等级
long l2 = System.currentTimeMillis();
this.refreshMemberExpAndLevel(tempExp, totalExp);
long l3 = System.currentTimeMillis();
log.info("----更新会员经验值与对应等级 ==>> {}, 总耗时 ==>> {}", totalExp, (l3-l2));
long l4 = System.currentTimeMillis();
this.doInsertExpDetail(tempExp, originExp, totalExp);
long l5 = System.currentTimeMillis();
log.info("----保存经验值历史 -->> 总耗时 -->> {}", (l5-l4));
this.refreshMemberExpAndLevel(_tempExp, totalExp);
log.info("----更新会员经验值与对应等级 ==>> {}", totalExp);
} catch (Exception e) {
log.error("成长值发放失败,{}",e.getMessage());
} finally {
this.redisUtils.doUnLock(RedisKeyConstants.updateCacheExpByMemberId + tempExp.getMemberId());
this.redisUtils.doUnLock(RedisKeyConstants.updateCacheExpByMemberId + _tempExp.getMemberId());
}
}
private long calculateTotalExp(long originalExp, TempExp tempExp) {
Long rewardExp = tempExp.getRewardExp();
return rewardExp + originalExp;
}
/**
*
* @param tempExp
* @return
*/
private long getExpByMemberId(TempExp tempExp) {
Long memberId = tempExp.getMemberId();
MemberDTO memberDTO = this.memberService.findById(memberId);
if (Objects.nonNull(memberDTO.getId())) {
Long exp = memberDTO.getExp();
return Objects.isNull(exp) ? 0L : exp;
}
return 0L;
}
/**
* 更新成长值与等级
*
* @param tempExp 成长值列表
*/
private void refreshMemberExpAndLevel(TempExp tempExp,long totalExp) {
private void refreshMemberExpAndLevel(TempExp tempExp, long totalExp) {
Integer memberLevel = tempExp.getMemberLevel();
Long memberId = tempExp.getMemberId();
String memberCode = tempExp.getMemberCode();
// 2.获取下一级需要的成长值
// TODO 需要缓存
MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberLevel + 1, 1);
MemberLevelDTO memberLevelDTO = this.memberLevelService.findByLevel(memberLevel + 1);
// 4.成长值比较,判断是否升级
Integer level = this.compareExp(totalExp, memberLevelDTO, memberLevel);
// 5.更新用户信息
this.updateMemberInfo(level, totalExp, memberId);
}
/**
*
* @param level
* @param totalExp 总积分
* @param memberId 会员id
*/
private void updateMemberInfo(Integer level,Long totalExp,Long memberId) {
MemberDTO memberDTO = this.findMemberByMemberId(memberId);
// 5.更新用户信息
Member member = new Member();
member.setId(memberDTO.getId());
member.setCode(memberDTO.getCode());
member.setId(memberId);
member.setCode(memberCode);
member.setExp(totalExp);
member.setLevel(level);
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberExpAndLevel(member);
/*this.threadPoolTaskExecutor.submit(() -> {
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncMemberExpAndLevel(member);
});*/
}
private MemberDTO findMemberByMemberId(Long memberId) {
MemberDTO memberDTO = this.memberService.findById(memberId);
return memberDTO;
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncMemberExpAndLevel(member);
if (level > memberLevel) {
MemberSimpleDTO memberSimpleDTO = this.memberService.findSimpleById(memberId);
if (Objects.nonNull(memberLevelDTO.getId())) {
memberSimpleDTO.setLevel(level);
boolean result = this.redisUtils.set(RedisKeyConstants.cacheMemberSimpleById + "::" + memberId, memberSimpleDTO);
log.info("更新redis中会员等级 ==>> {} || 更新结果 ==>>{}", memberSimpleDTO, result);
}
}
}
private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO, Integer oldMemberLevel) {
if (Objects.nonNull(memberLevelDTO)) {
if (Objects.nonNull(memberLevelDTO.getId())) {
Long nextLevelExp = memberLevelDTO.getExpValue();
if (Objects.nonNull(nextLevelExp) && nextLevelExp > 0)
if(newExp - nextLevelExp >= 0){
......@@ -185,38 +146,18 @@ public class ExpOperationServiceImpl implements ExpOperationService {
return oldMemberLevel;
}
private MemberLevelDTO getNextLevelExp(Integer i,Integer status) {
List<MemberLevelDTO> memberLevelDTOList = this.memberLevelService.findLevelAndStatus(i, status);
if (!CollectionUtils.isEmpty(memberLevelDTOList)) {
return memberLevelDTOList.get(0);
}
return null;
}
/**
* 获取当前会员的成长值
* @param memberId 会员id
* @return Long 当前会员成长值
*/
private MemberDTO getMemberInfoByMemberId(Long memberId) {
MemberDTO memberDTO = this.memberOperationService.findById(memberId);
return memberDTO;
}
/**
* 添加成长值记录
*
* @param tempExp 成长值列表
*/
private void doInsertExpDetail(TempExp tempExp,long originalExp,long totalExp) {
private long doInsertExpDetail(TempExp tempExp, long originalExp, long totalExp) {
// 获得的积分
Long rewardExp = tempExp.getRewardExp();
ExpDetail expDetail = new ExpDetail();
BeanUtils.copyProperties(tempExp,expDetail);
expDetail.setCode(String.valueOf(IdWorker.generator()));
BeanUtils.copyProperties(tempExp, expDetail);
expDetail.setCode("expD_"+UUID.randomUUID().toString());
// 原始积分
expDetail.setOriginalExp(originalExp);
// 总积分
......@@ -228,9 +169,9 @@ public class ExpOperationServiceImpl implements ExpOperationService {
}
this.expDetailService.create(expDetail);
/*this.threadPoolTaskExecutor.submit(() -> {
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncExpDetail(expDetail);
});*/
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncExpDetail(expDetail);
return totalExp;
}
}
......
......@@ -8,26 +8,19 @@ import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.points.available.domain.PointsAvailable;
import com.topdraw.business.module.points.available.service.PointsAvailableService;
import com.topdraw.business.module.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.module.points.detail.detailhistory.service.PointsDetailHistoryService;
import com.topdraw.business.module.points.detail.domain.PointsDetail;
import com.topdraw.business.module.points.detail.service.PointsDetailService;
import com.topdraw.business.module.points.service.PointsService;
import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO;
import com.topdraw.business.process.service.dto.CustomPointsResult;
import com.topdraw.business.process.service.member.MemberOperationService;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.mq.producer.MessageProducer;
import com.topdraw.util.DateUtil;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.RedisUtils;
import com.topdraw.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -38,10 +31,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
......@@ -81,6 +71,10 @@ public class PointsOperationServiceImpl implements PointsOperationService {
@AsyncMqSend
public void asyncPointsDetail(PointsDetail pointsDetail) {}
/**
* uc-admin调用此接口进行发放积分
* @param tempPoints
*/
@Override
public void grantPointsByManualByTempPoints(TempPoints tempPoints) {
Timestamp expireTime = tempPoints.getExpireTime();
......@@ -88,7 +82,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
tempPoints.setExpireTime(TimestampUtil.localDateTime2Timestamp(DateUtil.getLastDateTimeSecondYear()));
}
this.refresh(tempPoints);
this.refresh(Arrays.asList(tempPoints));
}
/**
......@@ -106,6 +100,8 @@ public class PointsOperationServiceImpl implements PointsOperationService {
try {
this.redisUtils.doLock(RedisKeyConstants.cacheMemberById + memberId.toString());
MemberDTO memberDTO = this.memberService.findById(memberId);
//1.删除过期的积分
this.cleanInvalidAvailablePointsByMemberId(memberId);
log.info("删除过期的积分 ==>> cleanInvalidAvailablePointsByMemberId ==>> ");
......@@ -115,7 +111,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
long currentPoints = this.findAvailablePointsByMemberId(memberId);
if (b) {
// 2.可用积分表,按照过期时间进行升序排列
List<PointsAvailableDTO> pointsAvailableDTOS = this.findByMemberIdOrderByExpireTime(tempPoints);
List<PointsAvailableDTO> pointsAvailableDTOS = this.pointsAvailableService.findByMemberIdOrderByExpireTime(tempPoints.getMemberId());
// 2.优先使用即将过期的积分,累加到超过需兑换积分时,需要进行拆分
Map<String, List<PointsAvailableDTO>> customAvailablePointsMap =
this.customAvailablePoints(tempPoints, pointsAvailableDTOS);
......@@ -125,11 +121,10 @@ public class PointsOperationServiceImpl implements PointsOperationService {
// 4.更新可用积分表,超过的删除,剩余的新增
long totalPoints = this.doFreshTrPointsAvailableByAvailablePointsMap(customAvailablePointsMap, currentPoints);
// 5.即将过期的积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
// long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
// 6.更新会员积分信息
this.freshMemberCurrentPoints(memberId, totalPoints, soonExpirePoints);
this.freshMemberCurrentPoints(memberId, memberDTO.getCode(), totalPoints);
customPointsResult.setResult(true);
customPointsResult.setPoint(totalPoints);
......@@ -275,14 +270,6 @@ public class PointsOperationServiceImpl implements PointsOperationService {
return map;
}
/**
* 可用积分表,按照过期时间进行升序排列
* @param tempPoints
* @return
*/
private List<PointsAvailableDTO> findByMemberIdOrderByExpireTime(TempPoints tempPoints) {
return this.pointsAvailableService.findByMemberIdOrderByExpireTime(tempPoints.getMemberId());
}
/**
* 检查当前用户可用积分是否足够
......@@ -308,9 +295,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
@Override
@Transactional(rollbackFor = Exception.class)
public void grantPointsThroughTempPoint(List<TempPoints> tempPointsList){
for (TempPoints tempPoints : tempPointsList){
this.refresh(tempPoints);
}
this.refresh(tempPointsList);
}
/**
......@@ -372,7 +357,6 @@ public class PointsOperationServiceImpl implements PointsOperationService {
member.setPoints(currentPoints);
member.setDuePoints(soonExpirePoints);
// this.memberOperationService.update(member);
this.memberOperationService.doUpdateMemberPoints(member);
}
......@@ -416,7 +400,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
pointsDetail.setCreateTime(TimestampUtil.now());
pointsDetail.setUpdateTime(TimestampUtil.now());
pointsDetail.setMemberCode(memberDTO.getCode());
this.pointsDetailService.create4Custom(pointsDetail);
this.pointsDetailService.insertPointsDetail(pointsDetail);
log.info("asyncPointsDetail ==>> pointsDetail ==>> {}",pointsDetail);
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsDetail(pointsDetail);
......@@ -425,47 +409,39 @@ public class PointsOperationServiceImpl implements PointsOperationService {
/**
* 模板方法,提供更新积分的总体流程
*
* @param tempPoints 积分
* @param tempPointsList 积分
*/
private void refresh(TempPoints tempPoints) {
private void refresh(List<TempPoints> tempPointsList) {
TempPoints tempPoints = tempPointsList.get(0);
Long memberId = tempPoints.getMemberId();
String memberCode = tempPoints.getMemberCode();
log.info("----------->> 会员id ===>>>>" + memberId);
try {
this.redisUtils.doLock(RedisKeyConstants.updateCachePointsByMemberId + memberId.toString());
// 1.可用总积分
long l = System.currentTimeMillis();
Long currentPoints = this.findAvailablePointsByMemberId(memberId);
long l1 = System.currentTimeMillis();
// log.info("查询大屏信息,总耗时 ==>> {}", (l1-l));
log.info("----------->> 获取会员当前可用总积分 --->>>> {}, 总耗时 ==>> {}", currentPoints, (l1-l));
log.info("----------->> 获取会员当前可用总积分 --->>>> {}", currentPoints);
// 2.计算总积分
Long totalPoints = currentPoints + tempPoints.getPoints();
log.info("----------->> 总积分(可用总积分+获得的积分) --->>> {}", totalPoints);
Long totalPoints = currentPoints;
for (TempPoints tempPoint : tempPointsList) {
// 3.添加积分明细
totalPoints = this.doInsertTrPointsDetail(memberId, memberCode, tempPoint, totalPoints, (totalPoints + tempPoint.getPoints()));
log.info("----------->> 总积分(可用总积分+获得的积分) --->>> {}", totalPoints);
// 3.添加积分明细
long l2 = System.currentTimeMillis();
this.doInsertTrPointsDetail(memberId, memberCode, tempPoints, currentPoints, totalPoints);
long l3 = System.currentTimeMillis();
log.info("----------->> 添加积分明细 --->>> 总耗时 ==>> {}", (l3-l2));
// 4.添加可用积分
this.doInsertTrPointsAvailable(tempPoint);
log.info("----------->> 添加可用积分结束");
// 4.添加可用积分
long l4 = System.currentTimeMillis();
this.doInsertTrPointsAvailable(tempPoints);
long l5 = System.currentTimeMillis();
log.info("----------->> 添加可用积分 -->>> 总耗时 ==>> {}", (l5-l4));
}
// 5.即将过期的积分
// TODO 查询的时候再更新过期积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
log.info("----------->> 即将过期的积分 ------->>>>> {}", soonExpirePoints);
// long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
// log.info("----------->> 即将过期的积分 ------->>>>> {}", soonExpirePoints);
// 6.更新会员的总积分
long l6 = System.currentTimeMillis();
this.freshMemberCurrentPoints(memberId, totalPoints, soonExpirePoints);
long l7 = System.currentTimeMillis();
log.info("----------->> 更新会员的总积分 ------->>>>> 总积分--->>> {} -->>总耗时 ==>> {}", totalPoints, (l7-l6));
this.freshMemberCurrentPoints(memberId, memberCode, totalPoints);
log.info("----------->> 更新会员的总积分 ------->>>>> 总积分--->>> {}", totalPoints);
} catch (Exception e) {
log.error(" ==>> {}", e.getMessage());
} finally {
......@@ -474,20 +450,6 @@ public class PointsOperationServiceImpl implements PointsOperationService {
}
/**
* 获取总积分
* @param tempPoints
* @param currentPoints
* @return
*/
private Long calculateTotalPoints(TempPoints tempPoints, Long currentPoints) {
// 获取的积分
Long rewardPoints = tempPoints.getPoints();
// 总积分
Long totalPoints = currentPoints + tempPoints.getPoints();
return totalPoints;
}
/**
* 获取即将过期的积分
* @param memberId
* @return
......@@ -516,24 +478,18 @@ public class PointsOperationServiceImpl implements PointsOperationService {
/**
* 更新会员总积分
* @param memberId 会员Id
* @param currentPoints 当前总积分
* @param memberCode 当前总积分
*/
private void freshMemberCurrentPoints(Long memberId, Long currentPoints, long duePoints) {
MemberDTO memberDTO = this.memberService.findById(memberId);
private void freshMemberCurrentPoints(Long memberId, String memberCode, Long currentPoints) {
Member member = new Member();
member.setId(memberDTO.getId());
member.setCode(memberDTO.getCode());
member.setId(memberId);
member.setCode(memberCode);
member.setPoints(Objects.nonNull(currentPoints) ? currentPoints:0);
member.setDuePoints(duePoints);
member.setUpdateTime(TimestampUtil.now());
try {
this.memberOperationService.doUpdateMemberPoints(member);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncMemberPoint(member);
});*/
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncMemberPoint(member);
} catch (Exception e){
log.error("同步会员积分异常,"+e.getMessage());
}
......@@ -549,7 +505,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
BeanUtils.copyProperties(tempPoints,pointsAvailable);
String description = pointsAvailable.getDescription();
pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
pointsAvailable.setCode("pointsA_"+UUID.randomUUID().toString());
pointsAvailable.setDescription(StringUtils.isEmpty(description)?"#":description);
Timestamp timestamp = tempPoints.getExpireTime();
if (Objects.nonNull(timestamp)) {
......@@ -557,9 +513,9 @@ public class PointsOperationServiceImpl implements PointsOperationService {
}
this.pointsAvailableService.create4Custom(pointsAvailable);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsAvailable(pointsAvailable);
});*/
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsAvailable(pointsAvailable);
}
/**
......@@ -568,30 +524,34 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param tempPoints 积分
* @return Integer 总积分
*/
private void doInsertTrPointsDetail(Long memberId, String memberCode, TempPoints tempPoints, Long currentPoints, Long totalPoints){
private Long doInsertTrPointsDetail(Long memberId, String memberCode, TempPoints tempPoints, Long currentPoints, Long totalPoints){
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(tempPoints, pointsDetail);
pointsDetail.setId(null);
pointsDetail.setMemberId(memberId);
pointsDetail.setMemberCode(memberCode);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setCode("pointsD_"+UUID.randomUUID().toString());
pointsDetail.setPoints(tempPoints.getPoints());
pointsDetail.setOriginalPoints(currentPoints);
pointsDetail.setResultPoints(totalPoints);
pointsDetail.setCreateTime(null);
pointsDetail.setUpdateTime(null);
String description = pointsDetail.getDescription();
pointsDetail.setEvtType(tempPoints.getEvtType());
pointsDetail.setDeviceType(tempPoints.getDeviceType());
pointsDetail.setOrderId(tempPoints.getOrderId());
pointsDetail.setMediaId(tempPoints.getMediaId());
pointsDetail.setAccountId(tempPoints.getAccountId());
pointsDetail.setActivityId(tempPoints.getActivityId());
pointsDetail.setAppCode(tempPoints.getAppCode());
String description = tempPoints.getDescription();
if (StringUtils.isEmpty(description)) {
pointsDetail.setDescription("#");
}
// 保存积分流水
this.pointsDetailService.create4Custom(pointsDetail);
this.pointsDetailService.insertPointsDetail(pointsDetail);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsDetail(pointsDetail);
});*/
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsDetail(pointsDetail);
return totalPoints;
}
}
......
......@@ -21,12 +21,8 @@ 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.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 权益处理
......@@ -77,31 +73,7 @@ public class RightsOperationServiceImpl implements RightsOperationService {
@Override
public Integer grantRights(Map<RightType, Object> tempRightsMap) {
this.threadPoolTaskExecutor.execute(()-> {
// 2.创建权益历史对象
List<RightsHistory> rightsList = this.getRightHistory(tempRightsMap);
if (!CollectionUtils.isEmpty(rightsList)) {
// log.info("异步保存权益领取历史开始 ==>> [{}]", rightsList);
long l = System.currentTimeMillis();
// 3.保存权益历史
this.doInsertTrRightHistory(rightsList);
long l1 = System.currentTimeMillis();
log.info("保存权益历史,总耗时 ==>> {}", l1-l);
}
});
// 1.权益下发
return this.refresh(tempRightsMap);
}
/**
*
* @param tempRightsMap
* @return
*/
private List<RightsHistory> getRightHistory(Map<RightType, Object> tempRightsMap) {
List<TempRights> values = (List<TempRights>)tempRightsMap.get(RightType.RIGHTS);
List<RightsHistory> rightsHistoryList = new ArrayList<>();
if (!CollectionUtils.isEmpty(values)) {
values.forEach(value -> {
RightsHistory rightsHistory = new RightsHistory();
......@@ -111,11 +83,18 @@ public class RightsOperationServiceImpl implements RightsOperationService {
rightsHistory.setExpireTime(value.getExpireTime());
String memberCode = value.getMemberCode();
rightsHistory.setMemberCode(memberCode);
rightsHistoryList.add(rightsHistory);
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);
});
}
return rightsHistoryList;
// 1.权益下发
return this.refresh(tempRightsMap);
}
/**
......@@ -155,29 +134,22 @@ public class RightsOperationServiceImpl implements RightsOperationService {
*/
private Integer refresh(Map<RightType, Object> tempRightsMap) {
// Future<?> submit = this.threadPoolTaskExecutor.submit(() -> {
List<TempPoints> tempPointsList = (List<TempPoints>) tempRightsMap.get(RightType.POINTS);
if (!CollectionUtils.isEmpty(tempPointsList)) {
// log.info("发放积分开始 ==>> [{}]", tempPointsList);
long l = System.currentTimeMillis();
// 积分
log.info("发放积分开始 ==>> {}", tempPointsList);
this.grantPoint(tempPointsList);
long l2 = System.currentTimeMillis();
log.info("发放积分结束,总耗时 ==>> {}", (l2 - l));
log.info("发放积分结束 ==>> {}", tempPointsList);
}
// });
this.threadPoolTaskExecutor.submit(() -> {
List<TempExp> tempExpList = (List<TempExp>) tempRightsMap.get(RightType.EXP);
if (!CollectionUtils.isEmpty(tempExpList)) {
// log.info("发放成长值开始 ==>> [{}]", tempExpList);
long l = System.currentTimeMillis();
// 成长值
log.info("发放成长值开始 ==>> {}", tempExpList);
this.grantExp(tempExpList);
long l2 = System.currentTimeMillis();
log.info("发放成长值结束,总耗时 ==>> {}", (l2 - l));
log.info("发放成长值结束 ==>> ");
}
});
// this.threadPoolTaskExecutor.submit(() -> {
/*List<TempCoupon> tempCouponList = (List<TempCoupon>) tempRightsMap.get(RightType.COUPON);
......@@ -192,15 +164,8 @@ public class RightsOperationServiceImpl implements RightsOperationService {
// });
// 其他权益
// Future<?> submit = this.threadPoolTaskExecutor.submit(() -> {
// log.info("发放其他权益开始 ==>> [{}]", tempRightsMap);
long l = System.currentTimeMillis();
this.grantOtherRight(tempRightsMap);
long l2 = System.currentTimeMillis();
log.info("发放其他权益结束 ==>> 总耗时 ==>> {}", l-l2);
// });
this.grantOtherRight(tempRightsMap);
log.info("发放其他权益结束 ==>>" );
return tempRightsMap.keySet().size();
}
......
package com.topdraw.business.process.service.impl;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.aspect.AsyncMqSend;
......@@ -227,25 +228,17 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// 大屏侧传递的参数是platformAccount
MemberSimpleDTO memberDTO = null;
if (Objects.nonNull(memberIdObj)) {
// 小屏侧传递的参数是memberId
memberDTO = this.memberService.findSimpleById(Long.valueOf(memberIdObj.toString()));
} else {
if (Objects.nonNull(platformAccountObj)) {
String platformAccount = platformAccountObj.toString();
long l = System.currentTimeMillis();
UserTvSimpleDTO userTvDTO = this.userTvService.findSimpleByPlatformAccount(platformAccount);
long l1 = System.currentTimeMillis();
log.info("查询大屏信息,总耗时 ==>> {}", (l1-l));
log.info("查询大屏信息 ==>> {}", userTvDTO);
if (Objects.nonNull(userTvDTO)) {
// 在查找任务之前对用户行为进行预处理
this.preFindTask(platformAccount, dataSyncMsg, msgData);
// 开启积分自动同步至小屏主会员
if (validPriorityMember == 0) {
String priorityMemberCode = userTvDTO.getPriorityMemberCode();
if (StringUtils.isNotBlank(priorityMemberCode)) {
// TODO 是否需要将code和id都进行缓存
......@@ -260,10 +253,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
} else {
long l2 = System.currentTimeMillis();
memberDTO = this.memberService.findSimpleById(userTvDTO.getMemberId());
long l3 = System.currentTimeMillis();
log.info("查询大屏会员信息,总耗时 ==>> {}", (l3-l2));
log.info("查询大屏会员信息 ==>> {}", memberDTO);
}
} else {
......@@ -273,6 +264,9 @@ public class TaskOperationServiceImpl implements TaskOperationService {
log.info("获取大屏会员信息 ==>> platformAccount ==>> {} || 会员信息 ==>> {}", platformAccount, memberDTO);
} else {
// 小屏侧传递的参数是memberId
memberDTO = this.memberService.findSimpleById(Long.valueOf(memberIdObj.toString()));
}
if (Objects.isNull(memberDTO.getId())) {
......@@ -299,23 +293,9 @@ public class TaskOperationServiceImpl implements TaskOperationService {
if (!CollectionUtils.isEmpty(tasks)) {
// 5.权益区分(积分、权益、成长值)
Map<RightType,Object> tempRightsMap = this.distinguishRight(memberDTO, tasks, msgData, dataSyncMsg);
// log.info("获取当前任务对应的权益 tempRightsMap ==>> {} ", tempRightsMap);
// 6.风控检查 TODO
// boolean result = this.checkRiskManagement(memberId, tempRightsMap);
// log.info("针对各项权益检查当前会员是否达到风控值 ==>> {},true:已达到风控指标 ", result);
// if (result) throw new BadRequestException("发放失败,已达风控上限");
// long l1 = System.currentTimeMillis();
// log.info("各项检查总耗时 ==>> {}", (l1-l));
// 7.权益发放
// log.info("下发开始 ==>> {}", tempRightsMap);
// long l2 = System.currentTimeMillis();
Integer integer = this.grantRight(tempRightsMap);
// long l3 = System.currentTimeMillis();
// log.info("下发结束,总耗时 ==>> {}", (l3-l2));
if (integer > 0) {
return ResultInfo.success(integer);
......@@ -326,42 +306,6 @@ public class TaskOperationServiceImpl implements TaskOperationService {
}
private void preFindTask(String platformAccount, DataSyncMsg dataSyncMsg, JSONObject msgData) {
switch (dataSyncMsg.getEvent()) {
case TaskEventType.PLAY:
this.calculateTotalPlayDuration(platformAccount, dataSyncMsg, msgData);
break;
}
}
private void calculateTotalPlayDuration(String platformAccount, DataSyncMsg dataSyncMsg, JSONObject msgData) {
String key = RedisKeyConstants.CACHE_PLATFROMACCOUNT_PLAYDURATION+"::"+platformAccount+"|"+dataSyncMsg.getTime().toLocalDate();
Map<Object, Object> hmget = this.redisUtils.hmget(key);
if (Objects.nonNull(hmget)) {
Object totalPlayDuration = hmget.get("total");
if (Objects.isNull(totalPlayDuration)) {
Map<Object, Object> map = new HashMap<>();
map.put("total", msgData.get("playDuration"));
// 存储时间36小时
this.redisUtils.hmset(key, map, 129600);
} else {
Map<Object, Object> map = new HashMap<>();
// 计算播放总时长 total = 播放总时长+当前播放时长
totalPlayDuration = Integer.parseInt(totalPlayDuration.toString()) + Integer.parseInt(msgData.get("playDuration").toString());
map.put("total", totalPlayDuration);
this.redisUtils.hmset(key, map);
msgData.put("playDuration", totalPlayDuration);
}
}
//
}
/**
*
* @param id 主键
......@@ -385,8 +329,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
TrTaskProgress _trTaskProgress = this.trTaskProgressService.create(trTaskProgress, LocalDateTimeUtil.todayStart());
if (status.equals(TASK_FINISH_STATUS) && Objects.nonNull(_trTaskProgress)) {
Map<Object, Object> hmget = this.redisUtils.hmget(RedisKeyConstants.cacheTodayFinishTaskCount + "::" + memberId + ":" + LocalDate.now());
if (Objects.isNull(hmget)) {
boolean todayFinishCount = this.redisUtils.hHasKey(RedisKeyConstants.cacheTodayFinishTaskCount + "::" + memberId + ":" + LocalDate.now(), task.getId().toString());
if (!todayFinishCount) {
Map<Object, Object> finishTasks = new HashMap<>();
finishTasks.put(task.getId(), 1);
// 单天的记录只存储一天
......@@ -395,6 +339,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
this.redisUtils.hincr(RedisKeyConstants.cacheTodayFinishTaskCount+"::"+memberId+":"+LocalDate.now(), task.getId().toString(), 1);
}
// 永久
this.redisUtils.hincr(RedisKeyConstants.cacheTotalFinishTaskCount+"::"+memberId, task.getId().toString(), 1);
}
......@@ -426,7 +371,6 @@ public class TaskOperationServiceImpl implements TaskOperationService {
List<Task> tasksResult = new ArrayList<>();
// 检查当前会员针对这些任务的完成情况
for (Task task : tasks) {
/*// 校验用户分组
if (StringUtils.isNotBlank(task.getGroups()) && !task.getGroups().contains(memberDTO.getGroups())) {
log.warn("此用户分组不满足任务要求,任务分组 ==>> {} || 会员分组 ==>> {}",task.getGroups(), memberDTO.getGroups());
......@@ -439,7 +383,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
Integer taskRepeatType = task.getTaskRepeatType();
if (taskDailyReset.equals(0)) {
// 不重置,检查是否做过此任务
Object finishCount = finishTaskCount.get(task.getId());
Object finishCount = finishTaskCount.get(task.getId().toString());
if (!taskRepeatType.equals(-1) && Objects.nonNull(finishCount)) {
if (Long.parseLong(finishCount.toString()) >= taskRepeatType) {
continue;
......@@ -448,8 +392,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
} else {
Object todayFinishCount = todayFinishTask.get(task.getId());
if (taskRepeatType > 1 && Objects.nonNull(todayFinishCount)) {
Object todayFinishCount = todayFinishTask.get(task.getId().toString());
if (taskRepeatType >= 1 && Objects.nonNull(todayFinishCount)) {
if (Long.parseLong(todayFinishCount.toString()) >= taskRepeatType) {
continue;
}
......@@ -589,7 +533,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
private boolean doSignEvent(JSONObject msgData, Task task, MemberSimpleDTO memberDTO) {
Integer actionAmount = task.getActionAmount();
// // 用户行为次数 签到天数
int signDays = msgData.getInteger("SIGN");
int signDays = msgData.getInteger("signDays");
if (signDays >= actionAmount) {
this.saveOrUpdateTaskProcess(null, memberDTO.getId(), task, signDays, TASK_FINISH_STATUS);
return true;
......@@ -625,7 +569,9 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* @param paramJsonObject
*/
private boolean doPlayEvent(JSONObject paramJsonObject, Task task, MemberSimpleDTO memberSimpleDTO) {
// 任务最低行为量
Integer actionAmount = task.getActionAmount();
// 用户实际播放时长
int playDuration = paramJsonObject.getInteger("playDuration");
if (playDuration >= actionAmount) {
......@@ -663,17 +609,17 @@ public class TaskOperationServiceImpl implements TaskOperationService {
/**
* 权益区分
*
* @param taskList 任务列表
* @param tasks 任务列表
* @return Map<RightType,Object> 权益分类
*/
private Map<RightType,Object> distinguishRight(MemberSimpleDTO memberDTO, List<Task> taskList, JSONObject msgData, DataSyncMsg dataSyncMsg) {
private Map<RightType,Object> distinguishRight(MemberSimpleDTO memberDTO, List<Task> tasks, JSONObject msgData, DataSyncMsg dataSyncMsg) {
Map<RightType,Object> map = new HashMap<>();
// 区分权益类型(成长值(reward_exp)、积分(reward_points)、实体券),并发放权益
List<TempPoints> tempPoints = new ArrayList<>();
List<TempExp> tempExps = new ArrayList<>();
for (Task task : taskList) {
for (Task task : tasks) {
// 积分
this.getTempPoints(memberDTO, msgData, task, dataSyncMsg, tempPoints);
......
......@@ -189,7 +189,7 @@ public class UserOperationServiceImpl implements UserOperationService {
* @return UserWeixinDTO
*/
@Override
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public UserWeixinDTO createWeixinUserAndMember(UserWeixin resources) {
return this.createWeixinUserAndMember(resources, 0);
}
......@@ -1075,7 +1075,7 @@ public class UserOperationServiceImpl implements UserOperationService {
UserTvSimpleDTO userTvSimpleDTO = this.userTvService.findSimpleByPlatformAccount(platformAccount);
if (Objects.nonNull(userTvDTO)) {
userTvSimpleDTO.setPriorityMemberCode(memberDTO.getCode());
HashMap hashMap = JSONObject.parseObject(userTvSimpleDTO.toString(), HashMap.class);
JSONObject hashMap = JSONObject.parseObject(JSON.toJSONString(userTvDTO), JSONObject.class);
this.redisUtils.set(RedisKeyConstants.cacheVisUserByPlatformAccount + "::" + platformAccount, hashMap);
}
return userTvDTO;
......
......@@ -73,19 +73,19 @@ public class MemberOperationServiceImpl implements MemberOperationService {
}
@Override
public MemberDTO doUpdateMemberExpAndLevel(Member resources) {
public Integer doUpdateMemberExpAndLevel(Member resources) {
return this.memberService.doUpdateMemberExpAndLevel(resources);
}
@Override
public MemberDTO doUpdateMemberPoints(Member resources) {
public Integer doUpdateMemberPoints(Member resources) {
return this.memberService.doUpdateMemberPoints(resources);
}
@Override
@CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#member.code", unless = "#result.id == null")
public MemberDTO doUpdateMemberCoupon(Member member) {
// @CachePut(cacheNames = RedisKeyConstants.cacheMemberByCode, key = "#member.code", unless = "#result.id == null")
public Integer doUpdateMemberCoupon(Member member) {
return this.memberService.doUpdateMemberCoupon(member);
}
......
......@@ -47,19 +47,19 @@ public interface MemberOperationService {
*
* @param resources
*/
MemberDTO doUpdateMemberExpAndLevel(Member resources);
Integer doUpdateMemberExpAndLevel(Member resources);
/**
*
* @param resources
*/
MemberDTO doUpdateMemberPoints(Member resources);
Integer doUpdateMemberPoints(Member resources);
/**
*
* @param resources
*/
MemberDTO doUpdateMemberCoupon(Member resources);
Integer doUpdateMemberCoupon(Member resources);
/**
*
......
......@@ -14,6 +14,7 @@ public interface RedisKeyConstants {
String cacheMemberById = "uce::member::id";
// 任务处理时会员信息
String cacheMemberSimpleById = "uce::memberSimple::id";
String cacheMemberSimpleByCode = "uce::memberSimple::code";
// 会员全量信息
String cacheMemberByCode = "uce::member::code";
......@@ -26,7 +27,7 @@ public interface RedisKeyConstants {
// 全量大屏信息
String cacheUserTvByPlatformAccount = "uce::userTv::platformAccount";
String cacheVisUserByPlatformAccount = "uus::visUser::platformAccount";
String cacheVisUserByPlatformAccount = "uus::visUser";
// 会员已完成的任务进度
String cacheTaskProcessByMemberId = "uce::taskProcess::memberId";
// 任务模板类型对应的全量任务
......