indexSearchService.php 7.51 KB
<?php


namespace App\Http\Service;


use App\Enums\ActivityAuditStatusEnum;
use App\Enums\ActivityCreateFormEnum;
use App\Enums\ActivitySongTypeEnum;
use App\Enums\ActivityStatusEnum;
use App\Enums\ActivityWorkStatusEnum;
use App\Enums\ActivityWorkTypeEnum;
use App\Models\Activity;
use App\Models\ActivityUser;
use App\Models\Pivots\UserActivityViewPivot;
use App\Models\Project;
use App\Models\SystemConfig;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;


class indexSearchService
{
    /**
     * @param $request
     * @return array
     */
    public function songSearch($request): array
    {
        $pageSize   = $request->get('size', 20);
        $activities = Activity::query()
            ->where('audit_status', ActivityAuditStatusEnum::SUCCESS)
            ->whereIn('status', [ActivityStatusEnum::UP, ActivityStatusEnum::MATCH, ActivityStatusEnum::SEND])
            ->whereIn('created_form', [ActivityCreateFormEnum::ADMIN, ActivityCreateFormEnum::PROJECT])
            ->when($request->get('text'), fn(Builder $query, $text) => $query->whereLike('song_name', $text))
            ->when($request->get('song_type', ActivitySongTypeEnum::SONG), fn(Builder $query, $type) => $query->where('song_type', $type))
            ->with(['linkArranger:id,nick_name', 'tags:id,name', 'project:id,name,cover', 'submitUsers:id,nick_name,real_name,avatar', 'comfirmTime:project_id,average_day,updated_at'])
            ->select(['id', 'project_id', 'song_name', 'sub_title', 'is_official', 'expand', 'sex', 'mark', 'speed', 'lang', 'publish_at', 'estimate_release_at', 'cover', 'lyric', 'clip_lyric', 'guide', 'guide_clip', 'karaoke', 'karaoke_clip', 'status'])
            ->addSelect([
                'is_view'       => UserActivityViewPivot::selectRaw('IF(COUNT(*) = 0, 0, 1)')->where('user_id', Auth::id())->whereColumn('activity_id', 'activitys.id'),
                'is_collection' => UserActivityViewPivot::selectRaw('IF(COUNT(*) = 0, 0, 1)')->where('user_id', Auth::id())->whereColumn('activity_id', 'activitys.id'),
                'is_take'       => ActivityUser::selectRaw('IF(COUNT(*) = 0, 0, 1)')->where('user_id', Auth::id())->whereColumn('activity_id', 'activitys.id')->where('type', ActivityWorkTypeEnum::SUBMIT)->where('status', ActivityWorkStatusEnum::SUCCESS),
            ])
            ->withCount(['totalSong', 'onlineSong', 'publicAudio'])
            ->withCount('viewUsers as view_count')
            ->orderBy('publish_at', 'desc')
            ->paginate($pageSize);


        $config = SystemConfig::parentKey(['activity_mark', 'activity_lang', 'activity_speed', 'activity_sex'])->where('status', 1)->get(['name', 'identifier', 'content']);

        return [
            'has_activitys'  => $activities->each(static function (Activity $activity) use ($config) {
                $activity->setRelation('attend_user', $activity->getRelation('submitUsers')?->unique()->take(5) ?? []);
                $activity->setAttribute('attend_count', $activity->getRelation('submitUsers')?->count() ?? 0);

                $activity->setAttribute('status_tag', $activity->getAttribute('is_view') === 1 ? 'listened' : 'new');
                $activity->setAttribute('sex', $config->where('identifier', $activity->getAttribute('sex'))->value('name', ''));
                $activity->setAttribute('speed', $config->where('identifier', $activity->getAttribute('speed'))->value('name', ''));
                $activity->setAttribute('mark', $config->where('identifier', $activity->getAttribute('mark'))->value('content', ''));
                $activity->setAttribute('lang', $config->whereIn('identifier', $activity->getAttribute('lang'))->pluck('name'));
                $activity->setAttribute('project', [$activity->getRelation('project')?->toArray()]);
                $activity->setAttribute('arranger', [
                    'in_side'  => $activity->getAttribute('linkArranger'),
                    'out_side' => data_get($activity->getAttribute('expand'), 'arranger.supplement', [])
                ]);

                unset($activity->linkArranger, $activity->expand);
                $activity->unsetRelation('project');
                $activity->unsetRelation('submitUsers');

            }),
            'user_count'     => $this->userCount($request),
            'project_count'  => $this->projectCount($request),
            'activity_count' => $activities->total()
        ];

    }


    public function projectSearch($request)
    {
        $pageSize = $request->integer('size', 20);

        $data = Project::query()->where('status', 1)
            ->when($request->get('text'), fn(Builder $query, $text) => $query->whereLike('name', $text))
            ->leftJoin('project_confirmation_times', 'project_confirmation_times.project_id', '=', 'projects.id')
            ->select(['projects.id', 'projects.name', 'projects.cover', 'projects.intro', 'project_confirmation_times.average_day'])
            ->withCount(['totalSong', 'onlineSong'])
            ->orderBy('online_song_count', 'desc')
            ->orderBy('projects.created_at')
            ->paginate($pageSize);

        return [
            'data'           => $data->items(),
            'user_count'     => $this->userCount($request),
            'project_count'  => $data->total(),
            'activity_count' => $this->activityCount($request)
        ];

    }

    public function userSeacher($request)
    {
        $pageSize = $request->integer('size', 20);
        $text     = $request->get('text');
        $query    = User::query()->where(['status' => 1, 'audit_status' => 1]);
        if ($text) {
            $query->whereLike('nick_name', $text);
        }
        $data = $query
            ->select(['id', 'nick_name', 'avatar', 'user_tag_id', 'identity'])
            ->when($request->get('text'), fn(Builder $query, $text) => $query->whereLike('nick_name', $text))
            ->withCount('submitActivities')
            ->with(['authTags:id,name', 'userTag:id,name,icon,frame'])
            ->orderBy('submit_activities_count', 'desc')
            ->orderBy('created_at', 'desc')
            ->paginate($pageSize);

        return [
            'data'           => $data->items(),
            'user_count'     => $data->total(),
            'project_count'  => $this->projectCount($request),
            'activity_count' => $this->activityCount($request)
        ];
    }

    /**
     * @param $request
     * @return int
     */
    public function activityCount($request): int
    {
        return Activity::query()
            ->where('audit_status', 1)->where('status', ActivityStatusEnum::UP)
            ->whereIn('created_form', [ActivityCreateFormEnum::ADMIN, ActivityCreateFormEnum::PROJECT])
            ->when($request->get('song_type', 1), fn(Builder $query, $type) => $query->where('song_type', $type))
            ->when($request->get('text'), fn(Builder $query, string $text) => $query->whereLike('song_name', $text))
            ->count();
    }

    /**
     * @param $request
     * @return int
     */
    public function projectCount($request): int
    {
        return Project::query()->where('status', 1)
            ->when($request->get('text'), fn(Builder $query, string $text) => $query->whereLike('name', $text))
            ->count();
    }

    /**
     * @param $request
     * @return int
     */
    public function userCount($request): int
    {
        return User::query()
            ->where('status', 1)
            ->where('audit_status', 1)
            ->when($request->get('text'), fn(Builder $query, string $text) => $query->whereLike('nick_name', $text))
            ->count();
    }
}