AddExam.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <template>
  2. <el-dialog
  3. v-model="dialogVisible"
  4. title="新增考试"
  5. width="480px"
  6. class="page_dialog"
  7. :before-close="handleClose"
  8. >
  9. <el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
  10. <el-form-item label="考试名称:" prop="examSubjectName">
  11. <el-input v-model="formData.examSubjectName" placeholder="请输入考试名称" style="width: 300px;"/>
  12. </el-form-item>
  13. <el-form-item label="考试年级:" prop="gradeCode">
  14. <el-radio-group v-model="formData.gradeCode" @change="HandleGradeChange">
  15. <el-radio :value="grade.gradeCode" v-for="grade in gradeList">{{grade.gradeName}}</el-radio>
  16. </el-radio-group>
  17. </el-form-item>
  18. <el-form-item label="考试科目:" prop="courseCode">
  19. <el-radio-group v-model="formData.courseCode" @change="HandleCourseChange">
  20. <el-radio :value="subject.courseCode" v-for="subject in subjectList">{{subject.courseName}}</el-radio>
  21. </el-radio-group>
  22. </el-form-item>
  23. </el-form>
  24. <template #footer>
  25. <span class="dialog-footer">
  26. <el-button @click="HandleCancel">取消</el-button>
  27. <el-button type="primary" :loading="loading" @click="HandleSubmit">确定</el-button>
  28. </span>
  29. </template>
  30. </el-dialog>
  31. </template>
  32. <script lang="ts" setup>
  33. import { ref, reactive, computed, watch } from 'vue'
  34. import type { FormInstance, FormRules } from 'element-plus'
  35. import { ElMessage } from 'element-plus'
  36. // 1. 确保导入接口函数,请根据实际路径调整
  37. import { getExamTypeData,createExamSubject } from '@/api/exam'
  38. // 定义 Props 和 Emits
  39. const props = defineProps<{
  40. modelValue: boolean,
  41. editData: Record<string, any> | null ,
  42. }>()
  43. const emit = defineEmits<{
  44. (e: 'update:modelValue', value: boolean): void
  45. (e: 'success'): void
  46. }>()
  47. // 弹窗显示状态的双向绑定
  48. const dialogVisible = computed({
  49. get: () => props.modelValue,
  50. set: (val) => emit('update:modelValue', val)
  51. })
  52. // 表单引用
  53. const formRef = ref<FormInstance>()
  54. //定义用于存储下拉菜单选项的响应式数据
  55. const gradeList=ref<any[]>([]);
  56. const subjectList=ref<any[]>([]);
  57. // 表单数据
  58. const formData = reactive({
  59. id:'',//考试科目列表id 不为空表示修改
  60. schoolYearId:'',//学年id
  61. schoolYearGradeId:'',//学年表id
  62. schoolYearCode:'',//学年code
  63. levelCode:'',//学段code
  64. levelName:'',//学段名称
  65. graduates:'',//毕业年份
  66. gradeCode:'',//年级code
  67. gradeName:'',//年级名称
  68. examSubjectName:'',//考试科目名称
  69. courseCode:'',//科目code
  70. courseName:'',//科目名称
  71. })
  72. // 重置表单
  73. const ResetForm = () => {
  74. if (formRef.value) {
  75. formRef.value.resetFields()
  76. }
  77. Object.assign(formData, {
  78. id:'',//考试科目列表id 不为空表示修改
  79. schoolYearId:'',//学年id
  80. schoolYearGradeId:'',//学年表id
  81. schoolYearCode:'',//学年code
  82. levelCode:'',//学段code
  83. levelName:'',//学段名称
  84. graduates:'',//毕业年份
  85. gradeCode:'',//年级code
  86. gradeName:'',//年级名称
  87. examSubjectName:'',//考试科目名称
  88. courseCode:'',//科目code
  89. courseName:'',//科目名称
  90. })
  91. }
  92. //监听数据变化
  93. watch(() => props.editData, (newData) => {
  94. if (newData)
  95. {
  96. // --- 编辑模式:回填数据 ---
  97. console.log('编辑模式,回填数据:', newData);
  98. //编辑模式 回填数据
  99. Object.assign(formData, newData)
  100. console.log('回填数据:', formData)
  101. // 2. 关键:根据回填的 gradeCode,手动更新 subjectList 和其他关联字段
  102. // 因为 HandleGradeChange 是用户交互触发的,程序赋值不会触发它,
  103. // 所以我们需要手动执行一次类似的逻辑,确保科目列表正确显示,且隐藏字段完整
  104. if (formData.gradeCode && gradeList.value.length > 0) {
  105. const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
  106. if (selectedGrade) {
  107. subjectList.value = selectedGrade.gradeCourseVOS || [];
  108. // 补全隐藏字段(确保提交时数据完整)
  109. formData.schoolYearId = selectedGrade.schoolYearId;
  110. formData.schoolYearGradeId = selectedGrade.id;
  111. formData.schoolYearCode = selectedGrade.schoolYearCode;
  112. formData.levelCode = selectedGrade.levelCode;
  113. const code = String(selectedGrade.levelCode);
  114. formData.levelName = LEVEL_NAME_MAP[code] || '';
  115. formData.graduates = selectedGrade.graduates;
  116. formData.gradeName = selectedGrade.gradeName;
  117. // 补全 courseName (防止后端没传或数据不一致)
  118. if (formData.courseCode) {
  119. const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
  120. if (selectedCourse) {
  121. formData.courseName = selectedCourse.courseName;
  122. }
  123. }
  124. }
  125. }
  126. }
  127. else
  128. {
  129. //新增模式 清空表单数据
  130. ResetForm()
  131. }
  132. },{ immediate: true } // 【关键】立即执行,确保组件挂载时就能处理初始 prop
  133. )
  134. // 表单验证规则
  135. const rules = reactive<FormRules>({
  136. examSubjectName: [
  137. { required: true, message: '请输入考试名称', trigger: 'blur' },
  138. { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  139. ],
  140. gradeCode: [
  141. { required: true, message: '请选择考试年级', trigger: 'change' }
  142. ],
  143. courseCode: [
  144. { required: true, message: '请选择考试科目', trigger: 'change' }
  145. ]
  146. })
  147. const loading=ref(false);//加载状态
  148. // 关闭弹窗前的处理
  149. const handleClose = (done: () => void) => {
  150. // 可以在这里添加确认关闭的逻辑
  151. done()
  152. }
  153. // 获取下拉菜单选项
  154. const GetExamType=async()=>{
  155. const res:any = await getExamTypeData({});
  156. console.log("打印获取的结果",res)
  157. if(res.code==200 && res.data)
  158. {
  159. gradeList.value=res.data.schoolGrade;
  160. console.log("打印formData",formData)
  161. // if(props.editData==null)
  162. // {
  163. // formData.gradeCode=res.data.schoolGrade[0].gradeCode;
  164. // subjectList.value=res.data.schoolGrade[0].gradeCourseVOS || [];
  165. // formData.courseCode=res.data.schoolGrade[0].gradeCourseVOS[0].courseCode;
  166. // }
  167. // 如果当前是编辑模式,且已经回填了 formData,但 subjectList 还没更新
  168. // 说明 watch(editData) 先于 GetExamType 执行了,这里需要手动补救一下
  169. if (props.editData && formData.gradeCode) {
  170. const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
  171. if (selectedGrade) {
  172. subjectList.value = selectedGrade.gradeCourseVOS || [];
  173. // 再次补全隐藏字段,确保万无一失
  174. formData.schoolYearId = selectedGrade.schoolYearId;
  175. formData.schoolYearGradeId = selectedGrade.id;
  176. formData.schoolYearCode = selectedGrade.schoolYearCode;
  177. formData.levelCode = selectedGrade.levelCode;
  178. const code = String(selectedGrade.levelCode);
  179. formData.levelName = LEVEL_NAME_MAP[code] || '';
  180. formData.graduates = selectedGrade.graduates;
  181. formData.gradeName = selectedGrade.gradeName;
  182. if (formData.courseCode) {
  183. const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
  184. if (selectedCourse) {
  185. formData.courseName = selectedCourse.courseName;
  186. }
  187. }
  188. }
  189. }
  190. // 如果是新增模式,自动选中第一个
  191. else if (!props.editData && !formData.gradeCode && gradeList.value.length > 0) {
  192. const firstGrade = gradeList.value[0];
  193. subjectList.value = firstGrade.gradeCourseVOS || [];
  194. formData.gradeCode = firstGrade.gradeCode;
  195. formData.schoolYearId = firstGrade.schoolYearId;
  196. formData.schoolYearGradeId = firstGrade.id;
  197. formData.schoolYearCode = firstGrade.schoolYearCode;
  198. formData.levelCode = firstGrade.levelCode;
  199. const code = String(firstGrade.levelCode);
  200. formData.levelName = LEVEL_NAME_MAP[code] || '';
  201. formData.graduates = firstGrade.graduates;
  202. formData.gradeName = firstGrade.gradeName;
  203. if (subjectList.value.length > 0) {
  204. formData.courseCode = subjectList.value[0].courseCode;
  205. formData.courseName = subjectList.value[0].courseName;
  206. }
  207. }
  208. }
  209. }
  210. //监听弹窗打开,调用接口
  211. watch(dialogVisible, (val) => {
  212. if (val)
  213. {
  214. //弹窗打开时获取数据
  215. GetExamType()
  216. }
  217. })
  218. // 学段名称映射表
  219. const LEVEL_NAME_MAP: Record<string, string> = {
  220. '1': '小学',
  221. '2': '初中',
  222. '3': '高中'
  223. }
  224. //切换年级改变事件
  225. const HandleGradeChange=()=>{
  226. // 在 gradeList 中找到当前选中的年级对象
  227. const selectedGrade = gradeList.value.find((item: any) => item.gradeCode === formData.gradeCode);
  228. console.log('选中的年级对象:', selectedGrade);
  229. if (selectedGrade) {
  230. // 更新科目列表
  231. subjectList.value = selectedGrade.gradeCourseVOS || [];
  232. formData.schoolYearId=selectedGrade.schoolYearId;//年级id
  233. formData.schoolYearGradeId=selectedGrade.id;//年级表id
  234. formData.schoolYearCode=selectedGrade.schoolYearCode;//年级code
  235. formData.levelCode=selectedGrade.levelCode;//学段code
  236. const code = String(selectedGrade.levelCode);
  237. formData.levelName = LEVEL_NAME_MAP[code] || ''; // 如果找不到对应代码,则设为空字符串
  238. formData.graduates=selectedGrade.graduates;//毕业年份
  239. formData.gradeName=selectedGrade.gradeName;//年级名称
  240. // 切换年级后,自动选中该年级的第一个科目(或者清空,视需求而定)
  241. if (subjectList.value.length > 0) {
  242. formData.courseCode = subjectList.value[0].courseCode;
  243. formData.courseName=subjectList.value[0].courseName;
  244. } else {
  245. formData.courseCode = '';
  246. }
  247. }
  248. }
  249. //切换科目改变事件
  250. const HandleCourseChange=()=>{
  251. //在gradeList 中找到当前选中的年级对象
  252. const selectedCourse = subjectList.value.find((item: any) => item.courseCode === formData.courseCode);
  253. console.log('选中的科目对象:', selectedCourse);
  254. if(selectedCourse)
  255. {
  256. // 更新科目列表
  257. formData.courseName=selectedCourse.courseName;
  258. }
  259. }
  260. // 取消按钮
  261. const HandleCancel = () => {
  262. dialogVisible.value = false
  263. ResetForm()
  264. }
  265. // 提交按钮
  266. const HandleSubmit = async () => {
  267. if (!formRef.value) return
  268. await formRef.value.validate()
  269. console.log('提交数据:', formData)
  270. // TODO: 调用接口提交数据
  271. let params={
  272. id:formData.id || '',//考试科目列表id 不为空表示修改
  273. examType:1,//考试类型
  274. schoolYearId:formData.schoolYearId,//学年id
  275. schoolYearGradeId:formData.schoolYearGradeId,//学年表id
  276. schoolYearCode:formData.schoolYearCode,//学年code
  277. levelCode:formData.levelCode,//学段code
  278. levelName:formData.levelName,//学段名称
  279. graduates:formData.graduates,//毕业年份
  280. gradeCode:formData.gradeCode,//年级code
  281. gradeName:formData.gradeName,//年级名称
  282. examSubjectName:formData.examSubjectName,//考试科目名称
  283. courseCode:formData.courseCode,//科目code
  284. courseName:formData.courseName,//科目名称
  285. };
  286. loading.value=true;
  287. const res:any=await createExamSubject(params);
  288. console.log("打印提交的结果",res)
  289. if(res.code==200)
  290. {
  291. loading.value=false;
  292. ElMessage.success('新增考试成功')
  293. dialogVisible.value = false
  294. emit('success')
  295. ResetForm()
  296. }
  297. // ElMessage.success('新增考试成功')
  298. // dialogVisible.value = false
  299. // emit('success')
  300. //
  301. }
  302. </script>
  303. <style lang="scss" scoped>
  304. .exam-form {
  305. padding-right: 20px;
  306. }
  307. </style>