You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.4 KiB

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\StudyTour;
use App\Support\StudyTourDeclarationParser;
use App\Support\StudyTourPayload;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class StudyTourController extends Controller
{
public function index(Request $request): JsonResponse
{
$q = StudyTour::query()->orderBy('sort')->orderByDesc('id');
StudyTourPayload::applyListFilters($q, $request);
return response()->json($q->get());
}
public function store(Request $request): JsonResponse
{
$this->ensureSuperAdmin($request);
$data = $request->validate(StudyTourPayload::validationRules(true));
$data = StudyTourPayload::normalizeIncoming($data);
$row = StudyTour::create($data + [
'tags' => $data['tags'] ?? [],
'venue_ids' => $data['venue_ids'] ?? [],
'venue_items' => $data['venue_items'] ?? [],
'seasons' => $data['seasons'] ?? [],
'suitable_audience' => $data['suitable_audience'] ?? null,
'route_plans' => $data['route_plans'] ?? [],
'courses' => $data['courses'] ?? [],
'gallery_media' => $data['gallery_media'] ?? [],
'sort' => $data['sort'] ?? 0,
'is_on_shelf' => $data['is_on_shelf'] ?? true,
]);
return response()->json($row, 201);
}
public function update(Request $request, StudyTour $studyTour): JsonResponse
{
$this->ensureSuperAdmin($request);
$data = $request->validate(StudyTourPayload::validationRules(false));
$data = StudyTourPayload::normalizeIncoming($data);
$studyTour->fill($data)->save();
return response()->json($studyTour->fresh());
}
public function destroy(Request $request, StudyTour $studyTour): JsonResponse
{
$this->ensureSuperAdmin($request);
$studyTour->delete();
return response()->json(['message' => '删除成功']);
}
public function parseDoc(Request $request): JsonResponse
{
$request->validate([
'file' => ['required', 'file', 'max:10240'],
]);
$uploaded = $request->file('file');
if ($uploaded === null) {
return response()->json(['message' => '请上传申报表文件'], 422);
}
$extension = strtolower((string) ($uploaded->getClientOriginalExtension() ?: $uploaded->extension()));
if (! in_array($extension, ['doc', 'docx'], true)) {
return response()->json(['message' => '仅支持 .doc / .docx 申报表'], 422);
}
$path = null;
try {
$storedPath = $uploaded->storeAs('tmp/declaration-import', Str::uuid()->toString().'.'.$extension);
$path = storage_path('app/'.$storedPath);
$result = StudyTourDeclarationParser::parseFile($path, $extension);
} catch (\Throwable $e) {
return response()->json(['message' => '申报表解析失败:'.$e->getMessage()], 422);
} finally {
if (isset($path) && is_file($path)) {
@unlink($path);
}
}
return response()->json($result);
}
private function ensureSuperAdmin(Request $request): void
{
abort_unless($request->user()?->isSuperAdmin(), 403, '仅超级管理员可操作');
}
}