From 26072ffe4ec6a4e7e2e6f511a5e315307ff98e5f Mon Sep 17 00:00:00 2001
From: yangbin <1796443586@qq.com>
Date: Thu, 27 Aug 2026 12:01:33 +0800
Subject: [PATCH] =?UTF-8?q?=E8=8B=A5=E5=B9=B2=E5=89=8D=E7=AB=AFbug?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/api/studentRecords/application.js | 2 +-
frontend/src/api/studentRecords/team.js | 9 +
.../src/views/student/shiftTeam/index.vue | 178 +++++++++---
.../src/views/student/statusChange/index.vue | 29 +-
.../src/views/student/studentInfo/index.vue | 260 ++++++++++++++++--
.../views/student/warningCondition/index.vue | 72 ++++-
.../views/subjectMajor/discipline/index.vue | 8 -
.../src/views/subjectMajor/major/index.vue | 6 -
frontend/src/views/textbook/index.vue | 12 -
9 files changed, 457 insertions(+), 119 deletions(-)
diff --git a/frontend/src/api/studentRecords/application.js b/frontend/src/api/studentRecords/application.js
index 33e5250d..1c64ebcc 100644
--- a/frontend/src/api/studentRecords/application.js
+++ b/frontend/src/api/studentRecords/application.js
@@ -21,7 +21,7 @@ export function getApplication(bh) {
})
}
-// 新增学籍异动申请(请求体 XYXJYDSQB 实体;bh 需前端传入,创建/修改时间后端自动维护)
+// 新增学籍异动申请(编号、状态和创建/修改时间由后端维护)
export function addApplication(data) {
return request({
url: '/student-records/application/add',
diff --git a/frontend/src/api/studentRecords/team.js b/frontend/src/api/studentRecords/team.js
index 65e27b14..b36d8bc4 100644
--- a/frontend/src/api/studentRecords/team.js
+++ b/frontend/src/api/studentRecords/team.js
@@ -21,6 +21,15 @@ export function getTeam(xydbh) {
})
}
+// 根据是否为主体培训任务查询可选培训任务
+export function listTrainingTasks(ztpxrw) {
+ return request({
+ url: '/student-records/training-tasks',
+ method: 'get',
+ params: { ztpxrw }
+ })
+}
+
// 新增学员队(请求体 XYDB)
export function addTeam(data) {
return request({
diff --git a/frontend/src/views/student/shiftTeam/index.vue b/frontend/src/views/student/shiftTeam/index.vue
index 620b4892..4869c172 100644
--- a/frontend/src/views/student/shiftTeam/index.vue
+++ b/frontend/src/views/student/shiftTeam/index.vue
@@ -21,7 +21,14 @@
-
+
+
+
@@ -32,8 +39,8 @@
-
-
+
+
@@ -74,7 +81,7 @@
- {{ Number(row.xslx) === 1 ? '实' : '虚' }}
+ {{ Number(row.xslx) === 1 ? '是' : '否' }}
@@ -156,17 +163,38 @@
-
+
+
+
-
+
+
+
-
+
+
+
@@ -176,7 +204,14 @@
-
+
+
+
@@ -196,14 +231,14 @@
-
-
+
+
-
+
@@ -211,12 +246,26 @@
-
+
+
+
-
+
@@ -233,9 +282,6 @@
-
-
-
@@ -266,7 +312,7 @@
{{ detailForm.rwlb || '-' }}
- {{ Number(detailForm.xslx) === 1 ? '实' : '虚' }}
+ {{ Number(detailForm.xslx) === 1 ? '是' : '否' }}
@@ -282,7 +328,6 @@
{{ detailForm.rxrq || '-' }}
{{ detailForm.byrq || '-' }}
- {{ detailForm.jsonzd || '-' }}
{{ detailForm.bz || '-' }}
@@ -301,10 +346,17 @@ import {
addTeam,
updateTeam,
delTeam,
+ listTrainingTasks,
importTeam,
exportTeam,
downloadTeamTemplate
} from '@/api/studentRecords/team'
+import { getDicts } from '@/api/system/dict/data'
+
+const TEAM_TYPE_DICT_CODE = 'stu_type'
+const SESSION_CATEGORY_DICT_CODE = 'session_category'
+const SYSTEM_MODE_DICT_CODE = 'system_mode'
+const UNIT_CATEGORY_DICT_CODE = 'sys_unit_category'
export default {
name: 'ShiftTeamIndex',
@@ -319,6 +371,12 @@ export default {
rwlb: '',
xslx: undefined
},
+ teamTypeOptions: [],
+ sessionCategoryOptions: [],
+ systemModeOptions: [],
+ unitCategoryOptions: [],
+ trainingTaskOptions: [],
+ trainingTaskLoading: false,
// ==================== 文件导入 ====================
selectedFile: null,
@@ -346,9 +404,9 @@ export default {
xslx: [{ required: true, message: '请选择虚实类型', trigger: 'change' }],
rxrq: [{ required: true, message: '请选择入学日期', trigger: 'change' }],
byrq: [{ required: true, message: '请选择毕业日期', trigger: 'change' }],
- xydlx: [{ required: true, message: '请输入学员队类型', trigger: 'blur' }],
- jclb: [{ required: true, message: '请输入节次类别', trigger: 'blur' }],
- xtms: [{ required: true, message: '请输入系统模式', trigger: 'blur' }],
+ xydlx: [{ required: true, message: '请选择学员队类型', trigger: 'change' }],
+ jclb: [{ required: true, message: '请选择节次类别', trigger: 'change' }],
+ xtms: [{ required: true, message: '请选择系统模式', trigger: 'change' }],
ztpxrw: [{ required: true, message: '请选择主体培训任务', trigger: 'change' }]
},
@@ -364,9 +422,25 @@ export default {
}
},
mounted() {
+ this.loadTeamDictionaries()
this.fetchList()
},
methods: {
+ /** 加载学员队相关字典。 */
+ async loadTeamDictionaries() {
+ const emptyResponse = { data: [] }
+ const [teamTypeResponse, sessionCategoryResponse, systemModeResponse, unitCategoryResponse] = await Promise.all([
+ getDicts(TEAM_TYPE_DICT_CODE).catch(() => emptyResponse),
+ getDicts(SESSION_CATEGORY_DICT_CODE).catch(() => emptyResponse),
+ getDicts(SYSTEM_MODE_DICT_CODE).catch(() => emptyResponse),
+ getDicts(UNIT_CATEGORY_DICT_CODE).catch(() => emptyResponse)
+ ])
+ this.teamTypeOptions = teamTypeResponse.data || []
+ this.sessionCategoryOptions = sessionCategoryResponse.data || []
+ this.systemModeOptions = systemModeResponse.data || []
+ this.unitCategoryOptions = unitCategoryResponse.data || []
+ },
+
createEmptyForm() {
return {
xydbh: '',
@@ -376,7 +450,7 @@ export default {
zydh: '',
zyjsbh: '',
bz: '',
- zxzt: 1,
+ zxzt: undefined,
xh: undefined,
rwlb: '',
xslx: 1,
@@ -402,6 +476,17 @@ export default {
return val === null || val === undefined || val === '' ? '-' : val
},
+ normalizeSchoolStatus(value) {
+ if (value === 1 || value === '1' || value === '在校') {
+ return 1
+ }
+ if (value === 0 || value === '0' || value === '毕业') {
+ return 0
+ }
+
+ return undefined
+ },
+
/** 构建查询条件(不含分页),供列表查询与导出共用 */
buildQuery() {
const params = {}
@@ -464,6 +549,7 @@ export default {
this.isAdd = true
this.dialogTitle = '新增学员队'
this.form = this.createEmptyForm()
+ this.loadTrainingTaskOptions(this.form.ztpxrw)
this.formDialogVisible = true
this.$nextTick(() => {
this.$refs.formRef && this.$refs.formRef.clearValidate()
@@ -488,7 +574,7 @@ export default {
zydh: d.zydh || '',
zyjsbh: d.zyjsbh || '',
bz: d.bz || '',
- zxzt: d.zxzt !== null && d.zxzt !== undefined ? Number(d.zxzt) : 1,
+ zxzt: this.normalizeSchoolStatus(d.zxzt),
xh: d.xh !== null && d.xh !== undefined ? d.xh : undefined,
rwlb: d.rwlb || '',
xslx: d.xslx !== null && d.xslx !== undefined ? Number(d.xslx) : 1,
@@ -503,9 +589,36 @@ export default {
ssdw: d.ssdw || '',
ztpxrw: d.ztpxrw !== null && d.ztpxrw !== undefined ? Number(d.ztpxrw) : 1
}
+ this.loadTrainingTaskOptions(this.form.ztpxrw)
}).catch(() => {})
},
+ /** 按主体培训任务标志加载后端培训任务选项。 */
+ async loadTrainingTaskOptions(ztpxrw) {
+ this.trainingTaskLoading = true
+ try {
+ const response = await listTrainingTasks(ztpxrw)
+ this.trainingTaskOptions = Array.isArray(response.data) ? response.data : []
+ } catch (error) {
+ this.trainingTaskOptions = []
+ } finally {
+ this.trainingTaskLoading = false
+ }
+ },
+
+ handlePrimaryTrainingTaskChange(ztpxrw) {
+ this.form.pxrwbsh = ''
+ this.loadTrainingTaskOptions(ztpxrw)
+ },
+
+ formatTrainingTaskLabel(item) {
+ if (!item.mc) {
+ return item.bsh
+ }
+
+ return `${item.mc}(${item.bsh})`
+ },
+
buildPayload() {
const f = this.form
const payload = {
@@ -516,16 +629,17 @@ export default {
xydlx: f.xydlx,
jclb: f.jclb,
xtms: f.xtms,
- zxzt: Number(f.zxzt),
xslx: Number(f.xslx),
ztpxrw: Number(f.ztpxrw)
}
// 数值字段
if (f.xydrs !== '' && f.xydrs !== null && f.xydrs !== undefined) payload.xydrs = Number(f.xydrs)
- if (f.xh !== '' && f.xh !== null && f.xh !== undefined) payload.xh = Number(f.xh)
- // 日期字段
- if (f.rxrq) payload.rxrq = f.rxrq
- if (f.byrq) payload.byrq = f.byrq
+ // 字符串字段
+ if (f.zxzt !== '' && f.zxzt !== null && f.zxzt !== undefined) payload.zxzt = String(f.zxzt)
+ if (f.xh !== '' && f.xh !== null && f.xh !== undefined) payload.xh = String(f.xh)
+ // 后端字段为 LocalDateTime,日期选择器值统一补齐当天零点。
+ if (f.rxrq) payload.rxrq = `${this.formatDate(f.rxrq)}T00:00:00`
+ if (f.byrq) payload.byrq = `${this.formatDate(f.byrq)}T00:00:00`
// 其余文本字段非空才传
;['nj', 'zyjsbh', 'pxrwbsh', 'jsonzd', 'jc', 'ssdw', 'bz'].forEach(key => {
if (f[key] !== '' && f[key] !== null && f[key] !== undefined) {
@@ -635,14 +749,14 @@ export default {
}
.shift-team-page {
+ .w-full {
+ width: 100%;
+ }
+
.search-card {
margin-bottom: 16px;
.search-form {
- .w-full {
- width: 100%;
- }
-
.search-actions-row {
margin-top: 2px;
border-top: 1px dashed #ebeef5;
diff --git a/frontend/src/views/student/statusChange/index.vue b/frontend/src/views/student/statusChange/index.vue
index 3bfbb722..52d89ca2 100644
--- a/frontend/src/views/student/statusChange/index.vue
+++ b/frontend/src/views/student/statusChange/index.vue
@@ -106,9 +106,6 @@
@update:visible="val => formDialogVisible = val"
>
-
-
-
-
-
-
-
-
取消
@@ -270,11 +262,13 @@ export default {
verifiedStudentNo: '',
form: this.createEmptyForm(),
formRules: {
- bh: [{ required: true, message: '请输入编号', trigger: 'blur' }],
- xh: [{ required: true, message: '请输入学号', trigger: 'blur' }],
+ xh: [
+ { required: true, message: '请输入学号', trigger: 'blur' },
+ { max: 50, message: '学号不能超过50个字符', trigger: 'blur' },
+ { pattern: /^[A-Za-z0-9]+$/, message: '学号只能包含字母和数字', trigger: 'blur' }
+ ],
sqlx: [{ required: true, message: '请选择申请类型', trigger: 'change' }],
- sy: [{ required: true, message: '请输入事由', trigger: 'blur' }],
- zt: [{ required: true, message: '请选择状态', trigger: 'change' }]
+ sy: [{ required: true, message: '请输入事由', trigger: 'blur' }]
},
// ==================== 详情 ====================
@@ -543,11 +537,16 @@ export default {
buildPayload() {
const f = this.form
const payload = {
- bh: f.bh,
xybh: f.xybh,
sqlx: f.sqlx,
- sy: f.sy,
- zt: Number(f.zt)
+ sy: f.sy
+ }
+ // 新增编号和状态由后端生成;编辑时仅回传记录定位编号和原状态。
+ if (!this.isAdd) {
+ payload.bh = f.bh
+ if (f.zt !== null && f.zt !== undefined && f.zt !== '') {
+ payload.zt = Number(f.zt)
+ }
}
// 备注留空则移除
if (f.bz !== '' && f.bz !== null && f.bz !== undefined) {
diff --git a/frontend/src/views/student/studentInfo/index.vue b/frontend/src/views/student/studentInfo/index.vue
index 244eaeba..e4467777 100644
--- a/frontend/src/views/student/studentInfo/index.vue
+++ b/frontend/src/views/student/studentInfo/index.vue
@@ -77,8 +77,15 @@
-
-
+
+
+
+
@@ -150,7 +157,7 @@
@update:visible="val => dialogVisible = val"
>
-
+
@@ -160,15 +167,59 @@
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -180,12 +231,12 @@
-
+
-
-
+
+
@@ -217,10 +268,21 @@
学员:{{ gradesStudent || '-' }}
学号:{{ gradesStudentNo || '-' }}
+
+ 年度:
+
+
+
+
-
+
@@ -235,11 +297,10 @@
{{ formatPassStatus(row.ytg) }}
-
-
+
@@ -251,7 +312,6 @@
-
@@ -277,26 +337,82 @@ import {
exportStudentProcessGrades
} from "@/api/studentRecords/studentRecords"
import { getDicts } from '@/api/system/dict/data'
+import { optionselect } from '@/api/system/dict/type'
const POLITICAL_STATUS_DICT_CODE = 'sys_political_status'
const NATION_DICT_CODE = 'nation_type'
const DEGREE_DICT_CODE = 'sys_degree_type'
const EDUCATION_LEVEL_DICT_CODE = 'sys_edu_level'
+const GRADES_VIEW_DISABLED_VALUES = new Set(['0', 'false', '否', '不允许'])
+const RESIDENT_IDENTITY_CARD_TYPES = new Set(['居民身份证', '身份证'])
+const IDENTITY_CARD_CHECK_CODES = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
+const IDENTITY_CARD_WEIGHTS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
+const PHONE_NUMBER_PATTERN = /^(1[3-9]\d{9}|0\d{2,3}-?\d{7,8})$/
+
+function isResidentIdentityCardType(certificateType) {
+ return RESIDENT_IDENTITY_CARD_TYPES.has(String(certificateType || '').trim())
+}
+
+function isValidIdentityCard(identityCard) {
+ const normalizedValue = String(identityCard || '').trim().toUpperCase()
+ if (!/^\d{17}[\dX]$/.test(normalizedValue)) {
+ return false
+ }
+
+ const year = Number(normalizedValue.slice(6, 10))
+ const month = Number(normalizedValue.slice(10, 12))
+ const day = Number(normalizedValue.slice(12, 14))
+ const birthDate = new Date(year, month - 1, day)
+ const isValidDate = birthDate.getFullYear() === year &&
+ birthDate.getMonth() === month - 1 && birthDate.getDate() === day
+ if (!isValidDate || birthDate > new Date()) {
+ return false
+ }
+
+ const checksum = IDENTITY_CARD_WEIGHTS.reduce((total, weight, index) => {
+ return total + Number(normalizedValue[index]) * weight
+ }, 0)
+
+ return IDENTITY_CARD_CHECK_CODES[checksum % 11] === normalizedValue[17]
+}
export default {
name: 'StudentInfoIndex',
data() {
+ const validateCertificateNumber = (rule, value, callback) => {
+ if (value && isResidentIdentityCardType(this.formData.jrzjlx) && !isValidIdentityCard(value)) {
+ callback(new Error('请输入合法的18位居民身份证号码'))
+ return
+ }
+ callback()
+ }
+ const validateBirthDate = (rule, value, callback) => {
+ if (value && new Date(`${value}T00:00:00`) > new Date()) {
+ callback(new Error('出生日期不能晚于今天'))
+ return
+ }
+ callback()
+ }
+ const validatePhoneNumber = (rule, value, callback) => {
+ if (value && !PHONE_NUMBER_PATTERN.test(String(value).trim())) {
+ callback(new Error('请输入正确的手机号码或固定电话号码'))
+ return
+ }
+ callback()
+ }
+
return {
// ==================== 查询条件 ====================
// 仅保留后端 XYXX 实体支持的字段:/student-records/list 会按实体字段动态构建查询条件
searchForm: {
xh: '', xm: '', xb: '', zjhm: '', zzmm: '', mz: '', jg: '', xw: '',
- ybzb: '', sfzh: '', whcd: '', bkbyyx: '', bq: '', lxdh: '', txdz: ''
+ ybzb: '', sfzh: '', whcd: '', bkbyyx: '', xylb: '', lxdh: '', txdz: ''
},
politicalStatusOptions: [],
nationOptions: [],
degreeOptions: [],
educationLevelOptions: [],
+ studentCategoryOptions: [],
// ==================== 数据表格 ====================
loading: false,
@@ -309,27 +425,29 @@ export default {
submitting: false,
formData: this.createEmptyForm(),
formRules: {
- bh: [{ required: true, message: '请输入编号', trigger: 'blur' }],
- xh: [{ required: true, message: '请输入学号', trigger: 'blur' }],
xm: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
xydqbh: [{ required: true, message: '请输入学员队期编号', trigger: 'blur' }],
- zjhm: [{ required: true, message: '请输入证件号码', trigger: 'blur' }],
- zzmm: [{ required: true, message: '请输入政治面貌', trigger: 'blur' }],
+ zjhm: [
+ { required: true, message: '请输入证件号码', trigger: 'blur' },
+ { validator: validateCertificateNumber, trigger: 'blur' }
+ ],
+ zzmm: [{ required: true, message: '请选择政治面貌', trigger: 'change' }],
xb: [{ required: true, message: '请选择性别', trigger: 'change' }],
- csrq: [{ required: true, message: '请选择出生日期', trigger: 'change' }],
- mz: [{ required: true, message: '请输入民族', trigger: 'blur' }],
+ csrq: [
+ { required: true, message: '请选择出生日期', trigger: 'change' },
+ { validator: validateBirthDate, trigger: 'change' }
+ ],
+ mz: [{ required: true, message: '请选择民族', trigger: 'change' }],
jg: [{ required: true, message: '请输入籍贯', trigger: 'blur' }],
- whcd: [{ required: true, message: '请输入文化程度', trigger: 'blur' }],
- xylb: [{ required: true, message: '请输入学员类别', trigger: 'blur' }],
+ whcd: [{ required: true, message: '请选择文化程度', trigger: 'change' }],
+ xylb: [{ required: true, message: '请选择学员类别', trigger: 'change' }],
ssjq: [{ required: true, message: '请输入所属军区', trigger: 'blur' }],
gfs: [{ required: true, message: '请选择国防生', trigger: 'change' }],
- txzt: [{ required: true, message: '请输入退学状态', trigger: 'blur' }],
- ljzt: [{ required: true, message: '请输入留级状态', trigger: 'blur' }],
- fbzt: [{ required: true, message: '请输入分班状态', trigger: 'blur' }],
yxckcj: [{ required: true, message: '请选择允许查看成绩', trigger: 'change' }],
dqbzbh: [{ required: true, message: '请输入当前班次编号', trigger: 'blur' }],
yzc: [{ required: true, message: '请选择已注册', trigger: 'change' }],
- jrzjlx: [{ required: true, message: '请输入军人证件类型', trigger: 'blur' }]
+ jrzjlx: [{ required: true, message: '请输入军人证件类型', trigger: 'blur' }],
+ lxdh: [{ validator: validatePhoneNumber, trigger: 'blur' }]
},
// ==================== 成绩弹窗 ====================
@@ -337,6 +455,7 @@ export default {
gradesTab: 'grades',
gradesData: [],
processGradesData: [],
+ gradesYear: '',
gradesStudent: '',
gradesStudentNo: '',
currentBh: '',
@@ -344,6 +463,22 @@ export default {
gradesExporting: false
}
},
+ computed: {
+ gradeYearOptions() {
+ const years = [...this.gradesData, ...this.processGradesData]
+ .map(item => item.nd)
+ .filter(year => year !== '' && year !== null && year !== undefined)
+ .map(String)
+
+ return [...new Set(years)].sort((firstYear, secondYear) => secondYear.localeCompare(firstYear))
+ },
+ filteredGradesData() {
+ return this.filterGradesByYear(this.gradesData)
+ },
+ filteredProcessGradesData() {
+ return this.filterGradesByYear(this.processGradesData)
+ }
+ },
created() {
this.loadStudentDictionaries()
},
@@ -354,27 +489,45 @@ export default {
/** 加载学员基础信息字典,业务字段按字典标签查询和提交。 */
async loadStudentDictionaries() {
const emptyResponse = { data: [] }
- const [politicalStatusResponse, nationResponse, degreeResponse, educationLevelResponse] =
+ const [politicalStatusResponse, nationResponse, degreeResponse, educationLevelResponse, dictTypeResponse] =
await Promise.all([
getDicts(POLITICAL_STATUS_DICT_CODE).catch(() => emptyResponse),
getDicts(NATION_DICT_CODE).catch(() => emptyResponse),
getDicts(DEGREE_DICT_CODE).catch(() => emptyResponse),
- getDicts(EDUCATION_LEVEL_DICT_CODE).catch(() => emptyResponse)
+ getDicts(EDUCATION_LEVEL_DICT_CODE).catch(() => emptyResponse),
+ optionselect().catch(() => emptyResponse)
])
this.politicalStatusOptions = politicalStatusResponse.data || []
this.nationOptions = nationResponse.data || []
this.degreeOptions = degreeResponse.data || []
this.educationLevelOptions = educationLevelResponse.data || []
+ this.studentCategoryOptions = await this.loadNamedDictionary(dictTypeResponse.data || [], '学员类别')
this.mergeExistingDictionaryOptions()
},
+ /** 根据字典名称匹配类型编码,避免业务页面硬编码数据库配置。 */
+ async loadNamedDictionary(dictTypes, dictName) {
+ const dictType = dictTypes.find(item => item.dictName === dictName) ||
+ dictTypes.find(item => String(item.dictName || '').includes(dictName))
+ if (!dictType || !dictType.dictType) {
+ return []
+ }
+ try {
+ const response = await getDicts(dictType.dictType)
+ return response.data || []
+ } catch (error) {
+ return []
+ }
+ },
+
/** 字典缺项时保留列表已有值,避免历史数据无法作为查询条件。 */
mergeExistingDictionaryOptions() {
this.politicalStatusOptions = this.mergeFieldOptions(this.politicalStatusOptions, 'zzmm')
this.nationOptions = this.mergeFieldOptions(this.nationOptions, 'mz')
this.degreeOptions = this.mergeFieldOptions(this.degreeOptions, 'xw')
this.educationLevelOptions = this.mergeFieldOptions(this.educationLevelOptions, 'whcd')
+ this.studentCategoryOptions = this.mergeFieldOptions(this.studentCategoryOptions, 'xylb')
},
mergeFieldOptions(dictionaryOptions, fieldName) {
@@ -427,7 +580,9 @@ export default {
/** 组装查询参数:仅传后端 XYXX 实体支持的字符串字段,空值忽略 */
buildQueryParams(params) {
- const textFields = ['xh', 'xm', 'zjhm', 'zzmm', 'mz', 'jg', 'xw', 'ybzb', 'sfzh', 'whcd', 'bkbyyx', 'bq', 'lxdh', 'txdz']
+ const textFields = [
+ 'xh', 'xm', 'zjhm', 'zzmm', 'mz', 'jg', 'xw', 'ybzb', 'sfzh', 'whcd', 'bkbyyx', 'xylb', 'lxdh', 'txdz'
+ ]
textFields.forEach(key => {
const v = this.searchForm[key]
if (v !== '' && v !== null && v !== undefined) params[key] = v.trim()
@@ -488,6 +643,13 @@ export default {
this.submitting = true
const isAdd = this.dialogTitle === '新增学员'
const payload = { ...this.formData }
+ if (isAdd) {
+ delete payload.bh
+ delete payload.xh
+ delete payload.txzt
+ delete payload.ljzt
+ delete payload.fbzt
+ }
const request = isAdd ? addStudentRecord(payload) : updateStudentRecord(payload)
request.then(() => {
this.$message.success(isAdd ? '新增成功' : '编辑成功')
@@ -516,11 +678,20 @@ export default {
// ==================== 成绩弹窗 ====================
async handleGrades(row) {
+ if (this.isGradesViewDisabled(row.yxckcj)) {
+ this.$alert('不允许查看该学员成绩', '提示', {
+ confirmButtonText: '确定',
+ type: 'warning'
+ }).catch(() => {})
+ return
+ }
+
this.gradesStudent = row.xm || ''
this.gradesStudentNo = row.xh || ''
this.currentBh = row.bh || ''
this.gradesData = []
this.processGradesData = []
+ this.gradesYear = ''
this.gradesTab = 'grades'
this.gradesVisible = true
this.gradesLoading = true
@@ -549,6 +720,18 @@ export default {
return '-'
},
+ isGradesViewDisabled(value) {
+ return GRADES_VIEW_DISABLED_VALUES.has(String(value).trim().toLowerCase())
+ },
+
+ filterGradesByYear(grades) {
+ if (!this.gradesYear) {
+ return grades
+ }
+
+ return grades.filter(item => String(item.nd) === this.gradesYear)
+ },
+
downloadGradesFile(blob, fileName) {
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
@@ -661,10 +844,27 @@ export default {
.student-summary {
display: flex;
+ flex-wrap: wrap;
+ align-items: center;
gap: 32px;
margin-bottom: 8px;
color: #303133;
line-height: 24px;
+
+ .grades-year-filter {
+ display: flex;
+ align-items: center;
+ margin-left: auto;
+
+ .filter-label {
+ flex-shrink: 0;
+ margin-right: 8px;
+ }
+
+ .el-select {
+ width: 160px;
+ }
+ }
}
}
diff --git a/frontend/src/views/student/warningCondition/index.vue b/frontend/src/views/student/warningCondition/index.vue
index a31c3073..29992204 100644
--- a/frontend/src/views/student/warningCondition/index.vue
+++ b/frontend/src/views/student/warningCondition/index.vue
@@ -11,12 +11,26 @@
-
+
+
+
-
+
+
+
@@ -101,12 +115,26 @@
-
+
+
+
-
+
+
+
@@ -116,12 +144,10 @@
-
-
-
-
-
-
+
+ 否
+ 是
+
@@ -243,6 +269,10 @@ import {
addWarningCondition,
updateWarningCondition
} from "@/api/studentRecords/warningCondition"
+import { getDicts } from '@/api/system/dict/data'
+
+const TRAINING_TYPE_DICT_CODE = 'train_type'
+const TRAINING_LEVEL_DICT_CODE = 'train_level'
export default {
name: "WarningCondition",
@@ -255,6 +285,8 @@ export default {
pxcc: '',
ty: 0
},
+ trainingTypeOptions: [],
+ trainingLevelOptions: [],
// ==================== 列表数据 ====================
loading: false,
@@ -272,8 +304,7 @@ export default {
formRules: {
mc: [{ required: true, message: "名称不能为空", trigger: "blur" }],
ty: [{ required: true, message: "停用不能为空", trigger: "change" }],
- bb: [{ required: true, message: "版本不能为空", trigger: "blur" }],
- xgsj: [{ required: true, message: "修改时间不能为空", trigger: "change" }]
+ bb: [{ required: true, message: "版本不能为空", trigger: "blur" }]
},
// ==================== 详情 ====================
@@ -283,9 +314,21 @@ export default {
}
},
created() {
+ this.loadTrainingDictionaries()
this.fetchList()
},
methods: {
+ /** 加载培训类型、培训层次字典。 */
+ async loadTrainingDictionaries() {
+ const emptyResponse = { data: [] }
+ const [typeResponse, levelResponse] = await Promise.all([
+ getDicts(TRAINING_TYPE_DICT_CODE).catch(() => emptyResponse),
+ getDicts(TRAINING_LEVEL_DICT_CODE).catch(() => emptyResponse)
+ ])
+ this.trainingTypeOptions = typeResponse.data || []
+ this.trainingLevelOptions = levelResponse.data || []
+ },
+
/** 创建空表单 */
createEmptyForm() {
return {
@@ -305,8 +348,7 @@ export default {
qbbjgmssx: undefined,
qbbjgmsxx: undefined,
ty: 0,
- bb: '',
- xgsj: ''
+ bb: ''
}
},
@@ -398,7 +440,7 @@ export default {
'qbksbjgmssx', 'qbksbjgmsxx',
'qbkcbjgmssx', 'qbkcbjgmsxx',
'qbbjgmssx', 'qbbjgmsxx',
- 'bb', 'xgsj'
+ 'bb'
]
const result = this.createEmptyForm()
fieldKeys.forEach(key => {
diff --git a/frontend/src/views/subjectMajor/discipline/index.vue b/frontend/src/views/subjectMajor/discipline/index.vue
index 4a8b328a..d1b8e208 100644
--- a/frontend/src/views/subjectMajor/discipline/index.vue
+++ b/frontend/src/views/subjectMajor/discipline/index.vue
@@ -191,13 +191,6 @@
-
-
-
-
-
-
-
@@ -233,7 +226,6 @@
{{ detailForm.tysj || '-' }}
- {{ detailForm.jsonzd || '-' }}
{{ detailForm.bz || '-' }}
diff --git a/frontend/src/views/subjectMajor/major/index.vue b/frontend/src/views/subjectMajor/major/index.vue
index 598e346b..1ffb312c 100644
--- a/frontend/src/views/subjectMajor/major/index.vue
+++ b/frontend/src/views/subjectMajor/major/index.vue
@@ -253,11 +253,6 @@
-
-
-
-
-
@@ -330,7 +325,6 @@
{{ viewForm.ty === 1 || viewForm.ty === true ? '是' : '否' }}
- {{ viewForm.jsonzd || '-' }}
{{ viewForm.pymb || '-' }}
{{ viewForm.zybz || '-' }}
{{ viewForm.zygf || '-' }}
diff --git a/frontend/src/views/textbook/index.vue b/frontend/src/views/textbook/index.vue
index d409d92f..adf9ce76 100644
--- a/frontend/src/views/textbook/index.vue
+++ b/frontend/src/views/textbook/index.vue
@@ -624,11 +624,6 @@
-
-
-
-
-
@@ -657,7 +652,6 @@
{{ stockDetailData.sprbh || '-' }}
{{ stockDetailData.zt || '-' }}
{{ stockDetailData.bz || '-' }}
- {{ stockDetailData.jsonzd || '-' }}
{{ fmtDateTime(stockDetailData.cjsj) || '-' }}
{{ fmtDateTime(stockDetailData.xgsj) || '-' }}
{{ fmtDateTime(stockDetailData.tjsj) || '-' }}
@@ -720,11 +714,6 @@
-
-
-
-
-
@@ -752,7 +741,6 @@
{{ fmtDateTime(detailViewData.hwbwsj) || '-' }}
{{ detailViewData.bz || '-' }}
- {{ detailViewData.jsonzd || '-' }}
{{ fmtVal(detailViewData.kzswHkcsl) }}
{{ fmtVal(detailViewData.kzswHjcsl) }}
{{ fmtVal(detailViewData.kzswQkcsl) }}