PHP用户连续签到赠送额外积分

目录
一、需求
1、为什么要赠送积分
2、怎么获取积分
3、积分如何使用
1)、兑换
2)、抵扣
3)、等等
二、规则
1、用户注册
2、成功邀请新用户
3、用户签到
4、联想
三、数据表
1、用户表 user
2、用户签到表 user_sign
3、积分(获取)日志表 integral_log
四、代码
1、用户签到方法
2、公共类 - 积分赠送日志方法
一、需求
1、为什么要赠送积分
用户(连续)签到赠送(额外)积分,可以增加用户的活跃度,少一些僵尸用户;邀请好友赠送积分,可以扩大平台的用户量。

2、怎么获取积分
这个范围就比较广了,给几个获取积分的例子

用户注册获取积分
成功邀请新用户获取积分
完成首购获取积分
用户消费获取积分
用户签到获取积分
完成新手任务获取积分
完善基本信息获取积分

3、积分如何使用
1)、兑换
可以弄个积分商城,直接用积分兑换商品
2)、抵扣
购买商品时,除了可以使用优惠券抵扣、余额抵扣,还可以使用积分抵扣
3)、等等
二、规则
1、用户注册
用户注册赠送积分
2、成功邀请新用户
成功邀请新用户,新用户有注册积分,邀请人有邀请积分
3、用户签到
用户每日签到可以获取固定的积分
用户连续签到满n天,额外赠送积分
如果用户同时满足多个连续签到任务,则取额外积分为最大签到天数的积分
多个签到任务:比如用户连续5天赠送1积分,用户连续签到10天赠送2积分;用户连续签到了10天,则既满足连续签到5天,又满足连续签到10天,我们取连续签到10天的2积分作为额外积分。(也可以都取,则额外积分为1+2=3,这个要看规则怎么定了)
4、联想
可以添加规则用户签到当天如果是用户生日,积分翻倍
Tips:如果生日可为公历,也可为农历,则要注意区分

三、数据表
1、用户表 user

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
...
`integral` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '总积分',
`signDay` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '连续签到天数',
`createTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updateTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',

2、用户签到表 user_sign

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`userId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`integral` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '积分',
`dateTime` varchar(50) NOT NULL DEFAULT '' COMMENT '签到日期:格式为2090-01-01',
`remark` text COMMENT '备注',
`createTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updateTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',

3、积分(获取)日志表 integral_log

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`userId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
`fkId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '关联id',
`fkType` int(1) unsigned NOT NULL DEFAULT '0' COMMENT '关联类型:1:新用户注册;2用户签到;3用户消费;4邀请新用户;...',
`integral` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '积分',
`remark` text COMMENT '备注',
`createTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updateTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',

 ​
四、代码
1、用户签到方法

/**
 * 用户签到
 * @return mixed
 * @throws Exception
 */
public function sign() {
    $userInfo = self::loginInfo();  //缓存中根据Token获取用户的登录信息
    if (!$userInfo){
        exit('请先登录');
    }
    $userId = $userInfo['id'];

    $userDao = new UserDao();       //实例化用户表
    $signDao = new UserSignDao();   //实例化用户签到表

    //判断用户今天是否签到
    $dateTime = date('Y-m-d');
    $todayParam = ['userId' => $userId, 'dateTime' => $dateTime];
    $todayInfo = $signDao->single($todayParam);
    if ($todayInfo){
        exit('您今天已经签到过了');
    }

    //判断用户昨天是否签到
    $yesterday = date('Y-m-d', strtotime('-1 day'));    //昨天的日期格式:2090-01-01
    $yesterdayParam = ['userId' => $userId, 'dateTime' => $yesterday];
    $yesterdayInfo = $signDao->single($yesterdayParam);
    if ($yesterdayInfo){    //昨天签到了,签到天数自增1
        $userDao->setInc(['id' => $userId], 'signDay', 1);  //第三个参数默认为1,可以不传。
    }else{  //昨天断签,连续签到天数重置为1
        $userDao->updateByQuery(['signDay' => 1], ['id' => $userId]);  //更新该用户的签到天数为1天
    }

    list($integral, $remark) = IntegralService::insert($userId, 2);    //记录签到积分日志

    //添加签到数据
    $data = [
        'userId' => $userId,        //用户ID
        'dateTime' => $dateTime,    //签到日期
        'integral' => $integral,    //签到赠送的积分
        'remark' => $remark         //签到日志
    ];
    $signDao->insert($data);        //添加数据,createTime,updateTime已在该方法中追加

    return 'success';
}


