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