all(); $list = $this->model->with('course') ->withCount(['courseContentEvaluationAsks' => fn ($q) => $q->where('edit_input', '!=', 'section'), 'courseContentEvaluationForms']) ->where(function ($query) use ($all) { if (isset($all['filter']) && !empty($all['filter'])) { foreach ($all['filter'] as $condition) { $key = $condition['key'] ?? null; $op = $condition['op'] ?? null; $value = $condition['value'] ?? null; if (!isset($key) || !isset($op) || !isset($value)) { continue; } // 等于 if ($op == 'eq') { $query->where($key, $value); } // 不等于 if ($op == 'neq') { $query->where($key, '!=', $value); } // 大于 if ($op == 'gt') { $query->where($key, '>', $value); } // 大于等于 if ($op == 'egt') { $query->where($key, '>=', $value); } // 小于 if ($op == 'lt') { $query->where($key, '<', $value); } // 小于等于 if ($op == 'elt') { $query->where($key, '<=', $value); } // 模糊搜索 if ($op == 'like') { $query->where($key, 'like', '%' . $value . '%'); } // 否定模糊搜索 if ($op == 'notlike') { $query->where($key, 'not like', '%' . $value . '%'); } // 范围搜索 if ($op == 'range') { list($from, $to) = explode(',', $value); if (empty($from) || empty($to)) { continue; } $query->whereBetween($key, [$from, $to]); } } } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { $list = $list->get()->toArray(); $export_fields = $all['export_fields'] ?? []; // 导出文件名字 $tableName = $this->model->getTable(); $filename = (new CustomForm())->getTableComment($tableName); return Excel::download(new BaseExport($export_fields, $list, $tableName), $filename . date('YmdHis') . '.xlsx'); } else { // 输出 $list = $list->paginate($all['page_size'] ?? 20); } return $this->success($list); } /** * @OA\Get( * path="/api/admin/course-content-evaluations/show", * tags={"问卷管理"}, * summary="详情", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function show() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $detail = $this->model->with('course')->find($all['id']); return $this->success($detail); } /** * @OA\Post( * path="/api/admin/course-content-evaluations/save", * tags={"问卷管理"}, * summary="保存", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="integer", format="int64"), required=true, description="课程内容评价字段ID(存在则更新,不存在则新增)"), * @OA\Parameter(name="course_id", in="query", @OA\Schema(type="integer"), required=false, description="课程ID"), * @OA\Parameter(name="course_content_id", in="query", @OA\Schema(type="integer"), required=false, description="课程内容ID,多个英文逗号分割"), * @OA\Parameter(name="title", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="问卷标题"), * @OA\Parameter(name="desc", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="问卷描述"), * @OA\Parameter(name="type_id", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="问卷类型ID"), * @OA\Parameter(name="start_time", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="问卷开始时间"), * @OA\Parameter(name="end_time", in="query", @OA\Schema(type="string", maxLength=255), required=false, description="问卷截止时间"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string", maxLength=255, default="0"), required=false, description="问卷状态(0未发布,1已发布)"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="认证token"), * @OA\Response( * response="200", * description="操作成功" * ) * ) */ public function save() { try { $model = DB::transaction(function () { $all = request()->all(); $model = !empty($all['id']) ? $this->model->whereKey($all['id'])->lockForUpdate()->firstOrFail() : new CourseContentEvaluation(); $copySource = null; $fields = ['title', 'desc', 'course_id', 'course_content_id', 'type_id', 'start_time', 'end_time', 'status', 'audience_course_ids']; if (array_key_exists('copy_from_id', $all)) { if ($model->exists || !is_scalar($all['copy_from_id']) || !ctype_digit((string) $all['copy_from_id']) || (int) $all['copy_from_id'] < 1) { throw new \InvalidArgumentException('复制问卷仅可用于新增,请选择有效的来源问卷'); } $copySource = $this->model->whereKey($all['copy_from_id'])->lockForUpdate()->first(); if (!$copySource) throw new \InvalidArgumentException('来源问卷不存在或已删除'); $all = array_replace(array_intersect_key($copySource->attributesToArray(), array_flip($fields)), ['audience_course_ids' => $copySource->audience_course_ids ?: []], $all); $all['status'] = 0; } if ($model->exists && $model->courseContentEvaluationForms()->exists()) { foreach (['title', 'desc', 'course_id', 'course_content_id', 'type_id'] as $field) { if (array_key_exists($field, $all) && (string) $all[$field] !== (string) $model->$field) { throw new \InvalidArgumentException('已有答卷,仅可调整开放时间与发布状态;请新建问卷修改内容'); } } } if (array_key_exists('audience_course_ids', $all)) { $ids = $all['audience_course_ids']; if (!is_array($ids) || count(array_filter($ids, fn ($id) => !is_scalar($id) || !ctype_digit((string) $id) || (int) $id < 1))) throw new \InvalidArgumentException('限定人群请选择有效课程'); $ids = array_values(array_unique(array_map('intval', $ids))); if (\App\Models\Course::whereIn('id', $ids)->count() !== count($ids)) throw new \InvalidArgumentException('限定人群中存在无效课程'); $all['audience_course_ids'] = $ids; } $original = $model->getOriginal(); $model->fill(array_intersect_key($all, array_flip($fields))); if (!$model->title) throw new \InvalidArgumentException('请输入问卷标题'); if ($model->start_time && $model->end_time && strtotime($model->start_time) >= strtotime($model->end_time)) { throw new \InvalidArgumentException('截止时间必须晚于开始时间'); } if ((int) $model->status === 1 && (!$model->exists || !$model->courseContentEvaluationAsks()->where('edit_input', '!=', 'section')->exists())) { throw new \InvalidArgumentException('至少添加一道题目后才能发布'); } if (!$model->exists) { // Older installations have only the original questionnaire columns. if (\Illuminate\Support\Facades\Schema::hasColumn($model->getTable(), 'admin_id')) $model->admin_id = $this->getUserId(); if (\Illuminate\Support\Facades\Schema::hasColumn($model->getTable(), 'department_id')) $model->department_id = $this->getUser()->department_id; } $model->save(); if ($copySource) { $scheduleIds = array_filter(array_map('trim', explode(',', (string) $model->course_content_id))); foreach ($copySource->courseContentEvaluationAsks()->orderBy('sort')->orderBy('id')->lockForUpdate()->get() as $sourceQuestion) { $question = $sourceQuestion->replicate(); $question->course_content_evaluation_id = $model->id; $question->course_id = $model->course_id; if ((string) $copySource->course_id !== (string) $model->course_id || !in_array((string) $question->course_content_id, $scheduleIds, true)) $question->course_content_id = null; $question->admin_id = $this->getUserId(); $question->department_id = $this->getUser()->department_id; $question->save(); } } $this->saveLogs($original, $model); return $model; }); return $this->success($model); } catch (\InvalidArgumentException $e) { return $this->fail([ResponseCode::ERROR_PARAMETER, $e->getMessage()]); } } /** * @OA\Get( * path="/api/admin/course-content-evaluations/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() { return parent::destroy(); } }