2、公共类 - 积分赠送日志方法
这个表可以再加个type字段,区分积分类型:积分获取/积分消费

class IntegralService{
    /**
     * [积分赠送日志]公共方法
     * @param $userId 用户ID
     * @param $fkType 赠送类型:1:新用户注册;2用户签到;3用户消费;4邀请新用户;...
     * @param int $fkId 关联ID:如果类型为用户消费,则关联ID为订单的ID;如果类型为邀请新用户,则关联ID为新用户的ID...
     * @return array 返回[积分,备注]
     */
    public static function insert($userId, $fkType, $fkId = 0){
        $remark = '';
        $integral = 0;
        $userDao = new UserDao();

        if ($fkType == 1){  //新用户注册
            $integral = 20; //新用户注册赠送积分:这个可以写到配置里
            $remark = '新用户赠送积分';
        }else if ($fkType == 2){    //每日签到赠送额外积分
            list($integral, $remark) = self::userSign($userId, $userDao);
        }else if ($fkType == 3){    //消费
            //...
        }else if ($fkType == 4){    //推荐新用户
            $userInfo = $userDao->info($fkId);  //新用户的ID
            if (empty($userInfo)){
                exit('被邀请用户不存在');
            }
            $integral = 10; //推荐新用户注册赠送积分:这个可以写到配置里
            $remark = '邀请新用户 [ ' . $userInfo['username'] . ' ] 赠送积分';
        }

        //积分日志记录
        $data = [
            'userId' => $userId,
            'fkId' => $fkId,
            'fkType' => $fkType,
            'integral' => $integral,
            'remark' => $remark
        ];
        $integralDao = new IntegralLogDao();
        $integralDao->insert($data);    //添加数据,createTime,updateTime已在该方法中追加

        //用户积分自增$integral
        $userDao->setInc(['id' => $userId], 'integral', $integral);

        return [$integral, $remark];
    }

    /**
     * 获取会员签到获取的积分,备注
     * @param $userId
     * @param $userDao
     * @return array
     */
    public static function userSign($userId, $userDao){
        $userInfo = $userDao->info($userId);
        if (empty($userInfo)){
            exit('用户不存在');
        }
        $signDay = $userInfo['signDay'];   //用户连续签到天数

        $remark = '';
        $integral = 3;  //用户每日签到积分:这个可以写到配置里
        if ($signDay != 0){ //如果签到日期不为0
            # 签到额外送积分:这个可以写到配置里
            /**
             * name:说明
             * desc:备注,这里表示连续签到天数
             * value:值,这里表示额外赠送积分数量
             */
            $extraIntegral = [
                ['name' => '连续签到7天额外赠送1积分', 'desc' => 7, 'value' => 1],
                ['name' => '连续签到15天额外赠送2积分', 'desc' => 15, 'value' => 2],
                ['name' => '连续签到30天额外赠送5积分', 'desc' => 30, 'value' => 5],
            ];

            //二维数组排序:按照积分降序,如果同时满足多个连续签到任务,则取最大签到天数的积分。
            $values = array_column($extraIntegral, 'value');
            array_multisort($values, SORT_DESC, $extraIntegral);

            $isGiveExtra = false;                   //是否已经赠送了额外积分
            foreach ($extraIntegral as $value){
                $day = $value['desc'];              //配置的签到天数
                $giveIntegral = $value['value'];    //赠送额外积分
                if (($signDay % $day) == 0){        //如果:用户连续签到天数 % 配置的连续签到天数 = 0;我们认为该用户可以获取额外积分
                    if ($isGiveExtra){              //如果:已经赠送了额外积分,则不再赠送,结束循环
                        break;
                    }
                    $integral += $giveIntegral;     //积分 = 每日签到默认积分 + 连续签到额外赠送的积分
                    $remark = "您已经连续签到了 [ {$day} ] 天,额外赠送您 [ {$giveIntegral} ] 积分"; //备注
                    $isGiveExtra = true;            //设置为true,已经赠送了积分,不再重复赠送
                    # 或者去除 $isGiveExtra 变量相关操作,直接在这里 break
                }
            }
        }
        $remark = $remark ? $remark : '签到赠送积分';

        return [$integral, $remark];
    }
}

 版权声明:本文为CSDN博主「꧁❦༺东伯༒雪鹰༻❦꧂」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36025814/article/details/107078614

上一篇:机器学习-1 绪论


下一篇:Nacos细节篇