ProjectController.php 11.1 KB
<?php

namespace App\Http\Container\AdminSection\Controllers\Audition;

use App\Enums\ActivitySongTypeEnum;
use App\Enums\ActivityStatusEnum;
use App\Excel\ProjectExcel;
use App\Helpers\OperationLog;
use App\Http\Container\AdminSection\Requests\Audition\ProjectCreateRequest;
use App\Http\Container\AdminSection\Requests\Audition\ProjectUpdateRequest;
use App\Http\Request\BooleanStatusRequest;
use App\Models\Activity;
use App\Models\Pivots\ActivityLinkPivot;
use App\Models\Pivots\ProjectMemberPivot;
use App\Models\Pivots\UserProjectPivot;
use App\Models\Project;
use App\Models\ProjectDynamic;
use App\Models\User;
use App\Models\Views\UserManageActivity;
use App\Support\Controller;
use Auth;
use DB;
use Hikoon\LaravelApi\Facades\Response;
use Hikoon\LaravelApi\Support\ApiCode;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class ProjectController extends Controller
{
    /**
     * @param \Illuminate\Http\Request $request
     * @return \Hikoon\LaravelApi\Facades\Response|\Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function index(Request $request): Response|BinaryFileResponse
    {
        $pageSize  = $request->get('pageSize', 20);
        $fetchType = $request->get('fetchType', 'page');
        $filter    = $request->except(['page', 'pageSize', 'fetchType']);

        Project::resolveRelationUsing('activity_up', static fn(Project $project) => $project->activities()->where('song_type', ActivitySongTypeEnum::SONG)->where('status', ActivityStatusEnum::UP));
        Project::resolveRelationUsing('activity_down', static fn(Project $project) => $project->activities()->where('song_type', ActivitySongTypeEnum::SONG)->where('status', ActivityStatusEnum::DOWN));
        Project::resolveRelationUsing('activity_match', static fn(Project $project) => $project->activities()->where('song_type', ActivitySongTypeEnum::SONG)->where('status', ActivityStatusEnum::MATCH));
        Project::resolveRelationUsing('activity_send', static fn(Project $project) => $project->activities()->where('song_type', ActivitySongTypeEnum::SONG)->where('status', ActivityStatusEnum::SEND));
        Project::resolveRelationUsing('manage', static fn(Project $project) => $project->belongsToMany(User::class, UserProjectPivot::class));
        Project::resolveRelationUsing('member', static fn(Project $project) => $project->belongsToMany(User::class, ProjectMemberPivot::class)->where('project_has_members.status', 1)->where('users.status', 1));

        $build = Project::filter($filter);

        return match ($fetchType) {
            'excel' => ProjectExcel::withBuilder($build)->download(),
            'all' => $this->successWithData($build->get()),
            default => $this->successWithData($build->paginate($pageSize))
        };
    }

    /**
     * @param \App\Http\Container\AdminSection\Requests\Audition\ProjectCreateRequest $request
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function store(ProjectCreateRequest $request): Response
    {
        $attribute = $request->safe()->merge(['user_id' => Auth::id()])->toArray();
        $data      = Project::query()->create($attribute);
        OperationLog::admin()->subject($data)->createAction()->content('厂牌《%s》', $data->getAttribute('name'));
        return $this->successWithData($data, ApiCode::CREATE_SUCCESS);
    }

    /**
     * @param \App\Models\Project $project
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function show(Project $project): Response
    {
        $project->load(['user:id,nick_name,real_name,identity', 'master:id,nick_name,real_name,identity']);
        $activity = Activity::filter(['project' => $project->getKey(), 'auditStatus' => 1])->get(['id', 'song_type', 'status']);
        $dynamics = ProjectDynamic::filter(['project' => $project->getKey()])->get(['id', 'type']);

        $project->setAttribute('activity_count', $activity->where('song_type', 1)->count());
        $project->setAttribute('activity_up_count', $activity->where('song_type', 1)->where('status', ActivityStatusEnum::UP)->count());
        $project->setAttribute('activity_match_count', $activity->where('song_type', 1)->where('status', ActivityStatusEnum::MATCH)->count());
        $project->setAttribute('activity_send_count', $activity->where('song_type', 1)->where('status', ActivityStatusEnum::SEND)->count());

        $project->setAttribute('demo_count', $activity->where('song_type', 2)->count());
        $project->setAttribute('demo_up_count', $activity->where('song_type', 2)->where('status', ActivityStatusEnum::UP)->count());


        $project->setAttribute('image_dynamic_count', $dynamics->where('type', 'image')->count());
        $project->setAttribute('audio_dynamic_count', $dynamics->where('type', 'audio')->count());
        $project->setAttribute('video_dynamic_count', $dynamics->where('type', 'video')->count());

        return $this->successWithData($project);
    }

    /**
     * @param \App\Http\Container\AdminSection\Requests\Audition\ProjectUpdateRequest $request
     * @param \App\Models\Project                                                     $project
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function update(ProjectUpdateRequest $request, Project $project): Response
    {
        $attribute = $request->safe()->toArray();
        $project->update($attribute);
        OperationLog::admin()->subject($project)->updateAction()->content('厂牌《%s》%s', $project->getAttribute('name'), $project->getChangeColumn()->format(',修改了:'));
        return $this->successWithData($project, ApiCode::UPDATE_SUCCESS);
    }

    /**
     * @param \App\Http\Request\BooleanStatusRequest $request
     * @param \App\Models\Project                                            $project
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function changeStatus(BooleanStatusRequest $request, Project $project): Response
    {
        $data = $request->safe()->toArray();
        $project->update($data);
        OperationLog::admin()->subject($project)->statusAction()->content('厂牌《%s》%s', $project->getAttribute('name'), ActivityStatusEnum::tryFrom($data['status'])?->label());
        return $this->success(ApiCode::UPDATE_SUCCESS);
    }

    /**
     * @param \App\Models\Project $project
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function destroy(Project $project): Response
    {
        if ($project->activities()->where('status', 1)->exists()) {
            return $this->fail(ApiCode::VALIDATION_ERROR, '厂牌下存在上架中活动,无法删除此厂牌');
        }

        DB::transaction(static function () use ($project) {
            Project::query()->whereKey($project->getKey())->delete();
            UserProjectPivot::query()->where('project_id', $project->getKey())->delete();
            ProjectMemberPivot::query()->where('project_id', $project->getKey())->delete();
            OperationLog::admin()->subject($project)->deleteAction()->content('厂牌《%s》', $project->getAttribute('name'));
        });

        return $this->success(ApiCode::DELETE_SUCCESS);
    }

    /**
     * @param \App\Models\Project      $project
     * @param \Illuminate\Http\Request $request
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function manageUser(Request $request, Project $project): Response
    {
        $pageSize = $request->get('pageSize', 20);
        $filter   = $request->except(['page', 'pageSize']);

        $data = User::filter($filter)
            ->joinSub(UserProjectPivot::query()->selectRaw('id as pivot_id,user_id')->where('project_id', $project->getKey()), 'pivot', 'users.id', 'pivot.user_id')
            ->select(['id', 'avatar', 'nick_name', 'real_name', 'identity', 'email', 'phone', 'area_code', 'status', 'official_status', 'sex', 'pivot_id'])
            ->paginate($pageSize);

        return $this->successWithData($data);
    }


    /**
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\Project      $project
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function memberUser(Request $request, Project $project): Response
    {
        $pageSize = $request->get('pageSize', 20);
        $filter   = $request->except(['page', 'pageSize']);


        $innerQuery = ProjectMemberPivot::query()
            ->selectRaw('id as pivot_id,user_id,is_top,updated_at as join_at')
            ->where('project_has_members.status', [1, 3])
            ->whereNull('project_has_members.deleted_at')
            ->where('project_id', $project->getKey());


        $data = User::filter($filter)
            ->joinSub($innerQuery, 'pivot', 'users.id', 'pivot.user_id')
            ->select(['id', 'avatar', 'nick_name', 'real_name', 'identity', 'email', 'phone', 'area_code', 'status', 'official_status', 'sex', 'pivot_id'])
            ->where('status', 1)
            ->latest('join_at')
            ->paginate($pageSize);

        return $this->successWithData($data);
    }

    /**
     * @param \App\Models\Project      $project
     * @param \Illuminate\Http\Request $request
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function outManageUser(Request $request, Project $project): Response
    {
        $pageSize = $request->get('pageSize', 20);
        $filter   = $request->except(['page', 'pageSize']);

        User::resolveRelationUsing('activities', static fn(User $user) => $user->hasMany(UserManageActivity::class)->where('project_id', $project->getKey()));

        $data = User::filter($filter)
            ->select(['id', 'avatar', 'nick_name', 'real_name', 'identity', 'email', 'phone', 'area_code', 'status', 'official_status', 'sex'])
            ->withCount('activities')
            ->whereHas('activities')->paginate($pageSize);

        return $this->successWithData($data);
    }

    /**
     * @param \App\Models\Project      $project
     * @param \Illuminate\Http\Request $request
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function deleteOutManageUser(Request $request, Project $project): Response
    {
        $user = User::query()->find($request->input('user_id', 0));

        if ($user) {
            ActivityLinkPivot::query()
                ->whereRelation('activity', 'project_id', $project->getKey())
                ->where('type', 'manager')
                ->where('link_type', User::class)
                ->where('link_id', $user->getKey())
                ->delete();

            OperationLog::admin()->subject($project)->deleteAction()->content('厂牌《%s》删除外部管理员:%s', $project->getAttribute('name'), $user->getAttribute('nick_name'));
        }

        return $this->success(ApiCode::DELETE_SUCCESS);
    }


    /**
     * @param \Illuminate\Http\Request $request
     * @param int                      $id
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function dynamic(Request $request, int $id): Response
    {
        $pageSize = $request->get('pageSize', 20);
        $filter   = $request->except(['page', 'pageSize']);

        $data = ProjectDynamic::filter($filter)->where('project_id', $id)->orderByDesc('created_at')->paginate($pageSize);

        return $this->successWithData($data);
    }
}