sign->continue_days; $counts = $user->sign->counts; if (SignLog::where('user_id', $user->id) ->whereDate('date', (clone $date)->subDay()->toDateString()) ->exists()) { $continue_days++; } else { $continue_days = 1; } $crystals = self::getSignCrystal($continue_days); $rule_name = $params['rule_name']; $str = "第{$continue_days}天签到"; if ($crystals > 0) { $user->account->rule($rule_name, 0, false, [ 'frozen_at' => now()->toDateTimeString(), 'settle_at' => now()->toDateTimeString(), 'remark' => '第'.$continue_days.'天签到', ]); $str .= ",获得{$crystals}水滴"."\n"; // $str .= '第'.$continue_days.'天签到'; } $task_crystals = self::getTaskCrystal($continue_days); if ($task_crystals > 0) { // $user->account->rule($rule_name, $task_crystals, true, [ // 'frozen_at' => now()->toDateTimeString(), // 'settle_at' => now()->toDateTimeString(), // 'remark' => '连续签到'.$continue_days.'天', // ]); // $str .= '连续签到'.$continue_days.'天,获得水晶'.$task_crystals; $str .= '连续签到'.$continue_days.'天'; } $user->sign->update([ 'continue_days' => $continue_days, 'counts' => ++$counts, 'last_sign_at' => $date, ]); SignLog::create([ 'user_id' => $user->id, 'date' => $date, 'type' => 0, ]); return [true, $str]; } catch (Exception $e) { return [false, $e->getMessage()]; } } /** * 返回连续签到额外任务 * * @param int $continue_days * @return int */ public static function getTaskCrystal(int $continue_days = 1): int { $tasks = SignConfig::getTasks(); $task = $tasks->firstWhere('day', $continue_days); return $task['number'] ?? 0; } public static function getNextTaskCrystal($continue_days = 1) { $tasks = SignConfig::getTasks(); return $tasks->where('day', ' > ', $continue_days) ->sortBy('day') ->first(); } /** * 返回签到奖励 * * @param int $continue_days * @return HigherOrderCollectionProxy|int|mixed */ public static function getSignCrystal(int &$continue_days = 1) { $params = SignConfig::getParams(); $crystals = 0; switch ($params['type']) { case 'single': $crystals = $params['single_number']; break; case 'continuous': $crystals = (int) $params['continuous_base'] + (int) bcmul($continue_days - 1, $params['continuous_incremental'], 0); break; case 'cycle': if ($continue_days > $params['cycle_day']) { $continue_days -= $params['cycle_day']; } $crystals = (int) $params['cycle_base'] + (int) bcmul($continue_days - 1, $params['cycle_incremental'], 0); break; } return $crystals; } /** * Notes : 某一天是否可签到 * * @Date : 2021/5/28 3:25 下午 * @Author : * @param User $user * @param Carbon $date * @return bool */ public static function canSign(User $user, DateTime $date): bool { $identityMiddle = $user->identityMiddle()->first(); $start_at = $identityMiddle->started_at; if (! $start_at) { $start_at = $identityMiddle->created_at; } return $identityMiddle->identity->order > 1 && Carbon::parse($date)->endOfDay()->gt($start_at) && ! $user->IsSign($date) && $date->isToday(); } /** * Notes: 是否可以补签 * * @Author: 玄尘 * @Date: 2022/8/12 8:51 * @param User $user * @param DateTime $date * @return bool */ public static function canReSign(User $user, DateTime $date): bool { $identityMiddle = $user->identityMiddle()->first(); $start_at = $identityMiddle->started_at; if (! $start_at) { $start_at = $identityMiddle->created_at; } return ! $user->IsSign($date) && now()->endOfDay()->gt($date) && ! $date->isToday() && Carbon::parse($date)->endOfDay()->gt($start_at); } /** * Notes: 获取不可打卡的信息 * * @Author: 玄尘 * @Date: 2022/8/10 13:18 */ public static function getNotSignText(User $user, DateTime $date) { $identityMiddle = $user->identityMiddle()->first(); if (SignLog::where('user_id', $user->id)->whereDate('date', $date)->exists()) { return '今日已打卡'; } if ($identityMiddle->identity->order < 2) { return '未开通会员'; } $started_at = $identityMiddle->started_at; if (! $started_at) { $started_at = $identityMiddle->created_at; } if ($started_at->gt(Carbon::parse($date)->startOfDay())) { return '当前时间还未开通会员'; } } /** * Notes : 补签 * * @Date : 2021/5/28 3:15 下午 * @Author : * @param User $user * @param DateTime $date * @return bool * @throws Exception */ public static function replenish(User $user, DateTime $date): array { if (! self::canReSign($user, $date)) { throw new Exception(self::getNotSignText($user, $date)); } $params = SignConfig::getParams(); $continue_days = $user->sign->continue_days; $crystals = self::getSignCrystal($continue_days); $rule_name = $params['rule_name']; $str = $date->format('Y-m-d')."号补签"; if ($crystals > 0) { $user->account->rule($rule_name, 0, false, [ 'frozen_at' => now()->toDateTimeString(), 'settle_at' => now()->toDateTimeString(), 'remark' => now()->toDateTimeString().'天补签到', ]); $str .= ",获得{$crystals}水滴"."\n"; } $counts = $user->sign->counts; $user->sign->update([ 'counts' => ++$counts, ]); $log = SignLog::create([ 'user_id' => $user->id, 'date' => $date, 'type' => 1, ]); self::recalculateContinueDays($user); return [true, $str]; } /** * Notes: 重新计算连续签到日期 * * @Author: 玄尘 * @Date: 2022/8/4 9:34 */ public static function recalculateContinueDays(User $user) { $reset_at = $user->sign->reset_at; $days = SignLog::query() ->byUser($user) ->when($reset_at, function ($q) use ($reset_at) { $q->where('date', '>=', $reset_at); }) ->latest('date') ->pluck('date'); $continue_days = 1; foreach ($days as $key => $day) { if (isset($days[$key + 1])) { if ($day->subDay()->isSameDay($days[$key + 1])) { $continue_days++; } else { break; } } } $user->sign->update([ 'continue_days' => max($continue_days, 1), 'counts' => $user->signLogs()->count() ]); return true; } }