all(); $model = !empty($input['id']) ? CourseForm::whereKey($input['id'])->lockForUpdate()->firstOrFail() : new CourseForm(); $courseId = $model->course_id ?? ($input['course_id'] ?? null); if (!$courseId || !\App\Models\Course::whereKey($courseId)->exists()) throw new \InvalidArgumentException('课程不存在'); $data = array_intersect_key($input, array_flip(['name', 'field', 'edit_input', 'rule', 'sort', 'help', 'select_item', 'need_fill', 'belong_user', 'belong_user_table', 'config'])); $data = \App\Services\Course\CourseFormSchema::validateDefinition(array_replace($model->toArray(), $data, ['course_id' => $courseId])); if ($model->exists && \App\Models\CourseSign::where('course_id', $courseId)->exists()) { foreach (['field', 'edit_input', 'belong_user', 'belong_user_table'] as $key) if ((string) ($data[$key] ?? '') !== (string) ($model->$key ?? '')) throw new \InvalidArgumentException('已有报名,不能修改字段标识、类型或学员关联;请新建字段'); $oldKeys = array_map('strval', array_column($model->select_item ?: [], 'key')); $newKeys = array_map('strval', array_column($data['select_item'], 'key')); if (array_diff($oldKeys, $newKeys)) throw new \InvalidArgumentException('已有报名,不能删除或修改已有选项的键;可以新增选项或调整顺序'); } $others = CourseForm::where('course_id', $courseId)->where('id', '!=', $model->id ?? 0)->get()->toArray(); if (in_array($data['field'], array_column($others, 'field'), true)) throw new \InvalidArgumentException('同一课程的字段标识不能重复'); $collection = array_merge($others, [$data + ['id' => $model->id ?? PHP_INT_MAX]]); usort($collection, fn ($a, $b) => [($a['sort'] ?? 1), ($a['id'] ?? PHP_INT_MAX)] <=> [($b['sort'] ?? 1), ($b['id'] ?? PHP_INT_MAX)]); \App\Services\Survey\SurveySchema::validateConditions(array_map([\App\Services\Course\CourseFormSchema::class, 'field'], $collection)); if (!$model->exists) { $data['admin_id'] = $this->getUserId(); $data['department_id'] = $this->getUser()->department_id; } $model->fill(array_intersect_key($data, array_flip(['course_id', 'admin_id', 'department_id', 'name', 'field', 'edit_input', 'rule', 'sort', 'help', 'select_item', 'need_fill', 'belong_user', 'belong_user_table', 'config']))); $model->save(); return $model; }); return $this->success($model); } catch (\InvalidArgumentException $error) { return $this->fail([ResponseCode::ERROR_PARAMETER, $error->getMessage()]); } } /** * @OA\Get( * path="/api/admin/course-forms/destroy", * tags={"课程表单"}, * summary="删除", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function destroy() { $model = CourseForm::findOrFail(request('id')); if (\App\Models\CourseSign::where('course_id', $model->course_id)->exists()) return $this->fail([ResponseCode::ERROR_BUSINESS, '已有报名,不能删除字段;请使用新课程或新表单']); foreach (CourseForm::where('course_id', $model->course_id)->get() as $field) { if (($field->config['visible_when']['field'] ?? null) === $model->field) return $this->fail([ResponseCode::ERROR_BUSINESS, '该字段被显示条件引用,请先调整条件']); } return parent::destroy(); } /** * @OA\Post( * path="/api/admin/course-forms/excel-show", * tags={"课程表单"}, * summary="导入预览", * description="", * @OA\Parameter(name="file", in="query", @OA\Schema(type="string"), required=true, description="文件"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function excelShow() { return parent::excelShow(); } /** * @OA\Post( * path="/api/admin/course-forms/import", * tags={"课程表单"}, * summary="导入", * description="", * @OA\Parameter(name="data", in="query", @OA\Schema(type="string"), required=true, description="导入分析获取到的二维数组"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function import() { return parent::import(); } /** * @OA\Get( * path="/api/admin/course-forms/clone", * tags={"课程表单"}, * summary="克隆表单", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="验证token"), * @OA\Parameter(name="from_course_id", in="query", @OA\Schema(type="string"), description="来源课程id"), * @OA\Parameter(name="to_course_id", in="query", @OA\Schema(type="string", format="date"), description="目标课程id"), * @OA\Response( * response=200, * description="操作成功" * ) * ) */ public function clone() { $all = \request()->all(); $messages = [ 'from_course_id.required' => '来源Id必填', 'to_course_id.required' => '目标Id必填', ]; $validator = Validator::make($all, [ 'from_course_id' => 'required', 'to_course_id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } if (!\App\Models\Course::whereKey($all['from_course_id'])->exists() || !\App\Models\Course::whereKey($all['to_course_id'])->exists() || !CourseForm::where('course_id', $all['from_course_id'])->exists()) return $this->fail([ResponseCode::ERROR_PARAMETER, '来源或目标课程不存在,或来源表单为空']); if (\App\Models\CourseSign::where('course_id', $all['to_course_id'])->exists()) return $this->fail([ResponseCode::ERROR_BUSINESS, '当前课程已有人员报名,不可克隆覆盖']); if ((string) $all['from_course_id'] === (string) $all['to_course_id']) return $this->fail([ResponseCode::ERROR_PARAMETER, '不能克隆到原课程']); \Illuminate\Support\Facades\DB::transaction(function () use ($all) { CourseForm::where('course_id', $all['to_course_id'])->delete(); foreach (CourseForm::where('course_id', $all['from_course_id'])->orderBy('sort')->orderBy('id')->get() as $fromForm) { $copy = $fromForm->replicate(); $copy->course_id = $all['to_course_id']; $copy->save(); } }); return $this->success('克隆成功'); } }