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', '')]; | ||
|  |     } | ||
|  | 
 | ||
|  | } |