123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- <?php
- declare(encoding='UTF-8');
- namespace App\Services\Coach;
- use App\Enums\TechnicianAuthStatus;
- use App\Models\CoachInfoRecord;
- use App\Models\CoachQualRecord;
- use App\Models\CoachRealRecord;
- use App\Models\CoachUser;
- use App\Services\Third\AliRealAuthService;
- use Illuminate\Support\Facades\Auth;
- use Illuminate\Support\Facades\Cache;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Redis;
- class AuthService
- {
- // 缓存相关常量
- private const CACHE_KEY_PREFIX = 'coach_auth_';
- private const CACHE_TTL = 300; // 5分钟
- // 限流相关常量
- private const RATE_LIMIT_PREFIX = 'coach_auth_limit_';
- private const RATE_LIMIT_TTL = 86400; // 24小时
- private const MAX_ATTEMPTS = 5; // 每24小时最多提交5次
- protected ?CoachUser $coach;
- protected AliRealAuthService $aliRealAuthService;
- public function __construct(AliRealAuthService $aliRealAuthService)
- {
- $this->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);
- }
- }
|