ActivityController.php 10.6 KB
<?php

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

use App\Enums\ActivityAuditStatusEnum;
use App\Enums\ActivitySongTypeEnum;
use App\Enums\ActivityStatusEnum;
use App\Excel\ActivityDemoExcel;
use App\Excel\ActivityExcel;
use App\Excel\ActivitySongExcel;
use App\Helpers\OperationLog;
use App\Http\Container\AdminSection\Requests\Audition\ActivityChangeStatusRequest;
use App\Http\Container\ManageSection\Filters\ActivityFilter;
use App\Http\Container\ManageSection\Requests\Audition\ApplyCreateRequest;
use App\Http\Service\ActivityService;
use App\Jobs\ActivityChangeStatusJob;
use App\Jobs\ActivityMakeMediaJob;
use App\Models\Activity;
use App\Models\Pivots\UserActivityCollectionPivot;
use App\Models\Pivots\UserActivityViewPivot;
use App\Models\User;
use App\Models\Views\UserManageActivity;
use App\Support\Controller;
use App\Support\Model;
use Auth;
use Hikoon\LaravelApi\Facades\Response;
use Hikoon\LaravelApi\Support\ApiCode;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class ActivityController 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']);
        $build     = Activity::filter($filter, ActivityFilter::class)->where('audit_status', ActivityAuditStatusEnum::SUCCESS);

        return match ($fetchType) {
            'excel' => match ($request->integer('songType')) {
                1 => ActivitySongExcel::withBuilder($build)->download(),
                2 => ActivityDemoExcel::withBuilder($build)->download(),
                default => ActivityExcel::withBuilder($build)->download(),
            },
            default => $this->successWithData($build->paginate($pageSize))
        };
    }

    /**
     * @param \App\Models\Activity $activity
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function show(Request $request, int $id): Response
    {
        $activity = Activity::filter($request->all(), ActivityFilter::class)->findOrFail($id);

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

    /**
     * @param \App\Http\Container\ManageSection\Requests\Audition\ApplyCreateRequest $request
     * @param \App\Models\Activity                                                   $activity
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function update(ApplyCreateRequest $request, Activity $activity): Response
    {
        if ($activity->getAttribute('status') === ActivityStatusEnum::PROCESS) {
            return $this->fail(ApiCode::VALIDATION_ERROR, '音频处理中');
        }

        $activity->update(Model::dot($request->safe()));

        OperationLog::manage()->subject($activity)->updateAction()
            ->content('《%s》%s', $activity->getAttribute('song_name'), $activity->getChangeColumn()->except(['audit_status', 'status'])->format(',修改了:'));

        if ($activity->wasChanged(['lyric', 'clip_lyric', 'expand->guide_source->url', 'expand->karaoke_source->url'])) {
            ActivityMakeMediaJob::dispatch($activity, $activity->getAttribute('status'), $activity->wasChanged(['expand->guide_source->url', 'expand->karaoke_source->url']));
            $activity->update(['status' => 0]);
        }

        return $this->successWithData($activity, ApiCode::UPDATE_SUCCESS);
    }

    /**
     * @param \App\Http\Container\AdminSection\Requests\Audition\ActivityChangeStatusRequest $request
     * @param \App\Models\Activity                                                           $activity
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function changeStatus(ActivityChangeStatusRequest $request, Activity $activity, ActivityService $service): Response
    {
        $attribute = $request->validated();

        //上架
        if ($attribute['status'] === 'up' && $activity->getAttribute('status') === ActivityStatusEnum::DOWN) {
            $activity->update(['status' => ActivityStatusEnum::UP, 'p_is_top' => 0, 'publish_at' => now()->toDateTimeString()]);
            OperationLog::manage()->statusAction()->subject($activity)->content('上架试唱歌曲《%s》', $activity->getAttribute('song_name'));
            if ($activity->getAttribute('song_type') === ActivitySongTypeEnum::SONG->value) {
                ActivityChangeStatusJob::dispatch($activity, Auth::user());
            }
            return $this->success(ApiCode::UPDATE_SUCCESS);
        }

        //下架
        if ($attribute['status'] === 'down' && $activity->getAttribute('status') === ActivityStatusEnum::UP) {
            $activity->update(['status' => ActivityStatusEnum::DOWN]);
            OperationLog::manage()->statusAction()->subject($activity)->content('下架试唱歌曲《%s》,理由:%s', $activity->getAttribute('song_name'), $attribute['msg']);
            if ($activity->getAttribute('song_type') === ActivitySongTypeEnum::SONG->value) {
                ActivityChangeStatusJob::dispatch($activity, Auth::user(), ['msg' => $attribute['msg']]);
            }
            return $this->success(ApiCode::UPDATE_SUCCESS);
        }

        //发行
        if ($attribute['status'] === 'send' && $activity->getAttribute('status') === ActivityStatusEnum::MATCH) {
            if ($activity->getAttribute('status') === ActivityStatusEnum::MATCH) {
                $activity->update(['status' => ActivityStatusEnum::SEND, 'send_at' => now()->toDateTimeString(), 'send_url' => [['type' => 'default', 'url' => $attribute['link']]]]);
                OperationLog::manage()->statusAction()->subject($activity)->content('发行试唱歌曲《%s》', $activity->getAttribute('song_name'));
                if ($activity->getAttribute('song_type') === ActivitySongTypeEnum::SONG->value) {
                    ActivityChangeStatusJob::dispatch($activity, Auth::user());
                }
            }
            if ($activity->getAttribute('status') === ActivityStatusEnum::SEND) {
                $activity->update(['send_url->url' => $attribute['link']]);
                OperationLog::manage()->updateAction()->subject($activity)->content('试唱歌曲《%s》,修改了:外部平台播放链接', $activity->getAttribute('song_name'));
            }

            return $this->success(ApiCode::UPDATE_SUCCESS, $activity);
        }

        //重新上架
        if ($attribute['status'] === 'reUp' && $activity->getAttribute('status') === ActivityStatusEnum::MATCH) {
            $service->reUp($activity);
            OperationLog::manage()->statusAction()->subject($activity)->content('重新上架试唱歌曲《%s》', $activity->getAttribute('song_name'));
            return $this->success(ApiCode::UPDATE_SUCCESS);
        }


        return $this->fail(ApiCode::VALIDATION_ERROR, '此活动状态无法变更状态');
    }

    /**
     * @param \App\Models\Activity              $activity
     * @param \App\Http\Service\ActivityService $service
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function destroy(Activity $activity, ActivityService $service): Response
    {
        if ($activity->getAttribute('status') !== ActivityStatusEnum::DOWN) {
            return $this->fail(ApiCode::VALIDATION_ERROR, '只允许删除下架歌曲');
        }

        $service->delete($activity);
        OperationLog::admin()->subject($activity)->deleteAction()->content('歌曲《%s》', $activity->getAttribute('song_name'));

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

    /**
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\Activity     $activity
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function viewUser(Request $request, Activity $activity): Response
    {
        $pageSize = $request->get('pageSize', 20);

        $viewPivotQuery = UserActivityViewPivot::query()
            ->selectRaw('user_id,activity_id,updated_at as last_listen_at')
            ->where('activity_id', $activity->getKey());

        $data = User::withTrashed()
            ->filter($request->except(['page', 'pageSize']))
            ->select(['id', 'nick_name', 'real_name', 'avatar', 'role', 'sex', 'identity', 'last_listen_at'])
            ->joinSub($viewPivotQuery, 'views', 'user_id', 'users.id')
            ->withCount(['listenActivities as listen_count', 'likeActivities as collection_count', 'submitActivities as submit_work'])
            ->paginate($pageSize);

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

    /**
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\Activity     $activity
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function likeUser(Request $request, Activity $activity): Response
    {
        $pageSize = $request->get('pageSize', 20);

        $viewPivotQuery = UserActivityCollectionPivot::query()
            ->selectRaw('user_id,activity_id,updated_at as last_listen_at')
            ->where('activity_id', $activity->getKey());

        $data = User::withTrashed()
            ->filter($request->except(['page', 'pageSize']))
            ->select(['id', 'nick_name', 'real_name', 'avatar', 'role', 'sex', 'identity', 'last_listen_at'])
            ->joinSub($viewPivotQuery, 'views', 'user_id', 'users.id')
            ->withCount(['listenActivities as listen_count', 'likeActivities as collection_count', 'submitActivities as submit_work'])
            ->paginate($pageSize);

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

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

        if ($request->has('unSet')) {
            User::resolveRelationUsing('manageActivities', static fn(User $user) => $user->hasMany(UserManageActivity::class));

            return $this->successWithData(User::filter($filter)->withTrashed()
                ->whereDoesntHave('manageActivities', fn($query) => $query->where('activity_id', $activity->getKey()))
                ->paginate($pageSize));
        }

        return $this->successWithData(UserManageActivity::filter($filter)
            ->with('user:id,avatar,nick_name,real_name,sex,email,area_code,phone,official_status,status,identity')
            ->where('activity_id', $activity->getKey())
            ->paginate($pageSize));
    }
}