ApplyController.php 7.51 KB
<?php

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

use App\Enums\ActivityAuditStatusEnum;
use App\Enums\ActivitySongTypeEnum;
use App\Enums\ActivityStatusEnum;
use App\Helpers\OperationLog;
use App\Http\Container\AdminSection\Requests\Audition\ApplyAuditRequest;
use App\Http\Container\ManageSection\Requests\Audition\ApplyCreateRequest;
use App\Http\Container\ManageSection\Requests\Audition\ApplyUpdateRequest;
use App\Http\Service\ActivityService;
use App\Jobs\ActivityMakeMediaJob;
use App\Models\Activity;
use App\Models\ActivityApplyRecord;
use App\Notifications\ActivityApplyFailNotification;
use App\Notifications\ActivityApplySuccessNotification;
use App\Support\Controller;
use App\Support\Model;
use Arr;
use Hikoon\LaravelApi\Facades\Response;
use Hikoon\LaravelApi\Support\ApiCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;

class ApplyController extends Controller
{
    /**
     * @param \Illuminate\Http\Request $request
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function index(Request $request): Response
    {
        $pageSize = $request->get('pageSize', 20);

        $data = Activity::filter($request->mergeIfMissing(['audit_status' => [0, 2]])->except(['page', 'pageSize']))
            ->select(['id', 'song_name', 'cover', 'lang', 'speed', 'sub_title', 'sex', 'user_id', 'weight', 'project_id', 'lyric', 'clip_lyric', 'is_push', 'mark', 'is_official', 'expand', 'audit_status', 'created_at', 'estimate_release_at'])
            ->addSelect([
                'record_count' => ActivityApplyRecord::query()->selectRaw('count(*)')->whereColumn('activity_apply_records.activity_id', 'activitys.id'),
                'last_record'  => ActivityApplyRecord::query()->select('current')->whereColumn('activity_apply_records.activity_id', 'activitys.id')->latest()->limit(1)
            ])
            ->latest('updated_at')->withCasts(['last_record' => 'json'])->paginate($pageSize);

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

    /**
     * @param \App\Http\Container\ManageSection\Requests\Audition\ApplyCreateRequest $request
     * @param \App\Http\Service\ActivityService                                      $service
     * @return \Hikoon\LaravelApi\Facades\Response
     * @throws \Hikoon\LaravelApi\Exceptions\ValidationException
     */
    public function store(ApplyCreateRequest $request, ActivityService $service): Response
    {
        $attribute = array_merge($request->safe()->toArray(), ['user_id' => (int)Auth::id(), 'created_form' => 1]);

        if (Cache::lock('user-' . Auth::id() . '-apply', 5)->get()) {

            $activity = match ($request->integer('song_type')) {
                ActivitySongTypeEnum::SONG->value => $service->createActivityApply($attribute + ['lang' => [], 'is_push' => 0], false),
                ActivitySongTypeEnum::DEMO->value => $service->createDemoApply($attribute + ['is_push' => 1], false)
            };

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

        return $this->fail(ApiCode::REQUEST_LIMIT_ERROR);
    }

    /**
     * @param \App\Http\Container\ManageSection\Requests\Audition\ApplyUpdateRequest $request
     * @param \App\Models\Activity                                                   $apply
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function update(ApplyUpdateRequest $request, Activity $apply): Response
    {
        $apply->update(Model::dot($request->safe()->merge(['audit_status' => 0, 'status' => 0])));

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

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

    /**
     * @param \App\Http\Container\AdminSection\Requests\Audition\ApplyAuditRequest $request
     * @param \App\Models\Activity                                                 $apply
     * @param \App\Http\Service\ActivityService                                    $service
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function audit(ApplyAuditRequest $request, Activity $apply, ActivityService $service): Response
    {
        $data = $request->safe()->toArray();

        if ($data['audit_status'] === 1) {
            $data['publish_at'] = now()->toDateTimeString();
            $data['status']     = ActivityStatusEnum::PROCESS->value;
            $data['audit_at']   = now()->toDateTimeString();

            DB::transaction(static function () use ($apply, $data, $service) {
                $apply->update(Model::dot(Arr::except($data, 'out_side_manages')));
                $change = $apply->getChangeColumn();

                if (isset($data['out_side_manages'])) {
                    $syncResult = $service->syncManageLink($apply, $data['out_side_manages']);

                    if (count($syncResult) !== 0) {
                        $change->add('manage_link');
                    }
                }

                OperationLog::admin()->statusAction()->subject($apply)->content('歌曲《%s》,审核通过%s', $apply->getAttribute('song_name'), $change->format(',修改了:'));
                ActivityMakeMediaJob::dispatch($apply, ActivityStatusEnum::UP, true);
                //推送申请人通知
                Notification::send($apply->getAttribute('user'), new ActivityApplySuccessNotification($apply));
            });
        }

        if ($data['audit_status'] === 2) {
            DB::transaction(static function () use ($apply, $data) {
                $apply->applyRecords()->create(['audit_user_id' => Auth::id(), 'audit_msg' => $data['msg'], 'current' => $apply->attributesToArray()]);
                OperationLog::admin()->statusAction()->subject($apply)->content('歌曲《%s》,审核不通过,理由:%s', $apply->getAttribute('song_name'), $data['msg']);
                $apply->update(['audit_status' => 2]);
                //推送申请人通知
                Notification::send($apply->getAttribute('user'), new ActivityApplyFailNotification($apply, $data['msg']));
            });
        }

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

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

        $data = ActivityApplyRecord::filter($filter)->where('activity_id', $apply->getKey())->paginate($pageSize);
        return $this->successWithData($data);
    }


    /**
     * @param \App\Models\Activity              $apply
     * @param \App\Http\Service\ActivityService $service
     * @return \Hikoon\LaravelApi\Facades\Response
     */
    public function destroy(Activity $apply, ActivityService $service): Response
    {
        if ($apply->getAttribute('audit_status') !== ActivityAuditStatusEnum::FAIL->value) {
            return $this->fail(ApiCode::VALIDATION_ERROR, '只允许删除审核未通过歌曲');
        }

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

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