all(); $list = $this->model->with('user')->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-evaluation-form/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('user')->find($all['id']); if (!$detail) return $this->fail([ResponseCode::ERROR_BUSINESS, '答卷不存在']); $questions = CourseContentEvaluationAsk::where('course_content_evaluation_id', $detail->course_content_evaluation_id)->orderBy('sort')->orderBy('id')->get()->toArray(); $detail->questions = SurveySchema::replyQuestions($questions, $detail->data, $detail->snapshot); return $this->success($detail); } /** * @OA\Post( * path="/api/admin/course-content-evaluation-form/save", * tags={"评价内容管理"}, * summary="保存", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="integer", format="int64"), required=true, description="课程内容评价字段ID(存在则更新,不存在则新增)"), * @OA\Parameter(name="course_content_id", in="query", @OA\Schema(type="integer", format="int32"), required=true, description="课程排课ID"), * @OA\Parameter(name="title", in="query", @OA\Schema(type="string"), required=true, description="标题"), * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="字段类型。单选radio,多选checkbox,问答text,评分number,日期date,日期时间datetime"), * @OA\Parameter(name="key", in="query", @OA\Schema(type="string"), required=true, description="英文标识"), * @OA\Parameter(name="remark", in="query", @OA\Schema(type="string"), required=false, description="备注"), * @OA\Parameter(name="sort", in="query", @OA\Schema(type="integer", format="int32"), required=false, description="排序"), * @OA\Parameter(name="options", 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 save() { return $this->fail([ResponseCode::ERROR_BUSINESS, '答卷保存后不可修改,请通过学员端提交']); } /** * @OA\Get( * path="/api/admin/course-content-evaluation-form/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(); } public function statistics() { $survey = CourseContentEvaluation::findOrFail(request('course_content_evaluation_id')); $questions = $survey->courseContentEvaluationAsks()->with('courseContent.teacher')->orderBy('sort')->orderBy('id')->get()->toArray(); // All v2 replies share a frozen structure. Prefer the authoritative snapshot. $first = $survey->courseContentEvaluationForms()->whereNotNull('snapshot')->orderBy('id')->first(); if ($first && isset($first->snapshot['questions'])) $questions = $first->snapshot['questions']; return $this->success(SurveyStatistics::summarize($questions, $survey->courseContentEvaluationForms()->select(['id', 'data', 'snapshot'])->cursor())); } public function textAnswers() { $survey = CourseContentEvaluation::findOrFail(request('course_content_evaluation_id')); $questionId = (string) request('question_id'); $other = request('kind') === 'other'; $page = max(1, (int) request('page', 1)); $size = min(50, max(1, (int) request('page_size', 20))); $total = 0; $items = []; foreach ($survey->courseContentEvaluationForms()->orderByDesc('id')->cursor() as $response) { $raw = SurveySchema::answerMap($response->data)[$questionId] ?? []; $value = $other ? ($raw['other_text'] ?? $raw['allow_input_text'] ?? null) : ($raw['value'] ?? null); if (!is_scalar($value) || SurveySchema::blank($value)) continue; if ($total >= ($page - 1) * $size && count($items) < $size) { $items[] = ['id' => $response->id, 'text' => (string) $value, 'created_at' => (string) $response->created_at]; } $total++; } return $this->success(['data' => $items, 'total' => $total, 'current_page' => $page]); } }