|  | @@ -364,9 +364,38 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |              throw new BizException("暂不支持非老师学生会员的增加或扣减");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          if (EVipRecordStatus.DEDUCTION.equals(addVipCardRecord.getStatus())) {
 | 
	
		
			
				|  |  | -            deductVip(addVipCardRecord);
 | 
	
		
			
				|  |  | +            VipCardRecord vipCardRecord = deductVip(addVipCardRecord);
 | 
	
		
			
				|  |  | +            vipCardRecord.setDisplayFlag(true);
 | 
	
		
			
				|  |  | +            this.save(vipCardRecord);
 | 
	
		
			
				|  |  |          } else if (EVipRecordStatus.ADD.equals(addVipCardRecord.getStatus())) {
 | 
	
		
			
				|  |  | -            addVip(addVipCardRecord);
 | 
	
		
			
				|  |  | +            VipCardRecord addVip = addVip(addVipCardRecord);
 | 
	
		
			
				|  |  | +            this.save(addVip);
 | 
	
		
			
				|  |  | +            Integer vipDays = addVipCardRecord.getVipDays();
 | 
	
		
			
				|  |  | +            // 存在转换,先扣除,再添加
 | 
	
		
			
				|  |  | +            if (vipDays != null && vipDays > 0) {
 | 
	
		
			
				|  |  | +                VipCardRecordWrapper.AddVipCardRecord dedectRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecordWrapper.AddVipCardRecord.class);
 | 
	
		
			
				|  |  | +                dedectRecord.setStatus(EVipRecordStatus.DEDUCTION);
 | 
	
		
			
				|  |  | +                dedectRecord.setVipType(EVipType.VIP);
 | 
	
		
			
				|  |  | +                dedectRecord.setType(PeriodEnum.DAY);
 | 
	
		
			
				|  |  | +                dedectRecord.setTimes(vipDays);
 | 
	
		
			
				|  |  | +                dedectRecord.setReason("后台转换扣减");
 | 
	
		
			
				|  |  | +                deductVip(dedectRecord);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                VipCardRecordWrapper.AddVipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecordWrapper.AddVipCardRecord.class);
 | 
	
		
			
				|  |  | +                addRecord.setStatus(EVipRecordStatus.ADD);
 | 
	
		
			
				|  |  | +                addRecord.setVipType(EVipType.SVIP);
 | 
	
		
			
				|  |  | +                addRecord.setType(PeriodEnum.DAY);
 | 
	
		
			
				|  |  | +                addRecord.setTimes(vipDays);
 | 
	
		
			
				|  |  | +                addRecord.setReason("后台转换添加");
 | 
	
		
			
				|  |  | +                VipCardRecord convertVip = addVip(dedectRecord);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                convertVip.setDisplayFlag(true);
 | 
	
		
			
				|  |  | +                convertVip.setStatus(EVipRecordStatus.UPDATE);
 | 
	
		
			
				|  |  | +                convertVip.setSourceType(SourceTypeEnum.FREE_UPGRADE);
 | 
	
		
			
				|  |  | +                // 添加转换记录
 | 
	
		
			
				|  |  | +                this.save(convertVip);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (Boolean.TRUE.equals(addVipCardRecord.getSendMsg())) {
 | 
	
	
		
			
				|  | @@ -398,7 +427,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 会员添加
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public void addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
 | 
	
		
			
				|  |  | +    public VipCardRecord addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
 | 
	
		
			
				|  |  |          List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
 | 
	
		
			
				|  |  |                  .eq(VipCardRecord::getClientType, addVipCardRecord.getClientType())
 | 
	
		
			
				|  |  |                  .eq(VipCardRecord::getUserId, addVipCardRecord.getUserId())
 | 
	
	
		
			
				|  | @@ -412,12 +441,12 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          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("已经是永久会员");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +//        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 now = new Date();
 | 
	
		
			
				|  |  |          Date startTime = now;
 | 
	
	
		
			
				|  | @@ -433,8 +462,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |              addRecord.setEfficientFlag(true);
 | 
	
		
			
				|  |  |              addRecord.setStartTime(startTime);
 | 
	
		
			
				|  |  |              addRecord.setEndTime(endDate);
 | 
	
		
			
				|  |  | -            save(addRecord);
 | 
	
		
			
				|  |  | -            return;
 | 
	
		
			
				|  |  | +            return addRecord;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 找到插入数据的位置
 | 
	
	
		
			
				|  | @@ -470,33 +498,29 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |          newRecord.setEndTime(endDate);
 | 
	
		
			
				|  |  |          newRecord.setDisplayFlag(true);
 | 
	
		
			
				|  |  |          newRecord.setEfficientFlag(true);
 | 
	
		
			
				|  |  | -        save(newRecord);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 平移时间
 | 
	
		
			
				|  |  |          long plusMills = endDate.getTime() - startTime.getTime();
 | 
	
		
			
				|  |  |          for (int i = 0; i < vipCardRecordList.size(); i++) {
 | 
	
		
			
				|  |  |              VipCardRecord vipCardRecord = vipCardRecordList.get(i);
 | 
	
		
			
				|  |  |              if (i >= index) {
 | 
	
		
			
				|  |  | -                Long refId = null;
 | 
	
		
			
				|  |  | -                if (plusMills > 0L) {
 | 
	
		
			
				|  |  | -                    VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
 | 
	
		
			
				|  |  | -                    addRecord.setStatus(EVipRecordStatus.UPDATE);
 | 
	
		
			
				|  |  | -                    long startTimeMills = Math.max(vipCardRecord.getStartTime().getTime(), now.getTime());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    Date startDate = new Date(startTimeMills + plusMills + 1000);
 | 
	
		
			
				|  |  | -                    Calendar instance = Calendar.getInstance();
 | 
	
		
			
				|  |  | -                    instance.setTime(startDate);
 | 
	
		
			
				|  |  | -                    instance.set(Calendar.SECOND, 0);
 | 
	
		
			
				|  |  | -                    instance.set(Calendar.MILLISECOND, 0);
 | 
	
		
			
				|  |  | -                    addRecord.setStartTime(instance.getTime());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    int days = (int) Math.ceil(plusMills * 1.0D / (24 * 60 * 60 * 1000));
 | 
	
		
			
				|  |  | -                    addRecord.setEndTime(plusDate(vipCardRecord.getEndTime(), PeriodEnum.DAY, days));
 | 
	
		
			
				|  |  | -                    addRecord.setDisplayFlag(false);
 | 
	
		
			
				|  |  | -                    addRecord.setEfficientFlag(true);
 | 
	
		
			
				|  |  | -                    save(addRecord);
 | 
	
		
			
				|  |  | -                    refId = addRecord.getId();
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +                VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
 | 
	
		
			
				|  |  | +                addRecord.setStatus(EVipRecordStatus.UPDATE);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                long startTimeMills = Math.max(vipCardRecord.getStartTime().getTime(), now.getTime());
 | 
	
		
			
				|  |  | +                Date startDate = new Date(startTimeMills + plusMills + 1000);
 | 
	
		
			
				|  |  | +                Calendar instance = Calendar.getInstance();
 | 
	
		
			
				|  |  | +                instance.setTime(startDate);
 | 
	
		
			
				|  |  | +                instance.set(Calendar.SECOND, 0);
 | 
	
		
			
				|  |  | +                instance.set(Calendar.MILLISECOND, 0);
 | 
	
		
			
				|  |  | +                addRecord.setStartTime(instance.getTime());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                int days = (int) Math.ceil(plusMills * 1.0D / (24 * 60 * 60 * 1000));
 | 
	
		
			
				|  |  | +                addRecord.setEndTime(plusDate(vipCardRecord.getEndTime(), PeriodEnum.DAY, days));
 | 
	
		
			
				|  |  | +                addRecord.setDisplayFlag(false);
 | 
	
		
			
				|  |  | +                addRecord.setEfficientFlag(true);
 | 
	
		
			
				|  |  | +                save(addRecord);
 | 
	
		
			
				|  |  | +                Long refId = addRecord.getId();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
 | 
	
		
			
				|  |  |                  updateRecord.setEfficientFlag(false);
 | 
	
	
		
			
				|  | @@ -504,11 +528,12 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |                  updateById(updateRecord);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        return newRecord;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 会员扣减
 | 
	
		
			
				|  |  | -    private void deductVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
 | 
	
		
			
				|  |  | +    private VipCardRecord deductVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 所有的会员重新生成
 | 
	
		
			
				|  |  |          List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
 | 
	
	
		
			
				|  | @@ -523,26 +548,20 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 当前类型的VIP
 | 
	
		
			
				|  |  |          PeriodEnum period = addVipCardRecord.getType();
 | 
	
		
			
				|  |  | +        // 扣减永久
 | 
	
		
			
				|  |  |          if (PeriodEnum.PERPETUAL.equals(period)) {
 | 
	
		
			
				|  |  | -            deductedSVipPerpetual(addVipCardRecord, vipCardRecordList);
 | 
	
		
			
				|  |  | -            return;
 | 
	
		
			
				|  |  | +            return deductedSVipPerpetual(addVipCardRecord, vipCardRecordList);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // 扣减非永久
 | 
	
		
			
				|  |  |          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();
 | 
	
		
			
				|  |  | +        LocalDateTime maxEndTime = collect.stream().map(VipCardRecord::getEndTime).max(Comparator.naturalOrder()).get().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
 | 
	
		
			
				|  |  |          // 扣减后的开始时间
 | 
	
		
			
				|  |  | -        LocalDate deductedStartTime;
 | 
	
		
			
				|  |  | +        LocalDateTime deductedStartTime;
 | 
	
		
			
				|  |  |          switch (period) {
 | 
	
		
			
				|  |  |              case DAY:
 | 
	
		
			
				|  |  |                  deductedStartTime = maxEndTime.minusDays(addVipCardRecord.getTimes());
 | 
	
	
		
			
				|  | @@ -551,22 +570,18 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |                  deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes());
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              case QUARTERLY:
 | 
	
		
			
				|  |  | -                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 3);
 | 
	
		
			
				|  |  | +                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 3L);
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              case YEAR_HALF:
 | 
	
		
			
				|  |  | -                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 6);
 | 
	
		
			
				|  |  | +                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 6L);
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              case YEAR:
 | 
	
		
			
				|  |  |                  deductedStartTime = maxEndTime.minusYears(addVipCardRecord.getTimes());
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  | -            case PERPETUAL:
 | 
	
		
			
				|  |  | -                // 永久扣减
 | 
	
		
			
				|  |  | -                deductedSVipPerpetual(addVipCardRecord, vipCardRecordList);
 | 
	
		
			
				|  |  | -                return;
 | 
	
		
			
				|  |  |              default:
 | 
	
		
			
				|  |  |                  throw new BizException("不支持的扣减类型");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        Date deductedStartDate = Date.from(deductedStartTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
 | 
	
		
			
				|  |  | +        Date deductedStartDate =  Date.from(deductedStartTime.atZone(ZoneId.systemDefault()).toInstant());;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          Date minStartTime = collect.stream().map(VipCardRecord::getStartTime).min(Comparator.naturalOrder()).get();
 | 
	
		
			
				|  |  |          // 如果扣减的数量超过1天,则提示扣减数量不足
 | 
	
	
		
			
				|  | @@ -596,6 +611,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |                  addRecord.setDisplayFlag(false);
 | 
	
		
			
				|  |  |                  addRecord.setEfficientFlag(true);
 | 
	
		
			
				|  |  |                  addRecord.setEndTime(deductedStartDate);
 | 
	
		
			
				|  |  | +                addRecord.setStatus(EVipRecordStatus.UPDATE);
 | 
	
		
			
				|  |  |                  save(addRecord);
 | 
	
		
			
				|  |  |                  addId = addRecord.getId();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -623,14 +639,15 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |          this.updateBatchById(updateRecords, 100);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
 | 
	
		
			
				|  |  | -        vipCardRecord.setDisplayFlag(true);
 | 
	
		
			
				|  |  |          vipCardRecord.setEfficientFlag(false);
 | 
	
		
			
				|  |  | +        vipCardRecord.setStartTime(deductedStartDate);
 | 
	
		
			
				|  |  | +        vipCardRecord.setEndTime(Date.from(maxEndTime.atZone(ZoneId.systemDefault()).toInstant()));
 | 
	
		
			
				|  |  |          vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
 | 
	
		
			
				|  |  | -        this.save(vipCardRecord);
 | 
	
		
			
				|  |  | +        return vipCardRecord;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 扣减永久SVIP会员
 | 
	
		
			
				|  |  | -    private void deductedSVipPerpetual(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord, List<VipCardRecord> vipCardRecordList) {
 | 
	
		
			
				|  |  | +    private VipCardRecord deductedSVipPerpetual(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord, List<VipCardRecord> vipCardRecordList) {
 | 
	
		
			
				|  |  |          List<VipCardRecord> collect = vipCardRecordList.stream()
 | 
	
		
			
				|  |  |                  .filter(n -> n.getVipType().equals(addVipCardRecord.getVipType()) && n.getType().equals(PeriodEnum.PERPETUAL))
 | 
	
		
			
				|  |  |                  .collect(Collectors.toList());
 | 
	
	
		
			
				|  | @@ -672,10 +689,9 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
 | 
	
		
			
				|  |  | -        vipCardRecord.setDisplayFlag(true);
 | 
	
		
			
				|  |  |          vipCardRecord.setEfficientFlag(false);
 | 
	
		
			
				|  |  |          vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
 | 
	
		
			
				|  |  | -        this.save(vipCardRecord);
 | 
	
		
			
				|  |  | +        return vipCardRecord;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private Date plusDate(Date start, PeriodEnum period, long times) {
 |