Browse Source

选择题判分系统新增考试增加班级选择功能

dengshaobo 1 month ago
parent
commit
0d9ea996f2
4 changed files with 659 additions and 72 deletions
  1. 9 0
      src/api/exam.ts
  2. 469 0
      src/components/AddExam copy.vue
  3. 179 70
      src/components/AddExam.vue
  4. 2 2
      src/views/exam/scanList.vue

+ 9 - 0
src/api/exam.ts

@@ -439,4 +439,13 @@ export const getExamProcess= (data:any):Promise<ApiResponse> => {
     method: 'get',
     params: data
   })
+}
+
+// 48. 编辑考试 获取选择的班级
+export const getExamClassList= (data:any):Promise<ApiResponse> => {
+  return request({
+    url: '/api/v1/ai_home/find_smart_exam_subject_class',
+    method: 'get',
+    params: data
+  })
 }

+ 469 - 0
src/components/AddExam copy.vue

@@ -0,0 +1,469 @@
+<template>
+  <el-dialog
+    v-model="dialogVisible"
+    title="新增考试"
+    width="800px"
+    class="page_dialog"
+    :before-close="handleClose"
+  >
+    <el-form ref="formRef"   :model="formData"  :rules="rules"  label-width="105px">
+      <el-form-item label="考试名称:" prop="examSubjectName">
+        <el-input v-model="formData.examSubjectName" placeholder="请输入考试名称" style="width: 300px;"/>
+      </el-form-item>
+      
+      <el-form-item label="考试年级:" prop="gradeCode">
+        <el-radio-group v-model="formData.gradeCode" @change="HandleGradeChange" :disabled="formData.canDelete==0">
+          <el-radio :value="grade.gradeCode"  v-for="grade in gradeList">{{grade.gradeName}}</el-radio>
+
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="考试科目:" prop="courseCode">
+        <el-radio-group v-model="formData.courseCode" @change="HandleCourseChange" :disabled="formData.canDelete==0">
+          <el-radio :value="subject.courseCode"  v-for="subject in subjectList">{{subject.courseName}}</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="班级类型:" prop="classType" v-if="showClassType" :disabled="isDisabledClassType">
+        <el-radio-group v-model="formData.classType" @change="HandleCourseChange" >
+          <el-radio :value="subject.value"  v-for="subject in classTypeList">{{subject.label}}</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="选择班级:" prop="checkClassList">
+          <el-checkbox-group v-model="formData.checkClassList">
+            <el-checkbox :label="item.className" :value="item.classIdCode" v-for="item in classList"  :disabled="item.cancelFlag==0?true:false"/>
+          </el-checkbox-group>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="HandleCancel">取消</el-button>
+        <el-button type="primary" :loading="loading" @click="HandleSubmit">确定</el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, computed, watch } from 'vue'
+import type { FormInstance, FormRules } from 'element-plus'
+import { ElMessage } from 'element-plus'
+// 1. 确保导入接口函数,请根据实际路径调整
+import { getExamTypeData,createExamSubject,getExamClassList} from '@/api/exam' 
+// 定义 Props 和 Emits
+const props = defineProps<{
+  modelValue: boolean,
+  editData: Record<string, any> | null ,
+}>()
+
+const emit = defineEmits<{
+  (e: 'update:modelValue', value: boolean): void
+  (e: 'success'): void
+}>()
+
+// 弹窗显示状态的双向绑定
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
+})
+
+// 表单引用
+const formRef = ref<FormInstance>()
+
+//定义用于存储下拉菜单选项的响应式数据
+const gradeList=ref<any[]>([]);
+const subjectList=ref<any[]>([]);
+const classTypeList=ref<any[]>([
+  {
+    label: '行政班',
+    value: 0
+  },
+  {
+    label: '教学班',
+    value: 1
+  }
+]);
+const isDisabledClassType=ref(false);//是否禁用班级类型选择
+const allClassList=ref<any[]>([]);//年级下的所有班级列表
+// 计算属性输出class字符串
+const classList = computed(() => {
+  let arr=[];
+  if(formData.classType==0)
+  {
+    //行政班
+    arr = allClassList.value.filter(item => {
+      return item.classType === formData.classType
+    })
+  }
+  else
+  {
+    //教学班
+    arr = allClassList.value.filter(item => {
+      return item.courseCode == formData.courseCode && item.classType == 1
+    })
+  }
+  return arr
+})
+
+//显示班级类型
+const showClassType=computed(() => { 
+  let result=false;
+  //判断allClassList.value里面是否有教学班的数据
+  let arr=allClassList.value.filter(item => {
+    return item.classType == 1
+  })
+  if(arr.length>0)
+  {
+    result=true;
+  }
+  return result;
+})
+// 表单数据
+const formData = reactive({
+    id:'',//考试科目列表id 不为空表示修改
+    canDelete:1,//是否可删除 0-否 1-是
+    schoolYearId:'',//学年id
+    schoolYearGradeId:'',//学年表id
+    schoolYearCode:'',//学年code
+    levelCode:'',//学段code
+    levelName:'',//学段名称
+    graduates:'',//毕业年份
+    gradeCode:'',//年级code
+    gradeName:'',//年级名称
+    examSubjectName:'',//考试科目名称
+    courseCode:'',//科目code
+    courseName:'',//科目名称
+    classType:0,//0 行政班 1 教学班
+    checkClassList:[],//班级列表
+})
+// 重置表单
+const ResetForm = () => {
+  if (formRef.value) {
+    formRef.value.resetFields()
+  }
+  Object.assign(formData, {
+    id:'',//考试科目列表id 不为空表示修改
+    schoolYearId:'',//学年id
+    canDelete:1,//是否可删除 0-否 1-是
+    schoolYearGradeId:'',//学年表id
+    schoolYearCode:'',//学年code
+    levelCode:'',//学段code
+    levelName:'',//学段名称
+    graduates:'',//毕业年份
+    gradeCode:'',//年级code
+    gradeName:'',//年级名称
+    examSubjectName:'',//考试科目名称
+    courseCode:'',//科目code
+    courseName:'',//科目名称
+  })
+}
+//监听数据变化
+watch(() => props.editData, (newData) => { 
+  if (newData) 
+  {
+    // --- 编辑模式:回填数据 ---
+    console.log('编辑模式,回填数据:', newData);
+    //编辑模式 回填数据
+    Object.assign(formData, newData)
+    console.log('回填数据:', formData)
+    // 2. 关键:根据回填的 gradeCode,手动更新 subjectList 和其他关联字段
+      // 因为 HandleGradeChange 是用户交互触发的,程序赋值不会触发它,
+      // 所以我们需要手动执行一次类似的逻辑,确保科目列表正确显示,且隐藏字段完整
+      if (formData.gradeCode && gradeList.value.length > 0) {
+        const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
+        if (selectedGrade) {
+          subjectList.value = selectedGrade.gradeCourseVOS || [];
+          //更新班级列表
+          allClassList.value=selectedGrade.pcClassTblVOS || [];
+          
+          // 补全隐藏字段(确保提交时数据完整)
+          formData.schoolYearId = selectedGrade.schoolYearId;
+          formData.schoolYearGradeId = selectedGrade.id;
+          formData.schoolYearCode = selectedGrade.schoolYearCode;
+          formData.levelCode = selectedGrade.levelCode;
+          const code = String(selectedGrade.levelCode);
+          formData.levelName = LEVEL_NAME_MAP[code] || '';
+          formData.graduates = selectedGrade.graduates;
+          formData.gradeName = selectedGrade.gradeName;
+
+          // 补全 courseName (防止后端没传或数据不一致)
+          if (formData.courseCode) {
+            const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
+            if (selectedCourse) {
+              formData.courseName = selectedCourse.courseName;
+            }
+          }
+        }
+      }
+    let usedClassType=newData.usedClassType || 0;//默认行政班
+    formData.classType=usedClassType;//默认
+    
+  }
+  else
+  {
+    //新增模式 清空表单数据
+    ResetForm()
+  }
+},{ immediate: true } // 【关键】立即执行,确保组件挂载时就能处理初始 prop
+)
+//获取已经选中的班级
+const GetExamClassList =(examSubjectId:string,usedClassType:number)=>{
+  let params={
+    examSubjectId:examSubjectId,
+    usedClassType:usedClassType
+  };
+  getExamClassList(params).then((res:any) => { 
+    console.log("打印获取选择的班级结果",res);
+    if(res.code==200)
+    {
+      formData.checkClassList = (res.data ?? []).map((item: any) => item.classIdCode);
+      isDisabledClassType.value=res.data[0].canUpdateClassType==0?true:false;//0 禁用
+      const flagMap = new Map<string | number, number>()
+
+      if (Array.isArray(res.data)) {
+        (res.data as Array<{ classIdCode: string | number; cancelFlag: number }>).forEach(item2 => {
+          flagMap.set(item2.classIdCode, item2.cancelFlag)
+        })
+      }
+
+      // 遍历原数组,原地给对象追加 cancelFlag
+      allClassList.value.forEach(item => {
+        const matchValue = flagMap.get(item.classIdCode)
+        // 匹配到就用后端值,没匹配默认1
+        const finalVal = matchValue !== undefined ? matchValue : 1
+        Reflect.set(item, 'cancelFlag', finalVal)
+      })
+
+      console.log("打印所有班级列表",allClassList.value)
+      
+    }
+  });
+}
+
+// 表单验证规则
+const rules = reactive<FormRules>({
+  examSubjectName: [
+    { required: true, message: '请输入考试名称', trigger: 'blur' },
+    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
+  ],
+  gradeCode: [
+    { required: true, message: '请选择考试年级', trigger: 'change' }
+  ],
+  courseCode: [
+    { required: true, message: '请选择考试科目', trigger: 'change' }
+  ]
+})
+
+const loading=ref(false);//加载状态
+
+// 关闭弹窗前的处理
+const handleClose = (done: () => void) => {
+  // 可以在这里添加确认关闭的逻辑
+  done()
+}
+
+
+
+
+// 获取下拉菜单选项
+const GetExamType=async()=>{
+  const res:any = await getExamTypeData({});
+  console.log("打印获取的结果",res)
+  if(res.code==200 && res.data)
+  {
+    gradeList.value=res.data.schoolGrade;
+    console.log("打印formData",formData)
+    // if(props.editData==null)
+    // {
+    //   formData.gradeCode=res.data.schoolGrade[0].gradeCode;
+    //   subjectList.value=res.data.schoolGrade[0].gradeCourseVOS || [];
+    //   formData.courseCode=res.data.schoolGrade[0].gradeCourseVOS[0].courseCode;
+    // }
+
+    // 如果当前是编辑模式,且已经回填了 formData,但 subjectList 还没更新
+    // 说明 watch(editData) 先于 GetExamType 执行了,这里需要手动补救一下
+    if (props.editData && formData.gradeCode) {
+       const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
+       if (selectedGrade) {
+          subjectList.value = selectedGrade.gradeCourseVOS || [];
+          //更新班级列表
+          allClassList.value=selectedGrade.pcClassTblVOS || [];
+          // 再次补全隐藏字段,确保万无一失
+          formData.schoolYearId = selectedGrade.schoolYearId;
+          formData.schoolYearGradeId = selectedGrade.id;
+          formData.schoolYearCode = selectedGrade.schoolYearCode;
+          formData.levelCode = selectedGrade.levelCode;
+          const code = String(selectedGrade.levelCode);
+          formData.levelName = LEVEL_NAME_MAP[code] || '';
+          formData.graduates = selectedGrade.graduates;
+          formData.gradeName = selectedGrade.gradeName;
+          
+          if (formData.courseCode) {
+            const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
+            if (selectedCourse) {
+              formData.courseName = selectedCourse.courseName;
+            }
+          }
+
+          GetExamClassList(props.editData.id,formData.classType);
+       }
+    } 
+    // 如果是新增模式,自动选中第一个
+    else if (!props.editData && !formData.gradeCode && gradeList.value.length > 0) {
+       const firstGrade = gradeList.value[0];
+       subjectList.value = firstGrade.gradeCourseVOS || [];
+       //更新班级列表
+       allClassList.value=firstGrade.pcClassTblVOS || [];
+       
+       formData.gradeCode = firstGrade.gradeCode;
+       formData.schoolYearId = firstGrade.schoolYearId;
+       formData.schoolYearGradeId = firstGrade.id;
+       formData.schoolYearCode = firstGrade.schoolYearCode;
+       formData.levelCode = firstGrade.levelCode;
+       const code = String(firstGrade.levelCode);
+       formData.levelName = LEVEL_NAME_MAP[code] || '';
+       formData.graduates = firstGrade.graduates;
+       formData.gradeName = firstGrade.gradeName;
+       if (subjectList.value.length > 0) {
+         formData.courseCode = subjectList.value[0].courseCode;
+         formData.courseName = subjectList.value[0].courseName;
+       }
+    }
+   
+    console.log("打印所有班级列表",allClassList.value);
+  }
+}
+//监听弹窗打开,调用接口
+watch(dialogVisible, (val) => { 
+  if (val) 
+  {
+    //弹窗打开时获取数据
+    GetExamType()
+  }
+})
+// 学段名称映射表
+const LEVEL_NAME_MAP: Record<string, string> = {
+  '1': '小学',
+  '2': '初中',
+  '3': '高中'
+}
+
+//切换年级改变事件
+const HandleGradeChange=()=>{
+  // 在 gradeList 中找到当前选中的年级对象
+  const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
+  console.log('选中的年级对象:', selectedGrade);
+  if (selectedGrade) {
+    // 更新科目列表
+    subjectList.value = selectedGrade.gradeCourseVOS || [];
+    formData.schoolYearId=selectedGrade.schoolYearId;//年级id
+    formData.schoolYearGradeId=selectedGrade.id;//年级表id
+    formData.schoolYearCode=selectedGrade.schoolYearCode;//年级code
+    formData.levelCode=selectedGrade.levelCode;//学段code
+    const code = String(selectedGrade.levelCode); 
+    formData.levelName = LEVEL_NAME_MAP[code] || ''; // 如果找不到对应代码,则设为空字符串
+    formData.graduates=selectedGrade.graduates;//毕业年份
+    formData.gradeName=selectedGrade.gradeName;//年级名称
+    
+    // 切换年级后,自动选中该年级的第一个科目(或者清空,视需求而定)
+    if (subjectList.value.length > 0) {
+      formData.courseCode = subjectList.value[0].courseCode;
+      formData.courseName=subjectList.value[0].courseName;
+    } else {
+      formData.courseCode = '';
+    }
+
+    //更新班级列表
+    allClassList.value=selectedGrade.pcClassTblVOS || [];
+    console.log('打印切换后的所有班级列表:', allClassList.value)
+  }
+}
+
+//切换科目改变事件
+const HandleCourseChange=()=>{
+  //在gradeList 中找到当前选中的年级对象
+  const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
+  console.log('选中的科目对象:', selectedCourse);
+  if(selectedCourse) 
+  {
+    // 更新科目列表
+    formData.courseName=selectedCourse.courseName;
+  }
+}
+
+//获取选择的班级list
+const classDetailDTOS = computed(() => {
+  if (!Array.isArray(formData.checkClassList) || !Array.isArray(classList.value)) return []
+  // 类型断言 as string[] 消除 never 报错
+  const checkArr = formData.checkClassList as string[]
+
+  return classList.value
+    .filter(item => checkArr.includes(item.classIdCode))
+    .map(item => ({
+      classId: item.classId,
+      classIdCode: item.classIdCode
+    }))
+})
+
+// 取消按钮
+const HandleCancel = () => {
+  dialogVisible.value = false
+  ResetForm()
+}
+
+// 提交按钮
+const HandleSubmit = async () => {
+  if (!formRef.value) return
+  await formRef.value.validate()
+  console.log('提交数据:', formData)
+
+ 
+
+  console.log("打印选择的班级list",classDetailDTOS.value)
+  if(classDetailDTOS.value.length==0)
+  {
+    ElMessage.error('请至少选择一个班级!')
+    return
+  }
+
+  // TODO: 调用接口提交数据
+  let params={
+    id:formData.id || '',//考试科目列表id 不为空表示修改
+    examType:1,//考试类型
+    schoolYearId:formData.schoolYearId,//学年id
+    schoolYearGradeId:formData.schoolYearGradeId,//学年表id
+    schoolYearCode:formData.schoolYearCode,//学年code
+    levelCode:formData.levelCode,//学段code
+    levelName:formData.levelName,//学段名称
+    graduates:formData.graduates,//毕业年份
+    gradeCode:formData.gradeCode,//年级code
+    gradeName:formData.gradeName,//年级名称
+    examSubjectName:formData.examSubjectName,//考试科目名称
+    courseCode:formData.courseCode,//科目code
+    courseName:formData.courseName,//科目名称
+    usedClassType:formData.classType,//班级类型 班级类型 0-行政班 1-教学班
+    classDetailDTOS:classDetailDTOS.value,//班级信息
+  };
+  loading.value=true;
+  const res:any=await createExamSubject(params);
+  console.log("打印提交的结果",res)
+  if(res.code==200)
+  {
+    loading.value=false;
+    ElMessage.success('新增考试成功')
+    dialogVisible.value = false
+    emit('success')
+    ResetForm()
+  }
+  // ElMessage.success('新增考试成功')
+  // dialogVisible.value = false
+  // emit('success')
+  // 
+}
+
+
+</script>
+
+<style lang="scss" scoped>
+.exam-form {
+  padding-right: 20px;
+}
+</style>

