forked from integrated_whb/integrated_whb_vue
				
			班级管理/学员
							parent
							
								
									6699355494
								
							
						
					
					
						commit
						39ccafdc17
					
				|  | @ -40,3 +40,9 @@ export const getClassManagementSelectStudentList = (params) => | ||||||
|   post("/user/studentList", params); // 班级管理新增学员列表
 |   post("/user/studentList", params); // 班级管理新增学员列表
 | ||||||
| export const getClassManagementSelectStudentAdd = (params) => | export const getClassManagementSelectStudentAdd = (params) => | ||||||
|   post("/student/add", params); // 班级管理新增学员保存
 |   post("/student/add", params); // 班级管理新增学员保存
 | ||||||
|  | export const getClassManagementStudentLearningRecordsList = (params) => | ||||||
|  |   post("/coursestudyvideorecord/getAllByuserInfo", params); // 班级管理学员学习记录列表
 | ||||||
|  | export const getClassManagementStudentExamRecordsList = (params) => | ||||||
|  |   post("/stageexam/list", params); // 班级管理学员考试记录列表
 | ||||||
|  | export const getClassManagementStudentExamRecordsView = (params) => | ||||||
|  |   post("/stageexam/findExam", params); // 班级管理学员考试记录查看
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,107 @@ | ||||||
|  | <template> | ||||||
|  |   <el-dialog v-model="visible" title="考试详情" width="70%"> | ||||||
|  |     <el-divider content-position="left">考试学员信息</el-divider> | ||||||
|  |     <div style="display: flex; justify-content: space-around"> | ||||||
|  |       <div>学员名字:{{ info.USERNAME }}</div> | ||||||
|  |       <div>考试时间:{{ info.EXAMTIMEBEGIN + "至" + info.EXAMTIMEEND }}</div> | ||||||
|  |       <div>得分:{{ info.EXAMSCORE }}</div> | ||||||
|  |     </div> | ||||||
|  |     <el-divider content-position="left">试卷基本信息</el-divider> | ||||||
|  |     <div style="display: flex; justify-content: space-around"> | ||||||
|  |       <div>试卷名称:{{ info.EXAMNAME }}</div> | ||||||
|  |       <div>试卷总分:{{ info.PAPEREXAMSCORE }}</div> | ||||||
|  |       <div>考试时长:{{ info.ANSWERSHEETTIME }}分钟</div> | ||||||
|  |       <div>通过分数:{{ info.PASSSCORE }}</div> | ||||||
|  |     </div> | ||||||
|  |     <el-divider content-position="left">试卷内容信息</el-divider> | ||||||
|  |     <div class="items mt-20 p-20"> | ||||||
|  |       <div | ||||||
|  |         v-for="(item, index) in info.QUESTIONLIST" | ||||||
|  |         :key="item.PAPER_QUESTION_ID" | ||||||
|  |         class="item ptb-20" | ||||||
|  |       > | ||||||
|  |         <div class="mt-10"> | ||||||
|  |           {{ index + 1 }}. | ||||||
|  |           <span v-if="item.QUESTIONTYPE === '1'"> (单选题) </span> | ||||||
|  |           <span v-if="item.QUESTIONTYPE === '2'"> (多选题) </span> | ||||||
|  |           <span v-if="item.QUESTIONTYPE === '3'"> (判断题) </span> | ||||||
|  |           {{ item.QUESTIONDRY }} | ||||||
|  |           <span class="ml-10">(题目分值:{{ item.SCORE }})</span> | ||||||
|  |         </div> | ||||||
|  |         <div class="mt-10 ml-30"> | ||||||
|  |           <el-radio-group | ||||||
|  |             v-if="item.QUESTIONTYPE === '1'" | ||||||
|  |             disabled | ||||||
|  |             :model-value="item.ANSWER" | ||||||
|  |           > | ||||||
|  |             <el-radio label="A">A.{{ item.OPTIONA }}</el-radio> | ||||||
|  |             <el-radio label="B">B.{{ item.OPTIONB }}</el-radio> | ||||||
|  |             <el-radio label="C">C.{{ item.OPTIONC }}</el-radio> | ||||||
|  |             <el-radio label="D">D.{{ item.OPTIOND }}</el-radio> | ||||||
|  |           </el-radio-group> | ||||||
|  |           <el-checkbox-group | ||||||
|  |             v-if="item.QUESTIONTYPE === '2'" | ||||||
|  |             disabled | ||||||
|  |             :model-value="item.ANSWER?.split('')" | ||||||
|  |           > | ||||||
|  |             <el-checkbox label="A">A.{{ item.OPTIONA }}</el-checkbox> | ||||||
|  |             <el-checkbox label="B">B.{{ item.OPTIONB }}</el-checkbox> | ||||||
|  |             <el-checkbox label="C">C.{{ item.OPTIONC }}</el-checkbox> | ||||||
|  |             <el-checkbox label="D">D.{{ item.OPTIOND }}</el-checkbox> | ||||||
|  |           </el-checkbox-group> | ||||||
|  |           <el-radio-group | ||||||
|  |             v-if="item.QUESTIONTYPE === '3'" | ||||||
|  |             disabled | ||||||
|  |             :model-value="item.ANSWER" | ||||||
|  |           > | ||||||
|  |             <el-radio label="A">A.{{ item.OPTIONA }}</el-radio> | ||||||
|  |             <el-radio label="B">B.{{ item.OPTIONB }}</el-radio> | ||||||
|  |           </el-radio-group> | ||||||
|  |         </div> | ||||||
|  |         <div class="mt-10">答案:{{ item.ANSWER }}</div> | ||||||
|  |         <div class="mt-10">答案解析:{{ item.DESCR }}</div> | ||||||
|  |         <div class="mt-10">关联课件名称:{{ item.COURSEWARENAME }}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <template #footer> | ||||||
|  |       <el-button @click="visible = false">关闭</el-button> | ||||||
|  |     </template> | ||||||
|  |   </el-dialog> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup> | ||||||
|  | import { useVModel } from "@vueuse/core"; | ||||||
|  | 
 | ||||||
