feat
parent
d12fd88685
commit
45beeabf85
|
|
@ -1,109 +0,0 @@
|
|||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "分页查询学员考试记录",
|
||||
"description": "同步自 Apifox(学员考试记录),int64 主键按前端精度规范落为 string",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/safetyEval/classStudentExamRecord/page": {
|
||||
"get": {
|
||||
"summary": "分页查询学员考试记录",
|
||||
"tags": ["学员考试记录"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "current",
|
||||
"in": "query",
|
||||
"description": "当前页(默认1)",
|
||||
"required": false,
|
||||
"schema": { "type": "integer", "default": 1 }
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"description": "每页条数(默认10)",
|
||||
"required": false,
|
||||
"schema": { "type": "integer", "default": 10 }
|
||||
},
|
||||
{
|
||||
"name": "classId",
|
||||
"in": "query",
|
||||
"description": "所属班级ID(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "studentId",
|
||||
"in": "query",
|
||||
"description": "学员ID(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "examId",
|
||||
"in": "query",
|
||||
"description": "试卷id(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "passed",
|
||||
"in": "query",
|
||||
"description": "是否通过(0-未通过,1-通过)",
|
||||
"required": false,
|
||||
"schema": { "type": "integer" }
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/PageResponseClassStudentExamRecordVO" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"PageResponseClassStudentExamRecordVO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": { "type": "boolean", "description": "是否成功" },
|
||||
"code": { "type": "string", "description": "响应码" },
|
||||
"message": { "type": "string", "description": "响应消息" },
|
||||
"errMessage": { "type": "string", "description": "错误响应消息" },
|
||||
"data": {
|
||||
"type": "array",
|
||||
"description": "响应数据",
|
||||
"items": { "$ref": "#/components/schemas/ClassStudentExamRecordVO" }
|
||||
},
|
||||
"total": { "type": "integer", "description": "总条数" }
|
||||
}
|
||||
},
|
||||
"ClassStudentExamRecordVO": {
|
||||
"type": "object",
|
||||
"description": "学员考试记录",
|
||||
"properties": {
|
||||
"id": { "type": "string", "description": "主键" },
|
||||
"studentId": { "type": "string", "description": "学员ID(后端 Long;前端按字符串保证精度)" },
|
||||
"studentName": { "type": "string", "description": "学员名称" },
|
||||
"classId": { "type": "string", "description": "所属班级ID(后端 Long;前端按字符串保证精度)" },
|
||||
"paperName": { "type": "string", "description": "试卷名称" },
|
||||
"paperId": { "type": "string", "description": "试卷id(后端 Long;前端按字符串保证精度)" },
|
||||
"score": { "type": "number", "description": "得分" },
|
||||
"passed": { "type": "integer", "description": "是否通过(0-未通过,1-通过)" },
|
||||
"wrongCount": { "type": "integer", "description": "错误题数" },
|
||||
"accuracy": { "type": "number", "description": "正确率(百分比)" },
|
||||
"startTime": { "type": "string", "description": "考试开始时间" },
|
||||
"endTime": { "type": "string", "description": "考试结束时间" },
|
||||
"className": { "type": "string", "description": "app: 班级名称" },
|
||||
"examDurationMinutes": { "type": "integer", "description": "app: 考试时长分钟" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
* GET /safetyEval/classStudentExamRecord/page —— 分页查询学员考试记录
|
||||
* 契约见同目录 spec.json
|
||||
*/
|
||||
|
||||
/** 分页查询入参 */
|
||||
export interface ClassStudentExamRecordPageQuery {
|
||||
/** 当前页(默认1) */
|
||||
current?: number;
|
||||
/** 每页条数(默认10) */
|
||||
size?: number;
|
||||
/** 所属班级ID(后端 Long;前端按字符串保证精度) */
|
||||
classId?: string;
|
||||
/** 学员ID(后端 Long;前端按字符串保证精度) */
|
||||
studentId?: string;
|
||||
/** 试卷id(后端 Long;前端按字符串保证精度) */
|
||||
examId?: string;
|
||||
/** 是否通过(0-未通过,1-通过) */
|
||||
passed?: number;
|
||||
}
|
||||
|
||||
/** 学员考试记录 */
|
||||
export interface ClassStudentExamRecordVO {
|
||||
/** 主键 */
|
||||
id?: string;
|
||||
/** 学员ID(后端 Long;前端按字符串保证精度) */
|
||||
studentId?: string;
|
||||
/** 学员名称 */
|
||||
studentName?: string;
|
||||
/** 所属班级ID(后端 Long;前端按字符串保证精度) */
|
||||
classId?: string;
|
||||
/** 试卷名称 */
|
||||
paperName?: string;
|
||||
/** 试卷id(后端 Long;前端按字符串保证精度) */
|
||||
paperId?: string;
|
||||
/** 得分 */
|
||||
score?: number;
|
||||
/** 是否通过(0-未通过,1-通过) */
|
||||
passed?: number;
|
||||
/** 错误题数 */
|
||||
wrongCount?: number;
|
||||
/** 正确率(百分比) */
|
||||
accuracy?: number;
|
||||
/** 考试开始时间 */
|
||||
startTime?: string;
|
||||
/** 考试结束时间 */
|
||||
endTime?: string;
|
||||
/** app: 班级名称 */
|
||||
className?: string;
|
||||
/** app: 考试时长分钟 */
|
||||
examDurationMinutes?: number;
|
||||
}
|
||||
|
||||
/** 响应体 */
|
||||
export interface PageResponseClassStudentExamRecordVO {
|
||||
success?: boolean;
|
||||
code?: string;
|
||||
message?: string;
|
||||
errMessage?: string;
|
||||
data?: ClassStudentExamRecordVO[];
|
||||
total?: number;
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "分页查询学员学习记录",
|
||||
"description": "同步自 Apifox(学员学习记录),int64 主键按前端精度规范落为 string",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/safetyEval/classStudentLearningRecord/page": {
|
||||
"get": {
|
||||
"summary": "分页查询学员学习记录",
|
||||
"tags": ["学员学习记录"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "current",
|
||||
"in": "query",
|
||||
"description": "当前页(默认1)",
|
||||
"required": false,
|
||||
"schema": { "type": "integer", "default": 1 }
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"in": "query",
|
||||
"description": "每页条数(默认10)",
|
||||
"required": false,
|
||||
"schema": { "type": "integer", "default": 10 }
|
||||
},
|
||||
{
|
||||
"name": "classId",
|
||||
"in": "query",
|
||||
"description": "所属班级ID(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "studentId",
|
||||
"in": "query",
|
||||
"description": "学员ID(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "courseId",
|
||||
"in": "query",
|
||||
"description": "课程ID(后端 Long;前端按字符串保证精度)",
|
||||
"required": false,
|
||||
"schema": { "type": "string" }
|
||||
},
|
||||
{
|
||||
"name": "studyStatus",
|
||||
"in": "query",
|
||||
"description": "学习状态:0-未学习,1-学习中,2-已完成",
|
||||
"required": false,
|
||||
"schema": { "type": "integer" }
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PageResponseClassStudentLearningRecordVO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"PageResponseClassStudentLearningRecordVO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": { "type": "boolean", "description": "是否成功" },
|
||||
"code": { "type": "string", "description": "响应码" },
|
||||
"message": { "type": "string", "description": "响应消息" },
|
||||
"errMessage": { "type": "string", "description": "错误响应消息" },
|
||||
"data": {
|
||||
"type": "array",
|
||||
"description": "响应数据",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ClassStudentLearningRecordVO"
|
||||
}
|
||||
},
|
||||
"total": { "type": "integer", "description": "总条数" }
|
||||
}
|
||||
},
|
||||
"ClassStudentLearningRecordVO": {
|
||||
"type": "object",
|
||||
"description": "学员学习记录(节点级)",
|
||||
"properties": {
|
||||
"id": { "type": "string", "description": "主键" },
|
||||
"studentId": {
|
||||
"type": "string",
|
||||
"description": "学员ID(后端 Long;前端按字符串保证精度)"
|
||||
},
|
||||
"classId": {
|
||||
"type": "string",
|
||||
"description": "所属班级ID(后端 Long;前端按字符串保证精度)"
|
||||
},
|
||||
"courseId": {
|
||||
"type": "string",
|
||||
"description": "课程ID(后端 Long;前端按字符串保证精度)"
|
||||
},
|
||||
"courseName": { "type": "string", "description": "课程名称" },
|
||||
"coursewareName": { "type": "string", "description": "小节点名称" },
|
||||
"studyStatus": {
|
||||
"type": "integer",
|
||||
"description": "学习状态:0-未学习,1-学习中,2-已完成"
|
||||
},
|
||||
"learningProgress": { "type": "string", "description": "学习情况" },
|
||||
"startTime": { "type": "string", "description": "开始学习时间" },
|
||||
"endTime": { "type": "string", "description": "完成时间" },
|
||||
"lastWatchTime": { "type": "string", "description": "最近观看时间" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* GET /safetyEval/classStudentLearningRecord/page —— 分页查询学员学习记录
|
||||
* 契约见同目录 spec.json
|
||||
*/
|
||||
|
||||
/** 分页查询入参 */
|
||||
export interface ClassStudentLearningRecordPageQuery {
|
||||
/** 当前页(默认1) */
|
||||
current?: number;
|
||||
/** 每页条数(默认10) */
|
||||
size?: number;
|
||||
/** 所属班级ID(后端 Long;前端按字符串保证精度) */
|
||||
classId?: string;
|
||||
/** 学员ID(后端 Long;前端按字符串保证精度) */
|
||||
studentId?: string;
|
||||
/** 课程ID(后端 Long;前端按字符串保证精度) */
|
||||
courseId?: string;
|
||||
/** 学习状态:0-未学习,1-学习中,2-已完成 */
|
||||
studyStatus?: number;
|
||||
}
|
||||
|
||||
/** 学员学习记录(节点级) */
|
||||
export interface ClassStudentLearningRecordVO {
|
||||
/** 主键 */
|
||||
id?: string;
|
||||
/** 学员ID(后端 Long;前端按字符串保证精度) */
|
||||
studentId?: string;
|
||||
/** 所属班级ID(后端 Long;前端按字符串保证精度) */
|
||||
classId?: string;
|
||||
/** 课程ID(后端 Long;前端按字符串保证精度) */
|
||||
courseId?: string;
|
||||
/** 课程名称 */
|
||||
courseName?: string;
|
||||
/** 小节点名称 */
|
||||
coursewareName?: string;
|
||||
/** 学习状态:0-未学习,1-学习中,2-已完成 */
|
||||
studyStatus?: number;
|
||||
/** 学习情况 */
|
||||
learningProgress?: string;
|
||||
/** 开始学习时间 */
|
||||
startTime?: string;
|
||||
/** 完成时间 */
|
||||
endTime?: string;
|
||||
/** 最近观看时间 */
|
||||
lastWatchTime?: string;
|
||||
}
|
||||
|
||||
/** 分页响应体 */
|
||||
export interface PageResponseClassStudentLearningRecordVO {
|
||||
success?: boolean;
|
||||
code?: string;
|
||||
message?: string;
|
||||
errMessage?: string;
|
||||
data?: ClassStudentLearningRecordVO[];
|
||||
total?: number;
|
||||
}
|
||||
|
|
@ -210,3 +210,9 @@ export const classStudentExamRecordPage = declareRequest(
|
|||
"Get > /safetyEval/classStudentExamRecord/page",
|
||||
"examRecordList: [] | res.data || [] & examRecordTotal: 0 | res.total || 0",
|
||||
);
|
||||
|
||||
/** 考试试卷信息查询(按考试记录id,含试题列表及参考答案) */
|
||||
export const studentExamPaperInfo = declareRequest(
|
||||
"studentExamPaperLoading",
|
||||
"Get > /safetyEval/paperExam/exam/info",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -710,8 +710,8 @@ export const CLASS_STUDENT_FACE_AUTH_MAP = {
|
|||
export const CLASS_STUDENT_STUDY_STATUS_OPTIONS = [
|
||||
{ label: "未学习", value: 0 },
|
||||
{ label: "学习中", value: 1 },
|
||||
{ label: "已学完", value: 2 },
|
||||
{ label: "已完成", value: 3 },
|
||||
|
||||
{ label: "已完成", value: 2 },
|
||||
];
|
||||
|
||||
export const CLASS_STUDENT_STUDY_STATUS_MAP = CLASS_STUDENT_STUDY_STATUS_OPTIONS.reduce(
|
||||
|
|
@ -743,7 +743,7 @@ export const CLASS_STUDENT_EXAM_STATUS_OPTIONS = [
|
|||
{ label: "待考试", value: 1 },
|
||||
{ label: "考试未通过", value: 2 },
|
||||
{ label: "考试通过", value: 3 },
|
||||
{ label: "未参加", value: 4 },
|
||||
|
||||
];
|
||||
|
||||
export const CLASS_STUDENT_EXAM_STATUS_MAP = CLASS_STUDENT_EXAM_STATUS_OPTIONS.reduce(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import SearchForm from "~/components/SearchForm";
|
|||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||
|
||||
import StaffViewModal from "~/components/StaffViewModal";
|
||||
import {
|
||||
CLASS_STUDENT_EXAM_STATUS_OPTIONS,
|
||||
|
|
@ -32,7 +33,7 @@ const buildQuery = (value) => {
|
|||
|
||||
/** 班级详情 — 学员 Tab:班级学员查询 */
|
||||
function ClassStudentTab(props) {
|
||||
const { classId } = props;
|
||||
const { classId, form } = props;
|
||||
const [searchForm] = Form.useForm();
|
||||
const [query, setQuery] = useState({ current: 1, size: 10 });
|
||||
const [selectOpen, setSelectOpen] = useState(false);
|
||||
|
|
@ -228,7 +229,7 @@ function ClassStudentTab(props) {
|
|||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={tableSource}
|
||||
scroll={{ x: 1400 }}
|
||||
scroll={{ x: 1400, y: 400 }}
|
||||
loading={loading}
|
||||
pagination={{
|
||||
total,
|
||||
|
|
@ -265,6 +266,7 @@ function ClassStudentTab(props) {
|
|||
studentName: userName,
|
||||
department: deptName,
|
||||
phone: account,
|
||||
examStatus: form.getFieldValue("openExam"),
|
||||
studentId: studentId || id,
|
||||
fileNumber: fileNumber|| id,
|
||||
unitName: unitName,
|
||||
|
|
@ -395,4 +397,4 @@ function StudentSelectModal({
|
|||
);
|
||||
}
|
||||
|
||||
export default Connect([NS_COURSEWARE], true)(ClassStudentTab);
|
||||
export default Connect([NS_COURSEWARE], true)((ClassStudentTab) );
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ function ClassAddPage(props) {
|
|||
label: "学员",
|
||||
disabled: !unlocked,
|
||||
children: unlocked ? (
|
||||
<StudentTab classId={savedClassId} history={props.history} />
|
||||
<StudentTab classId={savedClassId} history={props.history} form={form} />
|
||||
) : null,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Empty, Modal, Tag } from "antd";
|
||||
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||
import {
|
||||
EXAM_RECORD_PASSED_MAP,
|
||||
QUESTION_TYPE_MAP,
|
||||
} from "~/enumerate/constant";
|
||||
|
||||
/** 区块标题 */
|
||||
const SectionTitle = ({ children }) => (
|
||||
<div className="srd-detail__section-title">{children}</div>
|
||||
);
|
||||
|
||||
/** label: value 字段 */
|
||||
const Field = ({ label, value }) => (
|
||||
<div className="srd-detail__field">
|
||||
<span className="srd-detail__label">{label}:</span>
|
||||
<span className="srd-detail__value">{value ?? "-"}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
/** 考试详情弹窗:学员信息 + 试卷基本信息 + 试卷内容(试题列表) */
|
||||
function ExamDetailModal({
|
||||
open,
|
||||
record,
|
||||
loading,
|
||||
fetchPaperInfo,
|
||||
resetModelState,
|
||||
onClose,
|
||||
}) {
|
||||
const [info, setInfo] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
resetModelState?.(NS_COURSEWARE, { studentExamPaperLoading: false });
|
||||
return;
|
||||
}
|
||||
if (!record?.id) return;
|
||||
setInfo(null);
|
||||
fetchPaperInfo({ paperExamId: record.id }).then((res) => {
|
||||
if (res?.success !== false) setInfo(res?.data || null);
|
||||
});
|
||||
}, [open, record?.id]);
|
||||
|
||||
const basic = info?.paperBasicInfoVO || {};
|
||||
const questionList = Array.isArray(info?.questionVOList)
|
||||
? info.questionVOList
|
||||
: [];
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
title={`考试详情${record?.studentName ? ` - ${record.studentName}` : ""}`}
|
||||
width={980}
|
||||
footer={
|
||||
<Button onClick={onClose}>关闭</Button>
|
||||
}
|
||||
destroyOnHidden
|
||||
loading={loading}
|
||||
onCancel={onClose}
|
||||
className="srd-detail"
|
||||
>
|
||||
<SectionTitle>考试学员信息</SectionTitle>
|
||||
<div className="srd-detail__grid">
|
||||
<Field label="考试学员" value={record?.studentName} />
|
||||
<Field
|
||||
label="状态"
|
||||
value={
|
||||
record?.passed != null ? (
|
||||
<Tag color={record.passed === 1 ? "green" : "red"}>
|
||||
{EXAM_RECORD_PASSED_MAP[record.passed]}
|
||||
</Tag>
|
||||
) : (
|
||||
"-"
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Field label="学员得分" value={record?.score} />
|
||||
<Field label="考试时间" value={record?.startTime} />
|
||||
<Field
|
||||
label="答题时长"
|
||||
value={
|
||||
record?.examDurationMinutes != null
|
||||
? `${record.examDurationMinutes}分钟`
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SectionTitle>试卷基本信息</SectionTitle>
|
||||
<div className="srd-detail__grid">
|
||||
<Field label="试卷名称" value={basic.paperName} />
|
||||
<Field
|
||||
label="考试时长"
|
||||
value={basic.examTime != null ? `${basic.examTime}分钟` : undefined}
|
||||
/>
|
||||
<Field label="总分" value={basic.paperTotalScore} />
|
||||
<Field label="合格分数" value={basic.paperPassScore} />
|
||||
</div>
|
||||
|
||||
<SectionTitle>试卷内容信息</SectionTitle>
|
||||
<div className="srd-detail__count">
|
||||
试题数量:<strong>{questionList.length}</strong>
|
||||
</div>
|
||||
{questionList.length === 0 ? (
|
||||
<Empty
|
||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||
description="暂无试题"
|
||||
/>
|
||||
) : (
|
||||
<div className="srd-detail__questions">
|
||||
{questionList.map((q, index) => (
|
||||
<div key={q.id} className="srd-detail__question">
|
||||
<div className="srd-detail__question-title">
|
||||
{index + 1}. {q.title || "-"}
|
||||
</div>
|
||||
<div className="srd-detail__question-meta">
|
||||
题型:{QUESTION_TYPE_MAP[q.questionType] || q.questionType || "-"}
|
||||
<span className="srd-detail__question-score">
|
||||
分值:{q.questionScore ?? q.score ?? "-"}
|
||||
</span>
|
||||
</div>
|
||||
{(q.questionOptionVOList || []).length > 0 && (
|
||||
<div className="srd-detail__options">
|
||||
{q.questionOptionVOList.map((o) => (
|
||||
<div key={o.id} className="srd-detail__option">
|
||||
{o.optionKey}. {o.optionText}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="srd-detail__question-info">
|
||||
参考答案:{q.answer || "-"}
|
||||
</div>
|
||||
<div className="srd-detail__question-info">
|
||||
答案解析:{q.analysis || "-"}
|
||||
</div>
|
||||
<div className="srd-detail__question-info">
|
||||
关联课程:{q.coursewareManagementName || "-"}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ExamDetailModal;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Form, Table, Tabs } from "antd";
|
||||
import { Button, Form, Table, Tabs } from "antd";
|
||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||
import SearchForm from "~/components/SearchForm";
|
||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
|
|
@ -12,6 +13,8 @@ import {
|
|||
LEARNING_RECORD_STUDY_STATUS_MAP,
|
||||
LEARNING_RECORD_STUDY_STATUS_OPTIONS,
|
||||
} from "~/enumerate/constant";
|
||||
import ExamDetailModal from "./ExamDetailModal";
|
||||
import "./index.less";
|
||||
|
||||
const { router } = tools;
|
||||
|
||||
|
|
@ -21,6 +24,7 @@ function ClassStudyRecordPage(props) {
|
|||
const [examSearchForm] = Form.useForm();
|
||||
const [activeTab, setActiveTab] = useState("study");
|
||||
const [examQuery, setExamQuery] = useState({ current: 1, size: 10 });
|
||||
const [examDetailRecord, setExamDetailRecord] = useState(null);
|
||||
const studentName = router.query?.studentName;
|
||||
const {
|
||||
learningRecordList: dataSource,
|
||||
|
|
@ -29,6 +33,7 @@ function ClassStudyRecordPage(props) {
|
|||
examRecordList: examDataSource,
|
||||
examRecordTotal: examTotal,
|
||||
examRecordLoading: examLoading,
|
||||
studentExamPaperLoading: examDetailLoading,
|
||||
} = props.courseware || {};
|
||||
|
||||
const handleSearch = () => {
|
||||
|
|
@ -169,6 +174,23 @@ function ClassStudyRecordPage(props) {
|
|||
width: 170,
|
||||
render: (v) => v || "-",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 110,
|
||||
fixed: "right",
|
||||
render: (_, record) => (
|
||||
<TableAction>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => setExamDetailRecord(record)}
|
||||
>
|
||||
考试详情
|
||||
</Button>
|
||||
</TableAction>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
/** 考试记录搜索/重置:试卷名称接口暂未支持,先行透传 */
|
||||
|
|
@ -302,6 +324,15 @@ function ClassStudyRecordPage(props) {
|
|||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<ExamDetailModal
|
||||
open={!!examDetailRecord}
|
||||
record={examDetailRecord}
|
||||
loading={examDetailLoading}
|
||||
fetchPaperInfo={props.studentExamPaperInfo}
|
||||
resetModelState={props.resetModelState}
|
||||
onClose={() => setExamDetailRecord(null)}
|
||||
/>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
/* StudyRecord — 考试详情弹窗样式(前缀 srd-) */
|
||||
.srd-detail {
|
||||
&__section-title {
|
||||
margin: 16px 0 12px;
|
||||
padding-left: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
border-left: 3px solid #fa8c16;
|
||||
}
|
||||
|
||||
&__grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
row-gap: 12px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
color: rgba(0, 0, 0, 45%);
|
||||
}
|
||||
|
||||
&__value {
|
||||
color: rgba(0, 0, 0, 88%);
|
||||
}
|
||||
|
||||
&__count {
|
||||
margin-bottom: 12px;
|
||||
color: rgba(0, 0, 0, 65%);
|
||||
}
|
||||
|
||||
&__questions {
|
||||
max-height: 420px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
&__question {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&-meta {
|
||||
margin-bottom: 8px;
|
||||
color: rgba(0, 0, 0, 65%);
|
||||
}
|
||||
|
||||
&-score {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
&-info {
|
||||
margin-top: 6px;
|
||||
color: rgba(0, 0, 0, 65%);
|
||||
}
|
||||
}
|
||||
|
||||
&__options {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
row-gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&__option {
|
||||
color: rgba(0, 0, 0, 85%);
|
||||
}
|
||||
}
|
||||
|
|
@ -213,18 +213,18 @@ const menuItems = [
|
|||
label: "项目踏勘监管",
|
||||
icon: <EnvironmentOutlined />,
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/Supervision/EvalPortrait",
|
||||
label: "安全评价画像",
|
||||
icon: <PieChartOutlined />,
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/Supervision/EvalReportDatabase",
|
||||
label: "安评报告数据库",
|
||||
label: "历史报告数据库",
|
||||
icon: <FileProtectOutlined />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/Supervision/EvalPortrait",
|
||||
label: "安评机构画像",
|
||||
icon: <PieChartOutlined />,
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/MonitorManage/RiskCenter",
|
||||
label: "风险预警中心",
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ const EvalPortrait = (props) => {
|
|||
return (
|
||||
<ConfigProvider theme={PROTO_THEME}>
|
||||
<PageLayout
|
||||
title="安全评价画像"
|
||||
title="安评机构画像"
|
||||
extra={
|
||||
<Button onClick={openRules}>指标说明</Button>
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ const EvalPortrait = (props) => {
|
|||
|
||||
{/* 查看画像 — 对齐原型 institutionProfile */}
|
||||
<Modal
|
||||
title={detail ? `安全评价画像 - ${detail.orgName}` : "安全评价画像"}
|
||||
title={detail ? `安评机构画像 - ${detail.orgName}` : "安评机构画像"}
|
||||
open={detailOpen}
|
||||
onCancel={() => setDetailOpen(false)}
|
||||
width={980}
|
||||
|
|
|
|||
|
|
@ -714,7 +714,7 @@ const EvalReportDatabase = (props) => {
|
|||
await downloadBinaryPost(
|
||||
"/safetyEval/regulator/eval-report/export-catalog",
|
||||
body,
|
||||
`安评报告数据库目录_${dayjs().format("YYYYMMDDHHmmss")}.csv`,
|
||||
`历史报告数据库目录_${dayjs().format("YYYYMMDDHHmmss")}.csv`,
|
||||
);
|
||||
message.success("目录导出已开始");
|
||||
setExportVisible(false);
|
||||
|
|
@ -929,7 +929,7 @@ const EvalReportDatabase = (props) => {
|
|||
|
||||
return (
|
||||
<ConfigProvider theme={PROTO_THEME}>
|
||||
<PageLayout title="安评报告数据库">
|
||||
<PageLayout title="历史报告数据库">
|
||||
<div className="redb-page">
|
||||
<div className="redb-summary-cards">
|
||||
<div className="redb-summary-card">
|
||||
|
|
@ -1265,7 +1265,7 @@ const EvalReportDatabase = (props) => {
|
|||
|
||||
{/* 导出目录 — 对齐原型 export */}
|
||||
<Modal
|
||||
title="安评报告数据库目录"
|
||||
title="历史报告数据库目录"
|
||||
open={exportVisible}
|
||||
onCancel={() => setExportVisible(false)}
|
||||
onOk={handleExportOk}
|
||||
|
|
|
|||
Loading…
Reference in New Issue