src/main/java/com/mzl/flower/constant/Constants.java
@@ -529,7 +529,7 @@ } public enum GROWTH_SOURCE { sign("签到"), consume("消费"); sign("签到"), consume("消费"), downgrading("降级"); GROWTH_SOURCE(String desc) { this.desc = desc; src/main/java/com/mzl/flower/entity/menber/MemberDowngradeRecord.java
对比新文件 @@ -0,0 +1,28 @@ package com.mzl.flower.entity.menber; import com.baomidou.mybatisplus.annotation.TableName; import com.mzl.flower.base.BaseAutoEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author fanghaowei * @version version2.0 * @className Member * @date 2024/9/02 * @description 会员降级记录表 */ @Data @TableName("t_member_downgrade_record") public class MemberDowngradeRecord extends BaseAutoEntity { @ApiModelProperty("用户ID") private String userId; @ApiModelProperty("会员等级ID") private Long memberId; @ApiModelProperty("会员等级名称") private String memberName; } src/main/java/com/mzl/flower/mapper/member/MemberDowngradeRecordMapper.java
对比新文件 @@ -0,0 +1,24 @@ package com.mzl.flower.mapper.member; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mzl.flower.entity.menber.MemberDowngradeRecord; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; /** * @author fanghaowei * @version version2.0 * @className MemberMapper * @date 2024/9/2 * @description 会员降级mapper */ @SuppressWarnings("ALL") @Repository public interface MemberDowngradeRecordMapper extends BaseMapper<MemberDowngradeRecord> { @Select("select count(1) from t_member_downgrade_record where user_id = #{userId} and deleted = '0' ") Integer getMemberByName(@Param("userId") String userId); } src/main/java/com/mzl/flower/mapper/member/MemberMapper.java
@@ -33,6 +33,10 @@ @Select("select * from t_member where start_point > #{growthValue} and deleted = '0' ") List<Member> getgtMembersByGrowthValue(@Param("growthValue") Integer growthValue); //获取成长值区间最大值小于当前值的会员 @Select("select * from t_member where end_point < #{growthValue} and deleted = '0' ORDER BY end_point DESC LIMIT 1") Member getgtMembersByEndPoint(@Param("growthValue") Integer growthValue); List<MemberVO> queryPage(@Param("dto") MemberQueryDTO dto, Page page); } src/main/java/com/mzl/flower/mapper/payment/OrderMapper.java
@@ -6,6 +6,7 @@ import com.mzl.flower.dto.response.payment.*; import com.mzl.flower.entity.payment.Order; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.time.LocalDateTime; @@ -36,4 +37,15 @@ Order getUserLastOrder(@Param("userId") String userId); List<OrderPointGoodsListDTO> getPointGoodsList(@Param("orderId") String orderId); @Select("SELECT t1.* " + "FROM t_order t1 " + "JOIN ( " + " SELECT create_by, MAX(receive_time) AS max_time " + " FROM t_order " + " where receive_time is not null and DATE(receive_time) < DATE(NOW()) - INTERVAL 30 DAY" + " GROUP BY create_by " + ") t2 ON t1.create_by = t2.create_by AND t1.receive_time = t2.max_time " + "LEFT JOIN t_customer_info c ON t1.create_by = c.user_id ") List<Order> getOrderInfoByReceiveTime(); } src/main/java/com/mzl/flower/schedule/ScheduleService.java
@@ -9,15 +9,16 @@ import com.mzl.flower.mapper.flower.FlowerCategoryMapper; import com.mzl.flower.mapper.partner.PartnerMapper; import com.mzl.flower.mapper.payment.OrderMapper; import com.mzl.flower.service.coupon.CouponRecordService; import com.mzl.flower.service.flower.FlowerCategoryService; import com.mzl.flower.service.flower.FlowerService; import com.mzl.flower.service.menber.impl.GrowthValueDealService; import com.mzl.flower.service.payment.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.time.LocalDate; import java.time.LocalDateTime; @@ -59,7 +60,7 @@ private OrderItemSettlementService orderItemSettlementService; @Autowired private CouponRecordService couponRecordService; private GrowthValueDealService growthValueDealService; @Scheduled(cron = "1 0/20 * * * ?") public void calculateAvePrice() { @@ -190,18 +191,23 @@ log.info("账单结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 30 0 1 * ?") public void grantVipCouponRecordList() { log.info("会员优惠券开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); couponRecordService.grantVipCouponRecordList(); log.info("会员优惠券结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } @Scheduled(cron = "0 30 0 1 * ?") public void expiredVipCouponRecordList() { log.info("会员优惠券过期开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); couponRecordService.expiredCouponRecordByListCurMonth(); log.info("会员优惠券过期结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); //成长值降级定时任务 @Scheduled(cron = "0 0 5 * * ?") public void deductGrowthValue() { log.info("成长值扣除开始:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); //获取当前员工 List<Order> orderList = orderMapper.getOrderInfoByReceiveTime(); if(!CollectionUtils.isEmpty(orderList)){ orderList.forEach(o->{ try { growthValueDealService.deductionGrowthValue(o); } catch (Exception e) { // 记录错误信息,例如将错误信息写入日志 log.info("处理订单 " + o.getId() + " 时出错: " + e.getMessage()); } }); } log.info("成长值扣除结束:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")); } } src/main/java/com/mzl/flower/service/menber/GrowthValueDeductionStrategy.java
对比新文件 @@ -0,0 +1,16 @@ package com.mzl.flower.service.menber; import com.mzl.flower.entity.payment.Order; /** * packageName com.mzl.flower.service.menber * @author fanghaowei * @version version2.0 * @className GrowthValueDeductionStrategy * @date 2024/9/2 * @description 成长值扣除策略 */ public interface GrowthValueDeductionStrategy { public void deduct(Order order); } src/main/java/com/mzl/flower/service/menber/MemberGrowthRecordService.java
@@ -9,6 +9,7 @@ import com.mzl.flower.dto.response.member.MemberGrowthRecordVO; import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.menber.MemberGrowthRecord; import com.mzl.flower.entity.payment.Order; public interface MemberGrowthRecordService extends IService<MemberGrowthRecord> { @@ -21,4 +22,6 @@ Page<MemberGrowthRecordVO> queryPage(MemberRecordQueryDTO memberRecordQueryDTO, Page page); Member getMemberByUserId(String userId); void growthValueDeduct(Order order); } src/main/java/com/mzl/flower/service/menber/impl/FirstDeductionStrategy.java
对比新文件 @@ -0,0 +1,26 @@ package com.mzl.flower.service.menber.impl; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.service.menber.GrowthValueDeductionStrategy; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * packageName com.mzl.flower.service.menber.impl * @author fanghaowei * @version version2.0 * @className FristDeductionStrategy * @date 2024/9/2 * @description TODO */ @Transactional @RequiredArgsConstructor @Service("FirstDeduction") public class FirstDeductionStrategy implements GrowthValueDeductionStrategy { @Override public void deduct(Order order) { } } src/main/java/com/mzl/flower/service/menber/impl/GrowthValueDealService.java
对比新文件 @@ -0,0 +1,48 @@ package com.mzl.flower.service.menber.impl; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.service.menber.GrowthValueDeductionStrategy; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; /** * packageName com.mzl.flower.service.menber.impl * @author fanghaowei * @version version2.0 * @className GrowthValueDealService * @date 2024/9/2 * @description TODO */ @Service public class GrowthValueDealService { @Resource private GrowthValueStrategyContext growthValueStrategyContext; public void deductionGrowthValue(Order order) { //当前时间 LocalDateTime now = LocalDateTime.now(); //最后消费时间 LocalDateTime receiveTime = order.getReceiveTime(); // 将时间转换为LocalDate,只保留年月日部分 LocalDate nowDate = now.toLocalDate(); LocalDate receiveTimeDate = receiveTime.toLocalDate(); long daysBetween = ChronoUnit.DAYS.between(receiveTimeDate, nowDate); if (daysBetween > 30 && daysBetween <= 90) { GrowthValueDeductionStrategy growthInfo = growthValueStrategyContext.getGrowthInfo("SecondDeduction"); growthInfo.deduct(order); } else if (daysBetween > 90) { GrowthValueDeductionStrategy growthInfo = growthValueStrategyContext.getGrowthInfo("ThirdDeduction"); growthInfo.deduct(order); } } } src/main/java/com/mzl/flower/service/menber/impl/GrowthValueStrategyContext.java
对比新文件 @@ -0,0 +1,24 @@ package com.mzl.flower.service.menber.impl; import com.mzl.flower.service.menber.GrowthValueDeductionStrategy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; @Service public class GrowthValueStrategyContext { @Autowired private final Map<String, GrowthValueDeductionStrategy> growthValueDeductionStrategyMap = new HashMap<>(); public GrowthValueStrategyContext(Map<String, GrowthValueDeductionStrategy> growthValueDeductionStrategyMap) { this.growthValueDeductionStrategyMap.clear(); growthValueDeductionStrategyMap.forEach((k, v) -> this.growthValueDeductionStrategyMap.put(k, v)); } public GrowthValueDeductionStrategy getGrowthInfo(String growthInfo) { return growthValueDeductionStrategyMap.get(growthInfo); } } src/main/java/com/mzl/flower/service/menber/impl/MemberGrowthRecordServiceImpl.java
@@ -14,6 +14,7 @@ import com.mzl.flower.entity.customer.Customer; import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.menber.MemberGrowthRecord; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.mapper.customer.CustomerMapper; import com.mzl.flower.mapper.member.MemberGrowthRecordMapper; import com.mzl.flower.mapper.member.MemberMapper; @@ -77,7 +78,7 @@ //保存会员记录逻辑: if (Constants.GROWTH_SOURCE.consume.name().equals(memberGrowthRecordDTO.getSource())) { //消费:成长值=消费金额/消费金额(元)*已消费产生的成长值 //消费:成长值=消费金额/消费金额(元)*已消费产生的成长值C BigDecimal totalAmount = memberGrowthRecordDTO.getTotalAmount(); int consumptionAmount = memberBefore.getConsumptionAmount(); int growthValue = memberBefore.getGrowthValue(); @@ -169,4 +170,39 @@ page.setRecords(list); return page; } @Override public void growthValueDeduct(Order order) { //超过30天不到90天,每天处理当前会员等级的成长值 CustomerDTO customerDTO = customerMapper.getCurrentCustomer(order.getCreateBy()); Customer customer = customerMapper.selectById(customerDTO.getId()); Member member = memberMapper.selectById(customer.getLevelId()); if(ObjectUtils.isEmpty(member)){ throw new ValidationException("用户会员等级未维护"); } int deductGrowthValue = member.getDowngradeValue(); Integer sumGrowthByUserId = memberGrowthRecordMapper.getSumGrowthByUsertId(order.getCreateBy()); //当前成长值如果是等于0不需要走扣除逻辑 if (sumGrowthByUserId != 0) { int waitDeductGrowthValue = 0; //判断当前用户的成长值是够扣除,如果够扣除直接减去成长值,如果不够扣除则全部减去 if (sumGrowthByUserId - deductGrowthValue > 0) { waitDeductGrowthValue = deductGrowthValue; } else { waitDeductGrowthValue = sumGrowthByUserId; } //保存会员成长记录到记录表 MemberGrowthRecordDTO memberGrowthRecordDTO = new MemberGrowthRecordDTO(); memberGrowthRecordDTO.setUserId(order.getCreateBy()); memberGrowthRecordDTO.setRecordDate(new Date()); memberGrowthRecordDTO.setGrowth(-waitDeductGrowthValue); memberGrowthRecordDTO.setSource(Constants.GROWTH_SOURCE.downgrading.name()); memberGrowthRecordDTO.setType(Constants.GROWTH_TYPE.reduce.name()); memberGrowthRecordDTO.setRemarks("自动扣除"); saveMemberGrowthRecord(memberGrowthRecordDTO); } } } src/main/java/com/mzl/flower/service/menber/impl/SecondDeductionStrategy.java
对比新文件 @@ -0,0 +1,30 @@ package com.mzl.flower.service.menber.impl; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.service.menber.GrowthValueDeductionStrategy; import com.mzl.flower.service.menber.MemberGrowthRecordService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * packageName com.mzl.flower.service.menber.impl * @author fanghaowei * @version version2.0 * @className SecondDeductionStrategy * @date 2024/9/2 * @description TODO */ @Transactional @RequiredArgsConstructor @Service("SecondDeduction") public class SecondDeductionStrategy implements GrowthValueDeductionStrategy { private final MemberGrowthRecordService memberGrowthRecordService; @Override public void deduct(Order order) { memberGrowthRecordService.growthValueDeduct(order); } } src/main/java/com/mzl/flower/service/menber/impl/ThirdDeductionStrategy.java
对比新文件 @@ -0,0 +1,91 @@ package com.mzl.flower.service.menber.impl; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.menber.MemberGrowthRecordDTO; import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.menber.MemberDowngradeRecord; import com.mzl.flower.entity.payment.Order; import com.mzl.flower.mapper.member.MemberDowngradeRecordMapper; import com.mzl.flower.mapper.member.MemberGrowthRecordMapper; import com.mzl.flower.mapper.member.MemberMapper; import com.mzl.flower.service.menber.GrowthValueDeductionStrategy; import com.mzl.flower.service.menber.MemberGrowthRecordService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.Date; /** * packageName com.mzl.flower.service.menber.impl * @author fanghaowei * @version version2.0 * @className ThirdDeductionStrategy * @date 2024/9/2 * @description TODO */ @Transactional @RequiredArgsConstructor @Service("ThirdDeduction") public class ThirdDeductionStrategy implements GrowthValueDeductionStrategy { private final MemberDowngradeRecordMapper memberDowngradeRecordMapper; private final MemberGrowthRecordService memberGrowthRecordService; private final MemberGrowthRecordMapper memberGrowthRecordMapper; private final MemberMapper memberMapper; @Override public void deduct(Order order) { LocalDate nowDate = LocalDateTime.now().toLocalDate(); LocalDate receiveTimeDate = order.getReceiveTime().toLocalDate(); long daysBetween = ChronoUnit.DAYS.between(receiveTimeDate, nowDate); //判断是否有会员降级记录 Integer countByUserId = memberDowngradeRecordMapper.getMemberByName(order.getCreateBy()); int day = (int) (daysBetween - countByUserId * 90); //扣除记录数*90 //0-90;1-180;2-270 if (countByUserId == 0 || day > 90) { //保存会员降级记录 Member member = memberGrowthRecordService.getMemberByUserId(order.getCreateBy()); MemberDowngradeRecord memberDowngradeRecord = new MemberDowngradeRecord(); memberDowngradeRecord.setUserId(order.getCreateBy()); memberDowngradeRecord.setMemberId(member.getId()); memberDowngradeRecord.setMemberName(member.getName()); memberDowngradeRecord.create(); memberDowngradeRecordMapper.insert(memberDowngradeRecord); //统计当前人员现有成长值 Integer sumGrowthByUserId = memberGrowthRecordMapper.getSumGrowthByUsertId(order.getCreateBy()); //当前人员需要降到的成长值 Member targetMember = memberMapper.getgtMembersByEndPoint(sumGrowthByUserId); if (!ObjectUtils.isEmpty(targetMember)) { //有降级目标 int targetGrowth = targetMember.getEndPoint() - 1; //需要降级扣除的成长值是目标值减去当前值 int needDeductGrowthValue = targetGrowth-sumGrowthByUserId; //保存会员成长记录到记录表 MemberGrowthRecordDTO memberGrowthRecordDTO = new MemberGrowthRecordDTO(); memberGrowthRecordDTO.setUserId(order.getCreateBy()); memberGrowthRecordDTO.setRecordDate(new Date()); memberGrowthRecordDTO.setGrowth(needDeductGrowthValue); memberGrowthRecordDTO.setSource(Constants.GROWTH_SOURCE.downgrading.name()); memberGrowthRecordDTO.setType(Constants.GROWTH_TYPE.reduce.name()); memberGrowthRecordDTO.setRemarks("自动降级"); memberGrowthRecordService.saveMemberGrowthRecord(memberGrowthRecordDTO); } else { memberGrowthRecordService.growthValueDeduct(order); } } else if (countByUserId > 0) { if (day > 30 && day <= 90) { memberGrowthRecordService.growthValueDeduct(order); } } } } src/main/java/com/mzl/flower/web/member/MemberController.java
@@ -102,5 +102,12 @@ UserGrowthRecordDTO userGrowthRecordDTO = memberGrowthRecordService.getInfoByUserId(String.valueOf(userId)); return returnData(R.SUCCESS.getCode(), userGrowthRecordDTO); } @GetMapping(value = "/app/member/info") @ApiOperation(value = "当前用户会员信息 ", httpMethod = "GET", notes = "ID") public ResponseEntity memberInfo2() { UserGrowthRecordDTO userGrowthRecordDTO = memberGrowthRecordService.getInfoByUserId(SecurityUtils.getUserId()); return returnData(R.SUCCESS.getCode(), userGrowthRecordDTO); } }