+ 179 - 70
src/components/AddExam.vue

@@ -1,8 +1,8 @@
 <template>
   <el-dialog
     v-model="dialogVisible"
-    title="新增考试"
-    width="480px"
+    :title="dialogTitle"
+    width="800px"
     class="page_dialog"
     :before-close="handleClose"
   >
@@ -13,17 +13,25 @@
       
       <el-form-item label="考试年级:" prop="gradeCode">
         <el-radio-group v-model="formData.gradeCode" @change="HandleGradeChange" :disabled="formData.canDelete==0">
-          <el-radio :value="grade.gradeCode"  v-for="grade in gradeList">{{grade.gradeName}}</el-radio>
-
+          <el-radio :value="grade.gradeCode"  v-for="grade in gradeList" :key="grade.gradeCode">{{grade.gradeName}}</el-radio>
         </el-radio-group>
       </el-form-item>
       <el-form-item label="考试科目:" prop="courseCode">
         <el-radio-group v-model="formData.courseCode" @change="HandleCourseChange" :disabled="formData.canDelete==0">
-          <el-radio :value="subject.courseCode"  v-for="subject in subjectList">{{subject.courseName}}</el-radio>
+          <el-radio :value="subject.courseCode"  v-for="subject in subjectList" :key="subject.courseCode">{{subject.courseName}}</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="班级类型:" prop="classType" v-if="showClassType">
+        <el-radio-group v-model="formData.classType" @change="HandleCourseChange" >
+          <el-radio :value="subject.value"  v-for="subject in classTypeList" :key="subject.value">{{subject.label}}</el-radio>
         </el-radio-group>
       </el-form-item>
