| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- <template>
- <!-- 考场名单 -->
- <div class="page_item page_list">
- <div class="search_content">
- <div class="content_left">
- <el-input placeholder="请输入学生姓名" v-model="searchContent" @input="GoSearch" @change="GoSearch()" style="width:240px;" >
- <!-- <el-button @click="GoSearch()" slot="append" icon="el-icon-search"></el-button> -->
- <template #append>
- <el-button :icon="Search" @click="GoSearch()"/>
- </template>
- </el-input>
- </div>
- <div class="content_right el_button">
- <el-button @click="Refresh()" class="refresh_btn"><i class="iconfont icon_shuaxin"></i>刷新</el-button>
- <!-- <el-button @click="ExportExamStudentList()" class="refresh_btn">
- <i class="iconfont icon_export" style="margin-right: 5px;"> </i> 导出
- </el-button> -->
- <!-- <el-button @click="BackToTemplate()" class="other_btn" >重新导入名单</el-button> -->
- <el-button @click="OpenAddStudent()" class="add_student" >新增学生</el-button>
- <el-button @click="BackToScan()" type="primary" >扫描页面</el-button>
- </div>
- </div>
- <div class="page_jg_20"></div>
- <div class="table_content">
- <div class="content_left page_table">
- <el-table :data="examRoomList" style="width: 100%" :height="tableHeight">
- <el-table-column align="center" width="50" prop="examInfo" >
- <template v-slot="scope">
- <el-radio v-model="selectExamRoomCode" :value="scope.row.examRoomCode"></el-radio>
- </template>
- </el-table-column>
- <el-table-column prop="examRoomName" label="班级" width="80" align="center">
- </el-table-column>
- <el-table-column prop="date" label="缺考/学生数" min-width="100" align="center">
- <template v-slot="scope">
- <div class="answer_input">
- {{scope.row.missExamNum}}/{{scope.row.totalStudentNum}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="fullScore" label="异常数" align="center">
- <template v-slot="scope">
- <div class="full_mark_input">
- {{scope.row.abnormalNum}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="已上传/学生数(%)" align="center" width="200" fixed="right">
- <template v-slot="scope">
- <!-- <div class="full_mark_input">
- {{scope.row.uploadedNum}}/{{scope.row.totalStudentNum}}
- <CircleProcess></CircleProcess>
- </div> -->
- <div class="table_row_scan_number">
- <div class="scan_number">
- {{ scope.row.uploadedNum<0?'0':scope.row.uploadedNum }}/{{scope.row.totalStudentNum}}
- </div>
- <div class="scan_progress">
- <div class="scan_progress_circle" >
- <CircleProcess :process="scope.row.uploadedRate"></CircleProcess>
- <span class="span_numbers">{{ scope.row.uploadedRate+'%' }}</span>
- </div>
-
- </div>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="content_right page_table">
- <el-table :data="examStudentList" style="width: 100%" :height="tableHeight">
- <el-table-column type="index" label="序号" width="100" align="center">
- </el-table-column>
- <el-table-column prop="studentCode" label="学号" width="120" align="center">
- </el-table-column>
- <el-table-column prop="fullScore" label="姓名" width="120" align="center">
- <template v-slot="scope">
- <div class="full_mark_input">
- {{scope.row.studentName}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="examCode" label="考号" width="170" align="center">
- <template v-slot="scope">
- {{scope.row.examCode}}
- </template>
- </el-table-column>
- <el-table-column prop="adminClassName" label="行政班" width="120" align="center">
- <template v-slot="scope">
- {{scope.row.adminClassName}}
- </template>
- </el-table-column>
- <el-table-column prop="teachingClassName" label="教学班" width="120" align="center">
- </el-table-column>
- <el-table-column label="状态" min-width="130" align="center">
- <template v-slot="scope">
- <div v-if="scope.row.scannedStatus==3" class="table_row_student_status"><div class="que_icon"></div>缺页</div>
- <div v-if="scope.row.scannedStatus==0" class="table_row_student_status"><div class="no_scan_icon"></div>未扫描</div>
- <div v-if="scope.row.scannedStatus==1" class="table_row_student_status"><div class="upload_icon"></div>已上传</div>
- <div v-if="scope.row.scannedStatus==2" class="table_row_student_status"><div class="qk_icon"></div>缺考</div>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="操作" align="center" width="150" fixed="right">
- <template v-slot="scope">
- <div class="table_row_option" >
- <div class="button_editor" @click="EditorStudent(scope.row)">
- 编辑
- </div>
- <!-- 逻辑 有图片的才能查看 无图片的不能查看 -->
- <div class="button_editor" v-if="scope.row.scanPictureVOS && scope.row.scanPictureVOS.length>0" @click="OpenImage(scope.row)">
- 查看
- </div>
- <div class="editor_disable" v-else>
- 查看
- </div>
- <div class="button_delete" @click="ConfirmDelete(scope.row)" v-if="scope.row.scannedStatus==0">
- 删除
- </div>
- <div class="editor_disable" v-else>
- 删除
- </div>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <div class="page_jg_20"></div>
- <div class="page_bottom">
- <div class="bottom_left">
- 班级数:<span class="span_number">{{examInfo.classCount}}个</span>
- 学生总数:<span class="span_number">{{examInfo.totalStudentCount}}个</span>
- 缺考人数:<span class="span_number">{{examInfo.missCount}}个</span>
- 已扫描学生:<span class="span_red">{{examInfo.uploadedCount}}个</span>
- 扫描进度:<span class="span_red">{{examInfo.scanRate}}%</span>
- </div>
- <div class="bottom_right">
- 当前选中班级:<span class="span_number">{{selectExamRoomName}}</span> 学生数:<span class="span_number">{{examStudentList.length }}</span>人
- </div>
- </div>
- <AddStudent ref="addStudentRef" v-model="showAddStudent" :selectSchoolId="selectSchoolId" @success="HandleSuccess" />
- <PaperPreview v-model="showPaperPreview" :imageList="previewImageList" :showDraw="true" :answerData="[]"></PaperPreview>
- </div>
- </template>
- <script lang="ts" setup>
- import { getExamRoomList,getExamRoomStudentList,deleteExamRoomStudent,getClassListData} from '@/api/exam'
- import { useExamStore } from '@/store/exam'
- import { useRouter } from 'vue-router'
- import { onMounted, onUnmounted, ref, nextTick,computed, watch } from 'vue';
- import { ElMessageBox, ElMessage } from 'element-plus'
- import AddStudent from './components/addStudent.vue' // 新增学生弹窗
- import PaperPreview from '@/views/exam/components/PaperPreview.vue';//试卷预览
- import CircleProcess from '@/views/exam/components/CircleProcess.vue'//圆形进度条
- import { Search } from '@element-plus/icons-vue'
- // 实例化 Store
- const examStore = useExamStore()
- const router = useRouter()
- const examRoomList=ref<any[]>([]);//考场列表
- const examStudentList=ref<any[]>([]);//考场学生列表
- const selectSchoolId=ref(0);
- const searchContent=ref('');//搜索内容
- const selectExamRoomCode=ref('');//选择的考场code
- const selectExamRoomName=ref('');//选择的考场名称
- const showAddStudent=ref(false);//是否显示新增学生弹窗
- const currentEditItem=ref<any>(null);//当前编辑的学生数据
- const addStudentRef = ref<any>(null);//新增学生弹窗实例
- const teachingClassList = ref<any[]>([]);
- const adminClassList = ref<any[]>([]);
- const studentTypeList=ref<any[]>([]);
- const showPaperPreview=ref(false);//是否显示图片预览
- const previewImageList=ref<any[]>([]);//预览图片列表
- const tableHeight=ref(400);//表格高度
- const examInfo=ref({
- classCount:0,//班级数
- totalStudentCount:0,//学生总数
- missCount:0,//缺考人数
- uploadedCount:0,//已上传学生数
- abnormalCount:0,//异常数
- scanRate:0,//扫描进度
- });
- // 考试科目 ID
- const examSubjectId = computed(() => {
- return examStore.currentExam?.id
- })//计算属性
- //学校id
- const schoolId = computed(() => {
- return examStore.currentExam?.schoolInfoId || 0
- })
- //刷新
- const Refresh = () => {
- examRoomList.value=[];
- examStudentList.value=[];
- GetExamRoomList();//获取考场列表
- }
- // 返回到扫描界面
- const BackToScan = () => {
- router.push({
- path: '/exam/scanList',
- query: {
- examSubjectId: examSubjectId.value,
- },
- });
- }
- // 监听选择的考场代码变化,自动更新考场名称
- watch(selectExamRoomCode, (newCode) => {
- // 在考场列表中查找匹配的项
- const selectedRoom = examRoomList.value.find((room: any) => room.examRoomCode === newCode);
-
- if (selectedRoom) {
- selectExamRoomName.value = selectedRoom.examRoomName;
- console.log('当前选中考场:', selectExamRoomName.value);
-
- // 可选:如果切换考场需要重新获取学生列表,可以在这里调用
- GetExamRoomStudentList();
- } else {
- selectExamRoomName.value = '';
- }
- });
- //搜索
- const GoSearch=()=>{
- console.log('搜索内容:', searchContent.value);
- GetExamRoomStudentList();
- }
- //重新导入名单
- const BackToTemplate =() =>
- {
-
- ElMessageBox.confirm('确认重新导入名单吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- customClass: 'page_dialog',
- }).then(() => {
- router.push({
- path: '/exam/selectExamination',
- query: {
- id: examSubjectId.value,
- reuse: 1,
- // schoolId: selectSchoolId.value,
- }
- })
- // router.push({
- // path: '/exam/selectExamination',
- // query: {
- // examSubjectId: examSubjectId.value,
- // },
- // });
- }).catch(() => {
- // 用户取消操作
- })
- }
- //导出学生名单
- const ExportExamStudentList=()=>
- {
- }
- //新增学生
- const OpenAddStudent=()=>{
- showAddStudent.value=true;
- }
- //编辑学生
- const EditorStudent=async (row:any)=>{
- console.log("打印编辑学生信息", row);
- if (addStudentRef.value) {
- addStudentRef.value.EditorStudent(row);
- }
- // 打开弹窗并传递编辑数据
- showAddStudent.value = true;
- }
- //编辑或者新增学生弹窗成功消息
- const HandleSuccess=() => {
-
- }
- //查看图片
- const OpenImage = (item: any) => {
- if (item.scanPictureVOS && item.scanPictureVOS.length > 0) {
- console.log("查看图片item", item);
- showPaperPreview.value = true;
- let imgList = [];
- item.scanPictureVOS.forEach((item: any) => {
- let obj = {
- url: item.recognizeUrl,
- };
- imgList.push(obj);
- });
- previewImageList.value = imgList;
- } else {
- ElMessage({
- type: 'info',
- message: '没有图片'
- });
- }
- };
- //获取考试班级列表
- const GetClassListData = () => {
- let param = {
- examSubjectId: examSubjectId.value,
- schoolId: schoolId.value,
- }
-
- getClassListData(param).then((res: any) => {
- if (res.code == 200) {
- adminClassList.value = res.data.adminClassSelect || []
- teachingClassList.value = res.data.teachClassSelect || []
- studentTypeList.value = res.data?.studentType || []
- examRoomList.value = res.data.examRoomSelect || []
- }
- })
- }
- //删除学生
- const ConfirmDelete=(row:any)=>{
- console.log('删除',row);
- let msg = `确定要删除当前选择的学生<span style="color:#F56C6C;font-weight:600;">「${row.studentName}」</span>吗?`;
- ElMessageBox.confirm(msg, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- dangerouslyUseHTMLString: true,
- customClass:'page_dialog'
- }).then(async () => {
- console.log('删除学生')
- const param={
- id:row.id,
- };
- const res = await deleteExamRoomStudent(param);
- console.log('删除结果:', res);
- if (res.code === 200) {
- ElMessage.success('删除成功');
- GetExamRoomStudentList();
- }
- else
- {
- ElMessage.error('删除失败!'+res.msg);
- }
-
- })
- }
- //获取考场列表
- const GetExamRoomList = async () => {
- try {
- const params={
- examSubjectId:examSubjectId.value,
- schoolId:schoolId.value,
- };
- const res = await getExamRoomList(params);
- if (res.code === 200) {
- examRoomList.value = res.data.examRoomTblVOS;
- console.log('打印考场列表',res);
- let allExamRoomItem={
- abnormalNum: 0,//异常数据
- examRoomCode:'',//考场编号
- examRoomName:'全部',//考场名称
- examRoomSort:'',//考场排序
- missExamNum:res.data.totalMissExamNum,//缺考学生数量
- totalStudentNum:res.data.totalStudentNum,//总学生数量
- uploadedNum:res.data.totalUploadedNum,//已上传学生数量
- uploadedRate:res.data.totalUploadRate,//上传进度
- };//第一条全部数据
- examRoomList.value.unshift(allExamRoomItem);//添加第一条数据
- selectExamRoomCode.value=examRoomList.value[0].examRoomCode;
- selectExamRoomName.value=examRoomList.value[0].examRoomName;
- // selectExamRoomNum.value=examRoomList[0].totalStudentNum;
- examInfo.value={
- classCount:res.data.examRoomNum,//班级数
- totalStudentCount:res.data.totalStudentNum,//学生总数
- missCount:res.data.totalMissExamNum,//缺考人数
- uploadedCount:res.data.totalUploadedNum,//已上传学生数
- abnormalCount:0,//异常数
- scanRate:res.data.totalUploadRate,//扫描进度
- };
- GetExamRoomStudentList();
- }
- console.log('考场列表', res);
- } catch (error) {
- console.error('获取考场列表失败', error);
- }
- };
- //获取扫描考场的学生列表
- const GetExamRoomStudentList = async () => {
- try {
- const params = {
- examSubjectId:examSubjectId.value,
- schoolId:schoolId.value,
- examRoomCode:selectExamRoomCode.value,
- studentName:searchContent.value,//学生姓名搜索
- pageNum:1,
- pageSize:1000,
- };
- console.log('获取考场学生列表参数', params); // 打印参数
- const res = await getExamRoomStudentList(params);
- if (res.code === 200)
- {
- examStudentList.value = res.data.records;
- }
- console.log('获取考场学生列表成功', res);
- } catch (error) {
- console.error('获取考场学生列表失败', error);
- return error;
- }
- }
- //计算高度的函数
- const CalculateTableHeight = () => {
- // nextTick 确保 DOM 更新后再获取尺寸
- nextTick(() => {
- // window.innerHeight 是浏览器可视区域高度
- // 简单算法:视窗高度 - 固定占用高度
- let computedHeight = window.innerHeight - 40 - 20 - 36 - 20 - 65;
-
- // 限制最小高度,防止太矮
- if (computedHeight < 200) {
- computedHeight = 200;
- }
- tableHeight.value = computedHeight;
- });
- };
- onMounted(() => {
-
- if (!examStore.currentExam) {
- console.warn('当前没有选中的考试信息')
- // 可选:如果没有数据,可以重定向回列表页或提示用户
-
- }
- GetExamRoomList();//获取考场列表
-
- // 初始化计算
- CalculateTableHeight();
-
- // 监听窗口大小变化
- window.addEventListener('resize', CalculateTableHeight);
- })
- // 卸载时移除监听,防止内存泄漏
- onUnmounted(() => {
- window.removeEventListener('resize', CalculateTableHeight);
- });
- </script>
-
- <style lang="scss" scoped>
- .table_content
- {
- width: 100%;
- display: flex;
- justify-content: space-between;
- height: calc(100vh - 140px - 40px);
- .content_left
- {
- width: 35%;
- height: 100%;
- }
- .content_right
- {
- width: calc(65% - 20px);
- height: 100%;
- }
- }
- //扫描进度
- .table_row_scan_number
- {
- display: flex;
- justify-content: space-between;
- font-weight: 400;
- font-size: 14px;
- color: #666666;
- width:calc(100% - 36px);
- height: 52px;
- line-height: 52px;
- margin: auto;
- .scan_number
- {
- width: 50%;
- }
- .scan_progress
- {
- width: 50%;
- .scan_progress_circle
- {
- display: flex;
- justify-content: flex-start;
- }
- .span_numbers
- {
- margin-left: 10px;
-
- }
- }
- }
- .span_number
- {
- font-weight: 600;
- font-size: 16px;
- color: #333;
- }
- </style>
|