coach = Auth::user()->coach; $this->aliRealAuthService = $aliRealAuthService; } /** * 检查提交��数限制 * * @param string $type 认证类型(basic_info/real_auth/qual_auth) * @throws \Exception 超出限制时抛出异常 */ private function checkRateLimit(string $type): void { $key = self::RATE_LIMIT_PREFIX . $this->coach->id . ':' . $type; $attempts = Redis::get($key) ?: 0; if ($attempts >= self::MAX_ATTEMPTS) { throw new \Exception('今日提交次数已达上限,请24小时后再试'); } // 增加计数 if ($attempts == 0) { Redis::setex($key, self::RATE_LIMIT_TTL, 1); } else { Redis::incr($key); } } /** * 提交基本信息认证 * * @param array $data * @return array * @throws \Exception */ public function submitBasicInfo(array $data): array { try { // 检查提交次数限制 $this->checkRateLimit('basic_info'); DB::beginTransaction(); // 创建基本信息记录 $infoRecord = CoachInfoRecord::create([ 'coach_id' => $this->coach->id, 'nickname' => $data['nickname'], 'avatar' => $data['avatar'], 'gender' => (int)$data['gender'], 'mobile' => $data['mobile'], 'age' => $data['age'], 'birthday' => $data['birthday'], 'work_years' => $data['work_years'], 'intention_city' => $data['intention_city'], 'introduction' => $data['introduction'], 'portrait_images' => $data['portrait_images'], 'state' => TechnicianAuthStatus::AUDITING->value ]); // 清除认证缓存 $this->clearAuthCache(); DB::commit(); return [ 'id' => $infoRecord->id, 'state' => $infoRecord->state, 'state_text' => TechnicianAuthStatus::fromValue($infoRecord->state)->label() ]; } catch (\Exception $e) { DB::rollBack(); $this->logError('提交基本信息认证失败', [], $e); throw $e; } } /** * 提交实名认证 * * @param array $data * @return array * @throws \Exception */ public function submitRealAuth(array $data): array { try { // 检查提交次数限制 $this->checkRateLimit('real_auth'); DB::beginTransaction(); // 创建实名认证记录 $realRecord = CoachRealRecord::create([ 'coach_id' => $this->coach->id, 'real_name' => $data['real_name'], 'id_card' => $data['id_card'], 'id_card_front_photo' => $data['id_card_front_photo'], 'id_card_back_photo' => $data['id_card_back_photo'], 'id_card_hand_photo' => $data['id_card_hand_photo'], 'state' => TechnicianAuthStatus::AUDITING->value ]); // 调用阿里实名认证 $response = $this->aliRealAuthService->verify([ 'real_name' => $data['real_name'], 'id_card' => $data['id_card'] ]); // 清除认证缓存 $this->clearAuthCache(); DB::commit(); return [ 'record' => [ 'id' => $realRecord->id, 'state' => $realRecord->state, 'state_text' => TechnicianAuthStatus::fromValue($realRecord->state)->label() ], 'can_proceed' => true, 'message' => '实名认证提交成功,系统正在审核,您可以继续提交资质认证' ]; } catch (\Exception $e) { DB::rollBack(); $this->logError('提交实名认证失败', [], $e); throw $e; } } /** * 提交资质认证 * * @param array $data * @return array * @throws \Exception */ public function submitQualAuth(array $data): array { try { // 检查提交次数限制 $this->checkRateLimit('qual_auth'); DB::beginTransaction(); // 创建资质认证记录 $qualRecord = CoachQualRecord::create([ 'coach_id' => $this->coach->id, 'qual_type' => $data['qual_type'], 'qual_no' => $data['qual_no'], 'qual_photo' => $data['qual_photo'], 'valid_start' => $data['valid_start'] ?? null, 'valid_end' => $data['valid_end'] ?? null, 'state' => TechnicianAuthStatus::AUDITING->value ]); // 检查实名认证状态,添加提示信息 $warning = null; if ($this->coach->real_auth?->state === TechnicianAuthStatus::AUDITING->value) { $warning = '实名认证正在审核中,如审核失败可能需要重新提交资质认证'; } // 清除认证缓存 $this->clearAuthCache(); DB::commit(); return [ 'record' => [ 'id' => $qualRecord->id, 'state' => $qualRecord->state, 'state_text' => TechnicianAuthStatus::fromValue($qualRecord->state)->label() ], 'warning' => $warning ]; } catch (\Exception $e) { DB::rollBack(); $this->logError('提交资质认证失败', [], $e); throw $e; } } /** * 检查认证状态 * * @return array 返回认证状态和详细信息 */ public function checkAuthStatus(): array { // 获取最新的基本信息记录 $latestInfo = CoachInfoRecord::where('coach_id', $this->coach->id) ->latest() ->first(); // 获取最新的实名认证记录 $latestRealAuth = CoachRealRecord::where('coach_id', $this->coach->id) ->latest() ->first(); // 获取最新的资质认证记录 $latestQualAuth = CoachQualRecord::where('coach_id', $this->coach->id) ->latest() ->first(); $getStateInfo = function ($record) { if (!$record) { return [ 'state' => 0, 'state_text' => '未提交' ]; } return [ 'state' => $record->state, 'state_text' => TechnicianAuthStatus::fromValue($record->state)->label() ]; }; return [ 'basic_info' => [ ...$getStateInfo($latestInfo), 'detail' => $latestInfo ? [ 'nickname' => $latestInfo->nickname, 'avatar' => $latestInfo->avatar, 'gender' => $latestInfo->gender, 'mobile' => $latestInfo->mobile, 'age' => $latestInfo->age, 'birthday' => $latestInfo->birthday, 'work_years' => $latestInfo->work_years, 'intention_city' => $latestInfo->intention_city, 'introduction' => $latestInfo->introduction, 'portrait_images' => $latestInfo->portrait_images, 'created_at' => $latestInfo->created_at, 'updated_at' => $latestInfo->updated_at, ] : null, ], 'real_auth' => [ ...$getStateInfo($latestRealAuth), 'detail' => $latestRealAuth ? [ 'real_name' => $latestRealAuth->real_name, 'id_card' => $latestRealAuth->id_card, 'id_card_front_photo' => $latestRealAuth->id_card_front_photo, 'id_card_back_photo' => $latestRealAuth->id_card_back_photo, 'id_card_hand_photo' => $latestRealAuth->id_card_hand_photo, 'created_at' => $latestRealAuth->created_at, 'updated_at' => $latestRealAuth->updated_at, ] : null, ], 'qual_auth' => [ ...$getStateInfo($latestQualAuth), 'detail' => $latestQualAuth ? [ 'qual_type' => $latestQualAuth->qual_type, 'qual_no' => $latestQualAuth->qual_no, 'qual_photo' => $latestQualAuth->qual_photo, 'valid_start' => $latestQualAuth->valid_start, 'valid_end' => $latestQualAuth->valid_end, 'created_at' => $latestQualAuth->created_at, 'updated_at' => $latestQualAuth->updated_at, ] : null, ], ]; } /** * 记录信息日志 */ private function logInfo(string $message, array $data = []) { Log::info($message, array_merge([ 'coach_id' => $this->coach->id, 'ip' => request()->ip(), 'timestamp' => now()->toDateTimeString(), ], $data)); } /** * 记录错误日志 */ private function logError(string $message, array $data = [], ?\Exception $e = null) { Log::error($message, array_merge([ 'coach_id' => $this->coach->id, 'ip' => request()->ip(), 'timestamp' => now()->toDateTimeString(), ], $data, $e ? [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ] : [])); } /** * 清除认证缓存 */ private function clearAuthCache() { Cache::forget(self::CACHE_KEY_PREFIX.$this->coach->id); } }