瀏覽代碼

扫描学生 编辑考场名单 新增学生 编辑学生功能更新

dengshaobo 1 月之前
父節點
當前提交
981a12d253

+ 30 - 1
src/api/exam.ts

@@ -380,4 +380,33 @@ export const setExamNumberPosition= (data:any):Promise<ApiResponse> => {
     method: 'post',
     data
   })
-}
+}
+
+// 42. 扫描学生 新增学生 搜索学生信息
+export const getExamStudentInfo= (data:any):Promise<ApiResponse> => {
+  data.useNew=1;
+  return request({
+    url: '/api/v1/pc_student/find_student_by_code',
+    method: 'get',
+    params: data
+  })
+}
+
+// 43. 扫描学生 新增学生 获取考场页面编辑弹窗里面的考场行政班教学班下拉列表数据
+export const getClassListData= (data:any):Promise<ApiResponse> => {
+  return request({
+    url: '/api/v1/ai_exam_room/find_multi_select_data',
+    method: 'get',
+    params:data
+  })
+}
+
+// 44. 扫描学生 新增学生 添加学生   修改学生信息
+
+export const updateExamStudentInfo= (data:any):Promise<ApiResponse> => {
+  return request({
+    url: '/api/v1/ai_exam_room/save_update_scan_student',
+    method: 'post',
+    data
+  })
+}

二進制
src/assets/icon/fit_screen_default.png


+ 13 - 4
src/styles/common.scss

