diff --git a/frontend/src/views/subjectMajor/discipline/index.vue b/frontend/src/views/subjectMajor/discipline/index.vue index 654f7e07e..791d7f8bb 100644 --- a/frontend/src/views/subjectMajor/discipline/index.vue +++ b/frontend/src/views/subjectMajor/discipline/index.vue @@ -123,7 +123,15 @@ - + + + @@ -265,11 +273,13 @@ import { updateDiscipline, disableDiscipline } from '@/api/subjectMajor/discipline' +import { listMajor } from '@/api/subjectMajor/major' import { getDicts } from '@/api/system/dict/data' import { optionselect } from '@/api/system/dict/type' const TRAINING_TYPE_DICT_CODE = 'train_type' const TRAINING_LEVEL_DICT_CODE = 'train_level' +const MAJOR_OPTION_PAGE_SIZE = 10000 export default { name: 'DisciplineIndex', @@ -300,7 +310,7 @@ export default { form: this.createEmptyForm(), formRules: { gfmc: [{ required: true, message: '请输入规范名称', trigger: 'blur' }], - zydm: [{ required: true, message: '请输入专业代码', trigger: 'blur' }], + zydm: [{ required: true, message: '请选择专业代码', trigger: 'change' }], zymc: [{ required: true, message: '请输入专业名称', trigger: 'blur' }], zyfx: [{ required: true, message: '请输入专业方向', trigger: 'blur' }], xnz: [{ required: true, message: '请输入学年制', trigger: 'blur' }], @@ -316,6 +326,9 @@ export default { trainingTypeOptions: [], trainingLevelOptions: [], studentCategoryOptions: [], + // 专业代码下拉选项(来源:专业管理-专业表,按专业代码去重) + majorOptions: [], + majorOptionsLoading: false, // ==================== 详情 ==================== detailDialogVisible: false, @@ -325,6 +338,7 @@ export default { }, mounted() { this.loadDisciplineDictionaries() + this.loadMajorOptions() this.fetchList() }, methods: { @@ -356,6 +370,74 @@ export default { } }, + /** 复用专业分页接口加载启用中的专业,作为专业代码下拉的全量选项(按专业代码去重)。 */ + async loadMajorOptions() { + this.majorOptionsLoading = true + try { + const response = await listMajor({ + pageNum: 1, + pageSize: MAJOR_OPTION_PAGE_SIZE, + ty: false + }) + const data = response.data || {} + const records = Array.isArray(data.records) ? data.records : [] + const seen = new Set() + this.majorOptions = records.filter(item => { + if (!item.zydm || seen.has(item.zydm)) { + return false + } + seen.add(item.zydm) + return true + }) + } catch (error) { + this.majorOptions = [] + } finally { + this.majorOptionsLoading = false + } + }, + + formatMajorLabel(item) { + const base = [item.zydm, item.zymc].filter(Boolean).join(' ') + return item.zyfx ? `${base}(${item.zyfx})` : (base || item.zydh) + }, + + /** 宽松布尔归一:兼容后端 Boolean、数字 0/1、字符串 'true'/'false'/'1'/'0'/'是'/'否';无效值返回 null */ + normBool(val) { + if (val === null || val === undefined || val === '') return null + if (typeof val === 'boolean') return val + if (typeof val === 'number') return val !== 0 + const s = String(val).trim() + if (['是', 'true', '1', 'Y', 'y'].indexOf(s) >= 0) return true + if (['否', 'false', '0', 'N', 'n'].indexOf(s) >= 0) return false + return null + }, + + /** 选择专业代码后,从专业表带出可对应的专业信息字段 */ + handleMajorCodeChange(zydm) { + if (!zydm) { + return + } + const major = this.majorOptions.find(item => item.zydm === zydm) + if (!major) { + return + } + const f = this.form + f.zymc = major.zymc || '' + f.zyfx = major.zyfx || '' + f.xnz = major.xnz || '' + f.xqs = major.xqs !== null && major.xqs !== undefined ? major.xqs : undefined + f.pxcc = major.pxcc || '' + f.pxlx = major.pxlx || '' + f.pxlx2 = major.pxlx2 || '' + f.jxgljgbh = major.jxgljgbh || '' + f.xylb = major.xylb || '' + f.zdyfl = major.zdyfl || '' + f.gfmc = major.gfmc || '' + const zgzy = this.normBool(major.zgzy) + f.zgzy = zgzy === null ? '' : (zgzy ? '是' : '否') + f.bz = major.zybz || '' + }, + /** 序号:按当前页数据索引生成跨页连续的序号 */ fmtXh(index) { return (this.pageNum - 1) * this.pageSize + index + 1