IndexController.php 10.4 KB
<?php


namespace App\Http\Container\AppSection\Controllers;


use App\Helpers\JsonResource;
use App\Http\Service\indexSearchService;
use App\Models\BrokerPushLevelRecordItem;
use App\Models\NotificationUser;
use App\Models\Project;
use App\Models\User;
use App\Models\UserFollowRelation;
use App\Models\Views\ActivitySubmitWork;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use URL;


class IndexController
{
    public function publicAudition(Request $request)
    {
        $pageSize   = $request->integer('size', 20);
        $page       = $request->integer('page', 1);
        $sort_field = $request->get('sort_field');
        $identifier = $request->get('identifier') ?? Str::uuid()->toString();
        $query      = ActivitySubmitWork::query()->where('is_hide', 0)
            ->whereHas('user', function ($q) { $q->where('deleted_at', NULL); })
            ->whereHas('activity', function ($q) { $q->where('deleted_at', NULL); });
        if ($sort_field === 'latest') {
            $data = $query->with(['activity:id,song_name,sub_title,cover', 'user:id,nick_name,real_name,avatar', 'user.styleTags:id,name'])
                ->select('id', 'user_id', 'demo_url', 'durations', 'activity_id', 'submit_at')
                ->orderBy('updated_at', 'desc')
                ->paginate($pageSize);

            return JsonResource::success(JsonResource::SUCCESS, ['works' => $data->items(), 'count' => $data->total(), 'identifier' => NULL,]);
        }

        $startIndex = ($page - 1) * $pageSize;
        $endIndex   = $startIndex + ($pageSize - 1);
        $key        = 'activity_public:' . $identifier . '-QMkKasdT';

        if ($page === 1) {
            //查询符合条件活动
            $data = $query->get(['id']);
            //插入有序集合中
            Redis::client()->del($key);
            Redis::client()->zAdd($key, ...$data->map(fn(ActivitySubmitWork $item) => [random_int(50, 200), $item->getKey()])->flatten()->toArray());
            Redis::client()->expire($key, 2 * 60 * 60);
        }
        $recommendIds = Redis::client()->zRevRange($key, $startIndex, $endIndex);

        $data = $query->with(['activity:id,song_name,sub_title,cover', 'user:id,nick_name,real_name,avatar', 'user.styleTags:id,name'])
            ->select('id', 'user_id', 'demo_url', 'durations', 'activity_id', 'submit_at')
            ->whereIn('id', $recommendIds)
            ->get();

        return JsonResource::success(JsonResource::SUCCESS, ['works' => $data, 'count' => Redis::client()->zCard($key), 'identifier' => $identifier,]);
    }

    public function bandList(Request $request)
    {
        $pageSize   = $request->integer('size', 20);
        $page       = $request->integer('page', 1);
        $sort_field = $request->get('sort_field');
        $identifier = $request->get('identifier') ?? Str::uuid()->toString();
        $query      = Project::query()
            ->whereRelation('activities', 'activitys.status', 1)
            ->leftJoin('project_confirmation_times', 'projects.id', 'project_confirmation_times.project_id')
            ->select(['projects.id', 'projects.name', 'projects.cover', 'projects.intro'])
            ->addSelect(DB::raw('IFNULL(project_confirmation_times.average_day,30.00) as average_day'))
            ->withCount(['totalSong', 'onlineSong'])
            ->where('projects.status', 1);

        if ($sort_field === 'comfirm_time') {
            $data = $query->orderBy('average_day')->paginate($pageSize);
            return JsonResource::success(JsonResource::SUCCESS, ['data' => $data->items(), 'count' => $data->total(), 'identifier' => NULL]);
        }
        $startIndex = ($page - 1) * $pageSize;
        $endIndex   = $startIndex + ($pageSize - 1);
        $key        = 'bandList:' . $identifier . '-YUMBGGLHJH';

        if ($page === 1) {
            //查询符合条件活动
            $data = $query->get(['id']);
            //插入有序集合中
            Redis::client()->del($key);
            Redis::client()->zAdd($key, ...$data->map(fn(Project $item) => [random_int(50, 200), $item->getKey()])->flatten()->toArray() ?? []);
            Redis::client()->expire($key, 2 * 60 * 60);
        }
        $recommendIds = Redis::client()->zRevRange($key, $startIndex, $endIndex);
        $data         = $query->whereIn('projects.id', $recommendIds)->get();
        return JsonResource::success(JsonResource::SUCCESS, ['data' => $data, 'count' => Redis::client()->zCard($key), 'identifier' => $identifier]);
    }