@@ -1953,8 +1953,6 @@ body {
       display: flex;
       align-items: center;
       font-size: 16px;
-      min-height: 40px;
-
       .upload_file_name {
         margin-left: 10px;
         line-height: 20px;
@@ -1966,6 +1964,10 @@ body {
       .score {
         padding-left: 5px;
       }
+      .el-select
+      {
+        width: 240px;
+      }
 
       // 下拉选择框 中间箭头上下居中
       .el-select .el-input .el-select__caret {
@@ -1984,6 +1986,10 @@ body {
 
       .el-input {
         width: 240px;
+        .el-input__wrapper
+        {
+          padding: 0;
+        }
       }
 
       .check_select {
@@ -1997,6 +2003,7 @@ body {
         height: 36px;
         line-height: 36px;
         font-size: 14px;
+        padding: 0 10px;
       }
 
       .el-input--mini {
@@ -2097,11 +2104,13 @@ body {
 
     .el-form-item {
       // margin-bottom: 15px !important;
-      min-height: 40px;
+      min-height: 36px;
       .el-form-item__label {
         font-size: 16px !important;
         padding: 0 !important;
         color: #666666;
+        height: 36px;
+        line-height: 36px;
       }
 
       .el-checkbox__label {
@@ -3601,7 +3610,7 @@ body {
     color: #666666;
 
     text-align: center;
-    background-image: url("../assets/icon/fit_screen_default.png");
+    background-image: url("../assets/icon/fit_screen_default.PNG");
     background-size: 16px 16px;
     background-position: 8px 50%;
     background-repeat: no-repeat;

+ 48 - 3
src/views/exam/abnormal/abnormal.vue

@@ -31,7 +31,7 @@
                 </div> -->
             </div>
             <div class="nav_button el_button">
-                <div :class="isShowDraw?'is_draw_data':'is_draw_active'" @click="ShowDrawData()" v-if="abnormalType==4">显示画框</div>
+                <!-- <div :class="isShowDraw?'is_draw_data':'is_draw_active'" @click="ShowDrawData()" v-if="abnormalType==4">显示画框</div> -->
                 <el-select  v-if="abnormalType==6" style="width: 100px;" v-model="isShowDrawType" placeholder="显示类型" @change="SubjectDataChange()">
                     <el-option label="答题卡" value="1"></el-option>
                     <el-option label="划分区" value="2"></el-option>
@@ -279,7 +279,7 @@
                     <el-table-column align="center" prop="adminClassName" width="65"  label="班级" show-overflow-tooltip></el-table-column>
                 </el-table>
                 <div class="right_title">
-                    <div >客观题异常处理
+                    <div >客观题异常处理  
                         <span @click="ClearValue()"  class="clear_value">清空</span>
                     </div>
                     
@@ -472,7 +472,7 @@ const AbnormalChanage = (type: number) => {
     abnormalType.value = type
     // TODO: 加载对应类型的异常列表数据
     console.log('切换异常类型:', type)
-    
+    ClearCurrentData();//先清空数据
     //定位异常处理
     if(type==2)
     {
@@ -540,12 +540,15 @@ const ClearCurrentData = () => {
     currentPaperList.value=[];//试卷图片列表
     currentPaperUrl.value="";//当前图片地址
     currentQuestionList.value=[];//清空客观题数据
+    currentDrawData.value=[];//清空画框数据
 }
 
 // 2. 刷新异常列表
 const RefreshAbnormalList = () => {
     // TODO: 调用接口刷新当前 abnormalType 的数据
     console.log('刷新列表')
+    ClearCurrentData();
+    GetAbnormalList();
 }
 
 // 3. 适应屏幕
@@ -558,6 +561,7 @@ const FitScreen = () => {
 const ShowDrawData = () => {
     isShowDraw.value = !isShowDraw.value
     // TODO: 更新 ActionImage 的 drawData 显示状态
+    
 }
 
 // 5. 客观题答案回显数据设置切换  客观题数据处理 客观题回显
@@ -841,6 +845,18 @@ const TableRowClassName = ({ row, rowIndex }: any) => {
 // 14. 客观题表格行样式
 const ObjectTableClassName=({ row, rowIndex }: any) => { 
 
+    // 检查当前行是否为异常题目
+    if(row.hasAbnormal==1)
+    {
+            console.log("客观题异常hasAbnormal的列是",row.objectiveName);
+        //异常的背景显示红色
+            return 'selected_row';
+    }
+    else
+    {
+        return '';
+    }
+
 }
 
 // 15. 获取批次号显示
@@ -1221,6 +1237,19 @@ const ChangeTab = (tab: string) => {
 const ClearValue = () => {
     // TODO: 清空当前题目的选择
     console.log('清空')
+
+    currentQuestionList.value.forEach(item => {
+        item.selectValue = '';
+    });
+    const obj=currentQuestionList.value.reduce((acc,item)=>{
+        acc[item.objectiveQuestionNum]=item.selectValue
+        return acc
+    },{});
+    console.log("打印新的答案对象",obj);
+    // this.objectData.jsonObj=JSON.stringify(obj);
+    // this.currentItem.objectiveQuestionVOS=this.objectData.jsonObj;
+    // console.log("打印新的答案字符串",this.objectData.jsonObj);
+    ObjectDataChange();//客观题数据处理
 }
 
 // 28. 客观题 - 选项转换辅助
@@ -1581,4 +1610,20 @@ const CalculateTableHeight = () => {
 {
     height: 100% !important;
 }
+
+.clear_value
+{
+    margin-left: 10px;
+    // text-emphasis-style: dot;        /* 实心小圆点 • */
+        // text-emphasis-style: circle;     /* 空心圆圈 ○ */
+        // text-emphasis-style: double-circle; /* 双圆圈 ◉ */
+        // text-emphasis-style: triangle;   /* 三角形 ▲ */
+
+        /* 自定义字符 */
+        // text-emphasis-style: '★';        /* 使用星号 */
+    text-emphasis-style: '※';       /* 使用参考标记 */
+    text-emphasis-color: red;
+    text-emphasis-position: under; /* 下方居中 */
+    cursor: pointer;
+}
 </style>

+ 1 - 0
src/views/exam/abnormalDetail.vue

@@ -152,6 +152,7 @@ const ScanStateChange=(state:number)=>{
 //关闭弹窗
 const CloseDialog = () => {
     showDialog.value = false;
+    emit('success');
 }
 
 

+ 466 - 0
src/views/exam/components/addStudent.vue

@@ -0,0 +1,466 @@
+<template>
+  <el-dialog
+    :title="studentDialogTitle"
+    v-model="showDialog"
+    :modal-append-to-body="false"
+    append-to-body
+    center
+    class="page_dialog"
+    width="480px"
+  >
+    <div class="dialog_center">
+      <el-form
+        :model="addStudentData"
+        ref="addStudentFormRef"
+        :rules="addStudentDataRules"
+        label-width="120px"
+      >
+        <el-form-item
+          label="学校:"
+          prop="schoolId"
+          v-if="schoolType == 1 && studentDialogTitle == '新增学生'"
+        >
+          <el-select
+            v-model="addStudentData.schoolId"
+            style="margin-right: 10px"
+            placeholder="选择学校"
+            :disabled="selectSchoolId != '-1'"
+            class="select_width"
+            v-if="schoolType == 1"
+            @change="AddChangeSchool"
+          >
+            <el-option
+              v-for="item in schoolList"
+              :key="item.schoolCode"
+              :label="item.schoolNickName || item.schoolName"
+              :value="item.schoolId"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="学号:" prop="studentCode">
+          <el-input
+            v-model="addStudentData.studentCode"
+            placeholder=""
+            @change="GetSchoolUserInfos"
+            :disabled="studentDialogTitle == '编辑学生'"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="姓名:" prop="studentName">
+          <el-input v-model="addStudentData.studentName" placeholder=""></el-input>
+        </el-form-item>
+        <el-form-item label="考号:" prop="exCode">
+          <el-input v-model="addStudentData.examCode" placeholder=""></el-input>
+        </el-form-item>
+        <el-form-item label="考场:" prop="examRoomCode">
+          <el-select  v-model="addStudentData.examRoomCode"  placeholder="请选择">
+            <el-option  v-for="(item, index) in examRoomList"  :key="'exam_room_' + index"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="行政班:" prop="adminClassIdCode">
+          <el-select
+            v-model="addStudentData.adminClassIdCode"
+            @change="ChangeAdminClass"
+            placeholder="请选择">
+            <el-option
+              v-for="(item, index) in adminClassList"
+              :key="'admin_class_' + index"
+              :label="item.className"
+              :value="item.classIdCode"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item
+          label="教学班:"
+          v-if="teachingClassList.length > 0"
+          prop="teachingClassIdCode"
+        >
+          <el-select
+            v-model="addStudentData.teachingClassIdCode"
+            @change="ChangeTeachingClass"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="(item, index) in teachingClassList"
+              :key="'teaching_class_' + index"
+              :label="item.className"
+              :value="item.classIdCode"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="学生类型:"
+          v-if="studentTypeList.length > 0"
+          prop="registrationTypeCode"
+        >
+          <el-select
+            v-model="addStudentData.registrationTypeCode"
+            @change="ChangeStudentType"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="(item, index) in studentTypeList"
+              :key="'teaching_class_' + index"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+    </div>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="showDialog = false">取 消</el-button>
+        <el-button type="primary" @click="EnterStudent()" :loading="loadingSubmit"
+          >确 定</el-button
+        >
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { useExamStore } from '@/store/exam'
+import { useUserStore } from '@/store/user'
+import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue'
+import { ElMessage } from 'element-plus'
+// 假设你有这些 API 导入,请根据实际路径调整
+import { getExamStudentInfo, getClassListData, updateExamStudentInfo } from '@/api/exam'
+// 假设你使用 Pinia 或 Vuex,这里需要引入对应的 store
+// import { useMakeTemplateStore } from '@/store/makeTemplate'
+// import { useUserStore } from '@/store/user'
+// 实例化 Store
+const examStore = useExamStore()
+// 定义 Props
+const props = defineProps<{
+  modelValue: boolean
+  selectSchoolId: string | number
+}>()
+
+// 定义 Emits
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void
+  (e: 'SaveSuccess'): void
+}>()
+
+// 双向绑定 showDialog
+const showDialog = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val),
+})
+
+// --- Store 数据模拟 (请根据你的实际 Store 实现替换) ---
+// const makeTemplateStore = useMakeTemplateStore()
+// const userStore = useUserStore()
+
+// 临时模拟 store 数据,实际使用时请取消注释上面的 store 并使用下面的计算属性
+const mockSchoolList = ref([]) 
+const mockExamTempDetail = ref({
+  examId: '',
+  id: '',
+  courseName: '',
+  courseCode: ''
+})
+
+const mockUserSchoolType = ref(0)
+
+const schoolList = computed(() => mockSchoolList.value) // 实际: makeTemplateStore.schoolList
+const examId = computed(()=>{
+  return examStore.currentExam?.id
+}) // 实际: makeTemplateStore.examTempDetail.examId
+// 考试科目 ID
+const examSubjectId = computed(() => {
+  return examStore.currentExam?.id
+})//计算属性
+
+const schoolYearCode = computed(() => {
+  return examStore.currentExam?.schoolYearCode
+})//计算属性
+
+// 学校 ID
+const schoolId= computed(() => {
+  return examStore.currentExam?.schoolInfoId
+})
+
+
+const schoolType = computed(() => mockUserSchoolType.value) // 实际: userStore.schoolType
+const currentCourseCode = computed(() => mockExamTempDetail.value.courseCode) // 实际: makeTemplateStore.examTempDetail.courseCode
+
+// --- 响应式数据 ---
+const studentDialogTitle = ref('新增学生')
+const loadingSubmit = ref(false)
+const addStudentFormRef = ref<any>(null)
+
+const addStudentData = reactive({
+  id: '',
+  schoolId: '',
+  studentName: '',
+  studentRegistrationCode: '',
+  studentCode: '',
+  examCode: '',
+  examRoomCode: '',
+  adminClassIdCode: '',
+  adminClassName: '',
+  adminClassSort: '',
+  teachingClassIdCode: '',
+  teachingClassName: '',
+  teachingClassSort: '',
+  registrationTypeCode: '',
+  registrationTypeName: '',
+})
+
+const addStudentDataRules = {
+  studentCode: [{ required: true, message: '请输入学号', trigger: 'change' }],
+  examCode: [{ required: true, message: '请输入考号', trigger: 'change' }],
+  studentName: [{ required: true, message: '请输入姓名', trigger: 'change' }],
+  adminClassIdCode: [{ required: true, message: '请选择行政班', trigger: 'change' }],
+  teachingClassIdCode: [{ required: true, message: '请选择教学班', trigger: 'change' }],
+}
+
+const studentTypeList = ref<any[]>([])
+const examRoomList = ref<any[]>([])
+const adminClassList = ref<any[]>([])
+const teachingClassList = ref<any[]>([])
+
+// --- Watch ---
+watch(
+  () => props.modelValue,
+  (newVal) => {
+    if (newVal) {
+      if (props.selectSchoolId != -1) {
+        addStudentData.schoolId = props.selectSchoolId as any 
+        GetClassListData()
+      }
+    }
+  }
+)
+
+// --- Methods ---
+
+const AddChangeSchool = () => {
+  if (props.selectSchoolId != -1) {
+    addStudentData.schoolId = props.selectSchoolId as any
+  }
+  let schoolId = addStudentData.schoolId
+  GetClassListData()
+}
+
+const AddStudent = () => {
+  studentDialogTitle.value = '新增学生'
+  resetFormData()
+  showDialog.value = true
+}
+
+//编辑学生
+const EditorStudent = (studentData: any) => {
+  console.log('打印传过来的编辑的学生信息', studentData)
+  studentDialogTitle.value = '编辑学生'
+  
+  Object.assign(addStudentData, {
+    id: studentData.id || '',
+    schoolId: studentData.schoolId || '',
+    studentName: studentData.studentName || '',
+    studentRegistrationCode: studentData.studentRegistrationCode || '',
+    studentCode: studentData.studentCode || '',
+    examCode: studentData.examCode || '',
+    examRoomCode: studentData.examRoomCode || '',
+    adminClassIdCode: studentData.adminClassIdCode || '',
+    adminClassName: studentData.adminClassName || '',
+    adminClassSort: studentData.adminClassSort,
+    teachingClassIdCode: studentData.teachingClassIdCode || '',
+    teachingClassName: studentData.teachingClassName || '',
+    teachingClassSort: studentData.teachingClassSort || '',
+    registrationTypeCode: studentData.registrationTypeCode || '',
+    registrationTypeName: studentData.registrationTypeName || '',
+  })
+  
+  GetClassListData()
+  showDialog.value = true
+}
+
+const resetFormData = () => {
+  Object.assign(addStudentData, {
+    id: '',
+    schoolId: '',
+    studentName: '',
+    studentRegistrationCode: '',
+    studentCode: '',
+    exCode: '',
+    examRoomCode: '',
+    adminClassIdCode: '',
+    adminClassName: '',
+    adminClassSort: '',
+    teachingClassIdCode: '',
+    teachingClassName: '',
+    teachingClassSort: '',
+    registrationTypeCode: '',
+    registrationTypeName: '',
+  })
+}
+
+const ChangeAdminClass = () => {
+  const classItem = adminClassList.value.find(
+    (item) => item.classIdCode === addStudentData.adminClassIdCode
+  )
+  if (classItem) {
+    addStudentData.adminClassName = classItem.className
+    addStudentData.adminClassSort = classItem.classCode
+  }
+}
+
+const ChangeTeachingClass = () => {
+  const classItem = teachingClassList.value.find(
+    (item) => item.classIdCode === addStudentData.teachingClassIdCode
+  )
+  if (classItem) {
+    addStudentData.teachingClassName = classItem.className
+    addStudentData.teachingClassSort = classItem.classCode
+  }
+}
+
+const ChangeStudentType = () => {
+  const classItem = studentTypeList.value.find(
+    (item) => item.value === addStudentData.registrationTypeCode
+  )
+  if (classItem) {
+    addStudentData.registrationTypeName = classItem.label
+  }
+}
+
+//获取考试学生信息
+const GetSchoolUserInfos = () => {
+  let params = {
+    studentCode: addStudentData.studentCode,
+    schoolYearCode: schoolYearCode.value,
+    schoolId: schoolId.value,
+  }
+  
+  getExamStudentInfo(params).then((res: any) => {
+    if (res.code == 200 && res.data) {
+      let teachingClassIdCode = ''
+      if (res.data.classTblVOS && res.data.classTblVOS.length > 0) {
+        const foundItem = res.data.classTblVOS.find(
+          (item: any) => item.courseCode == currentCourseCode.value
+        )
+        if (foundItem) {
+          teachingClassIdCode = foundItem.classIdCode
+        }
+      }
+
+      const teachingclassItem = teachingClassList.value.find(
+        (classItem) => classItem.classIdCode == teachingClassIdCode
+      )
+      const adminClassItem = adminClassList.value.find(
+        (classItem) => classItem.classIdCode == res.data.adminClassIdCode
+      )
+
+      Object.assign(addStudentData, {
+        id: '',
+        schoolId: res.data.schoolId,
+        studentName: res.data.studentName || '',
+        studentRegistrationCode: res.data.registrationCode,
+        studentCode: res.data.studentCode,
+        exCode: res.data.examCode,
+        examRoomCode: '',
+        adminClassIdCode: res.data.adminClassIdCode,
+        adminClassName: adminClassItem?.className,
+        adminClassSort: adminClassItem?.classCode,
+        teachingClassIdCode: teachingClassIdCode || '',
+        teachingClassName: teachingclassItem?.className || '',
+        teachingClassSort: teachingclassItem?.classCode || '',
+        registrationTypeCode: res.data.registrationTypeCode,
+        registrationTypeName: res.data.registrationTypeName,
+      })
+    } else {
+      addStudentData.studentCode = ''
+      ElMessage.error('没有查询到相关数据,请先去个人中心维护!')
+    }
+  })
+}
+
+//获取考试班级列表
+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 EnterStudent = () => {
+  // 表单验证
+  if (!addStudentFormRef.value) return
+  
+  addStudentFormRef.value.validate((valid: boolean) => {
+    if (!valid) return
+
+    if (addStudentData.studentRegistrationCode == '') {
+      ElMessage.error('该学生基础数据不存在,请到个人中心添加!')
+      return
+    }
+
+    let param = {
+      id: addStudentData.id,
+      schoolId: schoolId.value,
+      examId: examId.value,
+      examSubjectId: examSubjectId.value,
+      studentName: addStudentData.studentName,
+      studentRegistrationCode: addStudentData.studentRegistrationCode,
+      studentCode: addStudentData.studentCode,
+      examRoomCode: addStudentData.examRoomCode,
+      examCode: addStudentData.examCode,
+      adminClassIdCode: addStudentData.adminClassIdCode,
+      adminClassName: addStudentData.adminClassName,
+      adminClassSort: addStudentData.adminClassSort,
+      teachingClassIdCode: addStudentData.teachingClassIdCode,
+      teachingClassName: addStudentData.teachingClassName,
+      teachingClassSort: addStudentData.teachingClassSort,
+      registrationTypeCode: addStudentData.registrationTypeCode,
+      registrationTypeName: addStudentData.registrationTypeName,
+    }
+    
+    loadingSubmit.value = true
+    updateExamStudentInfo(param).then((res: any) => {
+      loadingSubmit.value = false
+      if (res.code == 200) {
+        emit('SaveSuccess')
+        ElMessage.success('保存成功')
+        showDialog.value = false
+      } else {
+        ElMessage.error('保存失败!' + res.msg)
+      }
+    })
+  })
+}
+
+// 暴露方法给父组件(如果需要)
+defineExpose({
+  AddStudent,
+  EditorStudent,
+})
+
+onMounted(() => {
+  if (props.selectSchoolId) {
+    GetClassListData()
+  } else {
+    GetClassListData(0)
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+/* 保持原有样式 */
+</style>

+ 101 - 2
src/views/exam/examList.vue

@@ -124,14 +124,16 @@
             当前选中班级:{{selectExamRoomName}}  学生数: {{examStudentList.length }}人
         </div>
     </div>
+    <AddStudent ref="addStudentRef"  v-model="showAddStudent" :selectSchoolId="selectSchoolId" @success="HandleSuccess" />
   </div>
 </template>
 <script lang="ts" setup>
-import { getExamRoomList,getExamRoomStudentList,deleteExamRoomStudent} from '@/api/exam'
+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' // 新增学生弹窗
 // 实例化 Store
 const examStore = useExamStore()
 const router = useRouter()
@@ -142,6 +144,14 @@ 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 tableHeight=ref(400);//表格高度
 const examInfo=ref({
     classCount:0,//班级数
@@ -157,8 +167,9 @@ const examSubjectId = computed(() => {
   return examStore.currentExam?.id
 })//计算属性
 
+//学校id
 const schoolId = computed(() => {
-    return examStore.currentExam?.schoolId || 0
+    return examStore.currentExam?.schoolInfoId || 0
 })
 
 //刷新
@@ -206,6 +217,94 @@ const GoSearch=()=>{
 }
 
 
+//新增学生
+const OpenAddStudent=()=>{
+    showAddStudent.value=true;
+}
+
+//编辑学生
+const EditorStudent=async (row:any)=>{
+    console.log('编辑',row);
+
+     // 获取班级列表数据
+    await GetClassListData();
+    
+    // 准备编辑数据
+    let teachingClassSort = null;
+    let adminClassSort = null;
+    
+    console.log("打印学生信息", row);
+    console.log("打印教学班列表", teachingClassList.value);
+    console.log("打印行政班列表", adminClassList.value);
+
+    const teachingclassItem = teachingClassList.value.find(
+        (classItem: any) => classItem.classIdCode == row.teachingClassIdCode
+    );
+    const adminClassItem = adminClassList.value.find(
+        (classItem: any) => classItem.classIdCode == row.adminClassIdCode
+    );
+    
+    console.log("打印教学班匹配项", teachingclassItem);
+    if (teachingclassItem) {
+        teachingClassSort = teachingclassItem.sort;
+    }
+    
+    console.log("打印行政班匹配项", adminClassItem);
+    if (adminClassItem) {
+        adminClassSort = adminClassItem.classCode;
+    }
+
+    // 设置当前编辑的数据
+    currentEditItem.value = {
+        id: row.id, //主键id
+        schoolId: row.schoolId, //学校id
+        studentName: row.studentName, //姓名
+        studentRegistrationCode: row.studentRegistrationCode, //账号
+        studentCode: row.studentCode, //学号
+        examCode: row.examCode, //考号
+        examRoomCode: row.examRoomCode, //考场编号
+        adminClassIdCode: row.adminClassIdCode, //行政班code
+        adminClassName: row.adminClassName, //行政班名称
+        adminClassSort: adminClassSort, //行政班排序
+        teachingClassIdCode: row.teachingClassIdCode, //教学班code
+        teachingClassName: row.teachingClassName, //教学班名称
+        teachingClassSort: teachingClassSort, //教学班排序
+        registrationTypeCode: row.registrationTypeCode,
+        registrationTypeName: row.registrationTypeName
+    };
+    
+    console.log("打印编辑学生信息", currentEditItem.value);
+    if (addStudentRef.value) {
+        addStudentRef.value.EditorStudent(currentEditItem.value);
+    }
+    
+    // 打开弹窗并传递编辑数据
+    showAddStudent.value = true;
+}
+
+//编辑或者新增学生弹窗成功消息
+const HandleSuccess=() => { 
+   
+}
+
+
+//获取考试班级列表
+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);

+ 1 - 1
src/views/exam/question.vue

@@ -568,7 +568,7 @@ onUnmounted(() => {
         {
             width: 88px;
             height: 34px;
-            line-height: 36px;
+            line-height: 34px;
             text-align: center;
             border-radius: 4px 4px 4px 4px;
             border: 1px solid #F56C6C;

+ 22 - 3
src/views/exam/scanList.vue

@@ -3,7 +3,7 @@
     
     <div class="search_content">
         <div class="content_left">
-                <span class="scan_state_title">客户端状态:</span> 
+                <span class="scan_state_title"><span>客户端状态</span>:</span> 
                 <span class="scan_state_open" v-if="scanClientStates">
                     <i class="iconfont icon_open"></i>已打开</span>
                 <span class="scan_state_close" v-else>
@@ -91,7 +91,7 @@
         </div>
         <div class="content_right">
             <div class="right_header">
-               <div class="scan_set" @click="OpenNumberSet()"> 考号设置</div>
+               <div class="scan_set scan_state_title" @click="OpenNumberSet()"> <span>考号设置</span></div>
                <div class="scan_set_scan_code">
     
                     <el-select style="width: 100px;margin-right: 6px;" v-model="useDriveUI" placeholder="是否显示驱动弹窗" @change="ChangeDriveUI">
@@ -161,7 +161,7 @@
         </div>
     </div>
     <!-- <SelectStudent v-model="showSelectStudent"  @success="StudentSuccess"></SelectStudent> -->
-    <AbnormalDetail v-model="showAbnormalDialog" :scanState="scanState"></AbnormalDetail>
+    <AbnormalDetail v-model="showAbnormalDialog" :scanState="scanState" @success="BackScan"></AbnormalDetail>
     <div class="page_dialog">
           <el-dialog
             v-model="showNumberSetDialog"
@@ -361,6 +361,12 @@ const Refresh = () => {
     GetScanBatchList();
 }
 
+//扫描异常返回
+const BackScan= () => { 
+    //更新列表
+    GetScanBatchList();
+}
+
 //扫描完成
 const FinishScanned= async () =>{
     console.log("打印完成")
@@ -1170,6 +1176,19 @@ onUnmounted(() => {
     font-size: 14px;
     color:#333;
     font-weight: 400;
+    span
+    {
+        text-emphasis-style: dot;        /* 实心小圆点 • */
+        // text-emphasis-style: circle;     /* 空心圆圈 ○ */
+        // text-emphasis-style: double-circle; /* 双圆圈 ◉ */
+        // text-emphasis-style: triangle;   /* 三角形 ▲ */
+
+        /* 自定义字符 */
+        // text-emphasis-style: '★';        /* 使用星号 */
+        // text-emphasis-style: '※';       /* 使用参考标记 */
+        text-emphasis-color: red;
+        text-emphasis-position: under; /* 下方居中 */
+    }
 
 }
 .scan_state_open