提交 0181d37d 编写于 作者: 街头小贩's avatar 街头小贩

增加MemberVipExchangeRecords

上级 23bfd310
package com.apobates.forum.member.api.dao;
import java.time.LocalDateTime;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.*;
import java.util.stream.Stream;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberGroupEnum;
......@@ -91,7 +87,15 @@ public interface MemberDao {
* @return
*/
int editMemberStatus(Map<Long,MemberStatusEnum> status);
/**
* 将指定的会员的组更新为MemberGroupEnum.CARD
*
* @param updateMemberIds 更新的会员ID集合
* @return
*/
int editMemberGroup(Set<Long> updateMemberIds);
/**
* 查看会员的头像
*
......
......@@ -33,31 +33,29 @@ public interface MemberPenalizeRecordsDao extends PagingAndSortingRepository<Mem
Stream<MemberPenalizeRecords> findAllByMember(long memberId);
/**
* 查看指定日期范围内可用的惩罚记录
* 查看指定日期范围内可用的惩罚记录,MemberPenalizeRecords.rebirthDateTime为参考
*
* @param start 开始日期
* @param finish 结束日期
* @return
*/
Stream<MemberPenalizeRecords> findAll(LocalDateTime start, LocalDateTime finish);
Stream<MemberPenalizeRecords> findAllByExpire(LocalDateTime start, LocalDateTime finish);
/**
* 更新惩罚记录的状态
*
* @param id 惩罚记录ID
* @param status 状态
* @return
*/
Optional<Boolean> editStatus(long id, boolean status);
Optional<Boolean> expired(long id);
/**
* 更新惩罚记录的状态
*
* @param idList 惩罚记录ID列表
* @param status 状态
* @return
*/
int editStatus(Collection<Long> idList, boolean status);
int expired(Collection<Long> idList);
/**
* 统计指定会员的惩罚记录
......
package com.apobates.forum.member.api.dao;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import com.apobates.forum.utils.persistence.PagingAndSortingRepository;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;
/**
*
* @author xiaofanku
* @since 20200921
*/
public interface MemberVipExchangeRecordsDao extends PagingAndSortingRepository<MemberVipExchangeRecords, Long> {
/**
* 查看指定会员的VIP交易记录
*
* @param memberId 会员ID
* @param pageable 分页请求参数
* @return
*/
Page<MemberVipExchangeRecords> findAllByMember(long memberId, Pageable pageable);
/**
* 查看指定日期范围的VIP交易记录
*
* @param start 开始日期
* @param finish 结束日期
* @param pageable 分页请求参数
* @return
*/
Page<MemberVipExchangeRecords> findAll(LocalDateTime start, LocalDateTime finish, Pageable pageable);
/**
* 最近的VIP交易记录
*
* @param size 显示的数量
* @return
*/
Stream<MemberVipExchangeRecords> findAllOfRecent(int size);
/**
* 查看即将到期的VIP交易记录,以MemberVipExchangeRecords.lapseDateTime为参考
*
* @param lapseDateStart 到期日期的开始(凌晨)
* @param lapseDateFinish 到期日期的结束(午夜)
* @return
*/
Stream<MemberVipExchangeRecords> findAllByExpire(LocalDateTime lapseDateStart, LocalDateTime lapseDateFinish);
/**
* 将指定的VIP交易记录作废
*
* @param idList 惩罚记录ID列表
* @return
*/
int expired(Collection<Long> idList);
/**
* 将指定的VIP交易记录作废
*
* @param id VIP交易记录ID
* @return
*/
Optional<Boolean> expired(long id);
}
......@@ -10,10 +10,7 @@ import java.util.stream.Stream;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.event.elderly.MemberActionDescriptor;
import com.apobates.forum.member.MemberProfileBean;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.entity.MemberStatusEnum;
import com.apobates.forum.member.entity.*;
import com.apobates.forum.member.exception.MemberNamesExistException;
import com.apobates.forum.member.exception.MemberNamesProtectException;
......@@ -160,7 +157,32 @@ public interface MemberService {
* @param actionDescriptor 会员请求描述符
*/
Optional<Boolean> signOut(String memberNames, Member member, MemberActionDescriptor actionDescriptor);
/**
* 将会员的默认组(CARD)提升至VIP
* @deprecated
* @param memberId 会员ID
* @param duration 有效日期时长
* @param unit 有效日期单位,只接受ForumCalendarUnitEnum.MONTH(月),只接受ForumCalendarUnitEnum.YEAR(年)
* @throws IllegalStateException
* @throws IllegalArgumentException
* @return
*/
Optional<Boolean> exchangeVIP(long memberId, int duration, ForumCalendarUnitEnum unit)throws IllegalStateException, IllegalArgumentException;
/**
* 将会员的默认组(CARD)提升至VIP
*
* @param memberId 会员ID
* @param duration 有效日期时长
* @param unit 有效日期单位,只接受ForumCalendarUnitEnum.MONTH(月),只接受ForumCalendarUnitEnum.YEAR(年)
* @param transerial 交易流水号
* @return
* @throws IllegalStateException
* @throws IllegalArgumentException
*/
Optional<Boolean> exchangeVIP(long memberId, int duration, ForumCalendarUnitEnum unit, String transerial)throws IllegalStateException, IllegalArgumentException;
/**
* 查看指定的会员
*
......
package com.apobates.forum.member.api.service;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.stream.Stream;
/**
*
* @author xiaofanku
* @since 20200921
*/
public interface MemberVipExchangeRecordsService {
/**
* 查看指定日期范围的VIP交易记录
*
* @param start 开始日期
* @param finish 结束日期
* @param pageable 分页请求参数
* @return
*/
Page<MemberVipExchangeRecords> getAll(LocalDateTime start, LocalDateTime finish, Pageable pageable);
/**
* 查看指定会员的VIP交易记录
*
* @param memberId 会员ID
* @param pageable 分页请求参数
* @return
*/
Page<MemberVipExchangeRecords> getAll(long memberId, Pageable pageable);
/**
* 查看所有的VIP交易记录
*
* @param pageable 分页请求参数
* @return
*/
Page<MemberVipExchangeRecords> getAll(Pageable pageable);
/**
* 最近的VIP交易记录
*
* @param size 显示的数量
* @return
*/
Stream<MemberVipExchangeRecords> getRecent(int size);
/**
* 手动结束VIP交易记录.必须是交易记录已经到期
*
* @param id VIP交易记录ID
* @return
*/
Optional<Boolean> expired(long id)throws IllegalArgumentException,IllegalStateException;
}
......@@ -7,6 +7,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.apobates.forum.member.api.dao.MemberVipExchangeRecordsDao;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -25,6 +28,8 @@ public class MemberTask {
@Autowired
private MemberPenalizeRecordsDao memberPenalizeRecordsDao;
@Autowired
private MemberVipExchangeRecordsDao memberVipExchangeRecordsDao;
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberTask.class);
......@@ -34,7 +39,7 @@ public class MemberTask {
LocalDateTime finish = LocalDateTime.now();
LocalDateTime start = DateTimeUtils.beforeMinuteForDate(finish, 1); //作业的执行周期
//
List<MemberPenalizeRecords> data = memberPenalizeRecordsDao.findAll(start, finish).collect(Collectors.toList());
List<MemberPenalizeRecords> data = memberPenalizeRecordsDao.findAllByExpire(start, finish).collect(Collectors.toList());
if(data.isEmpty()){ //没有结果
logger.info("[Task][Member][1]没有惩罚记录,作业退出");
return;
......@@ -47,8 +52,31 @@ public class MemberTask {
penalizeIds.add(mpr.getId());
memberStatus.put(mpr.getMemberId(), mpr.getOriginal()); //回到原来的状态
}
memberPenalizeRecordsDao.editStatus(penalizeIds, false);
memberPenalizeRecordsDao.expired(penalizeIds);
memberDao.editMemberStatus(memberStatus);
logger.info("[Task][Member][1]会员惩罚作业结束");
}
//VIP会员到斯后重设会员组
public void vipExchangeResetMemberGroupJob(){
logger.info("[Task][Member][3]VIP交易记录作业开始");
LocalDateTime finish = LocalDateTime.now();
LocalDateTime start = DateTimeUtils.beforeMinuteForDate(finish, 1); //作业的执行周期
//
List<MemberVipExchangeRecords> data = memberVipExchangeRecordsDao.findAllByExpire(start, finish).collect(Collectors.toList());
if (data.isEmpty()) { //没有结果
logger.info("[QuartzTask][Member][3]没有VIP交易记录,作业退出");
return;
}
//
Set<Long> exchangeIds = new HashSet<>();
Set<Long> memberIds = new HashSet<>();
//
for (MemberVipExchangeRecords ver : data) {
exchangeIds.add(ver.getId());
memberIds.add(ver.getMemberId());
}
memberVipExchangeRecordsDao.expired(exchangeIds);
memberDao.editMemberGroup(memberIds);
logger.info("[QuartzTask][Member][3]VIP交易记录作业结束");
}
}
......@@ -27,4 +27,11 @@ public class MemberTaskScheduleConfig {
getTask().rebirthMemberJob();
logger.info("[Task][member]penalize job end");
}
@Scheduled(fixedDelay = 60000) //1*60*1000
public void vipExchangeResetMemberGroupScheduleJob() {
logger.info("[Task][member]start Vip Exchange job");
getTask().vipExchangeResetMemberGroupJob();
logger.info("[Task][member]Vip Exchange job end");
}
}
......@@ -2,12 +2,8 @@ package com.apobates.forum.member.impl.dao;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.TreeMap;
import java.util.stream.Stream;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
......@@ -38,7 +34,7 @@ public class MemberDaoImpl implements MemberDao {
@Autowired
private MemberEventPublisher memberEventPublisher;
private final static Logger logger = LoggerFactory.getLogger(MemberDaoImpl.class);
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void save(Member member) {
......@@ -110,7 +106,7 @@ public class MemberDaoImpl implements MemberDao {
}
return complete;
}
/**
* 更新会员的状态,角色,组时要更新缓存@20200502
*/
......@@ -125,7 +121,7 @@ public class MemberDaoImpl implements MemberDao {
}
return complete;
}
/**
* 更新会员的状态,角色,组时要更新缓存@20200502
*/
......@@ -157,7 +153,7 @@ public class MemberDaoImpl implements MemberDao {
}
return Optional.empty();
}
@Override
public Optional<String> findSalt(String memberNames) {// salt
try {
......@@ -226,7 +222,7 @@ public class MemberDaoImpl implements MemberDao {
return 0L;
}
}
@Override
......@@ -241,7 +237,7 @@ public class MemberDaoImpl implements MemberDao {
}
return Optional.empty();
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Optional<Boolean> editAvatar(long id, String encodeAvatarPath) {
......@@ -308,6 +304,18 @@ public class MemberDaoImpl implements MemberDao {
return affect;
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public int editMemberGroup(Set<Long> updateMemberIds) {
int affect = 0;
for (Long memberId : updateMemberIds) {
if (editMemberGroup(memberId, MemberGroupEnum.CARD)) {
affect += 1;
}
}
return affect;
}
@Override
public TreeMap<String, Long> groupMemberForBirthDate(LocalDateTime start, LocalDateTime finish) {
final String SQL="SELECT FUNCTION('DATE', m.registeDateTime), COUNT(m) FROM Member m WHERE m.registeDateTime BETWEEN ?1 AND ?2 GROUP BY FUNCTION('DATE', m.registeDateTime)";
......@@ -358,7 +366,7 @@ public class MemberDaoImpl implements MemberDao {
continue;
}
data.put(k, v);
}
return data;
}
......@@ -385,7 +393,7 @@ public class MemberDaoImpl implements MemberDao {
continue;
}
data.put(k, v);
}
return data;
}
......@@ -412,7 +420,7 @@ public class MemberDaoImpl implements MemberDao {
continue;
}
data.put(k, v);
}
return data;
}
......
......@@ -146,7 +146,7 @@ public class MemberPenalizeRecordsDaoImpl implements MemberPenalizeRecordsDao{
}
@Override
public Stream<MemberPenalizeRecords> findAll(LocalDateTime start, LocalDateTime finish) {
public Stream<MemberPenalizeRecords> findAllByExpire(LocalDateTime start, LocalDateTime finish) {
final String SQL="SELECT mpr FROM MemberPenalizeRecords mpr WHERE mpr.status = :sta AND mpr.rebirthDateTime BETWEEN :art AND :ish";
return entityManager.createQuery(SQL, MemberPenalizeRecords.class)
.setParameter("sta", true)
......@@ -157,8 +157,12 @@ public class MemberPenalizeRecordsDaoImpl implements MemberPenalizeRecordsDao{
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Optional<Boolean> editStatus(long id, boolean status) {
int affect = entityManager.createQuery("UPDATE MemberPenalizeRecords mpr SET mpr.status = ?1 WHERE mpr.id = ?2").setParameter(1, status).setParameter(2, id).executeUpdate();
public Optional<Boolean> expired(long id) {
int affect = entityManager.createQuery("UPDATE MemberPenalizeRecords mpr SET mpr.status = ?1 WHERE mpr.id = ?2 AND mpr.status = ?3")
.setParameter(1, false)
.setParameter(2, id)
.setParameter(3, true)
.executeUpdate();
if(affect == 1){
return Optional.of(true);
}
......@@ -167,11 +171,11 @@ public class MemberPenalizeRecordsDaoImpl implements MemberPenalizeRecordsDao{
@Transactional(propagation = Propagation.REQUIRED)
@Override
public int editStatus(Collection<Long> idList, boolean status) {
public int expired(Collection<Long> idList) {
Integer affect = 0;
Query query = entityManager.createQuery("UPDATE MemberPenalizeRecords mpr SET mpr.status = ?1 WHERE mpr.id = ?2");
Query query = entityManager.createQuery("UPDATE MemberPenalizeRecords mpr SET mpr.status = ?1 WHERE mpr.id = ?2 AND mpr.status = ?3");
for (Long id : idList) {
affect += query.setParameter(1, status).setParameter(2, id).executeUpdate();
affect += query.setParameter(1, false).setParameter(2, id).setParameter(3, true).executeUpdate();
}
return affect;
}
......
package com.apobates.forum.member.impl.dao;
import com.apobates.forum.member.api.dao.MemberVipExchangeRecordsDao;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;
/**
*
* @author xiaofanku
* @since 20200921
*/
@Repository
public class MemberVipExchangeRecordsDaoImpl implements MemberVipExchangeRecordsDao {
@PersistenceContext
private EntityManager entityManager;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeRecordsDaoImpl.class);
@Override
public Page<MemberVipExchangeRecords> findAllByMember(long memberId, Pageable pageable) {
final long total = findAllByMemberCount(memberId);
if (total == 0) {
return emptyResult();
}
final String SQL = "SELECT ver FROM MemberVipExchangeRecords ver WHERE ver.memberId = ?1 ORDER BY ver.entryDateTime DESC";
TypedQuery<MemberVipExchangeRecords> query = entityManager.createQuery(SQL, MemberVipExchangeRecords.class).setParameter(1, memberId);
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
final Stream<MemberVipExchangeRecords> result = query.getResultStream();
return new Page<MemberVipExchangeRecords>() {
@Override
public long getTotalElements() {
return total;
}
@Override
public Stream<MemberVipExchangeRecords> getResult() {
return result;
}
};
}
private long findAllByMemberCount(long memberId){
try {
return entityManager.createQuery("SELECT COUNT(ver) FROM MemberVipExchangeRecords ver WHERE ver.memberId = ?1", Long.class).setParameter(1, memberId).getSingleResult();
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("[findAllByMemberCount][MemberVipExchangeRecords]", e);
}
}
return 0L;
}
@Override
public Page<MemberVipExchangeRecords> findAll(LocalDateTime start, LocalDateTime finish, Pageable pageable) {
final long total = countByDateRange(start, finish);
if (total == 0) {
return emptyResult();
}
final String SQL = "SELECT ver FROM MemberVipExchangeRecords ver WHERE ver.activeDateTime >= ?1 AND ver.lapseDateTime <= ?2 ORDER BY ver.entryDateTime DESC";
TypedQuery<MemberVipExchangeRecords> query = entityManager.createQuery(SQL, MemberVipExchangeRecords.class).setParameter(1, start).setParameter(2, finish);
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
final Stream<MemberVipExchangeRecords> result = query.getResultStream();
return new Page<MemberVipExchangeRecords>() {
@Override
public long getTotalElements() {
return total;
}
@Override
public Stream<MemberVipExchangeRecords> getResult() {
return result;
}
};
}
private long countByDateRange(LocalDateTime start, LocalDateTime finish){
try {
return entityManager.createQuery("SELECT COUNT(ver) FROM MemberVipExchangeRecords ver WHERE ver.activeDateTime >= ?1 AND ver.lapseDateTime <= ?2 ", Long.class)
.setParameter(1, start)
.setParameter(2, finish)
.getSingleResult();
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("[countByDateRange][MemberVipExchangeRecords]", e);
}
}
return 0L;
}
@Override
public Stream<MemberVipExchangeRecords> findAllOfRecent(int size) {
return entityManager.createQuery("SELECT ver FROM MemberVipExchangeRecords ver ORDER BY ver.entryDateTime DESC", MemberVipExchangeRecords.class).setMaxResults(size).getResultStream();
}
@Override
public Page<MemberVipExchangeRecords> findAll(Pageable pageable) {
final long total = count();
if (total == 0) {
return emptyResult();
}
final String SQL = "SELECT ver FROM MemberVipExchangeRecords ver ORDER BY ver.entryDateTime DESC";
TypedQuery<MemberVipExchangeRecords> query = entityManager.createQuery(SQL, MemberVipExchangeRecords.class);
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
final Stream<MemberVipExchangeRecords> result = query.getResultStream();
return new Page<MemberVipExchangeRecords>() {
@Override
public long getTotalElements() {
return total;
}
@Override
public Stream<MemberVipExchangeRecords> getResult() {
return result;
}
};
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void save(MemberVipExchangeRecords entity) {
entityManager.persist(entity);
}
@Override
public Optional<MemberVipExchangeRecords> findOne(Long primaryKey) {
return Optional.ofNullable(entityManager.find(MemberVipExchangeRecords.class, primaryKey));
}
@Override
public Optional<Boolean> edit(MemberVipExchangeRecords updateEntity) {
return Optional.empty();
}
@Override
public Stream<MemberVipExchangeRecords> findAll() {
return Stream.empty();
}
@Override
public long count() {
try {
return entityManager.createQuery("SELECT COUNT(ver) FROM MemberVipExchangeRecords ver", Long.class).getSingleResult();
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("[count][MemberVipExchangeRecords]", e);
}
}
return 0L;
}
@Override
public Stream<MemberVipExchangeRecords> findAllByExpire(LocalDateTime lapseDateStart, LocalDateTime lapseDateFinish) {
return entityManager.createQuery("SELECT ver FROM MemberVipExchangeRecords ver WHERE ver.lapseDateTime BETWEEN ?1 AND ?2 ORDER BY ver.entryDateTime DESC", MemberVipExchangeRecords.class)
.setParameter(1, lapseDateStart)
.setParameter(2, lapseDateFinish)
.getResultStream();
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public int expired(Collection<Long> idList) {
int affect = 0;
Query query = entityManager.createQuery("UPDATE MemberVipExchangeRecords ver SET ver.status = ?1 WHERE ver.id = ?2 AND ver.status = ?3");
for (Long id : idList) {
affect += query.setParameter(1, false).setParameter(2, id).setParameter(3, true).executeUpdate();
}
return affect;
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Optional<Boolean> expired(long id) {
int affect = entityManager.createQuery("UPDATE MemberVipExchangeRecords ver SET ver.status = ?1 WHERE ver.id = ?2 AND ver.status = ?3")
.setParameter(1, false)
.setParameter(2, id)
.setParameter(3, true)
.executeUpdate();
if (affect == 1) {
return Optional.of(true);
}
return Optional.empty();
}
}
......@@ -53,4 +53,12 @@ public class MemberEventPublisher {
public void publishChangeEvent(MemberChangeEvent memberChangeEvent){
applicationEventPublisher.publishEvent(memberChangeEvent);
}
/**
* 发布VIP交易记录
* @param memberVipExchangeEvent
*/
public void publishVipExchangeEvent(MemberVipExchangeEvent memberVipExchangeEvent){
applicationEventPublisher.publishEvent(memberVipExchangeEvent);
}
}
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import org.springframework.context.ApplicationEvent;
public class MemberVipExchangeEvent extends ApplicationEvent {
private final MemberVipExchangeRecords record;
public MemberVipExchangeEvent(Object source, MemberVipExchangeRecords record) {
super(source);
this.record = record;
}
public MemberVipExchangeRecords getRecord() {
return record;
}
}
\ No newline at end of file
package com.apobates.forum.member.impl.event.listener;
import com.apobates.forum.member.api.dao.MemberDao;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MemberVipExchangeGroupListener implements ApplicationListener<MemberVipExchangeEvent> {
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeGroupListener.class);
@Override
public void onApplicationEvent(MemberVipExchangeEvent event) {
logger.info("[Member][VipExchangeEvent][1]VIP会员的组变更开始");
MemberVipExchangeRecords vee = event.getRecord();
if (vee.getId() > 0) {
memberDao.editMemberGroup(vee.getMemberId(), MemberGroupEnum.VIP);
}
logger.info("[Member][VipExchangeEvent][1]VIP会员的组结束变更");
}
}
......@@ -13,6 +13,10 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.apobates.forum.member.api.dao.*;
import com.apobates.forum.member.entity.*;
import com.apobates.forum.member.impl.event.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -26,26 +30,10 @@ import com.apobates.forum.event.elderly.MemberActionDescriptor;
import com.apobates.forum.member.MemberBaseProfile;
import com.apobates.forum.member.MemberProfile;
import com.apobates.forum.member.MemberProfileBean;
import com.apobates.forum.member.api.dao.ForumScoreRoleDao;
import com.apobates.forum.member.api.dao.MemberActiveRecordsDao;
import com.apobates.forum.member.api.dao.MemberDao;
import com.apobates.forum.member.api.dao.MemberNamesProtectDao;
import com.apobates.forum.member.api.dao.RegisteInviteCodeDao;
import com.apobates.forum.member.api.service.MemberLevelService;
import com.apobates.forum.member.api.service.MemberService;
import com.apobates.forum.member.entity.ForumScoreRole;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberNamesProtect;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.entity.MemberStatusEnum;
import com.apobates.forum.member.entity.RegisteInviteCode;
import com.apobates.forum.member.exception.MemberNamesExistException;
import com.apobates.forum.member.exception.MemberNamesProtectException;
import com.apobates.forum.member.impl.event.MemberEventPublisher;
import com.apobates.forum.member.impl.event.MemberSignInEvent;
import com.apobates.forum.member.impl.event.MemberSignOutEvent;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.DateTimeUtils;
import com.apobates.forum.utils.lang.TriFunction;
......@@ -66,6 +54,8 @@ public class MemberServiceImpl implements MemberService{
@Autowired
private MemberLevelService memberLevelService;
@Autowired
private MemberVipExchangeRecordsDao memberVipExchangeRecordsDao;
@Autowired
private MemberEventPublisher memberEventPublisher;
private final static Logger logger = LoggerFactory.getLogger(MemberServiceImpl.class);
......@@ -324,7 +314,38 @@ public class MemberServiceImpl implements MemberService{
data.put("id", String.valueOf(inviteCodeId));
return data;
}
@Override
public Optional<Boolean> exchangeVIP(long memberId, int duration, ForumCalendarUnitEnum unit)throws IllegalStateException, IllegalArgumentException {
return exchangeVIP(memberId, duration, unit, null);
}
@Override
public Optional<Boolean> exchangeVIP(long memberId, int duration, ForumCalendarUnitEnum unit, String transerial) throws IllegalStateException, IllegalArgumentException {
if(memberId<=1){
return Optional.empty();
}
Member m = get(memberId).orElseThrow(()->new IllegalArgumentException("会员不存在或暂时无法访问"));
if(MemberGroupEnum.CARD != m.getMgroup()){
throw new IllegalArgumentException("不被支持的角色变更");
}
if(ForumCalendarUnitEnum.MONTH != unit && ForumCalendarUnitEnum.YEAR != unit ){
throw new IllegalArgumentException("支持的日期单位: Month or Year");
}
int limit = duration<=1?1:duration;
try{
MemberVipExchangeRecords ver = new MemberVipExchangeRecords(memberId, m.getNickname(), limit, unit);
if(Commons.isNotBlank(transerial)){
ver.setSerial(transerial);
}
memberVipExchangeRecordsDao.save(ver);
if(ver.getId()>0) {
memberEventPublisher.publishVipExchangeEvent(new MemberVipExchangeEvent(this, ver));
return Optional.of(true);
}
}catch(Exception e){
throw new IllegalStateException("提升VIP操作失败");
}
return Optional.empty();
}
private Optional<MemberProfileBean> calcMemberProfileBeanAsync(final long id, final Map<ForumActionEnum, Long> otherActionStats) {
final Optional<Member> member = get(id);
if (!member.isPresent()) {
......
package com.apobates.forum.member.impl.service;
import com.apobates.forum.member.api.dao.MemberDao;
import com.apobates.forum.member.api.dao.MemberVipExchangeRecordsDao;
import com.apobates.forum.member.api.service.MemberVipExchangeRecordsService;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.utils.DateTimeUtils;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.stream.Stream;
/**
*
* @author xiaofanku
* @since 20200921
*/
@Service
public class MemberVipExchangeRecordsServiceImpl implements MemberVipExchangeRecordsService {
@Autowired
private MemberVipExchangeRecordsDao memberVipExchangeRecordsDao;
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeRecordsServiceImpl.class);
@Override
public Page<MemberVipExchangeRecords> getAll(LocalDateTime start, LocalDateTime finish, Pageable pageable) {
return memberVipExchangeRecordsDao.findAll(start, finish, pageable);
}
@Override
public Page<MemberVipExchangeRecords> getAll(long memberId, Pageable pageable) {
return memberVipExchangeRecordsDao.findAllByMember(memberId, pageable);
}
@Override
public Page<MemberVipExchangeRecords> getAll(Pageable pageable) {
return memberVipExchangeRecordsDao.findAll(pageable);
}
@Override
public Stream<MemberVipExchangeRecords> getRecent(int size) {
return memberVipExchangeRecordsDao.findAllOfRecent(size);
}
@Override
public Optional<Boolean> expired(long id) throws IllegalArgumentException, IllegalStateException {
MemberVipExchangeRecords obj = memberVipExchangeRecordsDao.findOne(id).orElseThrow(()->new IllegalArgumentException("VIP交易记录不存在"));
//
if (DateTimeUtils.isFeatureDate(obj.getLapseDateTime())) {
throw new IllegalStateException("VIP会员未到期,不可以作废");
}
Optional<Boolean> result = memberVipExchangeRecordsDao.expired(obj.getId());
result.ifPresent(bol-> {
if(bol){ memberDao.editMemberGroup(obj.getMemberId(), MemberGroupEnum.CARD);}
});
return result;
}
}
package com.apobates.forum.member.entity;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* VIP交易记录
*
* @author xiaofanku
* @since 20200921
*/
@Entity
@Table(name = "apo_member_exchange", uniqueConstraints = {@UniqueConstraint(columnNames = {"memberId", "status"})})
public class MemberVipExchangeRecords implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
//会员
private long memberId;
private String memberNickname;
// 记录日期
private LocalDateTime entryDateTime;
// 开始日期
private LocalDateTime activeDateTime;
// 有效日期单位,只支持:月,年
@Basic
@Enumerated(EnumType.STRING)
private ForumCalendarUnitEnum durationUnit;
// 有效日期时长
private int duration;
// 结束日期
private LocalDateTime lapseDateTime;
// 是否有效,true(1)有效,false(0)无效
@Column(columnDefinition="tinyint(1) default 0")
private boolean status;
// 交易流水号
private String serial;
//empty constructor for JPA instantiation
public MemberVipExchangeRecords() {
}
public MemberVipExchangeRecords(long memberId, String memberNickname, int duration, ForumCalendarUnitEnum unit) {
this.id = 0L;
this.memberId = memberId;
this.memberNickname = memberNickname;
this.durationUnit = unit;
this.duration = duration;
this.status = true;
//
LocalDateTime entry = LocalDateTime.now();
this.activeDateTime = entry;
this.entryDateTime = entry;
this.lapseDateTime = unit.plug(duration, entry);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getMemberId() {
return memberId;
}
public void setMemberId(long memberId) {
this.memberId = memberId;
}
public String getMemberNickname() {
return memberNickname;
}
public void setMemberNickname(String memberNickname) {
this.memberNickname = memberNickname;
}
public LocalDateTime getEntryDateTime() {
return entryDateTime;
}
public void setEntryDateTime(LocalDateTime entryDateTime) {
this.entryDateTime = entryDateTime;
}
public LocalDateTime getActiveDateTime() {
return activeDateTime;
}
public void setActiveDateTime(LocalDateTime activeDateTime) {
this.activeDateTime = activeDateTime;
}
public ForumCalendarUnitEnum getDurationUnit() {
return durationUnit;
}
public void setDurationUnit(ForumCalendarUnitEnum durationUnit) {
this.durationUnit = durationUnit;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public LocalDateTime getLapseDateTime() {
return lapseDateTime;
}
public void setLapseDateTime(LocalDateTime lapseDateTime) {
this.lapseDateTime = lapseDateTime;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
@Override
public int hashCode() {
int hash = 3;
hash = 31 * hash + (int) (this.memberId ^ (this.memberId >>> 32));
hash = 31 * hash + (this.status ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MemberVipExchangeRecords other = (MemberVipExchangeRecords) obj;
if (this.memberId != other.memberId) {
return false;
}
if (this.status != other.status) {
return false;
}
return true;
}
}
package com.apobates.forum.trident.event;
import com.apobates.forum.letterbox.api.service.ForumLetterService;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.member.entity.ForumCalendarUnitEnum;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import com.apobates.forum.utils.DateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MemberVipExchangeNoticeListener implements ApplicationListener<MemberVipExchangeEvent> {
@Autowired
private ForumLetterService forumLetterService;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeNoticeListener.class);
@Override
public void onApplicationEvent(MemberVipExchangeEvent event) {
logger.info("[Member][VipExchangeEvent][2]VIP会员开通通知开始发送");
MemberVipExchangeRecords ver = event.getRecord();
forumLetterService.create(getVipGroupNotic(ver.getMemberId(), ver.getMemberNickname(), ver.getActiveDateTime(), ver.getDuration(), ver.getDurationUnit()));
logger.info("[Member][VipExchangeEvent][2]VIP会员开通通知发送结束");
}
private ForumLetter getVipGroupNotic(long memberId, String memberNickname, LocalDateTime activeDateTime, int duration, ForumCalendarUnitEnum durationUnit) {
return new ForumLetter(
"VIP会员开通通知",
String.format("恭喜您: %s, 您的VIP身份从%s开始,有效期: %d(%s)! 如果存在异议您可以联系在线管理员",
memberNickname, DateTimeUtils.getRFC3339(activeDateTime), duration, durationUnit.getTitle()),
memberId,
memberNickname);
}
}
......@@ -14,8 +14,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class ModeratorBornNoticeListener implements ApplicationListener<ModeratorBornEvent> {
@Autowired
private BoardService boardService;
......
......@@ -15,8 +15,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class ModeratorRecallNoticeListener implements ApplicationListener<ModeratorRecallEvent> {
@Autowired
private BoardService boardService;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册