UserAuthController.php 7.03 KB
<?php


namespace App\Http\Container\AppSection\Controllers;

use App\Enums\UserScopeEnum;
use App\Exceptions\SingerLimitException;
use App\Helpers\ConfigHelper;
use App\Helpers\JsonResource;
use App\Http\Container\AppSection\Requests\UserAuthCreateRequest;
use App\Http\Container\AppSection\Requests\UserAuthExamineRequests;
use App\Http\Service\UserService;
use App\Jobs\UserApplyCertifyJob;
use App\Jobs\UserSingerLimitJob;
use App\Models\GroupHasMember;
use App\Models\SystemTag;
use App\Models\User;
use App\Models\UserCertify;
use App\Models\Views\UserLastCertify;
use App\Notifications\UserCertifyFailNotification;
use App\Notifications\UserCertifySuccessNotification;
use DB;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Notification;
use RuntimeException;

class UserAuthController
{
    public function story(UserAuthCreateRequest $request)
    {
        $data      = $request->validated();
        $user_id   = Auth::id();
        $user      = Auth::user();
        $is_submit = UserCertify::query()->where(['user_id' => $user_id, 'status' => 0])->exists();
        if ($is_submit) {
            return JsonResource::fail(JsonResource::REPEAT_SUBMIT);
        }
        //判断被邀请人是否有歌手标签且自己团队歌手标签没超过限制
        $group_id      = GroupHasMember::query()->where(['member_id' => $user_id])->first()->group_id ?? 0;
        $singerTags    = ConfigHelper::getSingerTagIds();
        $is_singer_tag = ConfigHelper::hasSingerTag($data['tags'], $singerTags);

        $ids = GroupHasMember::query()->where(['group_id' => $group_id, 'role' => 3])->whereNot('member_id', $user_id)->pluck('member_id')->toArray();
        //计算团队歌手标签数,过滤掉当前用户
        $singer_tag_count = User::query()->whereIn('id', $ids)->whereNot('id', $user_id)
            ->whereHas('authTags', fn(Builder $builder) => $builder->whereIn('system_tags.id', $singerTags))
            ->count();

        $masterId = GroupHasMember::query()->where(['group_id' => $group_id, 'role' => 1])->first()->member_id ?? 0;
        if ($masterId) {
            $maxSingerNum = User::query()->whereKey($masterId)->value('business_singer_limit');
            if ($is_singer_tag && $singer_tag_count >= $maxSingerNum) {
                $master = User::query()->find($masterId, ['id', 'nick_name']);
                UserSingerLimitJob::dispatch([
                    'title'   => sprintf('%s:歌手额度已满', $master?->getAttribute('nick_name')),
                    'content' => sprintf('%s:提交歌手认证', $user?->getAttribute('nick_name'))
                ], [
                    'title'   => sprintf('%s:提交歌手认证', $user?->getAttribute('nick_name')),
                    'content' => sprintf('经纪人:%s', $master->getAttribute('nick_name')),
                    'limit'   => $maxSingerNum
                ]);
                return JsonResource::fail(JsonResource::TEAM_INVITE_SINGER_LIMIT, code: 403);
            }
        }
        $data['user_id'] = $user_id;
        $certify         = UserCertify::create($data);

        UserApplyCertifyJob::dispatch($certify);

        return JsonResource::success(JsonResource::CREATE_SUCCESS);

    }

    public function list(Request $request)
    {
        $size = $request->get('size', 10);
        $user = Auth::user();
        if ($user?->getAttribute('scope') === UserScopeEnum::SYSTEM) {
            $datas = User::query()
                ->join('user_auth_infos', 'user_auth_infos.user_id', '=', 'users.id')
                ->where('user_auth_infos.status', 0)
                ->where('user_auth_infos.deleted_at', NULL)
                ->select('users.id', 'users.nick_name', 'users.avatar', 'user_auth_infos.created_at', 'user_auth_infos.tags')
                ->orderBy('user_auth_infos.created_at', 'desc')
                ->paginate($size);
            foreach ($datas as $data) {
                $data['tag_list'] = SystemTag::query()->whereIn('id', json_decode($data->tags))->pluck('name');
                unset($data->tags);
            }
            return JsonResource::success(JsonResource::SUCCESS, ['data' => $datas->items(), 'count' => $datas->total()]);
        }

        return JsonResource::fail(JsonResource::NO_PERMISSION);
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function detail(Request $request): JsonResponse
    {
        $user = User::query()
            ->with(['authTags:id,name'])
            ->select(['id', 'nick_name', 'avatar', 'real_name', 'identity', 'register_type', 'register_remark', 'inviter_id'])
            ->findOrFail($request->get('id'));

        $user->setAttribute('auth_info', UserLastCertify::query()->where('user_id', $user->getKey())->first());
        $user->setAttribute('inviter', User::query()
            ->select(['id', 'nick_name', 'avatar', 'real_name', 'identity', 'user_tag_id'])
            ->with(['authTags:id,name', 'userTag:id,name,icon,frame'])
            ->find($user->getAttribute('inviter_id')));

        return JsonResource::success(JsonResource::SUCCESS, $user);
    }

    public function examine(UserAuthExamineRequests $request)
    {
        $data   = $request->validated();
        $id     = $data['id'];
        $status = $data['status'];
        $reason = $data['reason'] ?? NULL;
        $item   = UserCertify::with('user')->find($id);
        $user   = $item->getAttribute('user');

        try {
            DB::beginTransaction();
            //审核认证

            $item->update(['operator_id' => Auth::id(), 'status' => $status, 'reason' => $reason]);

            if ($status === 1) {
                UserService::updateAuthTags($user, $item->getAttribute('tags'), ['audit_at' => now()->toDateTimeString()]);
            }

            DB::commit();

            match ($item->getAttribute('status')) {
                1 => Notification::send($user, new UserCertifySuccessNotification()),
                2 => Notification::send($user, new UserCertifyFailNotification())
            };
            return JsonResource::success(JsonResource::UPDATE_SUCCESS);
        } catch (SingerLimitException $exception) {
            DB::rollBack();
            $master = User::query()->find($exception->masterId, ['id', 'nick_name']);
            UserSingerLimitJob::dispatch([
                'title'   => sprintf('%s:歌手额度已满', $master?->getAttribute('nick_name')),
                'content' => sprintf('审核歌手认证:%s', $user->getAttribute('nick_name'))
            ], [
                'title'   => sprintf('%s:审核歌手认证', $user->getAttribute('nick_name')),
                'content' => sprintf('经纪人:%s', $master->getAttribute('nick_name')),
                'limit'   => $exception->maxSingerNum
            ]);
            return JsonResource::fail(JsonResource::TEAM_INVITE_SINGER_LIMIT, code: 403);


        } catch (RuntimeException $exception) {
            DB::rollBack();
            throw $exception;
        }
    }
}