298 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			298 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace app\api\logic;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use app\common\basics\Logic;
							 | 
						||
| 
								 | 
							
								use app\common\logic\AccountLogLogic;
							 | 
						||
| 
								 | 
							
								use app\common\model\AccountLog;
							 | 
						||
| 
								 | 
							
								use app\common\model\sign_daily\SignDaily;
							 | 
						||
| 
								 | 
							
								use app\common\model\sign_daily\UserSign;
							 | 
						||
| 
								 | 
							
								use app\common\model\user\User;
							 | 
						||
| 
								 | 
							
								use app\common\server\ConfigServer;
							 | 
						||
| 
								 | 
							
								use app\common\server\UrlServer;
							 | 
						||
| 
								 | 
							
								use think\facade\Db;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 签到逻辑
							 | 
						||
| 
								 | 
							
								 * Class SignLogic
							 | 
						||
| 
								 | 
							
								 * @package app\api\logic
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class SignLogic extends Logic
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @notes 签到列表
							 | 
						||
| 
								 | 
							
								     * @param $user_id
							 | 
						||
| 
								 | 
							
								     * @return array
							 | 
						||
| 
								 | 
							
								     * @throws \think\db\exception\DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws \think\db\exception\DbException
							 | 
						||
| 
								 | 
							
								     * @throws \think\db\exception\ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     * @author 段誉
							 | 
						||
| 
								 | 
							
								     * @date 2022/2/17 18:29
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function lists($user_id)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        //用户信息
							 | 
						||
| 
								 | 
							
								        $user = User::where(['id' => $user_id])
							 | 
						||
| 
								 | 
							
								            ->field('id,nickname,avatar,user_integral')
							 | 
						||
| 
								 | 
							
								            ->find();
							 | 
						||
| 
								 | 
							
								        $user['avatar'] = UrlServer::getFileUrl($user['avatar']);
							 | 
						||
| 
								 | 
							
								        $user['today_sign'] = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //今天签到记录
							 | 
						||
| 
								 | 
							
								        $today_sign = UserSign::where(['del' => 0, 'user_id' => $user_id])
							 | 
						||
| 
								 | 
							
								            ->whereTime('sign_time', 'today')
							 | 
						||
| 
								 | 
							
								            ->find();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //昨天签到记录
							 | 
						||
| 
								 | 
							
								        $yester_sign = UserSign::where(['del' => 0, 'user_id' => $user_id])
							 | 
						||
| 
								 | 
							
								            ->whereTime('sign_time', 'yesterday')
							 | 
						||
| 
								 | 
							
								            ->find();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //今天是否已签到
							 | 
						||
| 
								 | 
							
								        $today_sign && $user['today_sign'] = 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //昨天没签到,则签到中断重新计算连续天数
							 | 
						||
