cloudroam
2024-09-03 e32fe26a1945fb44100d06b7049ccce865b11d4a
add:用户成长值降级规则开发
已修改7个文件
已添加8个文件
387 ■■■■■ 文件已修改
src/main/java/com/mzl/flower/constant/Constants.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/entity/menber/MemberDowngradeRecord.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/mapper/member/MemberDowngradeRecordMapper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/mapper/member/MemberMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/mapper/payment/OrderMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/schedule/ScheduleService.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/GrowthValueDeductionStrategy.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/MemberGrowthRecordService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/FirstDeductionStrategy.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/GrowthValueDealService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/GrowthValueStrategyContext.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/MemberGrowthRecordServiceImpl.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/SecondDeductionStrategy.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/menber/impl/ThirdDeductionStrategy.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/web/member/MemberController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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);
    }
}