Commit 2ce05838 2ce05838bb721d6932daae8876c0ca9d0b0bac8e by xianghan

1.优化部分任务处理接口,修改接收任务事件模型

2.为任务处理添加缓存
1 parent f97bb099
Showing 46 changed files with 744 additions and 260 deletions
package com.topdraw.business.module.member.domain;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.topdraw.business.module.common.validated.UpdateGroup;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member")
public class MemberSimple implements Serializable {
/** 主键 */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(message = "id can't be null!!",groups = {UpdateGroup.class})
private Long id;
/** 标识 */
@Column(name = "code")
private String code;
/** 状态 0:不可用;1:可用 */
@Column(name = "`status`")
private Integer status;
/** 分组信息 */
@Column(name = "`groups`")
private String groups;
/** 是否会员 0:非会员;1:会员 */
@Column(name = "vip")
private Integer vip;
/** 会员等级(对应level表的level字段,非id) */
@Column(name = "`level`")
private Integer level;
/** iptv账号id */
@Column(name = "user_iptv_id")
private Long userIptvId;
/** 是否在黑名单 1:是;0否 */
@Column(name = "black_status")
private Long blackStatus;
public void copy(MemberSimple source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(false));
}
}
package com.topdraw.business.module.member.level.service.impl;
import com.topdraw.business.module.member.level.domain.MemberLevel;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.module.member.level.repository.MemberLevelRepository;
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.level.service.mapper.MemberLevelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -42,8 +44,9 @@ public class MemberLevelServiceImpl implements MemberLevelService {
}
@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));
return this.memberLevelMapper.toDto(this.memberLevelRepository.findByLevelAndStatus(level, status));
}
}
......
package com.topdraw.business.module.member.repository;
import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.domain.MemberSimple;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
......
package com.topdraw.business.module.member.repository;
import com.topdraw.business.module.member.domain.MemberSimple;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberSimpleRepository extends JpaRepository<MemberSimple, Long>, JpaSpecificationExecutor<MemberSimple> {
@Query(value = "SELECT `id`, `code`, `status`, `groups`, `vip`, `level`,`user_iptv_id`, `black_status` FROM `uc_member` WHERE `id` = ?1", nativeQuery = true)
Optional<MemberSimple> findSimpleById(Long id);
@Query(value = "SELECT `id`, `code`, `status`, `groups`, `vip`, `level`,`user_iptv_id`, `black_status` FROM `uc_member` WHERE `code` = ?1", nativeQuery = true)
Optional<MemberSimple> findSimpleByCode(String code);
}
......@@ -2,6 +2,8 @@ package com.topdraw.business.module.member.service;
import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
......@@ -26,6 +28,13 @@ public interface MemberService {
MemberDTO findById(Long id);
/**
*
* @param id
* @return
*/
MemberSimpleDTO findSimpleById(Long id);
/**
* 通过code查询会员
* @param code 会员编码
* @return MemberDTO
......@@ -33,6 +42,13 @@ public interface MemberService {
MemberDTO findByCode(String code);
/**
*
* @param code
* @return
*/
MemberSimpleDTO findSimpleByCode(String code);
/**
* 保存
* @param resources
* @return Long id
......
package com.topdraw.business.module.member.service.dto;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberSimpleDTO implements Serializable {
/** 主键 */
private Long id;
/** 标识 */
private String code;
/** 昵称 */
private String nickname;
/** 状态 0:不可用;1:可用 */
private Integer status;
/** 分组信息 */
private String groups;
/** 是否会员 0:非会员;1:会员 */
private Integer vip;
/** 会员等级(对应level表的level字段,非id) */
private Integer level;
/** iptv账号id */
private Long userIptvId;
/** 是否在黑名单 1:是;0否 */
private Long blackStatus;
}
package com.topdraw.business.module.member.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.module.member.domain.MemberSimple;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberSimpleMapper extends BaseMapper<MemberSimpleDTO, MemberSimple> {
}
......@@ -101,5 +101,5 @@ public interface PointsAvailableService {
*
* @param pointsAvailable
*/
PointsAvailableDTO create4Custom(PointsAvailable pointsAvailable);
void create4Custom(PointsAvailable pointsAvailable);
}
......
......@@ -160,17 +160,8 @@ public class PointsAvailableServiceImpl implements PointsAvailableService {
}
@Override
public PointsAvailableDTO create4Custom(PointsAvailable resources) {
this.redisUtils.doLock("PointsAvailable::create::id"+resources.getMemberId().toString());
try {
PointsAvailable pointsAvailable = this.pointsAvailableRepository.save(resources);
return this.pointsAvailableMapper.toDto(pointsAvailable);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
this.redisUtils.doUnLock("PointsAvailable::create::id"+resources.getMemberId().toString());
}
public void create4Custom(PointsAvailable resources) {
this.pointsAvailableRepository.save(resources);
}
}
......
......@@ -27,6 +27,9 @@ import java.io.Serializable;
@NoArgsConstructor
public class TrTaskProgress implements Serializable {
@Transient
private String memberCode;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
......
......@@ -5,7 +5,10 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* @author XiangHan
......@@ -13,8 +16,17 @@ import java.util.List;
*/
public interface TrTaskProgressRepository extends JpaRepository<TrTaskProgress, Long>, JpaSpecificationExecutor<TrTaskProgress> {
@Query(value = "select id, member_id, task_id , current_action_amount , \n" +
" target_action_amount , `status` , completion_time,create_time,update_time from uc_tr_task_progress where member_id = ?1 \n" +
@Query(value = "select id, member_id, task_id, current_action_amount," +
" target_action_amount, `status`, completion_time, create_time, update_time from uc_tr_task_progress where member_id = ?1 " +
" and task_id = ?2 and Date(completion_time) = ?3 ",nativeQuery = true)
TrTaskProgress findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1);
Optional<TrTaskProgress> findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1);
Integer countByMemberIdAndTaskId(Long memberId, Long taskId);
@Query(value = "select `task_id` AS taskId, count(*) AS finishCount from uc_tr_task_progress where member_id = ?1 and `status` = 1 GROUP BY `task_id` ", nativeQuery = true)
List<Map<String, Object>> countFinishTaskGroupByMemberId(Long memberId);
@Query(value = "select `task_id` AS taskId, count(*) AS finishCount from uc_tr_task_progress where member_id = ?1 and Date(completion_time) = ?2 and `status` = 1 GROUP BY `task_id`", nativeQuery = true)
List<Map<String, Object>> countFinishTaskGroupByMemberIdAndToday(Long memberId, String todayStart);
}
......
......@@ -4,7 +4,9 @@ import com.topdraw.business.module.task.progress.domain.TrTaskProgress;
import com.topdraw.business.module.task.progress.service.dto.TrTaskProgressDTO;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
......@@ -44,6 +46,28 @@ public interface TrTaskProgressService {
* @param time1
* @return
*/
TrTaskProgressDTO findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1);
TrTaskProgress findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1);
/**
*
* @param memberId
* @param taskId
* @return
*/
Integer countByMemberIdAndTaskId(Long memberId, Long taskId);
/**
*
* @param id
* @return
*/
Map<Object, Object> countTotalFinishTaskByMemberId(Long id);
/**
*
* @param id
* @param todayStart
* @return
*/
Map<Object, Object> countTodayFinishTaskByMemberId(Long id, String todayStart);
}
......
package com.topdraw.business.module.task.progress.service.impl;
import cn.hutool.core.map.MapUtil;
import com.topdraw.business.module.task.progress.domain.TrTaskProgress;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.utils.RedisUtils;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.module.task.progress.repository.TrTaskProgressRepository;
import com.topdraw.business.module.task.progress.service.TrTaskProgressService;
......@@ -16,9 +18,13 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author XiangHan
......@@ -31,34 +37,30 @@ public class TrTaskProgressServiceImpl implements TrTaskProgressService {
@Autowired
private TrTaskProgressRepository trTaskProgressRepository;
@Autowired
private TrTaskProgressMapper trTaskProgressMapper;
@Autowired
private RedisUtils redisUtils;
@Override
public TrTaskProgressDTO findById(Long id) {
TrTaskProgress TrTaskProgress = this.trTaskProgressRepository.findById(id).orElseGet(TrTaskProgress::new);
ValidationUtil.isNull(TrTaskProgress.getId(),"TrTaskProgress","id",id);
return this.trTaskProgressMapper.toDto(TrTaskProgress);
}
@Override
@Transactional(rollbackFor = Exception.class)
@Cacheable(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#resources.memberId+':'+#resources.taskId+':'+#date", unless = "#result == null ")
// @CachePut(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#resources.memberId+':'+#resources.taskId+':'+#date", unless = "#result == null ")
public TrTaskProgress create(TrTaskProgress resources, String date) {
TrTaskProgress trTaskProgress = this.trTaskProgressRepository.save(resources);
return trTaskProgress;
return this.trTaskProgressRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@Cacheable(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#resources.memberId+':'+#resources.taskId+':'+#date", unless = "#result == null ")
// @CachePut(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#resources.memberId+':'+#resources.taskId+':'+#date", unless = "#result == null ")
public TrTaskProgress update(TrTaskProgress resources, String date) {
TrTaskProgress trTaskProgress = this.trTaskProgressRepository.findById(resources.getId()).orElseGet(TrTaskProgress::new);
ValidationUtil.isNull( trTaskProgress.getId(),"TrTaskProgress","id",resources.getId());
trTaskProgress.copy(resources);
TrTaskProgress save = this.trTaskProgressRepository.save(trTaskProgress);
return save;
return this.trTaskProgressRepository.save(resources);
}
@Override
......@@ -71,12 +73,68 @@ public class TrTaskProgressServiceImpl implements TrTaskProgressService {
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#memberId+':'+#taskId+':'+#time1", unless = "#result == null")
public TrTaskProgressDTO findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1) {
// @Cacheable(cacheNames = RedisKeyConstants.cacheTaskProcessByMemberId, key = "#memberId+':'+#taskId+':'+#time1", unless = "#result.id == null")
public TrTaskProgress findByMemberIdAndTaskIdAndCompletionTime(Long memberId, Long taskId, String time1) {
log.info("从数据库查询当前会员今天是否完成了此任务, memberId ==>> {} || taskId ==>> {}", memberId, taskId);
return this.trTaskProgressMapper.toDto(this.trTaskProgressRepository.findByMemberIdAndTaskIdAndCompletionTime(memberId,taskId,time1));
return this.trTaskProgressRepository.findByMemberIdAndTaskIdAndCompletionTime(memberId, taskId, time1).orElseGet(TrTaskProgress::new);
}
@Override
public Integer countByMemberIdAndTaskId(Long memberId, Long taskId) {
return this.trTaskProgressRepository.countByMemberIdAndTaskId(memberId, taskId);
}
@Override
public Map<Object, Object> countTotalFinishTaskByMemberId(Long memberId) {
Map<Object, Object> hmget = this.redisUtils.hmget(RedisKeyConstants.cacheTotalFinishTaskCount + "::" + memberId);
if (Objects.isNull(hmget)) {
List<Map<String, Object>> maps = this.trTaskProgressRepository.countFinishTaskGroupByMemberId(memberId);
if (!CollectionUtils.isEmpty(maps)) {
Map<Object, Object> finishTasks = new HashMap<>();
for (Map<String, Object> map : maps) {
Object taskId = map.get("taskId");
if (Objects.isNull(taskId)) {
continue;
}
finishTasks.put(Long.valueOf(taskId.toString()), Integer.valueOf(map.get("finishCount").toString()));
// 总记录一直存储
this.redisUtils.hmset(RedisKeyConstants.cacheTotalFinishTaskCount + "::" + memberId, finishTasks);
}
return finishTasks;
}
}
return hmget;
}
@Override
public Map<Object, Object> countTodayFinishTaskByMemberId(Long memberId, String todayStart) {
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<>();
for (Map<String, Object> map : maps) {
Object taskId = map.get("taskId");
if (Objects.isNull(taskId)) {
continue;
}
finishTasks.put(Long.valueOf(taskId.toString()), Integer.valueOf(map.get("finishCount").toString()));
// 单天的记录只存储一天
this.redisUtils.hmset(RedisKeyConstants.cacheTodayFinishTaskCount + "::" + memberId + ":" + LocalDate.now(), finishTasks, 24*60*60);
}
return finishTasks;
}
}
return hmget;
}
}
......
......@@ -28,6 +28,6 @@ public interface TaskRepository extends JpaRepository<Task, Long>, JpaSpecificat
@Query(value = "SELECT ta.*, attr.attr_str AS attr FROM tr_task ta LEFT JOIN tr_task_template tm ON ta.task_template_id = tm.id " +
" LEFT JOIN tr_task_attr attr ON attr.task_id = ta.id " +
" WHERE ta.`status` = 1 AND ta.valid_time <= now() and ta.expire_time >= now() AND ta.delete_mark = 0 AND " +
" tm.type = ?1 ", nativeQuery = true)
List<Task> findByEvent(Integer event);
" tm.type = ?1 AND ta.`member_level` <= ?2 and ta.`member_vip` <= ?3", nativeQuery = true)
List<Task> findByEvent(Integer event, Integer level, Integer vip);
}
......
package com.topdraw.business.module.task.service;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import com.topdraw.business.module.task.domain.Task;
import com.topdraw.business.module.task.progress.service.dto.TrTaskProgressDTO;
import com.topdraw.business.module.task.service.dto.TaskDTO;
......@@ -63,6 +64,6 @@ public interface TaskService {
* @param event
* @return
*/
List<Task> findByEvent(Integer event);
List<Task> findByEventAndMemberLevelAndVip(Integer event, Integer level, Integer vip);
}
......
package com.topdraw.business.module.task.service.impl;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import com.topdraw.business.module.task.domain.Task;
import com.topdraw.business.module.task.repository.TaskRepository;
import com.topdraw.business.module.task.service.TaskService;
import com.topdraw.business.module.task.service.dto.TaskDTO;
import com.topdraw.business.module.task.service.mapper.TaskMapper;
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.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
......@@ -30,6 +33,8 @@ public class TaskServiceImpl implements TaskService {
private TaskMapper taskMapper;
@Autowired
private TaskRepository taskRepository;
@Autowired
private RedisUtils redisUtils;
@Override
public TaskDTO findById(Long id) {
......@@ -72,9 +77,10 @@ public class TaskServiceImpl implements TaskService {
}
@Override
@Cacheable(value = RedisKeyConstants.cacheTaskByEvent, key = "#event" , unless = "#result.size() == 0")
public List<Task> findByEvent(Integer event) {
log.info("从数据库查询事件列表 ==>> {}", event);
return Objects.nonNull(event) ? this.taskRepository.findByEvent(event) : new ArrayList<>();
@Cacheable(cacheNames = RedisKeyConstants.cacheTaskByEventAndMemberLevelAndVip, key = "#event+':'+#level+':'+#vip",
unless = "#result.size() == 0")
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<>();
}
}
......
package com.topdraw.business.module.user.iptv.domain;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.topdraw.business.module.common.domain.AsyncMqModule;
import com.topdraw.business.module.common.validated.CreateGroup;
import com.topdraw.business.module.common.validated.UpdateGroup;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-12-16
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_user_tv")
public class UserTvSimple extends AsyncMqModule implements Serializable {
/** ID */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
/** 会员id */
@Column(name = "member_id")
private Long memberId;
/** 原vis_user_id */
@Column(name = "vis_user_id")
private Long visUserId;
/** 绑定的小屏账户会员编码 */
@Column(name = "priority_member_code")
private String priorityMemberCode;
public void copy(UserTvSimple source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(false));
}
}
package com.topdraw.business.module.user.iptv.repository;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
......
package com.topdraw.business.module.user.iptv.repository;
import com.topdraw.business.module.user.iptv.domain.UserTvSimple;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
/**
* @author XiangHan
* @date 2021-12-16
*/
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)
UserTvSimple findSimpleByPlatformAccount(String platformAccount);
}
......@@ -3,6 +3,7 @@ package com.topdraw.business.module.user.iptv.service;
import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
/**
* @author XiangHan
......@@ -51,6 +52,13 @@ public interface UserTvService {
/**
*
* @param platformAccount
* @return
*/
UserTvSimpleDTO findSimpleByPlatformAccount(String platformAccount);
/**
*
* @param memberCode
* @return
*/
......
package com.topdraw.business.module.user.iptv.service.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-12-16
*/
@Data
public class UserTvSimpleDTO implements Serializable {
private Long visUserId;
/** 绑定的小屏账户会员编码 */
private String priorityMemberCode;
/** 会员id */
private Long memberId;
private String platformAccount;
}
package com.topdraw.business.module.user.iptv.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.module.member.service.MemberService;
import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.process.service.impl.UserOperationServiceImpl;
import com.topdraw.business.module.user.iptv.domain.UserTvSimple;
import com.topdraw.business.module.user.iptv.repository.UserTvSimpleRepository;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
import com.topdraw.business.module.user.iptv.service.mapper.UserTvSimpleMapper;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.exception.EntityNotFoundException;
import com.topdraw.exception.GlobeExceptionMsg;
import com.topdraw.utils.RedisUtils;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.module.user.iptv.repository.UserTvRepository;
import com.topdraw.business.module.user.iptv.service.UserTvService;
......@@ -16,6 +21,7 @@ import com.topdraw.business.module.user.iptv.service.mapper.UserTvMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
......@@ -25,6 +31,8 @@ import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.util.Assert;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
......@@ -41,9 +49,16 @@ public class UserTvServiceImpl implements UserTvService {
@Autowired
private UserTvMapper userTvMapper;
@Autowired
private UserTvSimpleMapper userTvSimpleMapper;
@Autowired
private MemberService memberService;
@Autowired
private UserTvRepository userTvRepository;
@Autowired
private UserTvSimpleRepository userTvSimpleRepository;
@Autowired
private RedisUtils redisUtils;
@AsyncMqSend
public void asyncUpdateUserTvVisUserId(UserTvDTO userTvDTO) {}
......@@ -57,6 +72,7 @@ public class UserTvServiceImpl implements UserTvService {
* @return
*/
@Override
@Transactional(readOnly = true)
public MemberDTO findMemberByPlatformAccount(String platformAccount){
// 大屏账户
UserTvDTO userTvDTO = this.findByPlatformAccount(platformAccount);
......@@ -119,6 +135,7 @@ public class UserTvServiceImpl implements UserTvService {
}
@Override
@Transactional(readOnly = true)
public UserTvDTO findById(Long id) {
UserTv UserTv = this.userTvRepository.findById(id).orElseGet(UserTv::new);
ValidationUtil.isNull(UserTv.getId(),"UserTv","id",id);
......@@ -169,18 +186,39 @@ public class UserTvServiceImpl implements UserTvService {
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.cacheUserTvByPlatformAccount, key = "#platformAccount")
@Cacheable(cacheNames = RedisKeyConstants.cacheUserTvByPlatformAccount, key = "#platformAccount", unless = "#result.id == null")
@Transactional(readOnly = true)
public UserTvDTO findByPlatformAccount(String platformAccount) {
log.info("从数据库通过大屏账号检索大屏账号信息");
Optional<UserTv> userTv = this.userTvRepository.findByPlatformAccount(platformAccount);
if (userTv.isPresent()) {
ValidationUtil.isNull( userTv.get().getId(),"UserTv","id",userTv.get().getId());
return this.userTvMapper.toDto(userTv.get());
UserTv userTv = this.userTvRepository.findByPlatformAccount(platformAccount).orElseGet(UserTv::new);
return this.userTvMapper.toDto(userTv);
}
@Override
// @Cacheable(cacheNames = RedisKeyConstants.cacheUserTvByPlatformAccount, key = "#platformAccount")
public UserTvSimpleDTO findSimpleByPlatformAccount(String platformAccount) {
Object userTvSimpleObj = this.redisUtils.get(RedisKeyConstants.cacheVisUserByPlatformAccount + "::" + platformAccount);
if (Objects.nonNull(userTvSimpleObj)) {
Map<String, Object> map = (Map<String, Object>)userTvSimpleObj;
UserTvSimpleDTO userTvSimpleDTO = new UserTvSimpleDTO();
userTvSimpleDTO.setPlatformAccount(map.get("platformAccount").toString());
userTvSimpleDTO.setMemberId(Long.valueOf(map.get("memberId").toString()));
userTvSimpleDTO.setPriorityMemberCode(map.get("priorityMemberCode") == null ? "" : map.get("priorityMemberCode").toString());
return userTvSimpleDTO;
}
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);
return this.userTvSimpleMapper.toDto(userTvSimple);
}
return null;
}
@Override
@Transactional(readOnly = true)
public UserTvDTO findByPriorityMemberCode(String memberCode) {
Optional<UserTv> userTv = this.userTvRepository.findByPriorityMemberCode(memberCode);
if (userTv.isPresent()) {
......@@ -191,6 +229,7 @@ public class UserTvServiceImpl implements UserTvService {
}
@Override
@Transactional(readOnly = true)
public UserTvDTO findByMemberId(Long memberId) {
Optional<UserTv> userTv = this.userTvRepository.findByMemberId(memberId);
if (userTv.isPresent()) {
......@@ -201,6 +240,7 @@ public class UserTvServiceImpl implements UserTvService {
}
@Override
@Transactional(readOnly = true)
public boolean checkPriorityMemberByMemberIdOrMemberCode(Long memberId, String memberCode) {
// 检查会员是否存在
this.checkMember(memberId, memberCode);
......
package com.topdraw.business.module.user.iptv.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.module.user.iptv.domain.UserTvSimple;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-12-16
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserTvSimpleMapper extends BaseMapper<UserTvSimpleDTO, UserTvSimple> {
}
......@@ -35,6 +35,9 @@ public class TempRights {
@Transient
protected String memberCode;
@Transient
protected Integer memberLevel;
/** 账号id */
@Transient
protected Long userId;
......
......@@ -51,7 +51,7 @@ public class TaskOperationController {
/**
* 新增任务
*
*uc_tr_task_progress
* @param task 消息
*/
@PostMapping(value = "/createTask")
......
......@@ -473,8 +473,12 @@ public class UserOperationController {
@ApiOperation("保存大屏账户同时创建会员信息")
@AnonymousAccess
public ResultInfo createTvUserAndMember(@Validated(value = {CreateGroup.class}) @RequestBody UserTv resources) {
log.info("UserOperationController ==> createUserAndCreateMember ==>> param ==> [{}]",resources);
log.info("UserOperationController ==> createTvUserAndMember ==>> param ==> [{}]",resources);
String platformAccount = resources.getPlatformAccount();
if (StringUtils.isBlank(platformAccount)) {
log.error("保存大屏账户同时创建会员信息异常,参数错误,大屏账号不存在");
return ResultInfo.failure("参数错误,大屏账号不存在");
}
UserTvDTO result = this.userOperationService.createTvUserAndMember(resources);
return ResultInfo.success(result);
}
......
package com.topdraw.business.process.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author :
* @description:
* @function :
* @date :Created in 2022/6/22 14:05
* @version: :
* @modified By:
* @since : modified in 2022/6/22 14:05
*/
@Service
@Slf4j
public class AsyncTaskService {
}
......@@ -23,5 +23,5 @@ public interface RightsOperationService {
* 任务完成自动发放权益
* @param tempRightsMap
*/
void grantRights(Map<RightType, Object> tempRightsMap);
Integer grantRights(Map<RightType, Object> tempRightsMap);
}
......
......@@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
......@@ -43,6 +44,9 @@ public class CouponOperationServiceImpl implements CouponOperationService {
MemberService memberService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
private RedisUtils redisUtils;
// 过期阀值(默认一个月)
......@@ -137,7 +141,9 @@ public class CouponOperationServiceImpl implements CouponOperationService {
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberCoupon(member);
((CouponOperationServiceImpl) AopContext.currentProxy()).asyncMemberCoupon(member);
/*this.threadPoolTaskExecutor.submit(() -> {
((CouponOperationServiceImpl) AopContext.currentProxy()).asyncMemberCoupon(member);
});*/
}
private MemberDTO findMemberByMemberId(Long memberId) {
......
......@@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
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;
......@@ -43,6 +44,9 @@ public class ExpOperationServiceImpl implements ExpOperationService {
MemberService memberService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
private RedisUtils redisUtils;
@AsyncMqSend
......@@ -80,21 +84,27 @@ public class ExpOperationServiceImpl implements ExpOperationService {
this.redisUtils.doLock(RedisKeyConstants.updateCacheExpByMemberId + tempExp.getMemberId());
// 原始经验值
long l = System.currentTimeMillis();
long originExp = this.getExpByMemberId(tempExp);
log.info("----获取会员当前原始经验值 ==>> {}", originExp);
long l1 = System.currentTimeMillis();
log.info("----获取会员当前原始经验值 ==>> {}, 总耗时 -->> {}", originExp, (l1-l));
// 总经验值
// TODO
long totalExp = this.calculateTotalExp(originExp, tempExp);
log.info("----计算总经验值 ==>> {}", totalExp);
// 2.更新成长值与等级
log.info("----更新会员经验值与对应等级 ==>> {}", totalExp);
long l2 = System.currentTimeMillis();
this.refreshMemberExpAndLevel(tempExp, totalExp);
long l3 = System.currentTimeMillis();
log.info("----更新会员经验值与对应等级 ==>> {}, 总耗时 ==>> {}", totalExp, (l3-l2));
log.info("----保存经验值历史 ");
long l4 = System.currentTimeMillis();
this.doInsertExpDetail(tempExp, originExp, totalExp);
long l5 = System.currentTimeMillis();
log.info("----保存经验值历史 -->> 总耗时 -->> {}", (l5-l4));
} catch (Exception e) {
log.error("成长值发放失败,"+e.getMessage());
log.error("成长值发放失败,{}",e.getMessage());
} finally {
this.redisUtils.doUnLock(RedisKeyConstants.updateCacheExpByMemberId + tempExp.getMemberId());
}
......@@ -112,8 +122,8 @@ public class ExpOperationServiceImpl implements ExpOperationService {
*/
private long getExpByMemberId(TempExp tempExp) {
Long memberId = tempExp.getMemberId();
MemberDTO memberDTO = this.memberOperationService.findById(memberId);
if (Objects.nonNull(memberDTO)) {
MemberDTO memberDTO = this.memberService.findById(memberId);
if (Objects.nonNull(memberDTO.getId())) {
Long exp = memberDTO.getExp();
return Objects.isNull(exp) ? 0L : exp;
}
......@@ -127,13 +137,13 @@ public class ExpOperationServiceImpl implements ExpOperationService {
*/
private void refreshMemberExpAndLevel(TempExp tempExp,long totalExp) {
Integer memberLevel = tempExp.getMemberLevel();
Long memberId = tempExp.getMemberId();
// 1.获取当前成长值
MemberDTO memberDTO = this.getMemberInfoByMemberId(memberId);
// 2.获取下一级需要的成长值
MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberDTO.getLevel() + 1, 1);
// TODO 需要缓存
MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberLevel + 1, 1);
// 4.成长值比较,判断是否升级
Integer level = this.compareExp(totalExp, memberLevelDTO,memberDTO);
Integer level = this.compareExp(totalExp, memberLevelDTO, memberLevel);
// 5.更新用户信息
this.updateMemberInfo(level, totalExp, memberId);
}
......@@ -154,8 +164,9 @@ public class ExpOperationServiceImpl implements ExpOperationService {
member.setLevel(level);
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberExpAndLevel(member);
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncMemberExpAndLevel(member);
/*this.threadPoolTaskExecutor.submit(() -> {
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncMemberExpAndLevel(member);
});*/
}
private MemberDTO findMemberByMemberId(Long memberId) {
......@@ -163,7 +174,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
return memberDTO;
}
private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO,MemberDTO memberDTO) {
private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO, Integer oldMemberLevel) {
if (Objects.nonNull(memberLevelDTO)) {
Long nextLevelExp = memberLevelDTO.getExpValue();
if (Objects.nonNull(nextLevelExp) && nextLevelExp > 0)
......@@ -171,11 +182,11 @@ public class ExpOperationServiceImpl implements ExpOperationService {
return memberLevelDTO.getLevel();
}
}
return memberDTO.getLevel();
return oldMemberLevel;
}
private MemberLevelDTO getNextLevelExp(Integer i,Integer status) {
List<MemberLevelDTO> memberLevelDTOList = this.memberLevelService.findLevelAndStatus(i,status);
List<MemberLevelDTO> memberLevelDTOList = this.memberLevelService.findLevelAndStatus(i, status);
if (!CollectionUtils.isEmpty(memberLevelDTOList)) {
return memberLevelDTOList.get(0);
}
......@@ -217,8 +228,9 @@ public class ExpOperationServiceImpl implements ExpOperationService {
}
this.expDetailService.create(expDetail);
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncExpDetail(expDetail);
/*this.threadPoolTaskExecutor.submit(() -> {
((ExpOperationServiceImpl) AopContext.currentProxy()).asyncExpDetail(expDetail);
});*/
}
}
......
......@@ -52,22 +52,19 @@ import java.util.stream.Collectors;
public class PointsOperationServiceImpl implements PointsOperationService {
@Autowired
private PointsService pointsService;
@Autowired
private PointsDetailService pointsDetailService;
@Autowired
private PointsAvailableService pointsAvailableService;
@Autowired
private PointsDetailHistoryService pointsDetailHistoryService;
@Autowired
private MemberOperationService memberOperationService;
@Autowired
private MemberService memberService;
@Autowired
private RedisUtils redisUtils;
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
private RedisUtils redisUtils;
// 过期阈值 30天
private static final Integer EXPIRE_FACTOR = 30;
......@@ -200,6 +197,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
long currentPoints) {
// 兑换的积分
Long points = tempPoints.getPoints();
String memberCode = tempPoints.getMemberCode();
List<PointsAvailableDTO> pointsAvailableDTOS = customAvailablePointsMap.get(DELETE_AVAILABLE_POINTS);
......@@ -211,9 +209,9 @@ public class PointsOperationServiceImpl implements PointsOperationService {
BeanUtils.copyProperties(pointsAvailableDTO, _tempPoints);
BeanUtils.copyProperties(tempPoints, _tempPoints);
_tempPoints.setPoints(-(Math.abs(points)));
Long totalPoints = this.calculateTotalPoints(_tempPoints, currentPoints);
Long totalPoints = currentPoints + tempPoints.getPoints();
this.doInsertTrPointsDetail(memberId, _tempPoints, currentPoints, totalPoints);
this.doInsertTrPointsDetail(memberId, memberCode, _tempPoints, currentPoints, totalPoints);
}
}
......@@ -429,39 +427,47 @@ public class PointsOperationServiceImpl implements PointsOperationService {
*
* @param tempPoints 积分
*/
private void refresh(TempPoints tempPoints) {
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);
log.info("----------->> 获取会员当前可用总积分 --->>>> {}", currentPoints);
long l1 = System.currentTimeMillis();
// log.info("查询大屏信息,总耗时 ==>> {}", (l1-l));
log.info("----------->> 获取会员当前可用总积分 --->>>> {}, 总耗时 ==>> {}", currentPoints, (l1-l));
// 2.计算总积分
Long totalPoints = this.calculateTotalPoints(tempPoints, currentPoints);
Long totalPoints = currentPoints + tempPoints.getPoints();
log.info("----------->> 总积分(可用总积分+获得的积分) --->>> {}", totalPoints);
// 3.添加积分明细
this.doInsertTrPointsDetail(memberId, tempPoints, currentPoints, totalPoints);
log.info("----------->> 添加积分明细 --->>> ");
long l2 = System.currentTimeMillis();
this.doInsertTrPointsDetail(memberId, memberCode, tempPoints, currentPoints, totalPoints);
long l3 = System.currentTimeMillis();
log.info("----------->> 添加积分明细 --->>> 总耗时 ==>> {}", (l3-l2));
// 4.添加可用积分
long l4 = System.currentTimeMillis();
this.doInsertTrPointsAvailable(tempPoints);
log.info("----------->> 添加可用积分 -->>> ");
long l5 = System.currentTimeMillis();
log.info("----------->> 添加可用积分 -->>> 总耗时 ==>> {}", (l5-l4));
// 5.即将过期的积分
// TODO 查询的时候再更新过期积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
log.info("----------->> 即将过期的积分 ------->>>>> {}", soonExpirePoints);
// 6.更新会员的总积分
log.info("----------->> 更新会员的总积分 ------->>>>> 总积分--->>> {}", totalPoints);
long l6 = System.currentTimeMillis();
this.freshMemberCurrentPoints(memberId, totalPoints, soonExpirePoints);
long l7 = System.currentTimeMillis();
log.info("----------->> 更新会员的总积分 ------->>>>> 总积分--->>> {} -->>总耗时 ==>> {}", totalPoints, (l7-l6));
} catch (Exception e) {
e.printStackTrace();
throw e;
log.error(" ==>> {}", e.getMessage());
} finally {
this.redisUtils.doUnLock(RedisKeyConstants.updateCachePointsByMemberId + memberId.toString());
}
......@@ -477,7 +483,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
// 获取的积分
Long rewardPoints = tempPoints.getPoints();
// 总积分
Long totalPoints = currentPoints + rewardPoints;
Long totalPoints = currentPoints + tempPoints.getPoints();
return totalPoints;
}
......@@ -514,7 +520,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
*/
private void freshMemberCurrentPoints(Long memberId, Long currentPoints, long duePoints) {
MemberDTO memberDTO = this.findMemberByMemberId(memberId);
MemberDTO memberDTO = this.memberService.findById(memberId);
Member member = new Member();
member.setId(memberDTO.getId());
......@@ -525,17 +531,14 @@ public class PointsOperationServiceImpl implements PointsOperationService {
try {
this.memberOperationService.doUpdateMemberPoints(member);
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncMemberPoint(member);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncMemberPoint(member);
});*/
} catch (Exception e){
log.error("同步会员积分异常,"+e.getMessage());
}
}
private MemberDTO findMemberByMemberId(Long memberId) {
MemberDTO memberDTO = this.memberService.findById(memberId);
return memberDTO;
}
/**
* 更新可用积分表
* @param tempPoints
......@@ -554,8 +557,9 @@ public class PointsOperationServiceImpl implements PointsOperationService {
}
this.pointsAvailableService.create4Custom(pointsAvailable);
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsAvailable(pointsAvailable);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsAvailable(pointsAvailable);
});*/
}
/**
......@@ -564,15 +568,13 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param tempPoints 积分
* @return Integer 总积分
*/
private void doInsertTrPointsDetail(Long memberId, TempPoints tempPoints, Long currentPoints, Long totalPoints){
MemberDTO memberDTO = this.memberService.findById(memberId);
private void 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(memberDTO.getCode());
pointsDetail.setMemberCode(memberCode);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setPoints(tempPoints.getPoints());
pointsDetail.setOriginalPoints(currentPoints);
......@@ -587,7 +589,9 @@ public class PointsOperationServiceImpl implements PointsOperationService {
// 保存积分流水
this.pointsDetailService.create4Custom(pointsDetail);
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsDetail(pointsDetail);
/*this.threadPoolTaskExecutor.submit(() -> {
((PointsOperationServiceImpl) AopContext.currentProxy()).asyncPointsDetail(pointsDetail);
});*/
}
}
......
......@@ -21,8 +21,12 @@ 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;
/**
* 权益处理
......@@ -71,20 +75,23 @@ public class RightsOperationServiceImpl implements RightsOperationService {
* @param tempRightsMap 权益类型
*/
@Override
public void grantRights(Map<RightType, Object> tempRightsMap) {
public Integer grantRights(Map<RightType, Object> tempRightsMap) {
this.threadPoolTaskExecutor.execute(()-> {
// 2.创建权益历史对象
List<RightsHistory> rightsList = this.getRightHistory(tempRightsMap);
if (!CollectionUtils.isEmpty(rightsList)) {
log.info("异步保存权益领取历史开始 ==>> [{}]", rightsList);
// log.info("异步保存权益领取历史开始 ==>> [{}]", rightsList);
long l = System.currentTimeMillis();
// 3.保存权益历史
this.doInsertTrRightHistory(rightsList);
long l1 = System.currentTimeMillis();
log.info("保存权益历史,总耗时 ==>> {}", l1-l);
}
});
// 1.权益下发
this.refresh(tempRightsMap);
return this.refresh(tempRightsMap);
}
/**
......@@ -141,28 +148,29 @@ public class RightsOperationServiceImpl implements RightsOperationService {
this.couponOperationService.grantCouponThroughTempCoupon(tempCouponList);
}
/**
* 权益发放
* @param tempRightsMap
*/
private void refresh(Map<RightType, Object> tempRightsMap) {
private Integer refresh(Map<RightType, Object> tempRightsMap) {
this.threadPoolTaskExecutor.execute(() -> {
// Future<?> submit = this.threadPoolTaskExecutor.submit(() -> {
List<TempPoints> tempPointsList = (List<TempPoints>) tempRightsMap.get(RightType.POINTS);
if (!CollectionUtils.isEmpty(tempPointsList)) {
log.info("发放积分开始 ==>> [{}]", tempPointsList);
// log.info("发放积分开始 ==>> [{}]", tempPointsList);
long l = System.currentTimeMillis();
// 积分
this.grantPoint(tempPointsList);
long l2 = System.currentTimeMillis();
log.info("发放积分结束,总耗时 ==>> {}", (l2 - l));
}
});
// });
this.threadPoolTaskExecutor.execute(()-> {
this.threadPoolTaskExecutor.submit(() -> {
List<TempExp> tempExpList = (List<TempExp>) tempRightsMap.get(RightType.EXP);
if (!CollectionUtils.isEmpty(tempExpList)) {
log.info("发放成长值开始 ==>> [{}]", tempExpList);
// log.info("发放成长值开始 ==>> [{}]", tempExpList);
long l = System.currentTimeMillis();
// 成长值
this.grantExp(tempExpList);
......@@ -171,25 +179,30 @@ public class RightsOperationServiceImpl implements RightsOperationService {
}
});
this.threadPoolTaskExecutor.execute(()-> {
List<TempCoupon> tempCouponList = (List<TempCoupon>) tempRightsMap.get(RightType.COUPON);
// this.threadPoolTaskExecutor.submit(() -> {
/*List<TempCoupon> tempCouponList = (List<TempCoupon>) tempRightsMap.get(RightType.COUPON);
if (!CollectionUtils.isEmpty(tempCouponList)) {
log.info("发放优惠券开始 ==>> [{}]", tempCouponList);
// log.info("发放优惠券开始 ==>> [{}]", tempCouponList);
long l = System.currentTimeMillis();
// 优惠券
this.grantCoupon(tempCouponList);
long l2 = System.currentTimeMillis();
log.info("发放优惠券结束,总耗时 ==>> {}", (l2 - l));
}
});
}*/
// });
// 其他权益
this.threadPoolTaskExecutor.execute(()-> {
log.info("发放其他权益开始 ==>> [{}]", tempRightsMap);
// Future<?> submit = this.threadPoolTaskExecutor.submit(() -> {
// log.info("发放其他权益开始 ==>> [{}]", tempRightsMap);
long l = System.currentTimeMillis();
this.grantOtherRight(tempRightsMap);
log.info("发放其他权益结束 ==>> [{}]", tempRightsMap);
});
long l2 = System.currentTimeMillis();
log.info("发放其他权益结束 ==>> 总耗时 ==>> {}", l-l2);
// });
return tempRightsMap.keySet().size();
}
private void grantOtherRight(Map<RightType, Object> tempRightsMap) {
......
......@@ -10,11 +10,13 @@ import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.domain.MemberBuilder;
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.module.user.iptv.domain.UserConstant;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.module.user.iptv.domain.UserTvBuilder;
import com.topdraw.business.module.user.iptv.service.UserTvService;
import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
import com.topdraw.business.module.user.iptv.service.dto.UserTvSimpleDTO;
import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
import com.topdraw.business.module.user.weixin.collection.repository.UserCollectionDetailRepository;
......@@ -34,6 +36,7 @@ import com.topdraw.business.process.service.dto.MemberAndUserTvDTO;
import com.topdraw.business.process.service.dto.MemberAndWeixinUserDTO;
import com.topdraw.business.process.service.mapper.CollectionMq2DetailMapper;
import com.topdraw.config.LocalConstants;
import com.topdraw.config.RedisKeyConstants;
import com.topdraw.config.RedisKeyUtil;
import com.topdraw.exception.BadRequestException;
import com.topdraw.exception.EntityNotFoundException;
......@@ -49,6 +52,7 @@ import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
......@@ -119,8 +123,9 @@ public class UserOperationServiceImpl implements UserOperationService {
UserTvDTO userTvDTO = this.userTvService.findByPlatformAccount(platformAccount);
// 无账号
if (Objects.isNull(userTvDTO)) {
if (Objects.isNull(userTvDTO.getId())) {
// 会员昵称默认采用大屏账号,昵称通过base64加密与小屏保持一致
String platformAccountEncode = Base64Utils.encodeToString(platformAccount.getBytes());
// x_member
......@@ -133,14 +138,15 @@ public class UserOperationServiceImpl implements UserOperationService {
UserTv userTv = UserTvBuilder.build(memberDTO.getId(), memberDTO.getCode(), resources);
// 创建大屏账户
UserTvDTO tvUserDTO = this.createTvUser(userTv, memberDTO.getId(), memberDTO.getCode());
UserTvDTO _tvUserDTO = this.createTvUser(userTv, memberDTO.getId(), memberDTO.getCode());
((UserOperationServiceImpl)AopContext.currentProxy()).asyncMemberAndUserTv4Iptv(new MemberAndUserTvDTO(memberDTO, tvUserDTO));
((UserOperationServiceImpl)AopContext.currentProxy()).asyncMemberAndUserTv4Iptv(new MemberAndUserTvDTO(memberDTO, _tvUserDTO));
return tvUserDTO;
return _tvUserDTO;
}
log.error("保存大屏账号信息异常,无法创建大屏账号对应的会员,platoformAccount ==> {}", platformAccount);
throw new EntityNotFoundException(MemberDTO.class, "code", GlobeExceptionMsg.MEMBER_ID_IS_NULL);
// 有账号
......@@ -165,10 +171,10 @@ public class UserOperationServiceImpl implements UserOperationService {
UserTv userTv = new UserTv();
BeanUtils.copyProperties(userTvDTO, userTv);
UserTvDTO userTvDTO1 = this.updateUserTvUnsyncIptv(userTv);
((UserOperationServiceImpl)AopContext.currentProxy()).asyncMemberAndUserTv4Iptv(new MemberAndUserTvDTO(memberDTO, userTvDTO1));
UserTvDTO _userTvDTO = this.userTvService.update(userTv);
((UserOperationServiceImpl)AopContext.currentProxy()).asyncMemberAndUserTv4Iptv(new MemberAndUserTvDTO(memberDTO, _userTvDTO));
return userTvDTO1;
return _userTvDTO;
}
}
......@@ -1065,6 +1071,13 @@ public class UserOperationServiceImpl implements UserOperationService {
// 同步至iptv
((UserOperationServiceImpl)AopContext.currentProxy()).asyncMinaBind(new MemberAndUserTvDTO(memberDTO, userTvDTO));
// 修改缓存中MemberSimple的大屏主账号信息,因为执行任务之前会去检查主会员d
UserTvSimpleDTO userTvSimpleDTO = this.userTvService.findSimpleByPlatformAccount(platformAccount);
if (Objects.nonNull(userTvDTO)) {
userTvSimpleDTO.setPriorityMemberCode(memberDTO.getCode());
HashMap hashMap = JSONObject.parseObject(userTvSimpleDTO.toString(), HashMap.class);
this.redisUtils.set(RedisKeyConstants.cacheVisUserByPlatformAccount + "::" + platformAccount, hashMap);
}
return userTvDTO;
}
......@@ -1088,15 +1101,6 @@ public class UserOperationServiceImpl implements UserOperationService {
}
/**
*
* @param userTv 大屏账号
* @return UserTvDTO
*/
private UserTvDTO updateUserTvUnsyncIptv(UserTv userTv){
return this.userTvService.update(userTv);
}
/**
* 重置主账号
* @param memberDTO 会员code
* @param userTvDTO 大屏id
......@@ -1242,8 +1246,14 @@ public class UserOperationServiceImpl implements UserOperationService {
* @param member 会员信息
* @return MemberDTO
*/
private MemberDTO createMember(Member member){
return this.memberService.create(member);
public MemberDTO createMember(Member member){
MemberDTO memberDTO = this.memberService.create(member);
if (Objects.nonNull(memberDTO.getId())) {
MemberSimpleDTO memberSimpleDTO = new MemberSimpleDTO();
BeanUtils.copyProperties(memberDTO, memberSimpleDTO);
this.redisUtils.set(RedisKeyConstants.cacheMemberSimpleById+"::"+memberDTO.getId(), memberSimpleDTO);
}
return memberDTO;
}
/**
......
......@@ -10,19 +10,49 @@ package com.topdraw.config;
* @since : modified in 2022/6/18 13:25
*/
public interface RedisKeyConstants {
// 全量会员信息
String cacheMemberById = "uce::member::id";
// 任务处理时会员信息
String cacheMemberSimpleById = "uce::memberSimple::id";
// 会员全量信息
String cacheMemberByCode = "uce::member::code";
String updateCacheMemberById = "uce::updateMember::id";
// 修改会员积分时的分布式锁
String updateCachePointsByMemberId = "uce::updatePoints::memberId";
// 修改会员成长值时的分布式锁
String updateCacheExpByMemberId = "uce::updateExp::memberId";
// 修改会员优惠券时的分布式锁
String updateCacheCouponByMemberId = "uce::updateCoupon::memberId";
// 全量大屏信息
String cacheUserTvByPlatformAccount = "uce::userTv::platformAccount";
String cacheVisUserByPlatformAccount = "uus::visUser::platformAccount";
// 会员已完成的任务进度
String cacheTaskProcessByMemberId = "uce::taskProcess::memberId";
String cacheTaskByTaskTemplateId = "uce::task::taskTemplateId";
// 任务模板类型对应的全量任务
String cacheTaskByEvent = "uce::task::event";
// 全量优惠券信息
String cacheCouponById = "uce::coupon::id";
// 权益全量信息
String cacheRightById = "uce::right::id";
// 会员可以做的任务
String cacheTaskByEventAndMemberLevelAndVip = "uce::task::eventAndMemberLevelAndVip";
// 全量会员等级
String cacheMemberLevelByLevel = "uce::memberLevel::level";
// 今天处理完成任务数量
String cacheTodayFinishTaskCount = "uce::todayCount::memberId";
// 历史完成的任务数量
String cacheTotalFinishTaskCount = "uce::totalCount::memberId";
String CACHE_PLATFROMACCOUNT_PLAYDURATION = "uce::eventPlay::playduration";
String CACHE_TODAY_FINISH_COUNT = "todayFinishCount";
String CACHE_TOTAL_FINISH_COUNT = "totalFinishCount";
}
......
package com.topdraw.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author :
* @description:
* @function :
* @date :Created in 2022/6/22 11:06
* @version: :
* @modified By:
* @since : modified in 2022/6/22 11:06
*/
@Configuration
public class TheadPoolTaskExecutorConfiguration {
@Value("${task.pool.core-pool-size}")
private Integer corePoolSize;
@Value("${task.pool.core-pool-size}")
private Integer maxPoolSize;
@Value("${task.pool.keep-alive-seconds}")
private Integer keepAliveSeconds;
@Value("${task.pool.queue-capacity}")
private Integer queueCapacity;
@Bean
@Primary
public ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
/*@Bean
public ThreadPoolExecutor getThreadPoolTaskExecutor() {
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(queueCapacity);
ThreadPoolExecutor threadPoolTaskExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveSeconds, TimeUnit.SECONDS, arrayBlockingQueue);
return threadPoolTaskExecutor;
}*/
}
package com.topdraw.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author :
* @description:
* @function :
* @date :Created in 2022/6/19 16:30
* @version: :
* @modified By:
* @since : modified in 2022/6/19 16:30
*/
@Slf4j
@Configuration
public class UceRedisConfig {
@Autowired
private RedisConfig redisConfig;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean(value = "uceRedisTemplate")
public RedisTemplate<Object, Object> uceRedisTemplate() {
return redisConfig.redisTemplate(redisConnectionFactory);
}
/**
* 自定义缓存管理器
*/
@Bean(value = "uceCacheManagemer")
@Primary
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
Set<String> cacheNames = new HashSet<>();
// cacheNames.add("car");
// cacheNames.add(RedisKeyConstants.cacheTaskByEvent);
cacheNames.add(RedisKeyConstants.cacheTaskProcessByMemberId);
ConcurrentHashMap<String, RedisCacheConfiguration> configMap = new ConcurrentHashMap<>();
// configMap.put("car", config.entryTtl(Duration.ofMinutes(6L)));
configMap.put(RedisKeyConstants.cacheTaskProcessByMemberId, config.entryTtl(Duration.ofDays(1)));
// configMap.put(RedisKeyConstants.cacheTaskByEvent, config);
//需要先初始化缓存名称,再初始化其它的配置。
RedisCacheManager cacheManager = RedisCacheManager.builder(factory).
initialCacheNames(cacheNames).withInitialCacheConfigurations(configMap).build();
return cacheManager;
}
}
......@@ -6,7 +6,6 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
import java.time.LocalDateTime;
/**
......@@ -25,43 +24,8 @@ public class DataSyncMsg implements Serializable {
//设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
private Integer deviceType;
// 发送时间
private String time;
private LocalDateTime time;
// 消息体
private String msgData;
/**
* 消息体
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class MsgData {
/**备注*/
private String remarks;
// 会员id
private Long memberId;
// 账户id
private Long userId;
//用户对应的应用code
private String appCode;
// 会员code
private String memberCode;
// 账号id
private Long accountId;
// 订单Id
private Long orderId;
// 活动id
private Long activityId;
// 节目id
private Long mediaId;
// 产品id
private Long itemId;
// 模板参数
private String param;
// 描述
private String description;
// 大屏账号
private String platformAccount;
}
}
......
......@@ -5,7 +5,7 @@ spring:
url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user_admin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: root
# url: jdbc:log4jdbc:mysql://139.196.145.150:3306/ucs-small-sichuan?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:log4jdbc:mysql://139.196.145.150:3306/ucs_admin_chongshu?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: Tjlh@2021
......@@ -20,7 +20,7 @@ spring:
# 最大连接数
max-active: 15
# 获取连接超时时间
max-wait: 5000
max-wait: 5000000
# 连接有效性检测时间
time-between-eviction-runs-millis: 90000
# 最大空闲时间
......
......@@ -25,13 +25,13 @@ spring:
task:
pool:
# 核心线程池大小
core-pool-size: 10
core-pool-size: 16
# 最大线程数
max-pool-size: 30
max-pool-size: 35
# 活跃时间
keep-alive-seconds: 60
keep-alive-seconds: 10
# 队列容量
queue-capacity: 50
queue-capacity: 300
#登录图形验证码有效时间/分钟
loginCode:
......
......@@ -64,7 +64,7 @@
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO" additivity="false">
<logger name="jdbc.sqlonly" level="OFF" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
......
......@@ -96,11 +96,12 @@ public class TaskOperationControllerTest extends BaseTest {
public void play() {
try {
String s = "{\"evt\":\"PLAY\",\"event\":8,\"time\":\"2022-05-03 23:10:09\",\"deviceType\":1," +
"\"msgData\":{\"memberCode\":\"1537253277861699584\",\"param\":\"{\\\"playDuration\\\":60}\"}}";
"\"msgData\":{\"platformAccount\":\"1537253277861699584\",\"param\":\"{\\\"playDuration\\\":60}\"}}";
TaskOperationQueryCriteria pointsQueryCriteria = new TaskOperationQueryCriteria();
pointsQueryCriteria.setContent(s);
String s1 = JSON.toJSONString(pointsQueryCriteria);
this.taskOperationController.dealTask(pointsQueryCriteria);
System.out.println(s1);
// this.taskOperationController.dealTask(pointsQueryCriteria);
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -2,6 +2,8 @@ package com.topdraw.test.business.process.service;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.business.module.member.domain.Member;
import com.topdraw.business.module.member.service.MemberService;
import com.topdraw.business.module.member.service.dto.MemberSimpleDTO;
import com.topdraw.business.process.service.member.MemberOperationService;
import com.topdraw.BaseTest;
import com.topdraw.util.IdWorker;
......@@ -16,6 +18,15 @@ public class MemberOperationServiceTest extends BaseTest {
@Autowired
MemberOperationService memberOperationService;
@Autowired
MemberService memberService;
@Test
public void findMemberSimpleTest(){
MemberSimpleDTO memberSimpleDTO = this.memberService.findSimpleById(20718L);
System.out.println(memberSimpleDTO);
}
@Test
public void findById() {
Long memberId = 2L;
......
......@@ -19,11 +19,7 @@ public class TaskOperationServiceTest extends BaseTest {
DataSyncMsg dataSyncMsg = new DataSyncMsg();
// dataSyncMsg.setEntityType(EntityType.MEMBER);
dataSyncMsg.setEvt(EventType.LOGIN.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setRemarks("remark");
msgData.setMemberId(memberId);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
// dataSyncMsg.setMsgData(msgData);
String s = JSON.toJSONString(dataSyncMsg);
......
......@@ -22,10 +22,10 @@ public class MqTest extends BaseTest {
DataSyncMsg dataSyncMsg = new DataSyncMsg();
// dataSyncMsg.setEventType(EventType.LOGIN.name());
dataSyncMsg.setEvt(EventType.LOGIN.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
/* DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setRemarks("remark");
msgData.setMemberId(1L);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
msgData.setAppCode("WEI_XIN_GOLD_PANDA");*/
// dataSyncMsg.setMsgData(msgData);
String s = JSON.toJSONString(dataSyncMsg);
amqpTemplate.convertAndSend( "uc.route.key.direct.event.aaa", s);
......