| 
								 | 
							
								        if (!$yester_sign) {
							 | 
						||
| 
								 | 
							
								            $today_start = strtotime(date('Y-m-d') . '00:00:00');
							 | 
						||
| 
								 | 
							
								            UserSign::where(['del' => 0, 'user_id' => $user_id])
							 | 
						||
| 
								 | 
							
								                ->where('sign_time', '<', $today_start)
							 | 
						||
| 
								 | 
							
								                ->update(['del' => 1, 'update_time' => time()]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //签到规则
							 | 
						||
| 
								 | 
							
								        $sign_list = SignDaily::where(['del' => 0])
							 | 
						||
| 
								 | 
							
								            ->order('type asc,days asc')
							 | 
						||
| 
								 | 
							
								            ->column('*', 'days');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 根据签到奖励计算 (今天签到赠送的积分,累计签到天数,签到天列表)
							 | 
						||
| 
								 | 
							
								        $data = self::formatSignList($user_id, $sign_list);
							 | 
						||
| 
								 | 
							
								        // 累计签到天数
							 | 
						||
| 
								 | 
							
								        $user['days'] = $data['total_sign_days'];
							 | 
						||
| 
								 | 
							
								        // 赚积分描述
							 | 
						||
| 
								 | 
							
								        $integral_tips = self::getInegralTips($user_id, $user['today_sign'], $data['today_sign_integral']);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return [
							 | 
						||
| 
								 | 
							
								            'user' => $user,
							 | 
						||
| 
								 | 
							
								            'sign_list' => $data['days_list'],
							 | 
						||
| 
								 | 
							
								            'integral_tips' => $integral_tips,
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @notes 计算签到信息
							 | 
						||
| 
								 | 
							
								     * @param $user_id
							 | 
						||
| 
								 | 
							
								     * @param $sign_list
							 | 
						||
| 
								 | 
							
								     * @return array
							 | 
						||
| 
								 | 
							
								     * @author 段誉
							 | 
						||
| 
								 | 
							
								     * @date 2022/2/17 18:23
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function formatSignList($user_id, $sign_list)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // 今天签到赠送的积分
							 | 
						||
| 
								 | 
							
								        $today_sign_integral = 0;
							 | 
						||
| 
								 | 
							
								        // 累计签到天数
							 | 
						||
| 
								 | 
							
								        $total_sign_days = 0;
							 | 
						||
| 
								 | 
							
								        // 签到天
							 | 
						||
| 
								 | 
							
								        $days_list = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (empty($sign_list)) {
							 | 
						||
| 
								 | 
							
								            return [
							 | 
						||
| 
								 | 
							
								                'days_list' => $days_list,
							 | 
						||
| 
								 | 
							
								                'today_sign_integral' => $today_sign_integral,
							 | 
						||
| 
								 | 
							
								                'total_sign_days' => $total_sign_days
							 | 
						||
| 
								 | 
							
								            ];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 第一次签到规则
							 | 
						||
| 
								 | 
							
								        $start_sign = current($sign_list);
							 | 
						||
| 
								 | 
							
								        // 最后一次签到规则
							 | 
						||
| 
								 | 
							
								        $end_sign = end($sign_list);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 每天赠送的积分
							 | 
						||
| 
								 | 
							
								        $everyday_award_integral = 0;
							 | 
						||
| 
								 | 
							
								        $start_sign['integral_status'] && $everyday_award_integral = $start_sign['integral'];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 累计签到的总天数
							 | 
						||
| 
								 | 
							
								        $total_sign_days = UserSign::where(['del' => 0, 'user_id' => $user_id])
							 | 
						||
| 
								 | 
							
								            ->order('id desc')
							 | 
						||
| 
								 | 
							
								            ->value('days');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for ($days = 1; $days <= $end_sign['days']; $days++) {
							 | 
						||
| 
								 | 
							
								            $send_integral = $everyday_award_integral;
							 | 
						||
| 
								 | 
							
								            // 连接签到赠送的积分
							 | 
						||
| 
								 | 
							
								            if (isset($sign_list[$days]) && $sign_list[$days]['integral_status']) {
							 | 
						||
| 
								 | 
							
								                $send_integral = $everyday_award_integral + $sign_list[$days]['integral'];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // 合并数据
							 | 
						||
| 
								 | 
							
								            $days_list[$days] = [
							 | 
						||
| 
								 | 
							
								                'days' => $days,
							 | 
						||
| 
								 | 
							
								                'status' => 0,
							 | 
						||
| 
								 | 
							
								                'integral' => $send_integral,
							 | 
						||
| 
								 | 
							
								                'growth' => 0,
							 | 
						||
| 
								 | 
							
								            ];
							 | 
						||
| 
								 | 
							
								            // 更新签到天数之前的签到状态
							 | 
						||
| 
								 | 
							
								            if ($days === $total_sign_days) {
							 | 
						||
| 
								 | 
							
								                $today_sign_integral = $send_integral;// 今天签到获得的积分
							 | 
						||
| 
								 | 
							
								                for ($sign_day = $days; $sign_day >= 1; $sign_day--) {
							 | 
						||
| 
								 | 
							
								                    $days_list[$sign_day]['status'] = 1;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // 如果连续签到天数大于总天数,则全部标记为已签到状态
							 | 
						||
| 
								 | 
							
								            if ($total_sign_days > $end_sign['days']) {
							 | 
						||
| 
								 | 
							
								                $days_list[$days]['status'] = 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return [
							 | 
						||
| 
								 | 
							
								            'days_list' => array_values($days_list),
							 | 
						||
| 
								 | 
							
								            'today_sign_integral' => $today_sign_integral,
							 | 
						||
| 
								 | 
							
								            'total_sign_days' => empty($total_sign_days) ? 0 : $total_sign_days
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @notes 赚积分描述
							 | 
						||
| 
								 | 
							
								     * @param $user_id
							 | 
						||
| 
								 | 
							
								     * @param $today_sign_status
							 | 
						||
| 
								 | 
							
								     * @param $today_sign_integral
							 | 
						||
| 
								 | 
							
								     * @return array
							 | 
						||
| 
								 | 
							
								     * @author 段誉
							 | 
						||
| 
								 | 
							
								     * @date 2022/2/17 18:29
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function getInegralTips($user_id, $today_sign_status, $today_sign_integral)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        //赚积分
							 | 
						||
| 
								 | 
							
								        $tips[] = [
							 | 
						||
| 
								 | 
							
								            'name' => '每日签到',
							 | 
						||
| 
								 | 
							
								            'status' => $today_sign_status,
							 | 
						||
| 
								 | 
							
								            'type' => 1,//类型,主要用前端显示图标
							 | 
						||
| 
								 | 
							
								            'image' => UrlServer::getFileUrl('/static/common/image/default/sign.png')
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $open_award = ConfigServer::get('order_award', 'open_award', 0);
							 | 
						||
| 
								 | 
							
								        //消费送积分
							 | 
						||
| 
								 | 
							
								        if ($open_award > 0) {
							 | 
						||
| 
								 | 
							
								            $order_award = AccountLog::where(['user_id' => $user_id, 'source_type' => AccountLog::consume_award_integral])
							 | 
						||
| 
								 | 
							
								                ->whereDay('create_time')
							 | 
						||
| 
								 | 
							
								                ->findOrEmpty();
							 | 
						||
| 
								 | 
							
								            $tips[] = [
							 | 
						||
| 
								 | 
							
								                'name' => '消费送积分',
							 | 
						||
| 
								 | 
							
								                'status' => $order_award->isEmpty() ? 0 : 1,
							 | 
						||
| 
								 | 
							
								                'type' => 2,
							 | 
						||
| 
								 | 
							
								                'image' => UrlServer::getFileUrl('/static/common/image/default/place_order.png')
							 | 
						||
| 
								 | 
							
								            ];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return $tips;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @notes 签到
							 | 
						||
| 
								 | 
							
								     * @param $user_id
							 | 
						||
| 
								 | 
							
								     * @return array|false
							 | 
						||
| 
								 | 
							
								     * @author 段誉
							 | 
						||
| 
								 | 
							
								     * @date 2022/2/17 17:48
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function sign($user_id)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Db::startTrans();
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								            // 连续签到天数
							 | 
						||
| 
								 | 
							
								            $sign_list = SignDaily::where(['del' => 0, 'type' => 2])
							 | 
						||
| 
								 | 
							
								                ->order('type asc,days asc')
							 | 
						||
| 
								 | 
							
								                ->column('*', 'days');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $now = time();
							 | 
						||
| 
								 | 
							
								            $award_integral = 0;                    //签到赠送的总积分 (每天签到奖励 + 连续签到奖励)
							 | 
						||
| 
								 | 
							
								            $award_growth = 0;                      //签到赠送的成长值 (每天签到奖励 + 连续签到奖励)
							 | 
						||
| 
								 | 
							
								            $continuous_integral = 0;               //连续签到积分
							 | 
						||
| 
								 | 
							
								            $continuous_growth = 0;                 //连续签到成长值
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 每天签到的奖励
							 | 
						||
| 
								 | 
							
								            $everyday_sign = SignDaily::where(['del' => 0, 'type' => 1])->findOrEmpty();
							 | 
						||
| 
								 | 
							
								            // 每天签到奖励
							 | 
						||
| 
								 | 
							
								            if ($everyday_sign) {
							 | 
						||
| 
								 | 
							
								                if ($everyday_sign['integral_status'] && $everyday_sign['integral'] > 0) {
							 | 
						||
| 
								 | 
							
								                    $award_integral += $everyday_sign['integral'];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if ($everyday_sign['growth_status'] && $everyday_sign['growth'] > 0) {
							 | 
						||
| 
								 | 
							
								                    $award_growth += $everyday_sign['growth'];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 签到记录
							 | 
						||
| 
								 | 
							
								            $last_sign = UserSign::where(['del' => 0, 'user_id' => $user_id])
							 | 
						||
| 
								 | 
							
								                ->order('id desc')
							 | 
						||
| 
								 | 
							
								                ->findOrEmpty();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 无签到记录找是否有连续签到1天的奖励,有签到记录则找(上次签到天数+1天)的连续奖励
							 | 
						||
| 
								 | 
							
								            if ($last_sign->isEmpty()) {
							 | 
						||
| 
								 | 
							
								                $sign_day = 1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $sign_day = $last_sign['days'] + 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 累计签到天数,计算连续签到奖励
							 | 
						||
| 
								 | 
							
								            $continuous_sign = $sign_list[$sign_day] ?? [];
							 | 
						||
| 
								 | 
							
								            if ($continuous_sign) {
							 | 
						||
| 
								 | 
							
								                if ($continuous_sign['integral_status'] && $continuous_sign['integral'] > 0) {
							 | 
						||
| 
								 | 
							
								                    $award_integral += $continuous_sign['integral'];
							 | 
						||
| 
								 | 
							
								                    $continuous_integral = $continuous_sign['integral'];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if ($continuous_sign['growth_status'] && $continuous_sign['growth'] > 0) {
							 | 
						||
| 
								 | 
							
								                    $award_growth += $continuous_sign['growth'];
							 | 
						||
| 
								 | 
							
								                    $continuous_growth = $continuous_sign['growth'];
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            UserSign::create([
							 | 
						||
| 
								 | 
							
								                'user_id' => $user_id,
							 | 
						||
| 
								 | 
							
								                'days' => $sign_day,
							 | 
						||
| 
								 | 
							
								                'integral' => $everyday_sign['integral_status'] ? $everyday_sign['integral'] : 0,
							 | 
						||
| 
								 | 
							
								                'growth' => $everyday_sign['growth_status'] ? $everyday_sign['growth'] : 0,
							 | 
						||
| 
								 | 
							
								                'continuous_integral' => $continuous_integral,
							 | 
						||
| 
								 | 
							
								                'continuous_growth' => $continuous_growth,
							 | 
						||
| 
								 | 
							
								                'sign_time' => $now,
							 | 
						||
| 
								 | 
							
								            ]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($award_integral) {
							 | 
						||
| 
								 | 
							
								                User::where(['del' => 0, 'id' => $user_id])->inc('user_integral', $award_integral)->update();
							 | 
						||
| 
								 | 
							
								                AccountLogLogic::AccountRecord($user_id, $award_integral, 1, AccountLog::sign_in_integral);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if ($award_growth) {
							 | 
						||
| 
								 | 
							
								                User::where(['del' => 0, 'id' => $user_id])->inc('user_growth', $award_growth)->update();
							 | 
						||
| 
								 | 
							
								                AccountLogLogic::AccountRecord($user_id, $award_growth, 1, AccountLog::sign_give_growth);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Db::commit();
							 | 
						||
| 
								 | 
							
								            return [
							 | 
						||
| 
								 | 
							
								                'days' => $sign_day,
							 | 
						||
| 
								 | 
							
								                'integral' => $award_integral,
							 | 
						||
| 
								 | 
							
								                'growth' => $award_growth
							 | 
						||
| 
								 | 
							
								            ];
							 | 
						||
| 
								 | 
							
								        } catch (\Exception $e) {
							 | 
						||
| 
								 | 
							
								            Db::rollback();
							 | 
						||
| 
								 | 
							
								            self::$error = $e->getMessage();
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @notes 获取签到规则
							 | 
						||
| 
								 | 
							
								     * @return array|int|mixed|string|null
							 | 
						||
| 
								 | 
							
								     * @author 段誉
							 | 
						||
| 
								 | 
							
								     * @date 2022/2/17 14:47
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function getRule()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ['rule' => ConfigServer::get('sign_rule', 'instructions', '')];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |