ChatGPT项目引起的会员套餐分段生效思路

开通多个会员,如何分段生效,巧用时间推迟法

背景

项目开发中遇到这样一个场景,项目针对用户开放各种会员套餐,每种会员套餐对应每天可免费调用ChatGPT次数不同的权益,所以当一个会员未到期时,用户发生续费,或者开通其他会员,会员权益如何分配成了问题,老板要求享受最近开通的那个会员权益,那么到底该如何解决呢?下面看我来分析。

思路

首先我们要明确一点,本这个需求中的重点是什么?是会员吗?是会员权益吗?是用户的会员时长吗?

不,都不是!

我们来看boss的需求 享受最近开通的那个会员权益 那么问题来了,之前的会员的时间怎么计算?

基础表

按照正常场景,我们一般要有下面两个关键表

用户

这里只关注关键字段

id eff_date eff_date
1

订单

假设这个是用户已支付的订单表,套餐时长实际应该在套餐中,为了方便我这里就直接放在一起了

订单号 会员时长 用户id

常规场景

场景一

  1. 普通用户第一次开通会员
    这个场景很正常,直接会员以当前时间生效,购买了一天,就一天后失效,一个月就一个月失效。。。 假设用户3.20购买一个月会员,那么我们直接更新用户数据

订单表

订单号 会员时长 用户id
1 一个月 1

用户表

id eff_date exp_date
1 2023-03-20 2023-04-20

场景二

  1. 已经是会员了,再进行会员购买操作
    比如说已经购买的会员,生效时间是2023-03-20至2023-04-20,现在是2023-03-24,用户又购买了一个两个月会员。直接时长往后加就行

订单表

订单号 会员时长 用户id
1 一个月 1
2 两个月 1

用户表

id eff_date exp_date
1 2023-03-20 2023-06-20

不同会员权益场景

我遇到的场景是这样,老板设置的会员套餐,比如说一个月,每天可以享受免费调用查询次数是20,但是两个月是50次,半年是200次

这样的话,我们的套餐表就要改一下了,但是我懒,就直接放在订单表里了,我们再来复现上面的场景

场景一

  1. 普通用户第一次开通会员
    这里还是直接更新用户信息,会员次数直接关联订单表,没问题

订单表

订单号 会员时长 用户id 免费次数
1 一个月 1 10

用户表

id eff_date exp_date
1 2023-03-20 2023-04-20

场景二

  1. 已经是会员了,再进行会员购买操作
    比如说已经购买的会员,生效时间是2023-03-20至2023-04-20,现在是2023-03-24,用户又购买了一个两个月的会员。用户的会员总时长也可以直接往后加

订单表

订单号 会员时长 用户id 免费次数
1 一个月 1 10
2 两个月 1 50

用户表

id eff_date exp_date
1 2023-03-20 2023-06-20

那么问题来了,用户有开通了两个月的会员,每天可以调用50次,怎么办呢,总不能一直给他调用50次,或者还让用户调10次吧,一种老板不愿意,一种用户不愿意。
于是乎,我就又在订单表加了个该笔订单的会员失效时间,表就成了下面这样:

订单号 会员时长 用户id 免费次数 失效时间
1 一个月 1 10 2023-04-20
2 两个月 1 50 2023-06-20

但是有人又发现了,哎不对啊,不是说最先开的会员先生效吗,你这怎么搞呢?
对呀,按照需求新购买的会员生效时间应该是3.24-5.24,前面的会员5.25-6.20。但是这样算的话,难道还要加个生效时间?
其实不用,以这两笔订单为例,我们只要先不考虑以前的订单,只算出当前这笔订单有效时长,算出它的到期时间,然后把其他的未到期的订单到期时间加上最新的这笔时长,也就是失效时间在今天之后的,统一往后延迟两个月。也就是这样:

订单号 会员时长 用户id 免费次数 失效时间
1 一个月 1 10 2023-06-20
2 两个月 1 50 2023-05-24

嘿,我真是个大聪明,如果用户又开了半年
用户表

id eff_date exp_date
1 2023-03-20 2023-12-20
订单号 会员时长 用户id 免费次数 失效时间
1 一个月 1 10 2023-12-20
2 两个月 1 50 2023-11-24
3 半年 1 200 2023-09-24

这样每次我们只要查询下用户没到期的订单,以创建时间倒序一下取第一条就可以拉!下面是核心代码,哈哈哈!

    /**
     * 设置其他订单 exp时间
     *
     * @param userId   用户id
     * @param orderId  当前订单id
     * @param duration 持续时间
     * @param units    单位
     */
    private void setOtherVipExpTime(Long userId, Long orderId, int duration, String units) {
    
    
        List<Order> orders = orderService.list(new LambdaQueryWrapper<Order>().eq(Order::getUserId, userId).notIn(Order::getId, orderId));
        //处理订单过期时间
        orders.forEach(order -> {
    
    
            Date expTime = order.getExpTime();
            if(expTime.after(new Date())){
    
    
                if ("2".equals(units)){
    
    
                    order.setExpTime(DateUtils.addYears(expTime, duration));
                }
                if ("1".equals(units)){
    
    
                    order.setExpTime(DateUtils.monthAdd(expTime, duration));
                }
                if ("0".equals(units)){
    
    
                    order.setExpTime(DateUtils.addDays(expTime, duration));
                }
                orderService.updateById(order);
            }
        });

    }

使用权益时

Order one = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getUserId, appUser.getId())
.eq(Order::getStatus, "1").ge(Order::getExpTime, new Date()).orderByAsc(Order::getId).last("limit 1"));

canUse = vipPackageService.getById(one.getVipId()).getDayTimes();

总结

只要思想不滑坡,办法总比困难多。能偷懒就偷懒,有bug再说!大家看到bug,记得给我指出来!

猜你喜欢

转载自blog.csdn.net/lovejiwei/article/details/129729759