Commit a7042cbd a7042cbdbeec8c176c868582727e902f25cbeecd by xianghan@topdraw.cn

Merge branch 'release/1.0.3'

2 parents a9e7295a 61a8e0b2
Showing 49 changed files with 1120 additions and 417 deletions
RENAME TABLE tj_user_0819.uc_user__group TO tj_user_0819.uc_member_group;
ALTER TABLE tj_user_0819.uc_member_group ADD member_id varchar(100) NULL COMMENT '会员id';
......@@ -10,7 +10,7 @@
<entry key="lastExternalPluginCheckTime" value="1636770952724" />
</map>
</option>
<option name="version" value="5" />
<option name="version" value="6" />
</configuration>
</facet>
</component>
......
package com.topdraw.module.mq;
import javax.annotation.Resource;
// 关注的事件
public enum EventType {
......@@ -22,7 +24,7 @@ public enum EventType {
// 登录
LOGIN,
// 订购产品包
SUBSCRIBE_PRODUCT_PACKAGE
SUBSCRIBE_PRODUCT_PACKAGE,
// 签到
SIGN
}
......
......@@ -10,7 +10,7 @@
<entry key="lastExternalPluginCheckTime" value="1636770952726" />
</map>
</option>
<option name="version" value="5" />
<option name="version" value="6" />
</configuration>
</facet>
</component>
......
......@@ -125,6 +125,17 @@
<build>
<finalName>member-service</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
......@@ -143,6 +154,7 @@
</plugin>
<!-- 复制指定配置文件到指定目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
......
......@@ -28,7 +28,7 @@ public class AsyncMqProducer {
@Autowired
MessageProducer messageProducer;
@Resource(name = "executorTask")
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Pointcut(value = "@annotation(asyncMqSend)")
......
......@@ -121,7 +121,7 @@ public class Member implements Serializable {
// 是否在黑名单 1:是;0否
@Column(name = "black_status")
private Integer blackStatus;
private Long blackStatus;
public void copy(Member source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
......
package com.topdraw.business.basicdata.member.group.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member_group")
public class MemberGroup implements Serializable {
// ID ID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 分组ID
@Column(name = "group_id")
private Long groupId;
// 会员ID
@Column(name = "member_id")
private Long memberId;
// 运营商平台账号
@Column(name = "platform_account")
private String platformAccount;
// 手机号
@Column(name = "cellphone")
private String cellphone;
// 设备
@Column(name = "stb_id")
private String stbId;
// 有线MAC地址
@Column(name = "eth_mac")
private String ethMac;
// 无线MAC地址
@Column(name = "wifi_mac")
private String wifiMac;
// 描述
@Column(name = "description")
private String description;
// 创建者
@Column(name = "create_by")
private String createBy;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新者
@Column(name = "update_by")
private String updateBy;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(MemberGroup source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.group.repository;
import com.topdraw.business.basicdata.member.group.domain.MemberGroup;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-11-17
*/
public interface MemberGroupRepository extends JpaRepository<MemberGroup, Long>, JpaSpecificationExecutor<MemberGroup> {
}
package com.topdraw.business.basicdata.member.group.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.group.domain.MemberGroup;
import com.topdraw.business.basicdata.member.group.service.MemberGroupService;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Api(tags = "MemberGroup管理")
@RestController
@RequestMapping("/api/MemberGroup")
public class MemberGroupController {
@Autowired
private MemberGroupService MemberGroupService;
@GetMapping
@ApiOperation("查询MemberGroup")
public ResultInfo getMemberGroups(MemberGroupQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(MemberGroupService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有MemberGroup")
public ResultInfo getMemberGroups(MemberGroupQueryCriteria criteria) {
return ResultInfo.success(MemberGroupService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增MemberGroup")
public ResultInfo create(@Validated @RequestBody MemberGroup resources) {
MemberGroupService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改MemberGroup")
public ResultInfo update(@Validated @RequestBody MemberGroup resources) {
MemberGroupService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除MemberGroup")
public ResultInfo delete(@PathVariable Long id) {
MemberGroupService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.member.group.service;
import com.topdraw.business.basicdata.member.group.domain.MemberGroup;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupDTO;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-11-17
*/
public interface MemberGroupService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberGroupQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberGroupDTO>
*/
List<MemberGroupDTO> queryAll(MemberGroupQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberGroupDTO
*/
MemberGroupDTO findById(Long id);
void create(MemberGroup resources);
void update(MemberGroup resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.member.group.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Data
public class MemberGroupDTO implements Serializable {
// ID ID
private Long id;
// 分组ID
private Long groupId;
// 会员ID
private Long memberId;
// 运营商平台账号
private String platformAccount;
// 手机号
private String cellphone;
// 设备
private String stbId;
// 有线MAC地址
private String ethMac;
// 无线MAC地址
private String wifiMac;
// 描述
private String description;
// 创建者
private String createBy;
// 创建时间
private Timestamp createTime;
// 更新者
private String updateBy;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.member.group.service.dto;
import lombok.Data;
import com.topdraw.annotation.Query;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Data
public class MemberGroupQueryCriteria{
@Query(type = Query.Type.EQUAL)
private Long memberId;
}
package com.topdraw.business.basicdata.member.group.service.impl;
import com.topdraw.business.basicdata.member.group.domain.MemberGroup;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.utils.FileUtil;
import com.topdraw.business.basicdata.member.group.repository.MemberGroupRepository;
import com.topdraw.business.basicdata.member.group.service.MemberGroupService;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupDTO;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupQueryCriteria;
import com.topdraw.business.basicdata.member.group.service.mapper.MemberGroupMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberGroupServiceImpl implements MemberGroupService {
@Autowired
private MemberGroupRepository MemberGroupRepository;
@Autowired
private MemberGroupMapper MemberGroupMapper;
@Override
public Map<String, Object> queryAll(MemberGroupQueryCriteria criteria, Pageable pageable) {
Page<MemberGroup> page = MemberGroupRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(MemberGroupMapper::toDto));
}
@Override
public List<MemberGroupDTO> queryAll(MemberGroupQueryCriteria criteria) {
return MemberGroupMapper.toDto(MemberGroupRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberGroupDTO findById(Long id) {
MemberGroup MemberGroup = MemberGroupRepository.findById(id).orElseGet(MemberGroup::new);
ValidationUtil.isNull(MemberGroup.getId(),"MemberGroup","id",id);
return MemberGroupMapper.toDto(MemberGroup);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(MemberGroup resources) {
MemberGroupRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(MemberGroup resources) {
MemberGroup MemberGroup = MemberGroupRepository.findById(resources.getId()).orElseGet(MemberGroup::new);
ValidationUtil.isNull( MemberGroup.getId(),"MemberGroup","id",resources.getId());
MemberGroup.copy(resources);
MemberGroupRepository.save(MemberGroup);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
MemberGroup MemberGroup = MemberGroupRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", MemberGroup.class, id), 1));
MemberGroupRepository.delete(MemberGroup);
}
}
package com.topdraw.business.basicdata.member.group.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.group.domain.MemberGroup;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-11-17
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberGroupMapper extends BaseMapper<MemberGroupDTO, MemberGroup> {
}
......@@ -9,6 +9,7 @@ import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelQueryCriteria;
import com.topdraw.business.basicdata.member.level.service.mapper.MemberLevelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......
......@@ -83,5 +83,5 @@ public class MemberDTO implements Serializable {
private Timestamp updateTime;
// 是否在黑名单 1:是;0否
private Integer blackStatus;
private Long blackStatus;
}
......
......@@ -19,13 +19,18 @@ import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.Assert;
import java.util.List;
......@@ -38,6 +43,7 @@ import java.util.Objects;
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "uc-member-info")
public class MemberServiceImpl implements MemberService {
@Autowired
......@@ -61,12 +67,12 @@ public class MemberServiceImpl implements MemberService {
return memberMapper.toDto(memberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
// @Cacheable(cacheNames = "",key = "")
@Override
public MemberDTO findById(Long id) {
Member member = memberRepository.findById(id).orElseGet(Member::new);
ValidationUtil.isNull(member.getId(),"Member","id",id);
return memberMapper.toDto(member);
}
@Override
......@@ -99,6 +105,9 @@ public class MemberServiceImpl implements MemberService {
return member;
}
@Autowired
PlatformTransactionManager platformTransactionManager;
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
......@@ -106,10 +115,18 @@ public class MemberServiceImpl implements MemberService {
RLock rLock = this.redissonClient.getLock("updateMember" + resources.getId().toString());
try {
RedissonUtil.lock(rLock);
String name = Thread.currentThread().getName();
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> start ===>> ");
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> 【resources】 ===>> " + resources);
Member member = memberRepository.findById(resources.getId()).orElseGet(Member::new);
ValidationUtil.isNull(member.getId(), "Member", "id", resources.getId());
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> 【member-search】 ===>> " + member);
member.copy(resources);
memberRepository.save(member);
this.save(member);
// platformTransactionManager.commit(transaction);
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> 【exp】 ===>> " + member.getExp());
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> 【point】 ===>> " + member.getPoints());
System.out.println("=============>>>>【name】 ===== >> " + name + " =======>> 【member】 ===>> " + member);
} catch (Exception e) {
e.printStackTrace();
throw e;
......@@ -118,6 +135,11 @@ public class MemberServiceImpl implements MemberService {
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Member member){
memberRepository.save(member);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
......
......@@ -75,7 +75,7 @@ public interface PointsAvailableRepository extends JpaRepository<PointsAvailable
* @param memberId
* @return
*/
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where upa.member_id = ?1 and upa.expire_time >= now()"
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where upa.member_id = ?1 and upa.expire_time > now()"
,nativeQuery = true)
Long findAvailablePointsByMemberId(long memberId);
......@@ -87,4 +87,10 @@ public interface PointsAvailableRepository extends JpaRepository<PointsAvailable
void deleteBatchByIds(List<Long> id);
List<PointsAvailable> findByExpireTimeBefore(Timestamp now);
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where upa.member_id = ?1"
,nativeQuery = true)
long findTotalCountByMemberId(Long memberId);
List<PointsAvailable> findByMemberIdAndExpireTimeAfter(Long memberId, Date timestamp);
}
......
......@@ -80,6 +80,8 @@ public interface PointsAvailableService {
*/
List<PointsAvailableDTO> findByMemberIdAndExpireTimeBefore(Long memberId, Date timestamp);
List<PointsAvailableDTO> findByMemberIdAndExpireTimeAfter(Long memberId, Date timestamp);
/**
* 即将过期的积分
* @param memberId 会员id
......@@ -136,4 +138,6 @@ public interface PointsAvailableService {
List<PointsAvailableDTO> findByExpireTimeBefore(Timestamp now);
long findTotalPointsByMemberId(Long memberId);
}
......
......@@ -127,6 +127,13 @@ public class PointsAvailableServiceImpl implements PointsAvailableService {
}
@Override
public List<PointsAvailableDTO> findByMemberIdAndExpireTimeAfter(Long memberId, Date timestamp) {
return Objects.nonNull(memberId)?
PointsAvailableMapper.toDto(PointsAvailableRepository.findByMemberIdAndExpireTimeAfter(memberId, timestamp))
:null;
}
@Override
public Long findSoonExpireTime(Long memberId, Integer factor) {
return PointsAvailableRepository.findSoonExpireTime(memberId, factor);
}
......@@ -163,4 +170,9 @@ public class PointsAvailableServiceImpl implements PointsAvailableService {
return PointsAvailableMapper.toDto(this.PointsAvailableRepository.findByExpireTimeBefore(now));
}
@Override
public long findTotalPointsByMemberId(Long memberId) {
return this.PointsAvailableRepository.findTotalCountByMemberId(memberId);
}
}
......
......@@ -20,7 +20,7 @@ import io.swagger.annotations.*;
//@RequestMapping("/api/Points")
public class PointsController {
/* @Autowired
/*@Autowired
private PointsService PointsService;
@GetMapping
......@@ -33,9 +33,9 @@ public class PointsController {
@ApiOperation("查询所有Points")
public ResultInfo getPointss(PointsQueryCriteria criteria) {
return ResultInfo.success(PointsService.queryAll(criteria));
}
}*/
@Log
/*@Log
@PostMapping
@ApiOperation("新增Points")
public ResultInfo create(@Validated @RequestBody Points resources) {
......
......@@ -9,6 +9,7 @@ import com.topdraw.business.basicdata.task.service.dto.TaskDTO;
import com.topdraw.business.basicdata.task.service.dto.TaskQueryCriteria;
import com.topdraw.business.basicdata.task.service.mapper.TaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -79,6 +80,7 @@ public class TaskServiceImpl implements TaskService {
TaskRepository.delete(Task);
}
// @Cacheable(cacheNames = "uc-admin_taskList" , key = "#taskTemplateId")
@Override
public List<Task> findByTemplateId(Long taskTemplateId) {
return Objects.nonNull(taskTemplateId) ? this.TaskRepository.findByTaskTemplateId(taskTemplateId) : null;
......
......@@ -87,12 +87,13 @@ public class TaskTemplateServiceImpl implements TaskTemplateService {
: new TaskTemplateDTO();
}
// @Cacheable(cacheNames = "uc.taskTemplate" , key = "event")
@Override
public TaskTemplate findByEvent(String event) {
return StringUtils.isNotEmpty(event) ? this.TaskTemplateRepository.findByEvent(event) : null;
}
// @Cacheable(cacheNames = "uc-admin_taskTemplate" , key = "#event")
@Override
public TaskTemplate findByType(Integer event) {
return Objects.nonNull(event) ? this.TaskTemplateRepository.findByType(event) : null;
......
......@@ -20,6 +20,14 @@ public class TempRights {
@Transient
protected Long id;
/** 编号 */
@Transient
protected String code;
/** 权益名称 */
@Transient
protected String name;
/** 会员ID */
@Transient
@NotNull(message = "")
......
......@@ -17,9 +17,13 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
* @author XiangHan
* @date 2021-10-22
......@@ -32,11 +36,11 @@ public class PointsOperationController {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationController.class);
@Autowired
private PointsOperationService pointsOperationService;
PointsOperationService pointsOperationService;
@Autowired
private PointsDetailService pointsDetailService;
PointsDetailService pointsDetailService;
@Autowired
private PointsAvailableService pointsAvailableService;
PointsAvailableService pointsAvailableService;
@GetMapping(value = "/pagePointsDetails")
@ApiOperation("查询PointsDetail")
......@@ -56,10 +60,29 @@ public class PointsOperationController {
}
@Log
@GetMapping(value = "/cleanInvalidPointsAndCalculateCurrentPoints/{id}")
@ApiOperation("清除过期积分并计算总积分,供客户端会员查询积分时调用")
public ResultInfo cleanInvalidPointsAndCalculateCurrentPoints(@PathVariable("id") Long id) {
Long aLong = this.pointsOperationService.cleanInvalidPointsAndCalculateCurrentPoints(id);
return ResultInfo.success(Objects.isNull(aLong) ? 0L : aLong);
}
/*@Log
@PostMapping(value = "/cleanInvalidPointsAndCalculateCurrentPointsByMemberIds")
@ApiOperation("清除过期积分并计算总积分,管理端使用")
public ResultInfo cleanInvalidPointsAndCalculateCurrentPointsByMemberIds(List<Long> memberIds) {
if (!CollectionUtils.isEmpty(memberIds)) {
for (Long memberId : memberIds) {
this.pointsOperationService.cleanInvalidPointsAndCalculateCurrentPoints(memberId);
}
}
return ResultInfo.success();
}*/
@Log
@PostMapping(value = "/grantPointsByManual")
@ApiOperation("新增PointsDetail")
public ResultInfo grantPointsByManual(@Validated @RequestBody TempPoints tempPoints) {
LOG.info("======>>>>> grantPointsByManual start");
Long memberId = tempPoints.getMemberId();
this.pointsOperationService.grantPointsByManual(memberId,tempPoints);
return ResultInfo.success();
......
......@@ -5,6 +5,7 @@ import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.process.domian.TempPoints;
import java.util.List;
import java.util.Map;
/**
* @description 积分操作接口
......@@ -34,13 +35,11 @@ public interface PointsOperationService {
*/
void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList);
/**
* 清理过期的积分
*/
void cleanInvalidAvailablePoints();
/**
* 清理过期的积分
* 清理过期并计算可用总积分
* @param memberId
* @return
*/
void cleanInvalidAvailablePointsByMemberId(Long memberId);
Long cleanInvalidPointsAndCalculateCurrentPoints(Long memberId);
}
......
......@@ -19,10 +19,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
......@@ -45,9 +49,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
ThreadPoolTaskExecutor threadPoolTaskExecutor;
// 过期阀值(默认一个月)
private static final Integer EXPIRE_FACTOR_MONTH = 1;
private static final Integer EXPIRE_FACTOR_DAY = 30;
@Override
public void grantCouponThroughTempCoupon(List<TempCoupon> tempCouponList) {
......@@ -80,10 +82,10 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param tempCoupon 领取的优惠券
*/
private void refresh(TempCoupon tempCoupon) {
// 1.保存优惠券领取、使用历史记录表
this.threadPoolTaskExecutor.execute(()->this.doInsertCouponHistory(tempCoupon));
// 2.更新会员优惠券数量
// 1.更新会员优惠券数量
this.refreshMemberCoupon(tempCoupon);
// 2.保存优惠券领取、使用历史记录表
this.doInsertCouponHistory(tempCoupon);
}
......@@ -92,17 +94,20 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param tempCoupon 账号id
*/
private void refreshMemberCoupon(TempCoupon tempCoupon) {
Long userId = tempCoupon.getUserId();
// Long userId = tempCoupon.getUserId();
Long memberId = tempCoupon.getMemberId();
Integer rightsAmount = tempCoupon.getRightsAmount();
RLock rLock = this.redissonClient.getLock("refreshMemberCoupon:" + memberId.toString());
try {
RedissonUtil.lock(rLock);
// 1.获取用户领取的总优惠券
Long totalCouponCount = this.getTotalCoupon(userId);
// 1.历史总优惠券数量
Long historyCouponCount = this.getTotalHistoryCoupon(memberId);
// 1.当前总优惠券数量
Long totalCouponCount = this.getTotalCoupon(historyCouponCount,rightsAmount);
// 2.获取已过期的优惠券数量
Long expireCouponCount = this.getTotalExpireCoupon(userId);
Long expireCouponCount = this.getTotalExpireCoupon(memberId);
// 3.即将过期的优惠券数量
Long expireSoonCouponCount = this.getTotalExpireSoonCoupon(userId,EXPIRE_FACTOR_MONTH);
Long expireSoonCouponCount = this.getTotalExpireSoonCoupon(memberId,EXPIRE_FACTOR_DAY);
// 4.当前优惠券数量 = 总优惠券-已过期的优惠券
Long currentCoupon = this.getCurrentCoupon(totalCouponCount,expireCouponCount);
// 5.更新用户信息(优惠券数量、即将过期的优惠券数量)
......@@ -115,6 +120,10 @@ public class CouponOperationServiceImpl implements CouponOperationService {
}
}
private Long getTotalCoupon(Long historyCouponCount, Integer rightsAmount) {
return (Objects.nonNull(historyCouponCount) ? historyCouponCount: 0L) + (Objects.nonNull(rightsAmount) ? rightsAmount: 0L);
}
/**
* 更新当前用户优惠券信息
......@@ -149,28 +158,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @return
*/
private Long getTotalExpireSoonCoupon(Long userId, Integer expireFactor) {
LocalDateTime localDateTime = LocalDateTime.now();
String s = EXPIRE_FACTOR_MONTH.toString();
String[] s1 = s.split("_");
String s2 = s1[s1.length-1];
switch (s2) {
case "YEAR":
localDateTime.plusYears(expireFactor);
break;
case "MONTH":
localDateTime.plusMonths(expireFactor);
break;
case "DAY":
localDateTime.plusDays(expireFactor);
break;
case "HOUR":
localDateTime.plusHours(expireFactor);
break;
default:
break;
}
Timestamp expireTime = TimestampUtil.now(localDateTime);
Timestamp expireTime = TimestampUtil.localDateTime2Timestamp(LocalDateTime.now().plusDays(expireFactor));
return this.couponHistoryService.countByUserIdAndExpireTimeBetween(userId,TimestampUtil.now(),expireTime);
}
......@@ -190,7 +178,7 @@ public class CouponOperationServiceImpl implements CouponOperationService {
* @param userId
* @return
*/
private Long getTotalCoupon(Long userId) {
private Long getTotalHistoryCoupon(Long userId) {
return this.couponHistoryService.countByUserId(userId);
}
......@@ -204,10 +192,12 @@ public class CouponOperationServiceImpl implements CouponOperationService {
BeanUtils.copyProperties(tempCoupon,couponHistory);
couponHistory.setId(null);
couponHistory.setCouponId(tempCoupon.getId());
couponHistory.setUserId(tempCoupon.getUserId());
couponHistory.setUserId(tempCoupon.getMemberId());
couponHistory.setCouponCode(tempCoupon.getCode());
couponHistory.setUserNickname(tempCoupon.getUserNickname());
couponHistory.setOrderDetailId(tempCoupon.getOrderId());
couponHistory.setReceiveTime(TimestampUtil.now());
couponHistory.setUseStatus(Objects.nonNull(couponHistory.getUseStatus()) ? couponHistory.getUseStatus():0);
this.couponHistoryService.create(couponHistory);
}
......
......@@ -43,7 +43,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
MemberLevelService memberLevelService;
@Autowired
RedissonClient redissonClient;
@Resource(name = "executorTask")
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
......@@ -75,18 +75,19 @@ public class ExpOperationServiceImpl implements ExpOperationService {
* @param tempExp
*/
private void refresh(TempExp tempExp) {
RLock lock = this.redissonClient.getLock("refresh_exp:" + tempExp.getMemberId());
RLock lock = this.redissonClient.getLock("uc-refresh-exp:" + tempExp.getMemberId());
try {
RedissonUtil.lock(lock);
// 原始积分
long originExp = this.getExpByMemberId(tempExp);
// 总积分
long totalExp = this.calculateTotalExp(originExp, tempExp);
// 1.添加成长值记录
this.threadPoolTaskExecutor.execute(() -> this.doInsertExpDetail(tempExp, originExp, totalExp));
// this.threadPoolTaskExecutor.execute(() -> this.doInsertExpDetail(tempExp, originExp, totalExp));
// 2.更新成长值与等级
this.refreshMemberExpAndLevel(tempExp);
this.refreshMemberExpAndLevel(tempExp,totalExp);
this.doInsertExpDetail(tempExp, originExp, totalExp);
} catch (Exception e) {
e.printStackTrace();
......@@ -98,7 +99,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
private long calculateTotalExp(long originalExp,TempExp tempExp) {
Long rewardExp = tempExp.getRewardExp();
return (Objects.nonNull(rewardExp) ? rewardExp : 0L) + (Objects.nonNull(originalExp) ? originalExp : 0L);
return rewardExp + originalExp;
}
private long getExpByMemberId(TempExp tempExp) {
......@@ -114,57 +115,43 @@ public class ExpOperationServiceImpl implements ExpOperationService {
*
* @param tempExp 成长值列表
*/
private void refreshMemberExpAndLevel(TempExp tempExp) {
private void refreshMemberExpAndLevel(TempExp tempExp,long totalExp) {
Long memberId = tempExp.getMemberId();
RLock rLock = this.redissonClient.getLock("refreshMemberExpAndLevel" + memberId.toString());
try {
RedissonUtil.lock(rLock);
// 1.获取当前成长值
MemberDTO memberDTO = this.getMemberInfoByMemberId(memberId);
// 2.获取下一级需要的成长值
MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberDTO.getLevel() + 1, 1);
// 3.成长值累加
Long newExp = memberDTO.getExp() + tempExp.getRewardExp();
// 4.成长值比较,判断是否升级
long i = this.compareExp(newExp, memberLevelDTO);
Integer level = this.compareExp(totalExp, memberLevelDTO,memberDTO);
// 5.更新用户信息
this.updateMemberInfo(i, newExp, memberLevelDTO, memberId);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
RedissonUtil.unlock(rLock);
}
this.updateMemberInfo(level, totalExp, memberId);
}
/**
*
* @param i
* @param newExp 总积分
* @param memberLevelDTO 下一级
* @param level
* @param totalExp 总积分
* @param memberId 会员id
*/
private void updateMemberInfo(long i,Long newExp,MemberLevelDTO memberLevelDTO,Long memberId) {
private void updateMemberInfo(Integer level,Long totalExp,Long memberId) {
Member member = new Member();
member.setId(memberId);
member.setExp(newExp);
if (i > 0) {
Integer level = memberLevelDTO.getLevel();
member.setExp(totalExp);
member.setLevel(level);
}
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberInfo(member);
}
private long compareExp(long newExp, MemberLevelDTO memberLevelDTO) {
private Integer compareExp(long newExp, MemberLevelDTO memberLevelDTO,MemberDTO memberDTO) {
if (Objects.nonNull(memberLevelDTO)) {
Long nextLevelExp = memberLevelDTO.getExpValue();
if (Objects.nonNull(nextLevelExp) && nextLevelExp > 0)
return newExp - nextLevelExp;
if(newExp - nextLevelExp >= 0){
return memberLevelDTO.getLevel();
}
}
return -1;
return memberDTO.getLevel();
}
private MemberLevelDTO getNextLevelExp(Integer i,Integer status) {
......@@ -200,7 +187,7 @@ public class ExpOperationServiceImpl implements ExpOperationService {
expDetail.setCode(String.valueOf(IdWorker.generator()));
// 原始积分
expDetail.setOriginalExp(Objects.nonNull(originalExp) ? originalExp : 0L);
expDetail.setOriginalExp(originalExp);
// 总积分
expDetail.setResultExp(totalExp);
// 获得的积分
......
......@@ -16,6 +16,7 @@ import com.topdraw.util.IdWorker;
import com.topdraw.util.RedissonUtil;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
......@@ -39,6 +40,7 @@ import java.util.stream.Collectors;
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
@Slf4j
public class PointsOperationServiceImpl implements PointsOperationService {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationServiceImpl.class);
......@@ -62,12 +64,13 @@ public class PointsOperationServiceImpl implements PointsOperationService {
@Autowired
RedissonClient redissonClient;
@Resource(name = "executorTask")
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
@Transactional(rollbackFor = Exception.class)
public void grantPointsByManual(Long memberId,TempPoints tempPoints){
if (Objects.nonNull(tempPoints) && Objects.nonNull(tempPoints.getPoints()))
this.refresh(tempPoints);
}
......@@ -99,8 +102,10 @@ public class PointsOperationServiceImpl implements PointsOperationService {
this.doInsertTrPointsDetailByAvailablePointsMap(tempPoints, customAvailablePointsMap, currentPoints);
// 4.更新可用积分表,超过的删除,剩余的新增
long totalPoints = this.doFreshTrPointsAvailableByAvailablePointsMap(customAvailablePointsMap, currentPoints);
// 5.即将过期的积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
// 6.更新会员积分信息
this.freshMemberCurrentPoints(memberId, totalPoints);
this.freshMemberCurrentPoints(memberId, totalPoints,soonExpirePoints);
return true;
}
......@@ -167,7 +172,7 @@ public class PointsOperationServiceImpl implements PointsOperationService {
BeanUtils.copyProperties(pointsAvailableDTO,tempPoints1);
BeanUtils.copyProperties(tempPoints,tempPoints1);
tempPoints1.setPoints(-(Math.abs(points)));
long totalPoints = this.calculateTotalPoints(tempPoints1, currentPoints);
Long totalPoints = this.calculateTotalPoints(tempPoints1, currentPoints);
this.doInsertTrPointsDetail(memberId,tempPoints1,currentPoints,totalPoints);
}
}
......@@ -265,58 +270,95 @@ public class PointsOperationServiceImpl implements PointsOperationService {
@Override
@Transactional(rollbackFor = Exception.class)
public void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList){
log.info("------->>grantPointsThroughTempRightsList start1");
for (TempPoints tempPoints : tempPointsList){
log.info("------->>grantPointsThroughTempRightsList start");
this.refresh(tempPoints);
}
}
/**
* 定时清理过期的可用积分
* 清理过期积分
* @param memberId
*/
@Override
public void cleanInvalidAvailablePoints() {
// 获取已过期的积分
List<PointsAvailableDTO> pointsAvailableDTOS = pointsAvailableService.findByExpireTimeBefore(TimestampUtil.now());
private void cleanInvalidAvailablePointsByMemberId(Long memberId) {
List<PointsAvailableDTO> pointsAvailableDTOS =
pointsAvailableService.findByMemberIdAndExpireTimeBefore(memberId,TimestampUtil.now());
if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
//1.获取原始积分
for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
// 添加积分明细 uc_points_detail
this.doCreatePointsDetail(pointsAvailableDTOS);
this.doCreatePointsDetail(pointsAvailableDTO);
// 删除已过期的积分
this.doDeleteInvalidAvailablePoints(pointsAvailableDTOS);
this.doDeleteInvalidAvailablePoints(pointsAvailableDTO);
}
}
}
@Override
public void cleanInvalidAvailablePointsByMemberId(Long memberId) {
List<PointsAvailableDTO> pointsAvailableDTOS = pointsAvailableService.findByMemberIdAndExpireTimeBefore(memberId,TimestampUtil.now());
if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
// 添加积分明细 uc_points_detail
this.doCreatePointsDetail(pointsAvailableDTOS);
// 删除已过期的积分
this.doDeleteInvalidAvailablePoints(pointsAvailableDTOS);
public Long cleanInvalidPointsAndCalculateCurrentPoints(Long memberId) {
// 清理当前用户的过期积分
this.cleanInvalidAvailablePointsByMemberId(memberId);
// 获取当前用户的可用总积分
long currentPoints = this.findAvailablePointsByMemberId(memberId);
// 即将过期的积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, null);
// 更新会员信息
this.doUpdateMemberPoints(memberId,currentPoints,soonExpirePoints);
return currentPoints;
}
/**
* 获取可用总积分
* @param memberId
* @return
*/
private long findAvailablePointsByMemberId(Long memberId){
return this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
}
/**
* 修改会员信息
* @param memberId
* @param currentPoints
*/
private void doUpdateMemberPoints(Long memberId, long currentPoints,long soonExpirePoints) {
Member member = new Member();
member.setId(memberId);
member.setPoints(currentPoints);
member.setDuePoints(soonExpirePoints);
this.memberOperationService.doUpdateMemberPoints(member);
}
/**
*
* @param pointsAvailableDTOS
*/
private void doDeleteInvalidAvailablePoints(List<PointsAvailableDTO> pointsAvailableDTOS) {
private void doDeleteBatchInvalidAvailablePoints(List<PointsAvailableDTO> pointsAvailableDTOS) {
List<Long> collect = pointsAvailableDTOS.stream().map(pointsAvailableDTO -> pointsAvailableDTO.getId()).collect(Collectors.toList());
this.pointsAvailableService.deleteBatchByIds(collect);
}
/**
*
* @param pointsAvailableDTOS
* @param pointsAvailableDTO
*/
private void doCreatePointsDetail(List<PointsAvailableDTO> pointsAvailableDTOS) {
private void doDeleteInvalidAvailablePoints(PointsAvailableDTO pointsAvailableDTO) {
this.pointsAvailableService.delete(pointsAvailableDTO.getId());
}
//1.获取原始积分
for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
/**
* 可用积分
* @param pointsAvailableDTO
*/
private void doCreatePointsDetail(PointsAvailableDTO pointsAvailableDTO) {
Long memberId = pointsAvailableDTO.getMemberId();
// 原始积分
long availablePoints = this.findAvailablePointsByMemberId(memberId);
long availablePoints = this.pointsAvailableService.findTotalPointsByMemberId(memberId);//this.findAvailablePointsByMemberId(memberId);
// 过期积分
long l = pointsAvailableDTO.getPoints();
// 结果积分
......@@ -324,17 +366,16 @@ public class PointsOperationServiceImpl implements PointsOperationService {
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(pointsAvailableDTO,pointsDetail);
pointsDetail.setId(null);
pointsDetail.setPoints(-Math.abs(l));
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setOriginalPoints(availablePoints);
pointsDetail.setResultPoints(resultPoints);
pointsDetail.setDescription("过期积分");
pointsDetail.setEvtType(99);
pointsDetail.setCreateTime(TimestampUtil.now());
pointsDetail.setUpdateTime(TimestampUtil.now());
this.doInsertPointsDetail(pointsDetail);
// 更新会员积分
this.freshMemberCurrentPoints(memberId,resultPoints);
}
}
/**
......@@ -344,19 +385,38 @@ public class PointsOperationServiceImpl implements PointsOperationService {
*/
private void refresh(TempPoints tempPoints) {
Long memberId = tempPoints.getMemberId();
RLock rLock = this.redissonClient.getLock("refresh_point:" + memberId.toString());
log.info("----------->> points refresh start");
RLock rLock = this.redissonClient.getLock("uc-refresh-points:" + memberId.toString());
log.info("----------->> rLock --->> start" );
try {
RedissonUtil.lock(rLock);
log.info("----------->> refresh findAvailablePointsByMemberId start");
// 1.可用总积分
long currentPoints = this.findAvailablePointsByMemberId(memberId);
Long currentPoints = this.findAvailablePointsByMemberId(memberId);
log.info("----------->> refresh findAvailablePointsByMemberId currentPoints " + currentPoints);
// 2.计算总积分
long totalPoints = this.calculateTotalPoints(tempPoints, currentPoints);
// 2.添加积分明细,并计算总积分
this.threadPoolTaskExecutor.execute(()->this.doInsertTrPointsDetail(memberId, tempPoints, currentPoints,totalPoints));
// 4.更新会员的总积分
this.freshMemberCurrentPoints(memberId, totalPoints);
// 5.添加可用积分
Long totalPoints = this.calculateTotalPoints(tempPoints, currentPoints);
log.info("----------->> refresh findAvailablePointsByMemberId totalPoints " + totalPoints);
// 3.添加积分明细,并计算总积分
log.info(Thread.currentThread().getName() + "----------->> refresh doInsertTrPointsDetail start ");
this.doInsertTrPointsDetail(memberId, tempPoints, currentPoints, totalPoints);
log.info(Thread.currentThread().getName() + "----------->> refresh doInsertTrPointsDetail end ");
// 4.添加可用积分
log.info("----------->> refresh doInsertTrPointsAvailable start ");
this.doInsertTrPointsAvailable(tempPoints);
log.info("----------->> refresh doInsertTrPointsAvailable end ");
// 即将过期的积分
long soonExpirePoints = this.getSoonExpirePoints(memberId, tempPoints);
// 6.更新会员的总积分
log.info("----------->> refresh freshMemberCurrentPoints start ");
this.freshMemberCurrentPoints(memberId, totalPoints,soonExpirePoints);
log.info("----------->> refresh freshMemberCurrentPoints end ");
} catch (Exception e) {
e.printStackTrace();
throw e;
......@@ -371,11 +431,11 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param currentPoints
* @return
*/
private long calculateTotalPoints(TempPoints tempPoints, long currentPoints) {
private Long calculateTotalPoints(TempPoints tempPoints, Long currentPoints) {
// 获取的积分
long rewardPoints = tempPoints.getPoints();
Long rewardPoints = tempPoints.getPoints();
// 总积分
long totalPoints = currentPoints + rewardPoints;
Long totalPoints = currentPoints + rewardPoints;
return totalPoints;
}
......@@ -410,11 +470,11 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param memberId 会员Id
* @param currentPoints 当前总积分
*/
private void freshMemberCurrentPoints(Long memberId, Long currentPoints) {
private void freshMemberCurrentPoints(Long memberId, Long currentPoints,long duePoints) {
Member member = new Member();
member.setId(memberId);
member.setPoints(Objects.nonNull(currentPoints)?currentPoints:0);
// member.setDuePoints(duePoints);
member.setDuePoints(duePoints);
member.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
try {
this.memberOperationService.doUpdateMemberPoints(member);
......@@ -428,9 +488,9 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param memberId 会员id
* @return
*/
private long findAvailablePointsByMemberId(long memberId){
long availablePointsByMemberId = this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
return availablePointsByMemberId;
private Long findAvailablePointsByMemberId(long memberId){
Long availablePoints = this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
return Objects.nonNull(availablePoints) ? availablePoints : 0L;
}
/**
......@@ -468,23 +528,18 @@ public class PointsOperationServiceImpl implements PointsOperationService {
* @param tempPoints 积分
* @return Integer 总积分
*/
private void doInsertTrPointsDetail(Long memberId, TempPoints tempPoints,long totalPoints,long currentPoints){
private void doInsertTrPointsDetail(Long memberId, TempPoints tempPoints,Long currentPoints,Long totalPoints){
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(tempPoints,pointsDetail);
/* // 获取的积分
long rewardPoints = tempPoints.getPoints();
// 原始积分
long originalPoints = currentPoints;
// 总积分
long totalPoints = originalPoints + rewardPoints;*/
pointsDetail.setId(null);
pointsDetail.setMemberId(memberId);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setPoints(tempPoints.getPoints());
pointsDetail.setOriginalPoints(currentPoints);
pointsDetail.setResultPoints(totalPoints);
pointsDetail.setCreateTime(null);
pointsDetail.setUpdateTime(null);
String description = pointsDetail.getDescription();
if (StringUtils.isEmpty(description)) {
pointsDetail.setDescription("#");
......
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.coupon.service.CouponService;
import com.topdraw.business.basicdata.coupon.service.dto.CouponDTO;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.RightsHistoryService;
import com.topdraw.business.basicdata.rights.service.RightsService;
......@@ -17,10 +19,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.*;
/**
* 权益处理
......@@ -44,9 +46,13 @@ public class RightsOperationServiceImpl implements RightsOperationService {
ExpOperationService expOperationService;
@Autowired
PointsOperationService pointsOperationService;
@Autowired
CouponService couponService;
// @Autowired
// ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Resource(name = "executorTask")
ThreadPoolTaskExecutor threadPoolTaskExecutor;
private ExecutorService threadPoolTaskExecutor = Executors.newFixedThreadPool(10);
/**
* 系统手动发放
......@@ -71,16 +77,15 @@ public class RightsOperationServiceImpl implements RightsOperationService {
@Override
public void grantRights(Map<RightType, Object> tempRightsMap) {
this.threadPoolTaskExecutor.execute(()-> {
// this.threadPoolTaskExecutor.execute(()-> {
// 2.创建权益历史对象
List<RightsHistory> rightsList = this.getRightHistory(tempRightsMap);
// 3.保存权益历史
this.doInsertTrRightHistory(rightsList);
});
// });
// 1.权益下发
this.refresh(tempRightsMap);
}
/**
......@@ -104,7 +109,6 @@ public class RightsOperationServiceImpl implements RightsOperationService {
return rightsHistoryList;
}
/**
* 成长值发放,基于已获得的权益
* @param tempExpList 权益列表
......@@ -114,18 +118,18 @@ public class RightsOperationServiceImpl implements RightsOperationService {
this.expOperationService.grantPointsThroughTempExp(tempExpList);
}
/**
* 发放积分,基于已获得的权益
*
* @param tempPointsList 权益列表
*/
private void grantPoint(List<TempPoints> tempPointsList) {
log.info(Thread.currentThread().getName() + "=========>>grantPoint start");
if (!CollectionUtils.isEmpty(tempPointsList))
log.info("=======>> tempPointsList ======>> " + tempPointsList.toString());
this.pointsOperationService.grantPointsThroughTempRightsList(tempPointsList);
}
/**
* 发放优惠券,基于已获得的权益
*
......@@ -137,31 +141,78 @@ public class RightsOperationServiceImpl implements RightsOperationService {
this.couponOperationService.grantCouponThroughTempCoupon(tempCouponList);
}
/**
* 权益发放
* @param tempRightsMap
*/
private void refresh(Map<RightType, Object> tempRightsMap) {
this.threadPoolTaskExecutor.execute(()->{
/*FutureTask<Map<Long,Long>> futureTask1 = new FutureTask(()->{
log.info(Thread.currentThread().getName() + "=========>> start");
// 积分
this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
log.info(Thread.currentThread().getName() + "=========>>grantPoint end");
// 成长值
// this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
// 优惠券
// this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
return null;
});
this.threadPoolTaskExecutor.execute(()->{
FutureTask<Map<Long,Long>> futureTask2 = new FutureTask(()->{
// 积分
// this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
// 成长值
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
// 优惠券
// this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
return null;
});
this.threadPoolTaskExecutor.execute(()->{
FutureTask<Map<Long,Long>> futureTask3 = new FutureTask(()->{
// 积分
// this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
// 成长值
// this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
// 优惠券
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));
this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
return null;
});
this.threadPoolTaskExecutor.execute(futureTask1);
this.threadPoolTaskExecutor.execute(futureTask2);
this.threadPoolTaskExecutor.execute(futureTask3);*/
/*this.threadPoolTaskExecutor.execute(() -> {
// 积分
this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
// 成长值
this.grantExp((List<TempExp>) tempRightsMap.get(RightType.EXP));
// 优惠券
this.grantCoupon((List<TempCoupon>) tempRightsMap.get(RightType.COUPON));
});*/
/*this.threadPoolTaskExecutor.execute(() -> {
log.info(Thread.currentThread().getName() + "=========>> start");
// 积分
this.grantPoint((List<TempPoints>) tempRightsMap.get(RightType.POINTS));
log.info(Thread.currentThread().getName() + "=========>> end");
});*/
List<TempPoints> tempPointsList = (List<TempPoints>) tempRightsMap.get(RightType.POINTS);
if (!CollectionUtils.isEmpty(tempPointsList)) {
// 积分
this.grantPoint(tempPointsList);
}
List<TempExp> tempExpList = (List<TempExp>) tempRightsMap.get(RightType.EXP);
if (!CollectionUtils.isEmpty(tempExpList)) {
// 成长值
this.grantExp(tempExpList);
}
List<TempCoupon> tempCouponList = (List<TempCoupon>) tempRightsMap.get(RightType.COUPON);
if (!CollectionUtils.isEmpty(tempCouponList)) {
// 优惠券
this.grantCoupon(tempCouponList);
}
/*this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));*/
}
/**
......@@ -175,8 +226,6 @@ public class RightsOperationServiceImpl implements RightsOperationService {
// 优惠券
List<TempCoupon> tempCouponList = new ArrayList<>();
List<TempExp> tempExpList = new ArrayList<>();
List<TempPoints> tempPointsList = new ArrayList<>();
for (RightsHistory right : rightsList) {
Long rightId = right.getRightsId();
......@@ -186,62 +235,55 @@ public class RightsOperationServiceImpl implements RightsOperationService {
RightsDTO rightsDTO = this.getRights(rightId);
// 权益的实体类型 1:积分;2成长值;3优惠券
String type = rightsDTO.getEntityType();
String code = rightsDTO.getCode();
Long expireTime = rightsDTO.getExpireTime();
Timestamp validTime = rightsDTO.getValidTime();
switch (type) {
// 优惠券
case "3":
case "1":
Long entityId = rightsDTO.getEntityId();
CouponDTO couponDTO = this.findCouponById(entityId);
if (Objects.nonNull(couponDTO)) {
TempCoupon tempCoupon = new TempCoupon();
tempCoupon.setId(rightId);
tempCoupon.setId(couponDTO.getId());
tempCoupon.setMemberId(memberId);
tempCoupon.setUserId(userId);
tempCoupon.setRightsAmount(1);
tempCoupon.setRightsSendStrategy(0);
tempCoupon.setCode(couponDTO.getCode());
if (Objects.nonNull(expireTime))
tempCoupon.setExpireTime(TimestampUtil.long2Timestamp(expireTime));
tempCouponList.add(tempCoupon);
}
break;
// 成长值
// 观影券
case "2":
TempExp tempExp = new TempExp();
tempExp.setId(rightId);
tempExp.setMemberId(memberId);
tempExp.setUserId(userId);
tempExp.setRightsAmount(1);
tempExp.setRightsSendStrategy(0);
tempExpList.add(tempExp);
break;
// 积分
case "1":
TempPoints tempPoints = new TempPoints();
tempPoints.setId(rightId);
tempPoints.setMemberId(memberId);
tempPoints.setUserId(userId);
tempPoints.setRightsAmount(1);
tempPoints.setRightsSendStrategy(0);
tempPointsList.add(tempPoints);
// 活动参与机会
case "3":
break;
default:
break;
}
}
// TODO 其他
// 优惠券
if (!CollectionUtils.isEmpty(tempCouponList))
map.put(RightType.COUPON,tempCouponList);
// 成长值
if (!CollectionUtils.isEmpty(tempExpList))
map.put(RightType.EXP,tempExpList);
// 积分
if (!CollectionUtils.isEmpty(tempPointsList))
map.put(RightType.POINTS,tempPointsList);
return map;
}
/**
* 获取优惠券信息
* @param id
* @return
*/
private CouponDTO findCouponById(Long id) {
CouponDTO couponDTO = this.couponService.findById(id);
return couponDTO;
}
/**
* 权益详情
* @param rightsId
* @return
......@@ -260,8 +302,11 @@ public class RightsOperationServiceImpl implements RightsOperationService {
if (!CollectionUtils.isEmpty(rightsHistories)) {
for (RightsHistory rightsHistory : rightsHistories) {
Long operatorId = rightsHistory.getOperatorId();
String operatorName = rightsHistory.getOperatorName();
rightsHistory.setSendTime(TimestampUtil.now());
rightsHistory.setOperatorId(Objects.nonNull(operatorId)?operatorId:0);
rightsHistory.setOperatorName(!StringUtils.isEmpty(operatorName)?operatorName:"系统发放");
this.rightsHistoryService.create(rightsHistory);
}
......
package com.topdraw.business.process.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.business.basicdata.coupon.service.CouponService;
import com.topdraw.business.basicdata.coupon.service.dto.CouponDTO;
import com.topdraw.business.basicdata.member.group.service.MemberGroupService;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupDTO;
import com.topdraw.business.basicdata.member.group.service.dto.MemberGroupQueryCriteria;
import com.topdraw.business.basicdata.rights.permanentrights.service.PermanentRightsService;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsDTO;
import com.topdraw.business.basicdata.rights.service.RightsService;
......@@ -18,30 +23,24 @@ import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.TaskTemplateService;
import com.topdraw.business.process.domian.*;
import com.topdraw.exception.BadRequestException;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.util.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
/**
* 任务处理
......@@ -56,21 +55,23 @@ public class TaskOperationServiceImpl implements TaskOperationService {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationServiceImpl.class);
@Autowired
private TaskService taskService;
TaskService taskService;
@Autowired
private MemberService memberService;
MemberService memberService;
@Autowired
private RightsService rightsService;
RightsService rightsService;
@Autowired
private TaskTemplateService taskTemplateService;
TaskTemplateService taskTemplateService;
@Autowired
private RightsOperationService rightsOperationService;
RightsOperationService rightsOperationService;
@Autowired
private TrTaskProgressService trTaskProgressService;
TrTaskProgressService trTaskProgressService;
@Autowired
private PermanentRightsService permanentRightsService;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
PermanentRightsService permanentRightsService;
@Autowired
CouponService couponService;
@Autowired
MemberGroupService memberGroupService;
private static final Integer TASK_FINISH_STATUS = 1;
private static final Integer TASK_UNFINISH_STATUS = 2;
......@@ -86,11 +87,6 @@ public class TaskOperationServiceImpl implements TaskOperationService {
Long memberId = msgData.getMemberId();
long l = System.currentTimeMillis();
// 验证会员信息
boolean b = this.validatedMember(memberId);
if (b) {
throw new BadRequestException("【member status exception!!】");
}
// 1.通过任务标识获取任务模板,通过模板参数获取具体的模板
TaskTemplate taskTemplate = this.getTaskTemplate(event);
......@@ -99,9 +95,9 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// 4.判断当前用户是否满足任务完成条件
boolean checkResult = this.checkTaskCompletion(memberId,taskList);
if (checkResult) {
// 5.权益区分(积分、权益、成长值)
Map<RightType,Object> tempRightsMap = this.distinguishRight(memberId,taskList,msgData);
// 6.权益发放
this.grantRight(tempRightsMap);
......@@ -120,12 +116,13 @@ public class TaskOperationServiceImpl implements TaskOperationService {
private boolean validatedMember(Long memberId) {
log.info("validatedMember -->>【memberId】 -->> " + memberId);
MemberDTO memberDTO = this.memberService.findById(memberId);
Integer blackStatus = memberDTO.getBlackStatus();
if (Objects.nonNull(blackStatus) && blackStatus == 1) {
log.error("validatedMember -->> 会员已被加入黑名单 【blackStatus】 -->> " + blackStatus);
Long blackStatus = memberDTO.getBlackStatus();
// TODO 检查balckStatus无法获取的原因
if (Objects.isNull(blackStatus) || blackStatus == 1) {
log.error("validatedMember -->> 会员不存在或者已被加入黑名单 【blackStatus】 -->> " + blackStatus);
return false;
}
return Objects.nonNull(memberDTO) ? true:false;
return true;
}
/**
......@@ -133,6 +130,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* @param memberId 会员id
* @return PermanentRightsDTO 永久权益
*/
@Deprecated
private PermanentRightsDTO getPermanentRights(Long memberId) {
PermanentRightsDTO permanentRights = null;
MemberDTO memberDTO = this.memberService.findById(memberId);
......@@ -149,6 +147,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* @param taskTemplate 任务模板
* @return Map<String, Object> 模板参数解析结果
*/
@Deprecated
private Map<String, Object> parseTaskTemplateParam(TaskTemplate taskTemplate) {
if (Objects.nonNull(taskTemplate)) {
String params = taskTemplate.getParams();
......@@ -166,20 +165,12 @@ public class TaskOperationServiceImpl implements TaskOperationService {
*/
private void doRefreshTrTaskProcess(TrTaskProgress resources) {
Long id = resources.getId();
ReentrantReadWriteLock.WriteLock writeLock = this.reentrantReadWriteLock.writeLock();
try {
writeLock.lock();
if (Objects.nonNull(id)) {
resources.setUpdateTime(TimestampUtil.now());
this.trTaskProgressService.update(resources);
} else {
this.trTaskProgressService.create(resources);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}
/**
......@@ -326,16 +317,15 @@ public class TaskOperationServiceImpl implements TaskOperationService {
/**
* 创建权益
* @param memberId
* @param rightsId
* @param rightsAmount
* @param expireTime
* @return
*/
private TempRights tmpRightsBuild(Long memberId ,Long rightsId, Integer rightsAmount,Long expireTime){
private TempRights tmpRightsBuild(Long memberId ,Integer rightsAmount,RightsDTO rightsDTO){
TempRights tempRights = new TempRights();
BeanUtils.copyProperties(rightsDTO,tempRights);
tempRights.setMemberId(memberId);
tempRights.setRightsAmount(rightsAmount);
tempRights.setId(rightsId);
Long expireTime = rightsDTO.getExpireTime();
if (Objects.nonNull(expireTime))
tempRights.setExpireTime(TimestampUtil.long2Timestamp(expireTime));
return tempRights;
......@@ -344,17 +334,18 @@ public class TaskOperationServiceImpl implements TaskOperationService {
/**
* 优惠券
* @param memberId
* @param rightsId
* @param rightsAmount
* @param rightsSendStrategy
* @return
*/
private TempCoupon tempCouponBuild(Long memberId ,Long rightsId, Integer rightsAmount,Integer rightsSendStrategy){
private TempCoupon tempCouponBuild(Long memberId ,Integer rightsAmount,Integer rightsSendStrategy,CouponDTO couponDTO,String nickname){
TempCoupon tempCoupon = new TempCoupon();
BeanUtils.copyProperties(couponDTO,tempCoupon);
tempCoupon.setCode(couponDTO.getCode());
tempCoupon.setMemberId(memberId);
tempCoupon.setId(rightsId);
tempCoupon.setRightsAmount(rightsAmount);
tempCoupon.setRightsSendStrategy(Objects.isNull(rightsSendStrategy) ? 0 : rightsSendStrategy);
tempCoupon.setUserNickname(nickname);
return tempCoupon;
}
......@@ -369,6 +360,8 @@ public class TaskOperationServiceImpl implements TaskOperationService {
List<TempCoupon> tempCouponList = new ArrayList<>();
// 权益列表,用以保存权益记录
List<TempRights> rightsList = new ArrayList<>();
// 会员信息
MemberDTO memberDTO = this.findMemberById(memberId);
// 权益1
Long rights1Id = task.getRightsId();
......@@ -378,7 +371,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益1发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
// 权益分类
this.getTempRightType(memberId,rights1Id,rights1Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,rights1Id,rights1Amount,rightsSendStrategy,tempCouponList,rightsList);
}
// 权益2
......@@ -388,7 +381,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益2发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
// 权权益分类
this.getTempRightType(memberId,rights2Id,rights2Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,rights2Id,rights2Amount,rightsSendStrategy,tempCouponList,rightsList);
}
// 权益3
......@@ -398,7 +391,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
// TODO 权益3发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
// 权益分类
this.getTempRightType(memberId,rights3Id,rights3Amount,rightsSendStrategy,tempCouponList,rightsList);
this.getTempRightType(memberDTO,rights3Id,rights3Amount,rightsSendStrategy,tempCouponList,rightsList);
}
// 优惠券
map.put(RightType.COUPON,tempCouponList);
......@@ -406,35 +399,51 @@ public class TaskOperationServiceImpl implements TaskOperationService {
return map;
}
/**
* 权益分类
* 会员对象
* @param memberId
* @return
*/
private MemberDTO findMemberById(Long memberId) {
return this.memberService.findById(memberId);
}
/**
* 权益分类
* @param memberDTO
* @param rightsId
* @param rightsAmount
* @param rightsSendStrategy
* @param tempCouponList
* @param rightsList
*/
private void getTempRightType(Long memberId , Long rightsId, Integer rightsAmount,Integer rightsSendStrategy,List<TempCoupon> tempCouponList,
private void getTempRightType(MemberDTO memberDTO , Long rightsId, Integer rightsAmount,Integer rightsSendStrategy,List<TempCoupon> tempCouponList,
List<TempRights> rightsList) {
Long memberId = memberDTO.getId();
String nickname = memberDTO.getNickname();
// 权益详情
RightsDTO rightsDTO = this.getRight(rightsId);
if (Objects.nonNull(rightsDTO)){
// 用以保存权益历史
Long expireTime = rightsDTO.getExpireTime();
TempRights tempRights = this.tmpRightsBuild(memberId,rightsId,rightsAmount,expireTime);
TempRights tempRights = this.tmpRightsBuild(memberId,rightsAmount,rightsDTO);
rightsList.add(tempRights);
// 权益类型
String type = rightsDTO.getEntityType();
switch (type) {
case "1":
Long entityId = rightsDTO.getEntityId();
if (Objects.nonNull(entityId)) {
CouponDTO couponDTO = this.findCouponById(entityId);
if (Objects.nonNull(couponDTO)) {
// 优惠券
TempCoupon tempCoupon = this.tempCouponBuild(memberId,rightsId,rightsAmount,rightsSendStrategy);
TempCoupon tempCoupon = this.tempCouponBuild(memberId, rightsAmount, rightsSendStrategy, couponDTO, nickname);
tempCouponList.add(tempCoupon);
}
}
break;
default:
break;
......@@ -443,6 +452,16 @@ public class TaskOperationServiceImpl implements TaskOperationService {
}
/**
* 获取优惠券信息
* @param id
* @return
*/
private CouponDTO findCouponById(Long id) {
CouponDTO couponDTO = this.couponService.findById(id);
return couponDTO;
}
/**
*
* @param rightsId
* @return
......@@ -528,7 +547,7 @@ public class TaskOperationServiceImpl implements TaskOperationService {
* 1. task_repeat_type 任务重复类型,-1:不限次;1:单次;>1:多次
* 5. member_level 会员等级门槛(0表示无门槛)
* 6. member_vip 会员vip门槛(0表示没有门槛)
* 7. groups 能够获取该任务的用户分组,为空则都能获取
* 7. groups 能够获取该任务的用户分组,为空则都能获取 , 0
* 8. action_amount 行为量(完成此任务需要多少次相同行为的触发)
*
* @param taskList 任务列表
......@@ -539,24 +558,33 @@ public class TaskOperationServiceImpl implements TaskOperationService {
if (!CollectionUtils.isEmpty(taskList)) {
// 会员信息
MemberDTO memberDTO = this.memberService.findById(memberId);
// 判断是否完成任务
CompareTaskCondition compareTaskCondition =(MemberDTO memberDTO1,List<Task> taskList1) -> {
List<Task> taskStream = taskList1.stream().filter(task1 ->
task1.getStatus() == 1 &&
(Objects.isNull(task1.getExpireTime()) || task1.getExpireTime().compareTo(TimestampUtil.now()) >= 0) &&
(Objects.isNull(task1.getGroups()) || task1.getGroups().equalsIgnoreCase(memberDTO1.getGroups())) &&
(Objects.isNull(task1.getValidTime()) || task1.getValidTime().compareTo(TimestampUtil.now()) <= 0) &&
(Objects.isNull(task1.getMemberLevel()) || task1.getMemberLevel() == 0 || task1.getMemberLevel() <= memberDTO1.getLevel()) &&
(Objects.isNull(task1.getMemberVip()) || task1.getMemberVip() == 0 || task1.getMemberVip() <= memberDTO1.getVip())
).collect(Collectors.toList());
(Objects.isNull(task1.getMemberLevel()) || task1.getMemberLevel() <= memberDTO1.getLevel()) &&
(Objects.isNull(task1.getMemberVip()) || task1.getMemberVip() <= memberDTO1.getVip())
).collect(toList());
// 没有满足条件的数据
if (CollectionUtils.isEmpty(taskStream)) {
return false;
} else {
// 验证会员分组
boolean result1 = this.validatedMemberGroup(memberId,taskList);
if (!result1)
return false;
// 获取当前任务的完成情况
boolean result = this.checkAndRefreshTaskCompletion(memberId,taskList);
return result;
}
return true;
};
return compareTaskCondition.compareCondition(memberDTO,taskList);
}
......@@ -565,6 +593,96 @@ public class TaskOperationServiceImpl implements TaskOperationService {
}
/**
* 验证会员分组
* @param memberId
* @param taskList
* @return
*/
private boolean validatedMemberGroup(Long memberId,List<Task> taskList) {
List<MemberGroupDTO> groupDTO = this.findGroupByMemberId(memberId);
if (!CollectionUtils.isEmpty(groupDTO)) {
// 会员分组
List<String> list = new ArrayList<>();
for (MemberGroupDTO memberGroupDTO : groupDTO) {
String groupId = memberGroupDTO.getGroupId().toString();
list.add(groupId);
}
// 任务分组
List<String> strings = new ArrayList<>();
for (Task task : taskList) {
String groups = task.getGroups();
List<String> strings1 = UcStringUtils.parse2StrList(groups);
if (StringUtils.isEmpty(groups)) {
return true;
}
strings.addAll(strings1);
break;
}
// 如果任务分组为null或者空字符,则放过所有的会员
if (CollectionUtils.isEmpty(strings)) {
return true;
}
// 如果任务分组为0,则放过所有的分组
if (!CollectionUtils.isEmpty(strings) && (!CollectionUtils.isEmpty(list) && strings.contains("0")) ) {
return true;
}
if (!CollectionUtils.isEmpty(list)) {
// 只要会员分组满足任务分组之一就满足要求
if (list.size() > strings.size()) {
for (String s : list) {
boolean contains = strings.contains(s);
if (contains) {
return true;
}
}
}
}
if (!CollectionUtils.isEmpty(strings)) {
for (String s : strings) {
boolean contains = list.contains(s);
if (contains) {
return true;
}
}
}
}
return false;
}
/**
*
* @param memberId
* @return
*/
private List<MemberGroupDTO> findGroupByMemberId(Long memberId) {
MemberGroupQueryCriteria memberGroupQueryCriteria = new MemberGroupQueryCriteria();
memberGroupQueryCriteria.setMemberId(memberId);
return this.memberGroupService.queryAll(memberGroupQueryCriteria);
}
/**
* 通过会员id获取分组
* @param memberId
* @return
*/
/*private List<GroupDTO> findGroupByMemberId(Long memberId) {
GroupQueryCriteria groupQueryCriteria = new GroupQueryCriteria();
groupQueryCriteria.setUserId(memberId);
List<GroupDTO> groupDTO = this.groupService.queryAll(groupQueryCriteria);
return groupDTO;
}*/
/**
* 检查并更新当前任务的完成情况
*
* 1.每天都能做,但要求总次数达到行为量
......
......@@ -22,11 +22,10 @@ public class RedissonConfig {
private String password;
@Bean
public RedissonClient redisson(){
public Redisson redisson(){
Config config = new Config();
// config.useSingleServer().setAddress("redis://"+redisHost+":"+port).setPassword("redis123");
if (StringUtils.isNotEmpty(password)) {
config.useSingleServer().setAddress("redis://"+redisHost+":"+port).setPassword(password);;
config.useSingleServer().setAddress("redis://"+redisHost+":"+port).setPassword(password);
} else {
config.useSingleServer().setAddress("redis://"+redisHost+":"+port);
}
......@@ -34,7 +33,8 @@ public class RedissonConfig {
"redis://172.29.3.245:6375","redis://172.29.3.245:6376", "redis://172.29.3.245:6377",
"redis://172.29.3.245:6378","redis://172.29.3.245:6i379", "redis://172.29.3.245:6380")
.setPassword("a123456").setScanInterval(5000);*/
return Redisson.create(config);
Redisson redissonClient = (Redisson)Redisson.create(config);
return redissonClient;
}
}
......
......@@ -11,13 +11,12 @@ import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
/*@Configuration
@PropertySource(value = {"classpath:executor.properties"}, ignoreResourceNotFound=false, encoding="UTF-8")
@Slf4j
@EnableAsync
@Slf4j*/
public class ThreadPoolTaskExecutorConfig {
@Value("${threadPoolExecutor.core_pool_size}")
/*@Value("${threadPoolExecutor.core_pool_size}")
private int corePoolSize;
@Value("${threadPoolExecutor.max_pool_size}")
private int maxPoolSize;
......@@ -28,7 +27,7 @@ public class ThreadPoolTaskExecutorConfig {
@Value("${threadPoolExecutor.keep_alive_seconds}")
private int keepAliveSeconds;
@Bean(value = "executorTask")
@Bean
public ThreadPoolTaskExecutor executorTask(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
......@@ -46,6 +45,6 @@ public class ThreadPoolTaskExecutorConfig {
// 线程初始化
executor.initialize();
return executor;
}
}*/
}
......
......@@ -31,12 +31,12 @@ public class RabbitMqConfig {
}
@Bean
Binding fanoutExchangeBindingIptv(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueIptv){
Binding fanoutExchangeBindingIptv(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueIptv) {
return BindingBuilder.bind(ucFanoutQueueIptv).to(ucFanoutExchange);
}
@Bean
Binding fanoutExchangeBindingWeiXin(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueWeiXin){
Binding fanoutExchangeBindingWeiXin(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueWeiXin) {
return BindingBuilder.bind(ucFanoutQueueWeiXin).to(ucFanoutExchange);
}
......
......@@ -8,7 +8,7 @@ public class LocalDateTimeUtil {
public static String todayStart() {
LocalDate now = LocalDate.now();
return now+" 00:00:00";
return now.toString();
}
public static String todayEnd() {
......
......@@ -3,6 +3,7 @@ package com.topdraw.util;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
public class TimestampUtil {
......@@ -12,29 +13,46 @@ public class TimestampUtil {
}
public static Timestamp now(LocalDateTime localDateTime) {
long epochSecond = localDateTime.toInstant(ZoneOffset.of("+8")).getEpochSecond();
long epochSecond = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
return new Timestamp(epochSecond);
}
public static long localDateTime2Timestamp(LocalDateTime localDateTime){
long epochSecond = localDateTime.atZone(ZoneOffset.systemDefault()).toEpochSecond();
public static long localDateTime2long(LocalDateTime localDateTime){
long epochSecond = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
return epochSecond;
}
public static Timestamp localDateTime2Timestamp(LocalDateTime localDateTime){
long epochSecond = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
return long2Timestamp(epochSecond);
}
public static Timestamp long2Timestamp(long timestamp){
Timestamp timestamp1 = Timestamp.from(Instant.ofEpochSecond(timestamp));
Timestamp timestamp1 = Timestamp.from(Instant.ofEpochMilli(timestamp));
return timestamp1;
}
public static long Timestamp2long(Timestamp timestamp){
return timestamp.toInstant().getEpochSecond();
public static long timestamp2long(Timestamp timestamp){
long l = timestamp.toInstant().toEpochMilli();
return l;
}
public static void main(String[] args) {
LocalDateTime of = LocalDateTime.of(2021, 10, 28, 11, 00, 00);
long l = localDateTime2Timestamp(of);
long a = 1636616464000L;
long b = 1637046948588L;
long c = 1637047122176L;
// long l = 16342727230L;
// Timestamp now = now(LocalDateTime.now());
long l = localDateTime2long(LocalDateTime.now());
System.out.println(l);
// System.out.println(now.toString());
Timestamp timestamp1 = long2Timestamp(a);
// long l = localDateTime2Timestamp(of);
// long l = 16342727230L;
Timestamp timestamp = long2Timestamp(l);
System.out.println(timestamp.toString());
// Timestamp timestamp = long2Timestamp(l);
System.out.println(timestamp1.toString());
long l1 = localDateTime2long(LocalDateTime.now());
System.out.println(l1);
}
}
......
package com.topdraw.util;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class UcStringUtils {
public static List<String> parse2StrList(String resouce){
String[] split = resouce.split(",");
if (split.length > 0) {
List<String> collect = Arrays.stream(resouce.split(",")).collect(Collectors.toList());
return collect;
} else {
List<String> strings = Arrays.asList(resouce);
return strings;
}
}
}
......@@ -2,12 +2,15 @@
spring:
datasource:
# 测试/演示库
url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: Tjlh@2017
url: jdbc:log4jdbc:mysql://47.100.212.170:3306/ucs?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: Tjlh@2017
password: Tjlh@2021
# url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: root
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
......
......@@ -2,14 +2,9 @@
spring:
datasource:
# 测试/演示库
url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
url: jdbc:log4jdbc:mysql://172.0.31.10:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: Tjlh@2017
# url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: root
password: Tjlh@2021
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#Druid
type: com.alibaba.druid.pool.DruidDataSource
......@@ -53,24 +48,21 @@ spring:
max-request-size: 200MB
redis:
#数据库索引
database: 16
host: 122.112.214.149
# host: 139.196.4.234
database: 0
host: 127.0.0.1
port: 6379
password: redis123
# password:
#连接超时时间
timeout: 5000
rabbitmq:
host: 122.112.214.149 # rabbitmq的连接地址
host: 172.0.31.96 # rabbitmq的连接地址
#host: 139.196.192.242 # rabbitmq的连接地址
port: 5672 # rabbitmq的连接端口号
#virtual-host: /member_center # rabbitmq的虚拟host
#username: member_center # rabbitmq的用户名
#password: Tjlh@2021 # rabbitmq的密码
virtual-host: / # rabbitmq的虚拟host
username: guest # rabbitmq的用户名
password: guest # rabbitmq的密码
virtual-host: member_center # rabbitmq的虚拟host
username: admin # rabbitmq的用户名
password: Tjlh@2021 # rabbitmq的密码
publisher-confirms: true #如果对异步消息需要回调必须设置为true
#jwt。依赖的common中有需要jwt的部分属性。
......
server:
port: 8447
spring:
application:
name: member-service
......@@ -10,6 +9,8 @@ spring:
active: dev
jackson:
time-zone: GMT+8
cache:
type: simple
data:
redis:
repositories:
......
......@@ -39,16 +39,16 @@ public class GeneratorCode extends BaseTest {
@Rollback(value = false)
@Transactional(rollbackFor = Exception.class)
public void generator() {
var dbName = "uc_tr_task_progress";
var dbName = "uc_member_group";
// 表名称,支持多表
var tableNames = Arrays.asList(dbName);
String[] s = dbName.split("_");
var pre = s[0];
var target1 = s[s.length-1];
var preRoute = "com.topdraw.business.basicdata.task.";
var preRoute = "com.topdraw.business.basicdata.member.";
StringBuilder builder = new StringBuilder(preRoute);
builder.append("progress");
builder.append("group");
// builder.append(target);
tableNames.forEach(tableName -> {
......
......@@ -13,7 +13,7 @@ public class MemberServiceTest extends BaseTest {
@Test
public void findById(){
Long memberId = 1L;
Long memberId = 3L;
MemberDTO memberDTO = this.memberService.findById(memberId);
LOG.info("=====>>>" + memberDTO);
......
package com.topdraw.test.business.basicdata.task;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.BaseTest;
import com.topdraw.business.process.service.impl.CompareTaskCondition;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.assertj.core.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
//public class TaskServiceTest extends BaseTest {
public class TaskServiceTest {
@Test
public void dealTaskTest(){
// List<Task> taskList = this.taskService.findByTemplateId(1L);
// LOG.info("=====>>>" + taskList);
Task task = new Task();
task.setTaskTemplateId(1L);
task.setTaskDailyReset(1);
task.setActionAmount(1);
task.setValidTime(TimestampUtil.now());
task.setExpireTime(TimestampUtil.now());
task.setSequence(1);
task.setRewardExp(10L);
task.setRewardPoints(1L);
task.setRewardPointsExpireTime(TimestampUtil.Timestamp2long(TimestampUtil.now()));
task.setPointsType(1);
task.setRewardMaxPoints(1);
task.setGroups("groups");
task.setRightsSendStrategy(1);
task.setMemberLevel(1);
task.setMemberVip(1);
task.setRightsId(1L);
task.setRightsAmount(1);
task.setRights2Id(2L);
task.setRights2Amount(1);
task.setRights3Id(3L);
task.setRights3Amount(1);
task.setStatus(1);
List<Task> taskList = new ArrayList<>();
taskList.add(task);
MemberDTO member = new MemberDTO();
member.setCode(String.valueOf(IdWorker.generator()));
member.setType(1);
member.setStatus(1);
member.setNickname("nickname");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(10L);
member.setPoints(5L);
member.setDuePoints(0L);
member.setCouponAmount(1L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
member.setUpdateTime(TimestampUtil.now());
// 判断是否完成任务
CompareTaskCondition compareTaskCondition =(MemberDTO memberDTO1, List<Task> taskList1) -> {
List<Task> taskStream = taskList1.stream().filter(task1 ->
task1.getStatus() == 1 &&
(Objects.isNull(task1.getExpireTime()) || task1.getExpireTime().compareTo(TimestampUtil.now()) <= 0) &&
(Objects.isNull(task1.getGroups()) || task1.getGroups().equalsIgnoreCase(memberDTO1.getGroups())) &&
(Objects.isNull(task1.getValidTime()) || task1.getValidTime().compareTo(TimestampUtil.now()) <= 0) &&
(task1.getMemberLevel() == 0 || task1.getMemberLevel() <= memberDTO1.getLevel()) &&
(task1.getMemberVip() == 0 || task1.getMemberVip() == memberDTO1.getVip())
).collect(Collectors.toList());
if (CollectionUtils.isEmpty(taskStream)) {
return false;
}
return true;
};
boolean b = compareTaskCondition.compareCondition(member, taskList);
System.out.println(b);
}
}
......@@ -21,12 +21,11 @@ public class ExpOperationControllerTest extends BaseTest {
@Test
public void grantExpByManual(){
Long memberId = 2L;
Long memberId = 3L;
Long userId = 2L;
TempExp tempExp = new TempExp();
tempExp.setMemberId(memberId);
tempExp.setRewardExp(10L);
tempExp.setMemberId(2L);
tempExp.setRightsSendStrategy(0);
tempExp.setAccountId(userId);
tempExp.setExpireTime(Timestamp.valueOf("2021-10-28 09:00:00"));
......
......@@ -53,25 +53,47 @@ public class PointsOperationControllerTest extends BaseTest {
@Test
public void grantPointsByManual(){
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(10L);
tempPoints.setPoints(10L);
tempPoints.setPointsType(0);
tempPoints.setMemberId(3L);
tempPoints.setRightsSendStrategy(0);
tempPoints.setAccountId(2L);
tempPoints.setExpireTime(Timestamp.valueOf("2021-10-27 09:00:00"));
tempPoints.setExpireTime(Timestamp.valueOf("2021-11-27 09:00:00"));
tempPoints.setDeviceType(2);
tempPoints.setAppCode("WEI_XIN_GOLD_PANDA");
tempPoints.setOrderId(null);
tempPoints.setMediaId(null);
tempPoints.setActivityId(null);
tempPoints.setItemId(null);
tempPoints.setDescription("#");
tempPoints.setDescription("系统发放");
tempPoints.setEvtType(1);
String s = JSON.toJSONString(tempPoints);
ResultInfo byId = this.pointsOperationController.grantPointsByManual(tempPoints);
LOG.info("===>>>"+byId);
}
@Test
public void cleanInvalidPointsAndCalculateCurrentPoints(){
/*TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(5L);
tempPoints.setPoints(10L);
tempPoints.setPointsType(0);
tempPoints.setRightsSendStrategy(0);
tempPoints.setAccountId(2L);
tempPoints.setExpireTime(Timestamp.valueOf("2021-11-27 09:00:00"));
tempPoints.setDeviceType(2);
tempPoints.setAppCode("WEI_XIN_GOLD_PANDA");
tempPoints.setOrderId(null);
tempPoints.setMediaId(null);
tempPoints.setActivityId(null);
tempPoints.setItemId(null);
tempPoints.setDescription("系统发放");
tempPoints.setEvtType(1);
String s = JSON.toJSONString(tempPoints);*/
ResultInfo byId = this.pointsOperationController.cleanInvalidPointsAndCalculateCurrentPoints(5L);
LOG.info("===>>>"+byId);
}
/*@Test
public void update(){
MemberAddress memberAddress = new MemberAddress();
......
......@@ -18,7 +18,7 @@ public class RightOperationControllerTest extends BaseTest {
public void grantRightsByManual(){
RightsHistory rightsHistory = new RightsHistory();
rightsHistory.setRightsId(1L);
rightsHistory.setMemberId(5L);
rightsHistory.setMemberId(3L);
rightsHistory.setOperatorId(3L);
rightsHistory.setOperatorName("鲁二龙");
rightsHistory.setExpireTime(TimestampUtil.now());
......
......@@ -8,8 +8,17 @@ import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EntityType;
import com.topdraw.module.mq.EventType;
import com.topdraw.BaseTest;
import com.topdraw.utils.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TaskOperationControllerTest extends BaseTest {
......@@ -20,11 +29,11 @@ public class TaskOperationControllerTest extends BaseTest {
public void dealTask() {
try {
DataSyncMsg dataSyncMsg = new DataSyncMsg();
dataSyncMsg.setEventType(EventType.LOGIN.name());
dataSyncMsg.setEventType(EventType.VIEWING.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setEvent(6); // 类型 1-登录 2-观影 3-参加活动 4-订购 5-优享会员 6-签到
msgData.setRemarks("remark");
msgData.setMemberId(3L);
msgData.setMemberId(4L);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsg(msgData);
......@@ -37,9 +46,72 @@ public class TaskOperationControllerTest extends BaseTest {
} catch (Exception e) {
e.printStackTrace();
}
}
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
public void t1() throws InterruptedException {
Thread.sleep(1*1000);
System.out.println(Thread.currentThread().getName()+"=======>>> t1");
}
public void t2() throws InterruptedException {
Thread.sleep(1*1000);
System.out.println(Thread.currentThread().getName()+"=======>>> t2");
}
public void t3() throws InterruptedException {
Thread.sleep(1*1000);
System.out.println(Thread.currentThread().getName()+"=======>>> t3");
}
@Test
public void main() {
long l = System.currentTimeMillis();
FutureTask futureTask1 = new FutureTask(()->{
t1();
return null;
});
FutureTask futureTask2 = new FutureTask(()->{
t2();
return null;
});
FutureTask futureTask3 = new FutureTask(()->{
t3();
return null;
});
threadPoolTaskExecutor.execute(futureTask1);
threadPoolTaskExecutor.execute(futureTask2);
threadPoolTaskExecutor.execute(futureTask3);
long l1 = System.currentTimeMillis();
System.out.println(l1-l);
/*threadPoolTaskExecutor.execute(()->{
for (int i = 0; i < 10; i++) {
try {
// Thread.sleep(2*1000);
System.out.println("===>>>> ");
} catch (Exception e) {
e.printStackTrace();
}
}
});*/
System.out.println("======>>> main end");
}
}
......
......@@ -46,7 +46,8 @@ public class PointsOperationServiceTest extends BaseTest {
@Test
public void cleanInvalidAvailablePoints() {
this.pointsOperationService.cleanInvalidAvailablePoints();
Long memberId = 10L;
this.pointsOperationService.cleanInvalidPointsAndCalculateCurrentPoints(memberId);
}
}
......