|  | const props = defineProps({ | ||||||
|  |   visible: { | ||||||
|  |     type: Boolean, | ||||||
|  |     required: true, | ||||||
|  |     default: false, | ||||||
|  |   }, | ||||||
|  |   info: { | ||||||
|  |     type: Object, | ||||||
|  |     required: true, | ||||||
|  |     default: () => ({}), | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | const emits = defineEmits(["update:visible"]); | ||||||
|  | const visible = useVModel(props, "visible", emits); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .items { | ||||||
|  |   border: 1px solid var(--el-border-color); | ||||||
|  | 
 | ||||||
|  |   .item { | ||||||
|  |     border-bottom: 1px dashed #ebeef5; | ||||||
|  | 
 | ||||||
|  |     &:first-child { | ||||||
|  |       padding-top: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     &:last-child { | ||||||
|  |       border-bottom: none; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | @ -0,0 +1,102 @@ | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <el-form | ||||||
|  |       :model="searchForm" | ||||||
|  |       label-width="80px" | ||||||
|  |       @submit.prevent="fnResetPagination" | ||||||
|  |     > | ||||||
|  |       <el-row> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label="试卷名称" prop="KEYWORDS"> | ||||||
|  |             <el-input v-model="searchForm.KEYWORDS" /> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label-width="10px"> | ||||||
|  |             <el-button type="primary" native-type="submit">搜索</el-button> | ||||||
|  |             <el-button native-type="reset" @click="fnResetPagination"> | ||||||
|  |               重置 | ||||||
|  |             </el-button> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |       </el-row> | ||||||
|  |     </el-form> | ||||||
|  |     <layout-table | ||||||
|  |       v-model:pagination="pagination" | ||||||
|  |       :data="list" | ||||||
|  |       @get-data="fnGetData" | ||||||
|  |     > | ||||||
|  |       <el-table-column label="序号" width="60" fixed="left"> | ||||||
|  |         <template #default="{ $index }"> | ||||||
|  |           {{ serialNumber(pagination, $index) }} | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="试卷名称" prop="EXAMNAME" /> | ||||||
|  |       <el-table-column label="成绩" prop="EXAMSCORE" width="100" /> | ||||||
|  |       <el-table-column label="是否通过" width="100"> | ||||||
|  |         <template #default="{ row }"> | ||||||
|  |           {{ row.RESULT === "0" ? "未通过" : "" }} | ||||||
|  |           {{ row.RESULT === "1" ? "通过" : "" }} | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="正确题数" prop="EXAMQUESTIONRIGHT" width="100" /> | ||||||
|  |       <el-table-column label="错误题数" prop="EXAMQUESTIONWRONG" width="100" /> | ||||||
|  |       <el-table-column label="正确率(%)" prop="ACCURACY" width="100" /> | ||||||
|  |       <el-table-column label="考试时间" width="300"> | ||||||
|  |         <template #default="{ row }"> | ||||||
|  |           {{ row.EXAMTIMEBEGIN + "至" + row.EXAMTIMEEND }} | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="操作" width="80px"> | ||||||
|  |         <template #default="{ row }"> | ||||||
|  |           <el-button | ||||||
|  |             type="primary" | ||||||
|  |             text | ||||||
|  |             link | ||||||
|  |             @click="fnExamDetails(row.STAGEEXAM_ID)" | ||||||
|  |           > | ||||||
|  |             考试详情 | ||||||
|  |           </el-button> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |     </layout-table> | ||||||
|  |     <exam-details | ||||||
|  |       v-model:visible="data.examDetailsDialog.visible" | ||||||
|  |       :info="data.examDetailsDialog.info" | ||||||
|  |     /> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup> | ||||||
|  | import useListData from "@/assets/js/useListData.js"; | ||||||
|  | import { | ||||||
|  |   getClassManagementStudentExamRecordsList, | ||||||
|  |   getClassManagementStudentExamRecordsView, | ||||||
|  | } from "@/request/training_process_management.js"; | ||||||
|  | import { useRoute } from "vue-router"; | ||||||
|  | import { serialNumber } from "@/assets/js/utils.js"; | ||||||
|  | import { reactive } from "vue"; | ||||||
|  | import ExamDetails from "./exam_details.vue"; | ||||||
|  | 
 | ||||||
|  | const route = useRoute(); | ||||||
|  | const { STUDENT_ID, CLASS_ID } = route.query; | ||||||
|  | const { list, pagination, searchForm, fnGetData, fnResetPagination } = | ||||||
|  |   useListData(getClassManagementStudentExamRecordsList, { | ||||||
|  |     otherParams: { STUDENT_ID, CLASS_ID }, | ||||||
|  |   }); | ||||||
|  | const data = reactive({ | ||||||
|  |   examDetailsDialog: { | ||||||
|  |     visible: false, | ||||||
|  |     info: {}, | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | const fnExamDetails = async (STAGEEXAM_ID) => { | ||||||
|  |   const resData = await getClassManagementStudentExamRecordsView({ | ||||||
|  |     STAGEEXAM_ID, | ||||||
|  |   }); | ||||||
|  |   data.examDetailsDialog.info = resData.pd; | ||||||
|  |   data.examDetailsDialog.visible = true; | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped lang="scss"></style> | ||||||
|  | @ -0,0 +1,74 @@ | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <el-form :model="searchForm" label-width="80px" @submit.prevent="fnGetData"> | ||||||
|  |       <el-row> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label="课程名称" prop="CURRICULUMNAME"> | ||||||
|  |             <el-input v-model="searchForm.CURRICULUMNAME" /> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label="小节名称" prop="CHAPTERNAME"> | ||||||
|  |             <el-input v-model="searchForm.CHAPTERNAME" /> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label="学习状态" prop="STATE"> | ||||||
|  |             <el-select v-model="searchForm.STATE"> | ||||||
|  |               <el-option | ||||||
|  |                 v-for="item in stateList" | ||||||
|  |                 :key="item.ID" | ||||||
|  |                 :label="item.NAME" | ||||||
|  |                 :value="item.ID" | ||||||
|  |               /> | ||||||
|  |             </el-select> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |         <el-col :span="6"> | ||||||
|  |           <el-form-item label-width="10px"> | ||||||
|  |             <el-button type="primary" native-type="submit">搜索</el-button> | ||||||
|  |             <el-button native-type="reset" @click="fnGetData"> 重置 </el-button> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-col> | ||||||
|  |       </el-row> | ||||||
|  |     </el-form> | ||||||
|  |     <layout-table :data="list" :show-pagination="false"> | ||||||
|  |       <el-table-column label="序号" width="60" type="index" /> | ||||||
|  |       <el-table-column label="课程名称" prop="CURRICULUMNAME" /> | ||||||
|  |       <el-table-column label="小节名称" prop="CHAPTERNAME" /> | ||||||
|  |       <el-table-column label="学习情况" width="150"> | ||||||
|  |         <template #default="{ row }"> | ||||||
|  |           <span v-if="row.FINISHTIME">已完成</span> | ||||||
|  |           <span v-else-if="row.CREATTIME">学习中</span> | ||||||
|  |           <span v-else>未学习</span> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="开始学习时间" prop="CREATTIME" width="150" /> | ||||||
|  |       <el-table-column label="完成时间" prop="FINISHTIME" width="150" /> | ||||||
|  |       <el-table-column label="最近观看时间" prop="OPERATTIME" width="150" /> | ||||||
|  |     </layout-table> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup> | ||||||
|  | import useListData from "@/assets/js/useListData.js"; | ||||||
|  | import { getClassManagementStudentLearningRecordsList } from "@/request/training_process_management.js"; | ||||||
|  | import { useRoute } from "vue-router"; | ||||||
|  | 
 | ||||||
|  | const route = useRoute(); | ||||||
|  | const { STUDENT_ID, CLASS_ID } = route.query; | ||||||
|  | const stateList = [ | ||||||
|  |   { ID: "-1", NAME: "未学习" }, | ||||||
|  |   { ID: "0", NAME: "学习中" }, | ||||||
|  |   { ID: "1", NAME: "已完成" }, | ||||||
|  | ]; | ||||||
|  | const { list, searchForm, fnGetData } = useListData( | ||||||
|  |   getClassManagementStudentLearningRecordsList, | ||||||
|  |   { | ||||||
|  |     otherParams: { STUDENT_ID, CLASS_ID }, | ||||||
|  |     usePagination: false, | ||||||
|  |   } | ||||||
|  | ); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped lang="scss"></style> | ||||||
|  | @ -143,9 +143,19 @@ | ||||||
|           > |           > | ||||||
|             从本班移除 |             从本班移除 | ||||||
|           </el-button> |           </el-button> | ||||||
|           <el-button v-if="isEdit" type="primary" text link> |           <el-button | ||||||
|  |             v-if="isEdit" | ||||||
|  |             type="primary" | ||||||
|  |             text | ||||||
|  |             link | ||||||
|  |             @click=" | ||||||
|  |               router.push({ | ||||||
|  |                 path: '/training_process_management/class_management/student/learning_records', | ||||||
|  |                 query: { STUDENT_ID: row.STUDENT_ID, CLASS_ID }, | ||||||
|  |               }) | ||||||
|  |             " | ||||||
|  |           > | ||||||
|             学习记录 |             学习记录 | ||||||
|             <!--            TODO --> |  | ||||||
|           </el-button> |           </el-button> | ||||||
|         </template> |         </template> | ||||||
|       </el-table-column> |       </el-table-column> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,38 @@ | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <layout-card> | ||||||
|  |       <el-tabs v-model="active" @tab-change="fnTabChange"> | ||||||
|  |         <el-tab-pane label="学习记录" name="learning_records" lazy> | ||||||
|  |           <learning-records /> | ||||||
|  |         </el-tab-pane> | ||||||
|  |         <el-tab-pane label="考试记录" name="exam_records" lazy> | ||||||
|  |           <exam-records /> | ||||||
|  |         </el-tab-pane> | ||||||
|  |       </el-tabs> | ||||||
|  |     </layout-card> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup> | ||||||
|  | import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router"; | ||||||
|  | import { ref } from "vue"; | ||||||
|  | import LearningRecords from "./components/learning_records.vue"; | ||||||
|  | import ExamRecords from "./components/exam_records.vue"; | ||||||
|  | 
 | ||||||
|  | const router = useRouter(); | ||||||
|  | const route = useRoute(); | ||||||
|  | const defaultName = "learning_records"; | ||||||
|  | const active = ref(route.query.active || defaultName); | ||||||
|  | onBeforeRouteUpdate((to, from, next) => { | ||||||
|  |   active.value = to.query.active || defaultName; | ||||||
|  |   next(); | ||||||
|  | }); | ||||||
|  | const fnTabChange = (active) => { | ||||||
|  |   router.replace({ | ||||||
|  |     path: "/training_process_management/class_management/student/learning_records", | ||||||
|  |     query: { ...route.query, active }, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped lang="scss"></style> | ||||||
		Loading…
	
		Reference in New Issue