+      <el-form-item label="选择班级:" prop="checkClassList">
+          <el-checkbox-group v-model="formData.checkClassList">
+            <el-checkbox :label="item.className" :value="item.classIdCode" v-for="item in classList" :key="item.classIdCode"  :disabled="item.cancelFlag==0?true:false"/>
+          </el-checkbox-group>
+      </el-form-item>
     </el-form>
-
     <template #footer>
       <span class="dialog-footer">
         <el-button @click="HandleCancel">取消</el-button>
@@ -38,7 +46,7 @@ import { ref, reactive, computed, watch } from 'vue'
 import type { FormInstance, FormRules } from 'element-plus'
 import { ElMessage } from 'element-plus'
 // 1. 确保导入接口函数,请根据实际路径调整
-import { getExamTypeData,createExamSubject } from '@/api/exam' 
+import { getExamTypeData,createExamSubject,getExamClassList} from '@/api/exam' 
 // 定义 Props 和 Emits
 const props = defineProps<{
   modelValue: boolean,
@@ -59,9 +67,57 @@ const dialogVisible = computed({
 // 表单引用
 const formRef = ref<FormInstance>()
 
+const dialogTitle=ref('新增考试')
+
 //定义用于存储下拉菜单选项的响应式数据
 const gradeList=ref<any[]>([]);
 const subjectList=ref<any[]>([]);
+const classTypeList=ref<any[]>([
+  {
+    label: '行政班',
+    value: 0
+  },
+  {
+    label: '教学班',
+    value: 1
+  }
+]);
+const isDisabledClassType=ref(false);//是否禁用班级类型选择
+const allClassList=ref<any[]>([]);//年级下的所有班级列表
+
+const classList = computed(() => {
+  let arr=[];
+  if(formData.classType==0)
+  {
+    //行政班
+    arr = allClassList.value.filter(item => {
+      return item.classType === formData.classType
+    })
+  }
+  else
+  {
+    //教学班
+    arr = allClassList.value.filter(item => {
+      return item.courseCode == formData.courseCode && item.classType == 1
+    })
+  }
+  return arr
+})
+
+//显示班级类型
+const showClassType=computed(() => { 
+  let result=false;
+  //判断allClassList.value里面是否有教学班的数据
+  let arr=allClassList.value.filter(item => {
+    return item.classType == 1
+  })
+  if(arr.length>0)
+  {
+    result=true;
+  }
+  return result;
+})
+
 // 表单数据
 const formData = reactive({
     id:'',//考试科目列表id 不为空表示修改
@@ -77,7 +133,10 @@ const formData = reactive({
     examSubjectName:'',//考试科目名称
     courseCode:'',//科目code
     courseName:'',//科目名称
+    classType:0,//0 行政班 1 教学班
+    checkClassList:[],//班级列表
 })
+
 // 重置表单
 const ResetForm = () => {
   if (formRef.value) {
@@ -85,8 +144,8 @@ const ResetForm = () => {
   }
   Object.assign(formData, {
     id:'',//考试科目列表id 不为空表示修改
-    schoolYearId:'',//学年id
     canDelete:1,//是否可删除 0-否 1-是
+    schoolYearId:'',//学年id
     schoolYearGradeId:'',//学年表id
     schoolYearCode:'',//学年code
     levelCode:'',//学段code
@@ -97,52 +156,52 @@ const ResetForm = () => {
     examSubjectName:'',//考试科目名称
     courseCode:'',//科目code
     courseName:'',//科目名称
+    classType:0,//0 行政班 1 教学班
+    checkClassList:[],//班级列表
   })
 }
+
 //监听数据变化
 watch(() => props.editData, (newData) => { 
-  if (newData) 
+  if (!dialogVisible.value) return; //弹窗没打开,不处理
+  if (!newData) 
   {
-    // --- 编辑模式:回填数据 ---
-    console.log('编辑模式,回填数据:', newData);
-    //编辑模式 回填数据
-    Object.assign(formData, newData)
-    console.log('回填数据:', formData)
-    // 2. 关键:根据回填的 gradeCode,手动更新 subjectList 和其他关联字段
-      // 因为 HandleGradeChange 是用户交互触发的,程序赋值不会触发它,
-      // 所以我们需要手动执行一次类似的逻辑,确保科目列表正确显示,且隐藏字段完整
-      if (formData.gradeCode && gradeList.value.length > 0) {
-        const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
-        if (selectedGrade) {
-          subjectList.value = selectedGrade.gradeCourseVOS || [];
-          
-          // 补全隐藏字段(确保提交时数据完整)
-          formData.schoolYearId = selectedGrade.schoolYearId;
-          formData.schoolYearGradeId = selectedGrade.id;
-          formData.schoolYearCode = selectedGrade.schoolYearCode;
-          formData.levelCode = selectedGrade.levelCode;
-          const code = String(selectedGrade.levelCode);
-          formData.levelName = LEVEL_NAME_MAP[code] || '';
-          formData.graduates = selectedGrade.graduates;
-          formData.gradeName = selectedGrade.gradeName;
-
-          // 补全 courseName (防止后端没传或数据不一致)
-          if (formData.courseCode) {
-            const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
-            if (selectedCourse) {
-              formData.courseName = selectedCourse.courseName;
-            }
-          }
-        }
-      }
-  }
-  else
-  {
-    //新增模式 清空表单数据
     ResetForm()
   }
-},{ immediate: true } // 【关键】立即执行,确保组件挂载时就能处理初始 prop
-)
+})
+
+//获取已经选中的班级
+const GetExamClassList =(examSubjectId:string,usedClassType:number)=>{
+  let params={
+    examSubjectId:examSubjectId,
+    usedClassType:usedClassType
+  };
+  getExamClassList(params).then((res:any) => { 
+    console.log("打印获取选择的班级结果",res);
+    if(res.code==200)
+    {
+      const list = res.data ?? []
+      formData.checkClassList = list.map((item: any) => item.classIdCode);
+      isDisabledClassType.value= list.length>0 && list[0].canUpdateClassType==0 ? true : false;//0 禁用
+
+      const flagMap = new Map<string | number, number>()
+      if (Array.isArray(list)) {
+        (list as Array<{ classIdCode: string | number; cancelFlag: number }>).forEach(item2 => {
+          flagMap.set(item2.classIdCode, item2.cancelFlag)
+        })
+      }
+
+      // 遍历原数组,原地给对象追加 cancelFlag
+      allClassList.value.forEach(item => {
+        const matchValue = flagMap.get(item.classIdCode)
+        // 匹配到就用后端值,没匹配默认1
+        const finalVal = matchValue !== undefined ? matchValue : 1
+        Reflect.set(item, 'cancelFlag', finalVal)
+      })
+      console.log("打印所有班级列表",allClassList.value)
+    }
+  });
+}
 
 // 表单验证规则
 const rules = reactive<FormRules>({
@@ -173,21 +232,19 @@ const GetExamType=async()=>{
   if(res.code==200 && res.data)
   {
     gradeList.value=res.data.schoolGrade;
-    console.log("打印formData",formData)
-    // if(props.editData==null)
-    // {
-    //   formData.gradeCode=res.data.schoolGrade[0].gradeCode;
-    //   subjectList.value=res.data.schoolGrade[0].gradeCourseVOS || [];
-    //   formData.courseCode=res.data.schoolGrade[0].gradeCourseVOS[0].courseCode;
-    // }
-
-    // 如果当前是编辑模式,且已经回填了 formData,但 subjectList 还没更新
-    // 说明 watch(editData) 先于 GetExamType 执行了,这里需要手动补救一下
-    if (props.editData && formData.gradeCode) {
-       const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
+
+    // =========现在gradeList已经有数据,再做编辑回填=========
+    if (props.editData) {
+      dialogTitle.value = '编辑考试';
+       //先把编辑数据赋值表单
+       Object.assign(formData, props.editData)
+
+       const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === props.editData?.gradeCode);
        if (selectedGrade) {
           subjectList.value = selectedGrade.gradeCourseVOS || [];
-          // 再次补全隐藏字段,确保万无一失
+          //更新班级列表
+          allClassList.value=selectedGrade.pcClassTblVOS || [];
+          // 补全隐藏字段(确保提交时数据完整)
           formData.schoolYearId = selectedGrade.schoolYearId;
           formData.schoolYearGradeId = selectedGrade.id;
           formData.schoolYearCode = selectedGrade.schoolYearCode;
@@ -197,18 +254,25 @@ const GetExamType=async()=>{
           formData.graduates = selectedGrade.graduates;
           formData.gradeName = selectedGrade.gradeName;
           
+          // 补全 courseName (防止后端没传或数据不一致)
           if (formData.courseCode) {
             const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
             if (selectedCourse) {
               formData.courseName = selectedCourse.courseName;
             }
           }
+          // 获取已选班级数据
+          GetExamClassList(props.editData.id,formData.classType);
        }
     } 
     // 如果是新增模式,自动选中第一个
     else if (!props.editData && !formData.gradeCode && gradeList.value.length > 0) {
+       dialogTitle.value = '新增考试';
        const firstGrade = gradeList.value[0];
        subjectList.value = firstGrade.gradeCourseVOS || [];
+       //更新班级列表
+       allClassList.value=firstGrade.pcClassTblVOS || [];
+       
        formData.gradeCode = firstGrade.gradeCode;
        formData.schoolYearId = firstGrade.schoolYearId;
        formData.schoolYearGradeId = firstGrade.id;
@@ -223,17 +287,25 @@ const GetExamType=async()=>{
          formData.courseName = subjectList.value[0].courseName;
        }
     }
-   
+    console.log("打印所有班级列表",allClassList.value);
   }
 }
+
 //监听弹窗打开,调用接口
-watch(dialogVisible, (val) => { 
+watch(dialogVisible, async (val) => { 
   if (val) 
   {
-    //弹窗打开时获取数据
-    GetExamType()
+    // ✅每次打开弹窗,先清空残留数据,防止上一次缓存干扰
+    subjectList.value = []
+    allClassList.value = []
+    isDisabledClassType.value = false
+    await GetExamType()
+  }else{
+    //弹窗关闭,重置表单
+    ResetForm()
   }
 })
+
 // 学段名称映射表
 const LEVEL_NAME_MAP: Record<string, string> = {
   '1': '小学',
@@ -265,6 +337,11 @@ const HandleGradeChange=()=>{
     } else {
       formData.courseCode = '';
     }
+
+    //更新班级列表
+    allClassList.value=selectedGrade.pcClassTblVOS || [];
+    console.log('打印切换后的所有班级列表:', allClassList.value)
+    formData.checkClassList=[];//切换年级清空班级选择
   }
 }
 
@@ -280,6 +357,20 @@ const HandleCourseChange=()=>{
   }
 }
 
+//获取选择的班级list
+const classDetailDTOS = computed(() => {
+  if (!Array.isArray(formData.checkClassList) || !Array.isArray(classList.value)) return []
+  // 类型断言 as string[] 消除 never 报错
+  const checkArr = formData.checkClassList as string[]
+
+  return classList.value
+    .filter(item => checkArr.includes(item.classIdCode))
+    .map(item => ({
+      classId: item.classId,
+      classIdCode: item.classIdCode
+    }))
+})
+
 // 取消按钮
 const HandleCancel = () => {
   dialogVisible.value = false
@@ -291,6 +382,14 @@ const HandleSubmit = async () => {
   if (!formRef.value) return
   await formRef.value.validate()
   console.log('提交数据:', formData)
+
+  console.log("打印选择的班级list",classDetailDTOS.value)
+  if(classDetailDTOS.value.length==0)
+  {
+    ElMessage.error('请至少选择一个班级!')
+    return
+  }
+
   // TODO: 调用接口提交数据
   let params={
     id:formData.id || '',//考试科目列表id 不为空表示修改
@@ -306,6 +405,8 @@ const HandleSubmit = async () => {
     examSubjectName:formData.examSubjectName,//考试科目名称
     courseCode:formData.courseCode,//科目code
     courseName:formData.courseName,//科目名称
+    usedClassType:formData.classType,//班级类型 班级类型 0-行政班 1-教学班
+    classDetailDTOS:classDetailDTOS.value,//班级信息
   };
   loading.value=true;
   const res:any=await createExamSubject(params);
@@ -313,18 +414,26 @@ const HandleSubmit = async () => {
   if(res.code==200)
   {
     loading.value=false;
-    ElMessage.success('新增考试成功')
+    if (props.editData) 
+    {
+      ElMessage.success('编辑考试成功!')
+    }
+    else
+    {
+      ElMessage.success('新增考试成功!')
+    }
+    
     dialogVisible.value = false
     emit('success')
     ResetForm()
   }
-  // ElMessage.success('新增考试成功')
-  // dialogVisible.value = false
-  // emit('success')
-  // 
+  else
+  {
+    loading.value=false;
+    ElMessage.error(res.msg || "操作失败!");
+  }
 }
 
-
 </script>
 
 <style lang="scss" scoped>

+ 2 - 2
src/views/exam/scanList.vue

@@ -242,7 +242,7 @@ const currentUserName=computed(() => {
     return userStore.userName;
 })
 const isShowGroupAnalysis = computed(() => analysisStore?.isShowGroupAnalysis || false);
-//查询是否导入了学生名单
+//查询是否导入了学生名单 此方法以注释
 const HasImportStudent = async () => { 
     const params = {
       examSubjectId: examSubjectId.value,
@@ -268,7 +268,7 @@ const HasImportStudent = async () => {
 }
 
 // 组件创建时立即执行
-HasImportStudent();//查询是否导入了学生名单();
+// HasImportStudent();//查询是否导入了学生名单();
 
 const selectSchoolId=ref(0);//学校ID
 const showAbnormalDialog=ref(false);//异常弹窗