    public function musicianList(Request $request)
    {
        //TODO...慢SQL,待优化
        $pageSize   = $request->integer('size', 20);
        $page       = $request->integer('page', 1);
        $sort_field = $request->get('sort_field');
        $type       = $request->get('type', 1);
        $tags       = $request->get('tag');
        $identifier = $request->get('identifier') ?? Str::uuid()->toString();
        $query      = User::query()->where(['status' => 1, 'audit_status' => 1]);
        //音乐人
        if ($type == 1) {
            $query->whereIn('identity', [1, 3]);
        }
        //经纪人
        if ($type == 2) {
            $query->whereIn('identity', [2, 3]);
        }
        if ($tags) {
            $query->whereHas('authTags', fn(Builder $builder) => $builder->whereIn('system_tags.id', $tags));
        }
        //最新排序
        if ($sort_field === 'latest') {
            $data = $query
                ->select(['id', 'nick_name', 'avatar', 'identity'])
                ->with(['authTags:id,name'])
                ->orderBy('audit_at', 'desc')
                ->paginate($pageSize);
            foreach ($data as $d) {
                $d['is_follow'] = UserFollowRelation::query()->where(['following_id' => $d['id'], 'follower_id' => Auth::id() ?? 0])->exists();
            }
            return JsonResource::success(JsonResource::SUCCESS, ['data' => $data->items(), 'count' => $data->total(), 'identifier' => NULL,]);

        }
        //活跃度排序
        if ($sort_field === 'activation') {
            $data = $query
                ->select(['id', 'nick_name', 'avatar', 'identity', 'last_login'])
                ->withCount(['action as login_count' => function ($q) {
                    $q->select(DB::raw('COUNT(DISTINCT DATE(created_at))'))
                        ->where('event_name', 'login')->where('created_at', '>=', now()->subDays(30));
                }])
                ->withCount(['listenActivities', 'submitActivities'])
                ->with(['authTags:id,name'])
                ->orderBy('login_count', 'desc')
                ->orderBy('last_login', 'desc')
                ->orderBy('listen_activities_count', 'desc')
                ->orderBy('submit_activities_count', 'desc')
                ->paginate($pageSize);
            foreach ($data as $d) {
                $d['is_follow'] = UserFollowRelation::query()->where(['following_id' => $d['id'], 'follower_id' => Auth::id() ?? 0])->exists();
            }
            return JsonResource::success(JsonResource::SUCCESS, ['data' => $data->items(), 'count' => $data->total(), 'identifier' => NULL]);

        }
        //随机排序
        $startIndex = ($page - 1) * $pageSize;
        $endIndex   = $startIndex + ($pageSize - 1);
        $key        = 'musicianList:' . $identifier . '-LMBNFESWW';

        if ($page === 1) {
            //查询符合条件活动
            $data = $query->get(['id']);
            //插入有序集合中
            Redis::client()->del($key);
            Redis::client()->zAdd($key, ...$data->map(fn(User $item) => [random_int(50, 200), $item->getKey()])->flatten()->toArray());
            Redis::client()->expire($key, 2 * 60 * 60);
        }
        $recommendIds = Redis::client()->zRevRange($key, $startIndex, $endIndex);

        $data = $query
            ->whereIn('id', $recommendIds)
            ->select(['id', 'nick_name', 'avatar', 'identity'])
            ->with(['authTags:id,name'])
            ->get();
        foreach ($data as $d) {
            $d['is_follow'] = UserFollowRelation::query()->where(['following_id' => $d['id'], 'follower_id' => Auth::id() ?? 0])->exists();
        }
        return JsonResource::success(JsonResource::SUCCESS, ['data' => $data, 'count' => Redis::client()->zCard($key), 'identifier' => $identifier,]);
    }


    public function indexSearch(Request $request, indexSearchService $indexSearchService)
    {
        return match ($request->integer('type', 1)) {
            1 => JsonResource::success(JsonResource::SUCCESS, $indexSearchService->songSearch($request)),
            2 => JsonResource::success(JsonResource::SUCCESS, $indexSearchService->projectSearch($request)),
            3 => JsonResource::success(JsonResource::SUCCESS, $indexSearchService->userSeacher($request)),
            default => JsonResource::success(JsonResource::SUCCESS, [])
        };
    }

    public function notificationListen()
    {
        $filter = ['user_id' => Auth::id(), 'status' => 2];
        $data1  = NotificationUser::query()->where($filter)
            ->whereRelation('notification', 'is_alert', 1)
            ->orderByDesc('send_at')->first();
        $data2  = BrokerPushLevelRecordItem::query()->where($filter)
            ->whereRelation('record', 'is_alert', 1)->orderByDesc('send_at')->first();


        $send_at1 = $data1['send_at'] ?? '';
        $send_at2 = $data2['send_at'] ?? '';
        if ($send_at1 > $send_at2 && $data1 && $data1['read_at'] === NULL) {
            $data1['notification']['link_url']           = URL::action([NotificationController::class, 'show'], [$data1['notification']['id']]);
            $data1['notification']['notification_class'] = 'system_notification';
            return JsonResource::success(JsonResource::SUCCESS, $data1['notification']);
        }

        if ($data2 && $data2['read_at'] === NULL) {
            $data2['link_url']           = URL::action([NotificationController::class, 'show'], [$data2['id']]);
            $data2['link_type']          = 'none';
            $data2['notification_class'] = 'broker_level_record';
            //更改为已读
            BrokerPushLevelRecordItem::query()->where($filter)->whereRelation('record', 'is_alert', 1)->orderByDesc('send_at')->limit(1)->update(['read_at' => date("Y-m-d H:i:s")]);
            return JsonResource::success(JsonResource::SUCCESS, $data2);
        }

        return JsonResource::success(JsonResource::SUCCESS, NULL);
    }

}