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