刘俊驰 7 月之前
父節點
當前提交
e6988ab6e1

+ 65 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/DiscountCardRecordController.java

@@ -0,0 +1,65 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.DiscountCardRecordService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.DiscountCardRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/discountCardRecord")
+@Api(value = "畅学卡记录", tags = "畅学卡记录")
+public class DiscountCardRecordController extends BaseController {
+
+    @Autowired
+    private DiscountCardRecordService discountCardRecordService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @PostMapping("/page")
+    @ApiOperation(value = "畅学卡记录列表")
+    public R<PageInfo<DiscountCardRecordWrapper.DiscountCardRecord>> page(@RequestBody DiscountCardRecordWrapper.DiscountCardRecordQuery query) {
+
+        // 查询数据
+        IPage<DiscountCardRecordWrapper.DiscountCardRecord> pages = discountCardRecordService.selectPage(QueryInfo.getPage(query), query);
+
+
+        return R.from(QueryInfo.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增/扣减畅学卡", notes = "传入vipPurchaseRecord")
+    @PostMapping("/save")
+    public R<JSONObject> add(@Validated @RequestBody DiscountCardRecordWrapper.DiscountCardRecord result) {
+        SysUser sysUser = sysUserService.getUser();
+        if (sysUser == null  || sysUser.getId() == null) {
+            throw new BizException( "用户信息获取失败");
+        }
+        result.setCreateBy(sysUser.getId());
+        discountCardRecordService.addStudentVip(result);
+        return R.defaultR();
+    }
+
+
+
+    @PostMapping("/info")
+    public R<DiscountCardRecordWrapper.Info> info(@RequestBody DiscountCardRecordWrapper.InfoQuery infoQuery) {
+
+        return R.from(discountCardRecordService.info(infoQuery));
+    }
+}

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java

@@ -171,6 +171,8 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     TEACHER_UPDATE_COURSE_PLAN("老师修改课程规划"),
     TEACHER_UPDATE_COURSE_PLAN_VIP("老师修改课程规划"),
     TEACHER_UPDATE_COURSE_PLAN_PIANO_ROOM_CLASS("老师修改课程规划"),
+    DEDUCTION_DISCOUNT_SMS("扣减畅学卡"),
+    ADD_DISCOUNT_SMS("扣减畅学卡"),
     ;
 
     MessageTypeEnum(String msg) {

+ 2 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/PeriodEnum.java

@@ -8,8 +8,8 @@ import com.yonge.toolset.base.enums.BaseEnum;
  */
 public enum PeriodEnum implements BaseEnum<String, PeriodEnum> {
     // DAY 日 MONTH 月 QUARTERLY 季度 YEAR_HALF 半年 YEAR 年
-	DAY(""),
-	MONTH("月"),
+	DAY(""),
+	MONTH("月"),
 	QUARTERLY("季度"),
 	YEAR_HALF("半年"),
 	YEAR("年"),

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/DiscountCardRecordMapper.java

@@ -1,10 +1,12 @@
 package com.yonge.cooleshow.biz.dal.mapper;
 
+import java.util.Date;
 import java.util.List;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
+import com.yonge.cooleshow.biz.dal.wrapper.DiscountCardRecordWrapper;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 import com.yonge.cooleshow.biz.dal.entity.DiscountCardRecord;
@@ -17,4 +19,9 @@ import com.yonge.cooleshow.biz.dal.entity.DiscountCardRecord;
 public interface DiscountCardRecordMapper extends BaseMapper<DiscountCardRecord> {
 
     MemberPriceSettings detail(@Param("userId") Long userId, @Param("orderDetilId") Long orderDetilId);
+
+    IPage<DiscountCardRecordWrapper.DiscountCardRecord> selectPage(@Param("page") IPage<DiscountCardRecordWrapper.DiscountCardRecord> page,
+                                                                   @Param("param") DiscountCardRecordWrapper.DiscountCardRecordQuery query);
+
+    void updateUserDiscountTime(@Param("userId") Long userId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
 }

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/DiscountCardRecordService.java

@@ -1,8 +1,11 @@
 package com.yonge.cooleshow.biz.dal.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.entity.DiscountCardRecord;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
+import com.yonge.cooleshow.biz.dal.wrapper.DiscountCardRecordWrapper;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 购买会员卡记录表
@@ -12,4 +15,15 @@ public interface DiscountCardRecordService extends IService<DiscountCardRecord>
 
 
     void orderSuccess(UserOrderDetailVo userPaymentOrder);
+
+
+    void addStudentVip(DiscountCardRecordWrapper.DiscountCardRecord result);
+
+    IPage<DiscountCardRecordWrapper.DiscountCardRecord> selectPage(IPage<DiscountCardRecordWrapper.DiscountCardRecord> page, DiscountCardRecordWrapper.DiscountCardRecordQuery query);
+
+    /**
+     * 获取剩余时长
+     *
+     */
+    DiscountCardRecordWrapper.Info info(DiscountCardRecordWrapper.InfoQuery infoQuery);
 }

+ 274 - 54
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/DiscountCardRecordServiceImpl.java

@@ -1,31 +1,32 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import cn.hutool.core.thread.ThreadUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.yonge.cooleshow.biz.dal.entity.DiscountCardRecord;
-import com.yonge.cooleshow.biz.dal.entity.Student;
-import com.yonge.cooleshow.biz.dal.enums.EVipRecordStatus;
-import com.yonge.cooleshow.biz.dal.enums.EVipType;
-import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.mapper.DiscountCardRecordMapper;
-import com.yonge.cooleshow.biz.dal.service.DiscountCardRecordService;
-import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
-import com.yonge.cooleshow.biz.dal.service.StudentService;
-import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
-import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.DiscountCardRecordWrapper;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.utils.date.DateUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneId;
-import java.util.Date;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 购买会员卡记录表
@@ -41,6 +42,12 @@ public class DiscountCardRecordServiceImpl extends ServiceImpl<DiscountCardRecor
     @Autowired
     private StudentService studentService;
 
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private SysMessageService sysMessageService;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void orderSuccess(UserOrderDetailVo orderDetailVo) {
@@ -53,64 +60,277 @@ public class DiscountCardRecordServiceImpl extends ServiceImpl<DiscountCardRecor
             return;
         }
 
-
-        DiscountCardRecord discountCardRecord = new DiscountCardRecord();
+        DiscountCardRecordWrapper.DiscountCardRecordChange discountCardRecord = new DiscountCardRecordWrapper.DiscountCardRecordChange();
         discountCardRecord.setUserId(orderDetailVo.getUserId());
         discountCardRecord.setVipCardId(orderDetailVo.getBizId());
         discountCardRecord.setOrderNo(orderDetailVo.getOrderNo());
         discountCardRecord.setSourceType(SourceTypeEnum.ORDER);
         discountCardRecord.setClientType(orderDetailVo.getOrderClient());
         discountCardRecord.setSubOrderNo(orderDetailVo.getSubOrderNo());
-        discountCardRecord.setCreateBy(orderDetailVo.getUserId());
+//        discountCardRecord.setCreateBy(orderDetailVo.getUserId());
         discountCardRecord.setType(detail.getPeriod());
         discountCardRecord.setTimes(orderDetailVo.getGoodNum());
-        discountCardRecord.setVipType(detail.getVipType());
+        discountCardRecord.setStatus(EVipRecordStatus.ADD);
+
+        addStudentDiscount(discountCardRecord);
+
+    }
+
+
+    private List<DiscountCardRecord> usedDiscountCardRecordList(Long userId) {
+        return this.lambdaQuery()
+                .eq(DiscountCardRecord::getUserId, userId)
+                .eq(DiscountCardRecord::getEfficientFlag, 1)
+                .gt(DiscountCardRecord::getEndTime, new Date())
+                .list();
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void addStudentVip(DiscountCardRecordWrapper.DiscountCardRecord result) {
+
+        // 扣减
+        if (result.getStatus() == EVipRecordStatus.DEDUCTION) {
+            result.setSourceType(SourceTypeEnum.PLATFORM_DEDUCT);
+            deductionStudentDiscount(result);
+        } else {
+            result.setSourceType(SourceTypeEnum.BACKEND_GIVE);
+            addStudentDiscount(JSON.parseObject(JSON.toJSONString(result), DiscountCardRecordWrapper.DiscountCardRecordChange.class));
+        }
+
+        if (Boolean.TRUE.equals(result.getSendMsg())) {
+            ThreadUtil.execute(() -> sendVipDeductionMessage(result));
+        }
+    }
+
+    private void sendVipDeductionMessage(DiscountCardRecordWrapper.DiscountCardRecord result) {
+        // 添加VIP时长短信
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserService.getByUserId(result.getUserId());
+        if (sysUser == null) {
+            return;
+        }
+
+        Map<Long, String> receivers = new HashMap<>();
+        receivers.put(sysUser.getId(), sysUser.getPhone());
+
+
+        // 短信
+        MessageTypeEnum messageTypeEnum = MessageTypeEnum.ADD_DISCOUNT_SMS;
+        if (result.getStatus() == EVipRecordStatus.DEDUCTION) {
+            messageTypeEnum = MessageTypeEnum.DEDUCTION_DISCOUNT_SMS;
+        }
+        try {
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageTypeEnum,receivers,
+                    null,0,null,ClientEnum.STUDENT.name()
+                    ,result.getTimes() + result.getType().name(),result.getReason());
+        } catch (Exception e) {
+            log.error("消息发送失败 ", e);
+        }
+    }
+
+    public long deductionStudentDiscount(DiscountCardRecordWrapper.DiscountCardRecord result) {
+
+
+        List<DiscountCardRecord> discountCardRecords = usedDiscountCardRecordList(result.getUserId());
+
+
+        // 最后匹配的激活记录
+
+        // 查询最大有效时间
+        if (CollectionUtils.isEmpty(discountCardRecords)) {
+            throw new BizException("会员时长不足");
+        }
+
+        // 根据结束时间倒序
+        discountCardRecords.sort(Comparator.comparing(DiscountCardRecord::getEndTime).reversed());
+        DiscountCardRecord record = discountCardRecords.stream().max(Comparator.comparing(DiscountCardRecord::getEndTime)).get();
+
+        Date membershipEndTime =  record.getEndTime();
+        membershipEndTime = addTime(membershipEndTime, result.getType(), result.getTimes(), 1);
+
+        DiscountCardRecord startVipPurchaseRecord = null;
+        for (DiscountCardRecord vipPurchaseRecord : discountCardRecords) {
+            vipPurchaseRecord.setEfficientFlag(false);
+            if (!DateUtil.addSeconds(membershipEndTime,1).before(vipPurchaseRecord.getStartTime())) {
+                if (DateUtil.addDays(membershipEndTime,1).after(new Date())) {
+                    // 会员匹配完
+                    startVipPurchaseRecord = JSON.parseObject(JSON.toJSONString(vipPurchaseRecord), DiscountCardRecord.class);
+                    break;
+                }
+            }
+        }
+        if (startVipPurchaseRecord == null) {
+            throw new BizException("会员时长不足");
+        }
+        List<DiscountCardRecord> saveList = new ArrayList<>();
+
+        startVipPurchaseRecord.setEfficientFlag(true);
+        long id = IdWorker.getId();
+        if (startVipPurchaseRecord.getStartTime().compareTo(membershipEndTime)>0) {
+            membershipEndTime = startVipPurchaseRecord.getStartTime();
+            startVipPurchaseRecord.setEfficientFlag(false);
+            startVipPurchaseRecord.setRefId(id);
+        } else {
+            startVipPurchaseRecord.setRefId(null);
+        }
+
+        startVipPurchaseRecord.setVipType(EVipType.DISCOUNT);
+        startVipPurchaseRecord.setId(id);
+        startVipPurchaseRecord.setEndTime(membershipEndTime);
+//        startVipPurchaseRecord.setVipCardId(-1L);
+        startVipPurchaseRecord.setOrderNo("");
+        startVipPurchaseRecord.setTimes(result.getTimes());
+        startVipPurchaseRecord.setMsgStatus(0);
+        startVipPurchaseRecord.setType(result.getType());
+        startVipPurchaseRecord.setUpdateTime(null);
+        startVipPurchaseRecord.setStatus(EVipRecordStatus.DEDUCTION);
+        startVipPurchaseRecord.setCreateTime(null);
+        startVipPurchaseRecord.setCreateBy(result.getCreateBy());
+        startVipPurchaseRecord.setDisplayFlag(true);
+        startVipPurchaseRecord.setReason(result.getReason());
+        startVipPurchaseRecord.setSendMsg(result.getSendMsg());
+        saveList.add(startVipPurchaseRecord);
+
+        for (DiscountCardRecord cardRecord : discountCardRecords) {
+            if (Boolean.FALSE.equals(cardRecord.getEfficientFlag())) {
+                DiscountCardRecord discountCardRecord = new DiscountCardRecord();
+                discountCardRecord.setId(cardRecord.getId());
+                discountCardRecord.setRefId(startVipPurchaseRecord.getId());
+                discountCardRecord.setEfficientFlag(false);
+                saveList.add(discountCardRecord);
+            }
+        }
+        saveOrUpdateBatch(saveList);
+
+        return id;
+
+    }
+
+
+    private Long addStudentDiscount(DiscountCardRecordWrapper.DiscountCardRecordChange result) {
+
+
+        DiscountCardRecord discountCardRecord = new DiscountCardRecord();
+        discountCardRecord.setUserId(result.getUserId());
+        discountCardRecord.setVipCardId(result.getVipCardId());
+        discountCardRecord.setOrderNo(result.getOrderNo());
+        discountCardRecord.setSourceType(result.getSourceType());
+        discountCardRecord.setClientType(ClientEnum.STUDENT);
+        discountCardRecord.setSubOrderNo(result.getSubOrderNo());
+        discountCardRecord.setCreateBy(result.getCreateBy());
+        discountCardRecord.setType(result.getType());
+        discountCardRecord.setTimes(result.getTimes());
+        discountCardRecord.setReason(result.getReason());
+        discountCardRecord.setVipType(EVipType.DISCOUNT);
         discountCardRecord.setStatus(EVipRecordStatus.ADD);
         discountCardRecord.setDisplayFlag(true);
         discountCardRecord.setEfficientFlag(true);
-        discountCardRecord.setSendMsg(false);
-
-        // 设置时间
-        Student student = studentService.getById(orderDetailVo.getUserId());
-        LocalDate startTime = LocalDate.now();
-        if (student.getDiscountEndTime() != null && student.getDiscountEndTime().after(new Date())) {
-            startTime = student.getDiscountEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-        }
-        LocalDate endTime = LocalDate.now();
-
-        switch (discountCardRecord.getType()) {
-            case DAY:
-                endTime = startTime.plusDays(discountCardRecord.getTimes());
-                break;
-            case MONTH:
-                endTime = startTime.plusMonths(discountCardRecord.getTimes());
-                break;
-            case QUARTERLY:
-                endTime = startTime.plusMonths(discountCardRecord.getTimes() * 3L);
-                break;
-            case YEAR_HALF:
-                endTime = startTime.plusMonths(discountCardRecord.getTimes() * 6L);
-                break;
-            case YEAR:
-                endTime = startTime.plusYears(discountCardRecord.getTimes());
-                break;
-            default:
-                log.error("时间类型错误{}", discountCardRecord.getType());
-        }
-        if (startTime.isAfter(LocalDate.now())) {
-            startTime = startTime.plusDays(1);
+
+        // 设置开始时间
+        List<DiscountCardRecord> discountCardRecords = usedDiscountCardRecordList(result.getUserId());
+        if (CollectionUtils.isNotEmpty(discountCardRecords)) {
+            discountCardRecord.setStartTime(discountCardRecords.stream().max(Comparator.comparing(DiscountCardRecord::getEndTime)).get().getEndTime());
+        } else {
+            discountCardRecord.setStartTime(new Date());
         }
-        discountCardRecord.setStartTime(DateUtil.localDateTimeToDate(startTime.atTime(LocalTime.MIN)));
-        discountCardRecord.setEndTime(DateUtil.localDateTimeToDate(endTime.atTime(23,59,59)));
 
-        this.save(discountCardRecord);
+        discountCardRecord.setEndTime(addTime(discountCardRecord.getStartTime(), discountCardRecord.getType(), discountCardRecord.getTimes(),1));
+
+        this.save(formatVipRecordTime(discountCardRecord));
 
         // 更新学生时长
-        studentService.lambdaUpdate()
-                .set(Student::getDiscountEndTime, discountCardRecord.getEndTime())
-                .set(student.getDiscountStartTime() == null,Student::getDiscountStartTime, discountCardRecord.getStartTime())
-                .eq(Student::getUserId, orderDetailVo.getUserId())
-                .update();
+        baseMapper.updateUserDiscountTime(result.getUserId(), discountCardRecord.getStartTime(), discountCardRecord.getEndTime());
+
+        return discountCardRecord.getId();
+    }
 
+    @Override
+    public IPage<DiscountCardRecordWrapper.DiscountCardRecord> selectPage(IPage<DiscountCardRecordWrapper.DiscountCardRecord> page, DiscountCardRecordWrapper.DiscountCardRecordQuery query) {
+        IPage<DiscountCardRecordWrapper.DiscountCardRecord> discountCardRecordIPage = baseMapper.selectPage(page, query);
+        List<DiscountCardRecordWrapper.DiscountCardRecord> records = discountCardRecordIPage.getRecords();
+        if (CollectionUtils.isEmpty(records)) {
+            return discountCardRecordIPage;
+        }
+        // 创建人ID集合
+        List<Long> createByList = records.stream()
+                .map(DiscountCardRecordWrapper.DiscountCardRecord::getCreateBy).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        Map<Long, SysUser> userMap = sysUserService.getMapByIds(createByList);
+        records.forEach(discountCardRecord -> {
+            SysUser sysUser = userMap.get(discountCardRecord.getCreateBy());
+            if (sysUser != null) {
+                discountCardRecord.setOperatorName(sysUser.getRealName());
+            }
+        });
+        return discountCardRecordIPage;
+    }
+
+
+    /**
+     * 获取剩余时长
+     *
+     */
+    @Override
+    public DiscountCardRecordWrapper.Info info(DiscountCardRecordWrapper.InfoQuery infoQuery) {
+        DiscountCardRecordWrapper.Info info = new DiscountCardRecordWrapper.Info();
+
+        List<DiscountCardRecord> discountCardRecords = usedDiscountCardRecordList(infoQuery.getUserId());
+        if (CollectionUtils.isEmpty(discountCardRecords)) {
+            return info;
+        }
+
+        // 最大时间
+        DiscountCardRecord discountCardRecord = discountCardRecords.stream().max(Comparator.comparing(DiscountCardRecord::getEndTime)).get();
+        info.setSurplusDay(DateUtil.daysBetweenUp(new Date(), discountCardRecord.getEndTime()));
+        return info;
+    }
+
+
+    private Date addTime(Date time, PeriodEnum period, Integer times, int type) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(time);
+
+        if (PeriodEnum.DAY.equals(period)) {
+            cal.add(Calendar.DAY_OF_MONTH, times);
+        } else if (PeriodEnum.MONTH.equals(period)) {
+            cal.add(Calendar.MONTH, times);
+        } else if (PeriodEnum.YEAR.equals(period)) {
+            cal.add(Calendar.YEAR, times);
+        }
+        if (type ==0) {
+            cal.set(Calendar.HOUR_OF_DAY, 0);
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+        } else {
+            cal.set(Calendar.HOUR_OF_DAY, 23);
+            cal.set(Calendar.MINUTE, 59);
+            cal.set(Calendar.SECOND, 59);
+            cal.set(Calendar.MILLISECOND, 0);
+        }
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
+
+    public DiscountCardRecord formatVipRecordTime(DiscountCardRecord discountCardRecord) {
+        // 如果开始时间是23:59:59,开始时间改为第二天的00:00:00
+        LocalDateTime startTime = discountCardRecord.getStartTime().toInstant()
+                .atZone(ZoneId.systemDefault()).toLocalDateTime();
+        if (startTime.toLocalTime().equals(LocalTime.of(23, 59, 59))) {
+            startTime = startTime.plusDays(1);
+        }
+
+        startTime = startTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
+        // 如果结束时间是00:00:00,开始时间改为前一天的23:59:59
+        LocalDateTime endTime = discountCardRecord.getEndTime().toInstant()
+                .atZone(ZoneId.systemDefault()).toLocalDateTime();
+        if (endTime.toLocalTime().equals(LocalTime.of(0, 0, 0))) {
+            endTime = endTime.plusDays(-1);
+        }
+        endTime = endTime.withHour(23).withMinute(59).withSecond(59).withNano(0);
+        discountCardRecord.setStartTime(Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()));
+        discountCardRecord.setEndTime(Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
+        if (discountCardRecord.getStartTime().after(discountCardRecord.getEndTime())) {
+            discountCardRecord.setEndTime(discountCardRecord.getStartTime());
+        }
+        return discountCardRecord;
     }
 }

+ 197 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/DiscountCardRecordWrapper.java

@@ -0,0 +1,197 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.enums.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang.StringUtils;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 购买会员卡记录表
+ * 2024-12-18 14:24:32
+ */
+@ApiModel(value = "DiscountCardRecordWrapper对象", description = "购买会员卡记录表查询对象")
+public class DiscountCardRecordWrapper {
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" DiscountCardRecordQuery-购买会员卡记录表")
+    public static class DiscountCardRecordQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+        private String keyword;
+
+        @ApiModelProperty("用户id")
+        @NotNull(message = "用户id不能为空")
+        private Long userId;
+
+        @ApiModelProperty("状态 ADD:新增,DEDUCTION:扣减")
+        private EVipRecordStatus status;
+
+        @ApiModelProperty("来源类型 : ACTIVITY :活动 ,ORDER:订单")
+        private SourceTypeEnum sourceType;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("操作人名称")
+        private String operatorName;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static DiscountCardRecordQuery from(String json) {
+            return JSON.parseObject(json, DiscountCardRecordQuery.class);
+        }
+    }
+
+    @Data
+    @ApiModel(" DiscountCardRecord-购买会员卡记录表")
+    public static class DiscountCardRecord {
+
+
+        @ApiModelProperty("会员记录id")
+        private Long id;
+
+        @ApiModelProperty("用户id")
+        private Long userId;
+
+        @ApiModelProperty("会员卡id")
+        private Long vipCardId;
+
+        @ApiModelProperty("订单号 ,活动id")
+        private String orderNo;
+
+        @ApiModelProperty("来源类型 : ACTIVITY :活动 ,ORDER:订单")
+        private SourceTypeEnum sourceType;
+
+        @ApiModelProperty("购买人员类型 TEACHRE :老师端 STUDNET : 学生端")
+        private ClientEnum clientType;
+
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("操作人ID")
+        private Long createBy;
+
+        @ApiModelProperty("操作人名称")
+        private String operatorName;
+
+        @ApiModelProperty("时间类型 DAY:天 MONTH:月,YEAR:年")
+        private PeriodEnum type;
+
+        @ApiModelProperty("添加时间数量")
+        private Integer times;
+
+        @ApiModelProperty("备注")
+        private String reason;
+
+        @ApiModelProperty("状态 ADD:新增,DEDUCTION:扣减")
+        private EVipRecordStatus status;
+
+
+        @ApiModelProperty("是否发送推送,1:是,0:否")
+        private Boolean sendMsg;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static DiscountCardRecord from(String json) {
+            return JSON.parseObject(json, DiscountCardRecord.class);
+        }
+    }
+
+
+    @Data
+    @ApiModel(" DiscountCardRecordChange")
+    public static class DiscountCardRecordChange {
+
+        @ApiModelProperty("用户id")
+        private Long userId;
+
+        @ApiModelProperty("会员卡id")
+        private Long vipCardId;
+
+        @ApiModelProperty("订单号 ,活动id")
+        private String orderNo;
+
+        @ApiModelProperty("订单详情号")
+        private String subOrderNo;
+
+        @ApiModelProperty("来源类型 : ACTIVITY :活动 ,ORDER:订单")
+        private SourceTypeEnum sourceType;
+
+        @ApiModelProperty("购买人员类型 TEACHRE :老师端 STUDNET : 学生端")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("操作人ID")
+        private Long createBy;
+
+
+        @ApiModelProperty("时间类型 DAY:天 MONTH:月,YEAR:年")
+        private PeriodEnum type;
+
+        @ApiModelProperty("添加时间数量")
+        private Integer times;
+
+        @ApiModelProperty("备注")
+        private String reason;
+
+        @ApiModelProperty("状态 ADD:新增,DEDUCTION:扣减")
+        private EVipRecordStatus status;
+
+    }
+
+    @Data
+    public static class InfoQuery {
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("类型")
+        private ClientEnum client;
+    }
+
+    @Data
+    public static class Info {
+
+        @ApiModelProperty("剩余天数")
+        private Integer surplusDay = 0;
+    }
+}

+ 37 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/DiscountCardRecordMapper.xml

@@ -41,4 +41,41 @@
             and t.user_id_ = #{userId}
         </if>
     </select>
+
+    <select id="selectPage"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.DiscountCardRecordWrapper$DiscountCardRecord">
+        select
+            t.*
+        from discount_card_record t
+
+        <if test="param.operatorName != null and param.operatorName != ''">
+            left join sys_user t1 on t.create_by_ = t1.id_
+        </if>
+        <where>
+            t.display_flag_ = 1
+            <if test="param.userId != null">
+                and t.user_id_ = #{param.userId} and t.client_type_ = 'STUDENT'
+            </if>
+            <if test="param.sourceType != null">
+                and t.source_type_ = #{param.sourceType}
+            </if>
+            <if test="param.status != null">
+                and t.status_ = #{param.status}
+            </if>
+            <if test="param.operatorName != null and param.operatorName != ''">
+                and t1.username_ like CONCAT('%',#{param.operatorName},'%')
+            </if>
+            <if test="param.startTime != null">
+                and t.create_time_ &gt;= #{param.startTime}
+            </if>
+            <if test="param.endTime != null">
+                and t.create_time_ &lt;= #{param.endTime}
+            </if>
+        </where>
+        order by t.id_ desc
+    </select>
+
+    <update id="updateUserDiscountTime">
+        update student t set t.discount_end_time_ = #{endTime},t.discount_start_time_ = ifnull(t.discount_start_time_,#{startTime}) where t.user_id_ = #{userId}
+    </update>
 </mapper>

+ 13 - 0
toolset/utils/src/main/java/com/yonge/toolset/utils/date/DateUtil.java

@@ -1584,4 +1584,17 @@ public class DateUtil {
 //				DateUtil.parse("2022-01-05",DEFAULT_PATTERN),
 //				DateUtil.parse("2022-02-04",DEFAULT_PATTERN)));
 	}
+
+
+	public static int daysBetweenUp(Date date, Date maxTime) {
+		long epochSecond = date.toInstant().getEpochSecond();
+		long epochSecond1 = maxTime.toInstant().getEpochSecond();
+		long i = (epochSecond1 - epochSecond)/(24*60*60)  ;
+		long j = (epochSecond1 - epochSecond)%(24*60*60)  ;
+		if (j >0) {
+			i++;
+		}
+		return (int)i;
+	}
+
 }