query('purpose'); $q = FormSchemaDefinition::query()->where('competition_id', $competition->id); if (in_array($purpose, [FormSchemaDefinition::PURPOSE_SIGNUP, FormSchemaDefinition::PURPOSE_REVIEW], true)) { $q->where('purpose', $purpose); } $rows = $q->orderByDesc('version')->orderByDesc('id')->get(); return response()->json([ 'data' => $rows->map(fn (FormSchemaDefinition $s) => $this->toBrief($s, $competition))->values(), ]); } public function store(StoreFormSchemaDefinitionRequest $request, Competition $competition): JsonResponse { $purpose = $request->validated('purpose'); $nextVersion = (int) FormSchemaDefinition::query() ->where('competition_id', $competition->id) ->where('purpose', $purpose) ->max('version') + 1; $schema = FormSchemaDefinition::query()->create([ 'competition_id' => $competition->id, 'purpose' => $purpose, 'name' => $request->validated('name'), 'version' => $nextVersion, 'schema_json' => $request->validated('schema_json'), 'is_published' => (bool) $request->validated('is_published', false), ]); return response()->json($this->toDetail($schema, $competition), 201); } public function show(Competition $competition, FormSchemaDefinition $formSchema): JsonResponse { $this->assertSchemaBelongs($competition, $formSchema); return response()->json($this->toDetail($formSchema, $competition)); } public function update(UpdateFormSchemaDefinitionRequest $request, Competition $competition, FormSchemaDefinition $formSchema): JsonResponse { $this->assertSchemaBelongs($competition, $formSchema); $formSchema->fill($request->validated()); $formSchema->save(); return response()->json($this->toDetail($formSchema->fresh(), $competition)); } public function destroy(Competition $competition, FormSchemaDefinition $formSchema): Response { $this->assertSchemaBelongs($competition, $formSchema); if ((int) $competition->form_schema_id === $formSchema->id || (int) $competition->review_form_schema_id === $formSchema->id) { return response()->json([ 'message' => '该版本正被本场赛事使用,请先更换绑定后再删除。', ], 422); } $formSchema->delete(); return response()->noContent(); } private function assertSchemaBelongs(Competition $competition, FormSchemaDefinition $formSchema): void { if ((int) $formSchema->competition_id !== (int) $competition->id) { abort(404); } } /** * @return array */ private function toBrief(FormSchemaDefinition $s, Competition $competition): array { return [ 'id' => $s->id, 'competition_id' => $s->competition_id, 'purpose' => $s->purpose, 'name' => $s->name, 'version' => $s->version, 'is_published' => $s->is_published, 'is_current_signup' => (int) $competition->form_schema_id === (int) $s->id, 'is_current_review' => (int) $competition->review_form_schema_id === (int) $s->id, 'field_labels' => $this->extractFieldLabels($s->schema_json ?? []), 'created_at' => $s->created_at?->toIso8601String(), 'updated_at' => $s->updated_at?->toIso8601String(), ]; } /** * @return array */ private function toDetail(FormSchemaDefinition $s, Competition $competition): array { $row = $this->toBrief($s, $competition); $row['schema_json'] = $s->schema_json ?? []; return $row; } /** * @param array $schemaJson * @return array */ private function extractFieldLabels(array $schemaJson): array { $labels = []; foreach ($schemaJson as $item) { if (is_array($item) && isset($item['label']) && is_string($item['label']) && $item['label'] !== '') { $labels[] = $item['label']; } if (count($labels) >= 12) { break; } } return $labels; } }