|
@@ -1,8 +1,11 @@
|
|
package com.yonge.cooleshow.biz.dal.service.impl;
|
|
package com.yonge.cooleshow.biz.dal.service.impl;
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.microsvc.toolkit.common.webportal.exception.BizException;
|
|
|
|
+import com.yonge.cooleshow.auth.api.entity.SysUser;
|
|
import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
|
|
import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
|
|
import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
|
|
import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
|
|
import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
|
|
import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
|
|
@@ -24,7 +27,10 @@ import org.springframework.stereotype.Service;
|
|
import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
|
|
import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
|
|
import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
|
|
import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
|
|
import com.yonge.cooleshow.biz.dal.dao.VipCardRecordDao;
|
|
import com.yonge.cooleshow.biz.dal.dao.VipCardRecordDao;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
+import java.time.ZoneId;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
@@ -50,6 +56,10 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
|
|
@Autowired
|
|
@Autowired
|
|
private UserOrderDetailService orderDetailService;
|
|
private UserOrderDetailService orderDetailService;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private SysUserService sysUserService;
|
|
|
|
+
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public VipCardRecordVo detail(Long orderDetilId) {
|
|
public VipCardRecordVo detail(Long orderDetilId) {
|
|
return baseMapper.detail(orderDetilId, null);
|
|
return baseMapper.detail(orderDetilId, null);
|
|
@@ -341,6 +351,287 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
|
|
return userVip;
|
|
return userVip;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
+ @Override
|
|
|
|
+ public void add(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
|
|
|
|
+ ClientEnum clientType = addVipCardRecord.getClientType();
|
|
|
|
+ if (!ClientEnum.STUDENT.equals(clientType) && !ClientEnum.TEACHER.equals(clientType)) {
|
|
|
|
+ throw new BizException("暂不支持非老师学生会员的增加或扣减");
|
|
|
|
+ }
|
|
|
|
+ if (EVipRecordStatus.DEDUCTION.equals(addVipCardRecord.getStatus())) {
|
|
|
|
+ deductVip(addVipCardRecord);
|
|
|
|
+ } else if (EVipRecordStatus.ADD.equals(addVipCardRecord.getStatus())) {
|
|
|
|
+ addVip(addVipCardRecord);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (Boolean.TRUE.equals(addVipCardRecord.getSendMsg())) {
|
|
|
|
+ sendAddVipMsg(addVipCardRecord);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 会员添加
|
|
|
|
+ private void addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
|
|
|
|
+ List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
|
|
|
|
+ .eq(VipCardRecord::getClientType, addVipCardRecord.getClientType())
|
|
|
|
+ .eq(VipCardRecord::getUserId, addVipCardRecord.getUserId())
|
|
|
|
+ .ge(VipCardRecord::getEndTime, new Date())
|
|
|
|
+ .eq(VipCardRecord::getEfficientFlag, true)
|
|
|
|
+ .list();
|
|
|
|
+
|
|
|
|
+ EVipType addVipType = addVipCardRecord.getVipType();
|
|
|
|
+ List<VipCardRecord> perpetualRecords = vipCardRecordList.stream()
|
|
|
|
+ .filter(n -> n.getVipType().equals(addVipType) && PeriodEnum.PERPETUAL.equals(n.getType()))
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ if (!perpetualRecords.isEmpty()) {
|
|
|
|
+ throw new BizException("已经是永久会员");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Date startTime = new Date();
|
|
|
|
+ // 没有会员信息
|
|
|
|
+ if (vipCardRecordList.isEmpty()) {
|
|
|
|
+ PeriodEnum period = addVipCardRecord.getType();
|
|
|
|
+ LocalDate startLocalDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
|
+ Date endDate = plusDate(startLocalDate, period, Long.valueOf(addVipCardRecord.getTimes()));
|
|
|
|
+
|
|
|
|
+ VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
|
|
|
|
+ addRecord.setSourceType(SourceTypeEnum.BACKEND_GIVE);
|
|
|
|
+ addRecord.setStatus(EVipRecordStatus.ADD);
|
|
|
|
+ addRecord.setDisplayFlag(true);
|
|
|
|
+ addRecord.setEfficientFlag(true);
|
|
|
|
+ addRecord.setStartTime(startTime);
|
|
|
|
+ addRecord.setEndTime(endDate);
|
|
|
|
+ save(addRecord);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 存在会员信息
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (int i = 0; i < vipCardRecordList.size(); i++) {
|
|
|
|
+ VipCardRecord vipCardRecord = vipCardRecordList.get(i);
|
|
|
|
+ if (vipCardRecord.getVipType().equals(addVipType)) {
|
|
|
|
+ index = i;
|
|
|
|
+ startTime = vipCardRecord.getEndTime();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ LocalDate startLocalDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
|
+ Date endDate = plusDate(startLocalDate, addVipCardRecord.getType(), Long.valueOf(addVipCardRecord.getTimes()));
|
|
|
|
+ // 平移时间
|
|
|
|
+ long plusMills = endDate == null ? 0L : (endDate.getTime() - startTime.getTime());
|
|
|
|
+ for (int i = 0; i < vipCardRecordList.size(); i++) {
|
|
|
|
+ if (index == i) {
|
|
|
|
+ VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
|
|
|
|
+ addRecord.setSourceType(SourceTypeEnum.BACKEND_GIVE);
|
|
|
|
+ addRecord.setStatus(EVipRecordStatus.ADD);
|
|
|
|
+ addRecord.setStartTime(startTime);
|
|
|
|
+ addRecord.setEndTime(endDate);
|
|
|
|
+ addRecord.setDisplayFlag(true);
|
|
|
|
+ addRecord.setEfficientFlag(true);
|
|
|
|
+ save(addRecord);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (i > index) {
|
|
|
|
+ VipCardRecord vipCardRecord = vipCardRecordList.get(i);
|
|
|
|
+ Long refId = null;
|
|
|
|
+ if (plusMills > 0L) {
|
|
|
|
+ VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ addRecord.setStatus(EVipRecordStatus.UPDATE);
|
|
|
|
+ addRecord.setStartTime(new Date(vipCardRecord.getStartTime().getTime() - plusMills));
|
|
|
|
+ addRecord.setEndTime(new Date(vipCardRecord.getEndTime().getTime() - plusMills));
|
|
|
|
+ addRecord.setDisplayFlag(false);
|
|
|
|
+ addRecord.setEfficientFlag(true);
|
|
|
|
+ save(addRecord);
|
|
|
|
+ refId = addRecord.getId();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ updateRecord.setEfficientFlag(false);
|
|
|
|
+ updateRecord.setRefId(refId);
|
|
|
|
+ updateById(updateRecord);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 会员扣减
|
|
|
|
+ private void deductVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
|
|
|
|
+
|
|
|
|
+ // 所有的会员重新生成
|
|
|
|
+ List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
|
|
|
|
+ .eq(VipCardRecord::getClientType, addVipCardRecord.getClientType())
|
|
|
|
+ .eq(VipCardRecord::getUserId, addVipCardRecord.getUserId())
|
|
|
|
+ .ge(VipCardRecord::getEndTime, new Date())
|
|
|
|
+// .eq(VipCardRecord::getDisplayFlag, false)
|
|
|
|
+ .eq(VipCardRecord::getEfficientFlag, true)
|
|
|
|
+ .list();
|
|
|
|
+
|
|
|
|
+ // 当前类型的VIP
|
|
|
|
+ List<VipCardRecord> collect = vipCardRecordList.stream().filter(n -> n.getVipType().equals(addVipCardRecord.getVipType())).collect(Collectors.toList());
|
|
|
|
+ if (collect.isEmpty()) {
|
|
|
|
+ throw new BizException("剩余扣减数量不足");
|
|
|
|
+ }
|
|
|
|
+// List<VipCardRecord> perpetualRecords = vipCardRecordList.stream()
|
|
|
|
+// .filter(n -> n.getVipType().equals(addVipCardRecord.getVipType()) && PeriodEnum.PERPETUAL.equals(n.getType()))
|
|
|
|
+// .collect(Collectors.toList());
|
|
|
|
+// if (!perpetualRecords.isEmpty()) {
|
|
|
|
+// throw new BizException("永久会员不支持扣减");
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ LocalDate maxEndTime = collect.stream().map(VipCardRecord::getEndTime).max(Comparator.naturalOrder()).get().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
|
+ PeriodEnum period = addVipCardRecord.getType();
|
|
|
|
+ // 扣减后的开始时间
|
|
|
|
+ LocalDate deductedStartTime;
|
|
|
|
+ switch (period) {
|
|
|
|
+ case DAY:
|
|
|
|
+ deductedStartTime = maxEndTime.minusDays(addVipCardRecord.getTimes());
|
|
|
|
+ break;
|
|
|
|
+ case MONTH:
|
|
|
|
+ deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes());
|
|
|
|
+ break;
|
|
|
|
+ case QUARTERLY:
|
|
|
|
+ deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 4);
|
|
|
|
+ break;
|
|
|
|
+ case YEAR_HALF:
|
|
|
|
+ deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 6);
|
|
|
|
+ break;
|
|
|
|
+ case YEAR:
|
|
|
|
+ deductedStartTime = maxEndTime.minusYears(addVipCardRecord.getTimes());
|
|
|
|
+ break;
|
|
|
|
+ case PERPETUAL:
|
|
|
|
+ // 永久扣减
|
|
|
|
+ deductedPerpetual(addVipCardRecord, vipCardRecordList);
|
|
|
|
+ return;
|
|
|
|
+ default:
|
|
|
|
+ throw new BizException("不支持的扣减类型");
|
|
|
|
+ }
|
|
|
|
+ Date deductedStartDate = Date.from(deductedStartTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
|
|
+
|
|
|
|
+ Date minStartTime = collect.stream().map(VipCardRecord::getStartTime).min(Comparator.naturalOrder()).get();
|
|
|
|
+ // 如果扣减的数量超过1天,则提示扣减数量不足
|
|
|
|
+ if (deductedStartDate.before(minStartTime)) {
|
|
|
|
+ double day = (minStartTime.getTime() - deductedStartDate.getTime()) * 1.0D / (24 * 60 * 60);
|
|
|
|
+ if (day > 1.0D) {
|
|
|
|
+ throw new BizException("剩余扣减数量不足");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 重新计算会员时间,每一条记录置换成一条新的记录,时间区间重新计算
|
|
|
|
+ List<VipCardRecord> updateRecords = new ArrayList<>();
|
|
|
|
+ Long deductMills = null;
|
|
|
|
+
|
|
|
|
+ for (VipCardRecord vipCardRecord : vipCardRecordList) {
|
|
|
|
+ Date startTime = vipCardRecord.getStartTime();
|
|
|
|
+ Date endTime = vipCardRecord.getEndTime();
|
|
|
|
+ if (endTime.before(deductedStartDate)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Long addId = null;
|
|
|
|
+ // 扣减到当前时间区间
|
|
|
|
+ if (deductedStartDate.after(startTime) && deductedStartDate.before(endTime)) {
|
|
|
|
+ VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ addRecord.setId(null);
|
|
|
|
+ addRecord.setDisplayFlag(false);
|
|
|
|
+ addRecord.setEfficientFlag(true);
|
|
|
|
+ addRecord.setEndTime(deductedStartDate);
|
|
|
|
+ save(addRecord);
|
|
|
|
+ addId = addRecord.getId();
|
|
|
|
+
|
|
|
|
+ deductMills = endTime.getTime() - deductedStartDate.getTime();
|
|
|
|
+ } else {
|
|
|
|
+ // 有扣减,整体时间前移
|
|
|
|
+ if (deductMills != null) {
|
|
|
|
+ VipCardRecord newRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ newRecord.setId(null);
|
|
|
|
+ newRecord.setEfficientFlag(true);
|
|
|
|
+ newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - deductMills));
|
|
|
|
+ newRecord.setEndTime(new Date(newRecord.getEndTime().getTime() - deductMills));
|
|
|
|
+ newRecord.setStatus(EVipRecordStatus.UPDATE);
|
|
|
|
+ save(newRecord);
|
|
|
|
+ addId = newRecord.getId();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ updateRecord.setEfficientFlag(false);
|
|
|
|
+ updateRecord.setRefId(addId);
|
|
|
|
+ updateRecords.add(updateRecord);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.updateBatchById(updateRecords, 100);
|
|
|
|
+
|
|
|
|
+ VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
|
|
|
|
+ vipCardRecord.setDisplayFlag(true);
|
|
|
|
+ vipCardRecord.setEfficientFlag(false);
|
|
|
|
+ vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
|
|
|
|
+ this.save(vipCardRecord);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 扣减永久会员
|
|
|
|
+ private void deductedPerpetual(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord, List<VipCardRecord> vipCardRecordList) {
|
|
|
|
+
|
|
|
|
+ EVipType vipType = addVipCardRecord.getVipType();
|
|
|
|
+ long deductMills = 0L;
|
|
|
|
+ Date now = new Date();
|
|
|
|
+ for (VipCardRecord vipCardRecord : vipCardRecordList) {
|
|
|
|
+ Date startTime = vipCardRecord.getStartTime();
|
|
|
|
+ Date endTime = vipCardRecord.getEndTime();
|
|
|
|
+
|
|
|
|
+ if (vipCardRecord.getVipType().equals(vipType)) {
|
|
|
|
+ deductMills += endTime.getTime() - Math.max(startTime.getTime(), now.getTime());
|
|
|
|
+ VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ updateRecord.setEfficientFlag(false);
|
|
|
|
+ updateById(updateRecord);
|
|
|
|
+ } else if (deductMills > 0L) {
|
|
|
|
+ VipCardRecord newRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ newRecord.setId(null);
|
|
|
|
+ newRecord.setDisplayFlag(false);
|
|
|
|
+ newRecord.setEfficientFlag(true);
|
|
|
|
+ newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - deductMills));
|
|
|
|
+ newRecord.setEndTime(new Date(newRecord.getEndTime().getTime() - deductMills));
|
|
|
|
+ save(newRecord);
|
|
|
|
+ Long refId = newRecord.getId();
|
|
|
|
+
|
|
|
|
+ VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
|
|
|
|
+ updateRecord.setEfficientFlag(false);
|
|
|
|
+ updateRecord.setRefId(refId);
|
|
|
|
+ updateById(updateRecord);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
|
|
|
|
+ vipCardRecord.setDisplayFlag(true);
|
|
|
|
+ vipCardRecord.setEfficientFlag(false);
|
|
|
|
+ vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
|
|
|
|
+ this.save(vipCardRecord);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Date plusDate(LocalDate start, PeriodEnum period, long times) {
|
|
|
|
+ LocalDate end = null;
|
|
|
|
+ switch (period) {
|
|
|
|
+ case DAY:
|
|
|
|
+ end = start.minusDays(times);
|
|
|
|
+ break;
|
|
|
|
+ case MONTH:
|
|
|
|
+ end = start.minusMonths(times);
|
|
|
|
+ break;
|
|
|
|
+ case QUARTERLY:
|
|
|
|
+ end = start.minusMonths(times * 4);
|
|
|
|
+ break;
|
|
|
|
+ case YEAR_HALF:
|
|
|
|
+ end = start.minusMonths(times * 6);
|
|
|
|
+ break;
|
|
|
|
+ case YEAR:
|
|
|
|
+ end = start.minusYears(times);
|
|
|
|
+ break;
|
|
|
|
+ case PERPETUAL:
|
|
|
|
+ return null;
|
|
|
|
+ default:
|
|
|
|
+ throw new BizException("不支持的扣减类型");
|
|
|
|
+ }
|
|
|
|
+ return Date.from(end.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
|
|
+ }
|
|
|
|
+
|
|
// 发送会员到期3天消息推送
|
|
// 发送会员到期3天消息推送
|
|
private void temporary3DaysSend(Long userId, String phone, ClientEnum clientType) {
|
|
private void temporary3DaysSend(Long userId, String phone, ClientEnum clientType) {
|
|
Map<Long, String> receivers = new HashMap<>();
|
|
Map<Long, String> receivers = new HashMap<>();
|
|
@@ -396,4 +687,22 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 添加、扣除会员发送推送
|
|
|
|
+ private void sendAddVipMsg(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
|
|
|
|
+ SysUser sysUser = sysUserService.getByUserId(addVipCardRecord.getUserId());
|
|
|
|
+ if (sysUser == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ MessageTypeEnum messageTypeEnum = EVipRecordStatus.ADD.equals(addVipCardRecord.getStatus()) ? MessageTypeEnum.TENANT_PLATFORM_ADD_VIP : MessageTypeEnum.TENANT_PLATFORM_DUDECT_VIP;
|
|
|
|
+ Map<Long, String> receivers = new HashMap<>();
|
|
|
|
+ receivers.put(addVipCardRecord.getUserId(), sysUser.getPhone());
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, messageTypeEnum,
|
|
|
|
+ receivers, null, 0, null, addVipCardRecord.getClientType().getCode());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("会员赠送消息发送失败 : {}", e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|