forked from liweijie/education
Merge branch 'main' of https://gitea.fengyingkj.top/zhaichao/education
This commit is contained in:
@@ -21,7 +21,7 @@ export function getApplication(bh) {
|
||||
})
|
||||
}
|
||||
|
||||
// 新增学籍异动申请(请求体 XYXJYDSQB 实体;bh 需前端传入,创建/修改时间后端自动维护)
|
||||
// 新增学籍异动申请(编号、状态和创建/修改时间由后端维护)
|
||||
export function addApplication(data) {
|
||||
return request({
|
||||
url: '/student-records/application/add',
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
:value="activeSemester ? activeSemester.nd : ''"
|
||||
placeholder="请选择学期"
|
||||
size="small"
|
||||
filterable
|
||||
class="semester-select"
|
||||
@change="handleSwitch"
|
||||
>
|
||||
|
||||
@@ -21,7 +21,14 @@
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
<el-form-item label="学员队类型">
|
||||
<el-input v-model="searchForm.xydlx" placeholder="请输入学员队类型" clearable @keyup.enter.native="handleSearch" />
|
||||
<el-select v-model="searchForm.xydlx" placeholder="请选择学员队类型" clearable filterable class="w-full">
|
||||
<el-option
|
||||
v-for="item in teamTypeOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
@@ -32,8 +39,8 @@
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
<el-form-item label="虚实类型">
|
||||
<el-select v-model="searchForm.xslx" placeholder="请选择虚实类型" clearable class="w-full">
|
||||
<el-option label="虚" :value="0" />
|
||||
<el-option label="实" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
<el-option label="是" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -74,7 +81,7 @@
|
||||
<el-table-column label="虚实类型" width="90" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="Number(row.xslx) === 1 ? 'success' : 'info'" size="mini">
|
||||
{{ Number(row.xslx) === 1 ? '实' : '虚' }}
|
||||
{{ Number(row.xslx) === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -146,7 +153,21 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="专业代号" prop="zydh">
|
||||
<el-input v-model="form.zydh" placeholder="请输入专业代号" />
|
||||
<el-select
|
||||
v-model="form.zydh"
|
||||
:loading="majorOptionsLoading"
|
||||
placeholder="请选择专业"
|
||||
clearable
|
||||
filterable
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in majorOptions"
|
||||
:key="item.zydh"
|
||||
:label="formatMajorLabel(item)"
|
||||
:value="item.zydh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -156,17 +177,38 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员队类型" prop="xydlx">
|
||||
<el-input v-model="form.xydlx" placeholder="请输入学员队类型" />
|
||||
<el-select v-model="form.xydlx" placeholder="请选择学员队类型" filterable class="w-full">
|
||||
<el-option
|
||||
v-for="item in teamTypeOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="节次类别" prop="jclb">
|
||||
<el-input v-model="form.jclb" placeholder="请输入节次类别" />
|
||||
<el-select v-model="form.jclb" placeholder="请选择节次类别" filterable class="w-full">
|
||||
<el-option
|
||||
v-for="item in sessionCategoryOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="系统模式" prop="xtms">
|
||||
<el-input v-model="form.xtms" placeholder="请输入系统模式" />
|
||||
<el-select v-model="form.xtms" placeholder="请选择系统模式" filterable class="w-full">
|
||||
<el-option
|
||||
v-for="item in systemModeOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -176,12 +218,14 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属单位">
|
||||
<el-input v-model="form.ssdw" placeholder="请输入所属单位" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="序号">
|
||||
<el-input-number v-model="form.xh" :min="0" controls-position="right" style="width: 100%" />
|
||||
<el-select v-model="form.ssdw" placeholder="请选择所属单位" clearable filterable class="w-full">
|
||||
<el-option
|
||||
v-for="item in unitCategoryOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -196,14 +240,14 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="虚实类型" prop="xslx">
|
||||
<el-select v-model="form.xslx" class="w-full">
|
||||
<el-option label="虚" :value="0" />
|
||||
<el-option label="实" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
<el-option label="是" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="主体培训任务" prop="ztpxrw">
|
||||
<el-select v-model="form.ztpxrw" class="w-full">
|
||||
<el-select v-model="form.ztpxrw" class="w-full" @change="handlePrimaryTrainingTaskChange">
|
||||
<el-option label="是" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
</el-select>
|
||||
@@ -211,12 +255,26 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训任务标识号">
|
||||
<el-input v-model="form.pxrwbsh" placeholder="请输入培训任务标识号" />
|
||||
<el-select
|
||||
v-model="form.pxrwbsh"
|
||||
:loading="trainingTaskLoading"
|
||||
placeholder="请选择培训任务"
|
||||
clearable
|
||||
filterable
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in trainingTaskOptions"
|
||||
:key="item.bsh"
|
||||
:label="formatTrainingTaskLabel(item)"
|
||||
:value="item.bsh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="在校状态">
|
||||
<el-select v-model="form.zxzt" class="w-full">
|
||||
<el-select v-model="form.zxzt" placeholder="请选择在校状态" clearable class="w-full">
|
||||
<el-option label="在校" :value="1" />
|
||||
<el-option label="毕业" :value="0" />
|
||||
</el-select>
|
||||
@@ -233,9 +291,6 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="JSON字段">
|
||||
<el-input v-model="form.jsonzd" placeholder="请输入 JSON 字段" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.bz" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
@@ -262,11 +317,10 @@
|
||||
<el-descriptions-item label="系统模式">{{ detailForm.xtms || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="简称">{{ detailForm.jc || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="所属单位">{{ detailForm.ssdw || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="序号">{{ fmtValue(detailForm.xh) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务类别">{{ detailForm.rwlb || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="虚实类型">
|
||||
<el-tag :type="Number(detailForm.xslx) === 1 ? 'success' : 'info'" size="mini">
|
||||
{{ Number(detailForm.xslx) === 1 ? '实' : '虚' }}
|
||||
{{ Number(detailForm.xslx) === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="主体培训任务">
|
||||
@@ -282,7 +336,6 @@
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="入学日期">{{ detailForm.rxrq || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="毕业日期">{{ detailForm.byrq || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="JSON字段" :span="2">{{ detailForm.jsonzd || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{ detailForm.bz || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
@@ -301,10 +354,19 @@ import {
|
||||
addTeam,
|
||||
updateTeam,
|
||||
delTeam,
|
||||
listTrainingTasks,
|
||||
importTeam,
|
||||
exportTeam,
|
||||
downloadTeamTemplate
|
||||
} from '@/api/studentRecords/team'
|
||||
import { getDicts } from '@/api/system/dict/data'
|
||||
import { listMajor } from '@/api/subjectMajor/major'
|
||||
|
||||
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'
|
||||
const MAJOR_OPTION_PAGE_SIZE = 10000
|
||||
|
||||
export default {
|
||||
name: 'ShiftTeamIndex',
|
||||
@@ -319,6 +381,14 @@ export default {
|
||||
rwlb: '',
|
||||
xslx: undefined
|
||||
},
|
||||
teamTypeOptions: [],
|
||||
sessionCategoryOptions: [],
|
||||
systemModeOptions: [],
|
||||
unitCategoryOptions: [],
|
||||
majorOptions: [],
|
||||
majorOptionsLoading: false,
|
||||
trainingTaskOptions: [],
|
||||
trainingTaskLoading: false,
|
||||
|
||||
// ==================== 文件导入 ====================
|
||||
selectedFile: null,
|
||||
@@ -341,14 +411,14 @@ export default {
|
||||
xydbh: [{ required: true, message: '请输入学员队编号', trigger: 'blur' }],
|
||||
xydmc: [{ required: true, message: '请输入学员队名称', trigger: 'blur' }],
|
||||
xydrs: [{ required: true, message: '请输入学员队人数', trigger: 'change' }],
|
||||
zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],
|
||||
zydh: [{ required: true, message: '请选择专业', trigger: 'change' }],
|
||||
rwlb: [{ required: true, message: '请输入任务类别', trigger: 'blur' }],
|
||||
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 +434,53 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTeamDictionaries()
|
||||
this.loadMajorOptions()
|
||||
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 || []
|
||||
},
|
||||
|
||||
/** 加载专业下拉选项,标签同时包含名称、代码和代号,便于直接模糊搜索。 */
|
||||
async loadMajorOptions() {
|
||||
this.majorOptionsLoading = true
|
||||
try {
|
||||
const response = await listMajor({
|
||||
pageNum: 1,
|
||||
pageSize: MAJOR_OPTION_PAGE_SIZE,
|
||||
ty: false
|
||||
})
|
||||
const data = response.data || {}
|
||||
this.majorOptions = Array.isArray(data.records) ? data.records : []
|
||||
} catch (error) {
|
||||
this.majorOptions = []
|
||||
} finally {
|
||||
this.majorOptionsLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
formatMajorLabel(item) {
|
||||
const identifiers = [item.zydm, item.zydh].filter(Boolean).join(' / ')
|
||||
if (!item.zymc) {
|
||||
return identifiers
|
||||
}
|
||||
|
||||
return identifiers ? `${item.zymc}(${identifiers})` : item.zymc
|
||||
},
|
||||
|
||||
createEmptyForm() {
|
||||
return {
|
||||
xydbh: '',
|
||||
@@ -376,8 +490,7 @@ export default {
|
||||
zydh: '',
|
||||
zyjsbh: '',
|
||||
bz: '',
|
||||
zxzt: 1,
|
||||
xh: undefined,
|
||||
zxzt: undefined,
|
||||
rwlb: '',
|
||||
xslx: 1,
|
||||
rxrq: '',
|
||||
@@ -402,6 +515,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 +588,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,8 +613,7 @@ export default {
|
||||
zydh: d.zydh || '',
|
||||
zyjsbh: d.zyjsbh || '',
|
||||
bz: d.bz || '',
|
||||
zxzt: d.zxzt !== null && d.zxzt !== undefined ? Number(d.zxzt) : 1,
|
||||
xh: d.xh !== null && d.xh !== undefined ? d.xh : undefined,
|
||||
zxzt: this.normalizeSchoolStatus(d.zxzt),
|
||||
rwlb: d.rwlb || '',
|
||||
xslx: d.xslx !== null && d.xslx !== undefined ? Number(d.xslx) : 1,
|
||||
rxrq: this.formatDate(d.rxrq),
|
||||
@@ -503,9 +627,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 +667,16 @@ 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)
|
||||
// 后端字段为 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 +786,14 @@ export default {
|
||||
}
|
||||
|
||||
.shift-team-page {
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.search-form {
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.search-form {
|
||||
.search-actions-row {
|
||||
margin-top: 2px;
|
||||
border-top: 1px dashed #ebeef5;
|
||||
|
||||
@@ -106,9 +106,6 @@
|
||||
@update:visible="val => formDialogVisible = val"
|
||||
>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="110px" class="add-form">
|
||||
<el-form-item label="编号" prop="bh">
|
||||
<el-input v-model="form.bh" placeholder="请输入编号" :disabled="!isAdd" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学号" prop="xh">
|
||||
<el-input
|
||||
ref="studentNoInput"
|
||||
@@ -134,11 +131,6 @@
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="zt">
|
||||
<el-select v-model="form.zt" placeholder="请选择状态" class="w-full">
|
||||
<el-option v-for="(item, key) in statusMap" :key="key" :label="item.label" :value="Number(key)" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="formDialogVisible = false">取消</el-button>
|
||||
@@ -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) {
|
||||
|
||||
@@ -77,8 +77,15 @@
|
||||
<el-form-item label="本科毕业院校">
|
||||
<el-input v-model="searchForm.bkbyyx" placeholder="请输入本科毕业院校" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="标签">
|
||||
<el-input v-model="searchForm.bq" placeholder="请输入标签" clearable />
|
||||
<el-form-item label="学员类别">
|
||||
<el-select v-model="searchForm.xylb" placeholder="请选择学员类别" clearable filterable class="full-width">
|
||||
<el-option
|
||||
v-for="item in studentCategoryOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="searchForm.lxdh" placeholder="请输入联系电话" clearable />
|
||||
@@ -150,7 +157,7 @@
|
||||
@update:visible="val => dialogVisible = val"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
|
||||
<el-row :gutter="20">
|
||||
<el-row v-if="dialogTitle !== '新增学员'" :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="编号" prop="bh"><el-input v-model="formData.bh" placeholder="请输入编号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="学号" prop="xh"><el-input v-model="formData.xh" placeholder="请输入学号" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
@@ -160,15 +167,59 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="出生日期" prop="csrq"><el-date-picker v-model="formData.csrq" type="date" placeholder="请选择" value-format="yyyy-MM-dd" class="full-width" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="民族" prop="mz"><el-input v-model="formData.mz" placeholder="请输入民族" /></el-form-item></el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="民族" prop="mz">
|
||||
<el-select v-model="formData.mz" placeholder="请选择民族" filterable class="full-width">
|
||||
<el-option
|
||||
v-for="item in nationOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="籍贯" prop="jg"><el-input v-model="formData.jg" placeholder="请输入籍贯" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="政治面貌" prop="zzmm"><el-input v-model="formData.zzmm" placeholder="请输入政治面貌" /></el-form-item></el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="政治面貌" prop="zzmm">
|
||||
<el-select v-model="formData.zzmm" placeholder="请选择政治面貌" filterable class="full-width">
|
||||
<el-option
|
||||
v-for="item in politicalStatusOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="文化程度" prop="whcd"><el-input v-model="formData.whcd" placeholder="请输入文化程度" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="学员类别" prop="xylb"><el-input v-model="formData.xylb" placeholder="请输入学员类别" /></el-form-item></el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="文化程度" prop="whcd">
|
||||
<el-select v-model="formData.whcd" placeholder="请选择文化程度" filterable class="full-width">
|
||||
<el-option
|
||||
v-for="item in educationLevelOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员类别" prop="xylb">
|
||||
<el-select v-model="formData.xylb" placeholder="请选择学员类别" filterable class="full-width">
|
||||
<el-option
|
||||
v-for="item in studentCategoryOptions"
|
||||
:key="item.dictCode || item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="学员队期编号" prop="xydqbh"><el-input v-model="formData.xydqbh" placeholder="请输入学员队期编号" /></el-form-item></el-col>
|
||||
@@ -180,12 +231,12 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="军人证件类型" prop="jrzjlx"><el-input v-model="formData.jrzjlx" placeholder="请输入军人证件类型" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="退学状态" prop="txzt"><el-input v-model="formData.txzt" placeholder="请输入退学状态" /></el-form-item></el-col>
|
||||
<el-col v-if="dialogTitle !== '新增学员'" :span="12"><el-form-item label="退学状态" prop="txzt"><el-input v-model="formData.txzt" placeholder="请输入退学状态" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8"><el-form-item label="国防生" prop="gfs"><el-select v-model="formData.gfs" placeholder="请选择" class="full-width"><el-option label="是" value="1" /><el-option label="否" value="0" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="留级状态" prop="ljzt"><el-input v-model="formData.ljzt" placeholder="请输入" /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="分班状态" prop="fbzt"><el-input v-model="formData.fbzt" placeholder="请输入" /></el-form-item></el-col>
|
||||
<el-col v-if="dialogTitle !== '新增学员'" :span="8"><el-form-item label="留级状态" prop="ljzt"><el-input v-model="formData.ljzt" placeholder="请输入" /></el-form-item></el-col>
|
||||
<el-col v-if="dialogTitle !== '新增学员'" :span="8"><el-form-item label="分班状态" prop="fbzt"><el-input v-model="formData.fbzt" placeholder="请输入" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8"><el-form-item label="允许查看成绩" prop="yxckcj"><el-select v-model="formData.yxckcj" placeholder="请选择" class="full-width"><el-option label="是" value="1" /><el-option label="否" value="0" /></el-select></el-form-item></el-col>
|
||||
@@ -217,10 +268,21 @@
|
||||
<div class="student-summary">
|
||||
<span><strong>学员:</strong>{{ gradesStudent || '-' }}</span>
|
||||
<span><strong>学号:</strong>{{ gradesStudentNo || '-' }}</span>
|
||||
<div class="grades-year-filter">
|
||||
<span class="filter-label">年度:</span>
|
||||
<el-select v-model="gradesYear" size="small" clearable placeholder="全部年度">
|
||||
<el-option
|
||||
v-for="year in gradeYearOptions"
|
||||
:key="year"
|
||||
:label="year"
|
||||
:value="year"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs v-model="gradesTab">
|
||||
<el-tab-pane label="成绩" name="grades">
|
||||
<el-table v-loading="gradesLoading" :data="gradesData" stripe border max-height="420">
|
||||
<el-table v-loading="gradesLoading" :data="filteredGradesData" stripe border max-height="420">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="nd" label="年度" width="85" align="center" />
|
||||
<el-table-column prop="kmbh" label="科目编号" min-width="120" align="center" show-overflow-tooltip />
|
||||
@@ -235,11 +297,10 @@
|
||||
<el-table-column label="考试结果" width="90" align="center">
|
||||
<template slot-scope="{ row }">{{ formatPassStatus(row.ytg) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bz" label="备注" min-width="120" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="进程成绩" name="process">
|
||||
<el-table v-loading="gradesLoading" :data="processGradesData" stripe border max-height="420">
|
||||
<el-table v-loading="gradesLoading" :data="filteredProcessGradesData" stripe border max-height="420">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="nd" label="年度" width="85" align="center" />
|
||||
<el-table-column prop="kmbh" label="科目编号" min-width="120" align="center" show-overflow-tooltip />
|
||||
@@ -251,7 +312,6 @@
|
||||
<el-table-column prop="bkcj3" label="补考成绩3" width="100" align="center" />
|
||||
<el-table-column prop="bkcs" label="补考次数" width="90" align="center" />
|
||||
<el-table-column prop="ksqk" label="考试情况" width="100" align="center" />
|
||||
<el-table-column prop="bz" label="备注" min-width="120" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,12 +11,26 @@
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
<el-form-item label="培训类型">
|
||||
<el-input v-model="searchForm.pxlx" placeholder="请输入培训类型" clearable @keyup.enter.native="handleSearch" />
|
||||
<el-select v-model="searchForm.pxlx" placeholder="请选择培训类型" clearable filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in trainingTypeOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
<el-form-item label="培训层次">
|
||||
<el-input v-model="searchForm.pxcc" placeholder="请输入培训层次" clearable @keyup.enter.native="handleSearch" />
|
||||
<el-select v-model="searchForm.pxcc" placeholder="请选择培训层次" clearable filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in trainingLevelOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8">
|
||||
@@ -101,12 +115,26 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训类型" prop="pxlx">
|
||||
<el-input v-model="form.pxlx" placeholder="请输入培训类型" />
|
||||
<el-select v-model="form.pxlx" placeholder="请选择培训类型" filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in trainingTypeOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训层次" prop="pxcc">
|
||||
<el-input v-model="form.pxcc" placeholder="请输入培训层次" />
|
||||
<el-select v-model="form.pxcc" placeholder="请选择培训层次" filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in trainingLevelOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictLabel"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -116,12 +144,10 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="停用" prop="ty">
|
||||
<el-switch v-model="form.ty" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="修改时间" prop="xgsj">
|
||||
<el-date-picker v-model="form.xgsj" type="datetime" placeholder="请选择修改时间" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" />
|
||||
<el-radio-group v-model="form.ty">
|
||||
<el-radio :label="0">否</el-radio>
|
||||
<el-radio :label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -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 => {
|
||||
|
||||
@@ -191,13 +191,6 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="JSON字段">
|
||||
<el-input v-model="form.jsonzd" placeholder="请输入JSON字段" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.bz" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
@@ -233,7 +226,6 @@
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="停用时间">{{ detailForm.tysj || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="JSON字段" :span="2">{{ detailForm.jsonzd || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{ detailForm.bz || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
@@ -253,11 +253,6 @@
|
||||
<el-input-number v-model="form.xhbs" :min="0" controls-position="right" style="width: 100%" placeholder="请输入序号标识" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="JSON字段">
|
||||
<el-input v-model="form.jsonzd" placeholder="请输入JSON字段" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="停用" prop="ty">
|
||||
<el-switch v-model="form.ty" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
||||
@@ -330,7 +325,6 @@
|
||||
{{ viewForm.ty === 1 || viewForm.ty === true ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="JSON字段">{{ viewForm.jsonzd || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="培养目标" :span="2">{{ viewForm.pymb || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="专业备注" :span="2">{{ viewForm.zybz || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="专业规范" :span="2">{{ viewForm.zygf || '-' }}</el-descriptions-item>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="app-container system-dict-data">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="字典名称" prop="dictType">
|
||||
<el-select v-model="queryParams.dictType">
|
||||
<el-select v-model="queryParams.dictType" filterable>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.dictId"
|
||||
|
||||
@@ -141,14 +141,14 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位">
|
||||
<el-select v-model="form.postIds" multiple placeholder="请选择岗位">
|
||||
<el-select v-model="form.postIds" multiple filterable placeholder="请选择岗位">
|
||||
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1" ></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色">
|
||||
<el-select v-model="form.roleIds" multiple placeholder="请选择角色">
|
||||
<el-select v-model="form.roleIds" multiple filterable placeholder="请选择角色">
|
||||
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
v-model="searchForm.nd"
|
||||
placeholder="请选择年度"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
<div class="section-card">
|
||||
<el-form :model="queryParams" :inline="true" size="small" class="search-form" @submit.native.prevent>
|
||||
<el-form-item label="年度">
|
||||
<el-select v-model="queryParams.nd" placeholder="请选择年度" clearable style="width: 140px">
|
||||
<el-select
|
||||
v-model="queryParams.nd"
|
||||
placeholder="请选择年度"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 140px"
|
||||
>
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -99,7 +105,13 @@
|
||||
<el-dialog title="新增课表调整申请" :visible.sync="addVisible" width="640px" append-to-body>
|
||||
<el-form ref="addForm" :model="addForm" :rules="addRules" label-width="110px">
|
||||
<el-form-item label="年度" prop="nd">
|
||||
<el-select v-model="addForm.nd" placeholder="请选择年度" style="width: 100%" @change="handleAddYearChange">
|
||||
<el-select
|
||||
v-model="addForm.nd"
|
||||
placeholder="请选择年度"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="handleAddYearChange"
|
||||
>
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
<div class="header-actions">
|
||||
<el-form inline class="toolbar-form" @submit.native.prevent>
|
||||
<el-form-item label="年度" class="year-item">
|
||||
<el-select v-model="nd" placeholder="请选择年度" style="width: 130px" @change="handleNdChange">
|
||||
<el-select
|
||||
v-model="nd"
|
||||
placeholder="请选择年度"
|
||||
filterable
|
||||
style="width: 130px"
|
||||
@change="handleNdChange"
|
||||
>
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y + ' 年'" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="年度" prop="nd">
|
||||
<el-select v-model="form.nd" placeholder="请选择年度" style="width: 100%">
|
||||
<el-select v-model="form.nd" placeholder="请选择年度" filterable style="width: 100%">
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -16,7 +16,14 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="年度">
|
||||
<el-select v-model="filterYear" placeholder="全部年度" clearable style="width: 140px" @change="handleYearChange">
|
||||
<el-select
|
||||
v-model="filterYear"
|
||||
placeholder="全部年度"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 140px"
|
||||
@change="handleYearChange"
|
||||
>
|
||||
<el-option v-for="y in yearFilterOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -131,7 +138,7 @@
|
||||
>
|
||||
<el-form ref="batchAddFormRef" :model="batchAddForm" :rules="batchAddRules" label-width="100px">
|
||||
<el-form-item label="年度" prop="nd">
|
||||
<el-select v-model="batchAddForm.nd" placeholder="请选择年度" style="width: 100%">
|
||||
<el-select v-model="batchAddForm.nd" placeholder="请选择年度" filterable style="width: 100%">
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="`${y}年`" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="年度">
|
||||
<el-select v-model="searchForm.nd" placeholder="请选择年度" clearable style="width: 140px">
|
||||
<el-select v-model="searchForm.nd" placeholder="请选择年度" clearable filterable style="width: 140px">
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -109,7 +109,7 @@
|
||||
<el-input v-model="form.rwmc" placeholder="请输入任务名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="年度" prop="nd">
|
||||
<el-select v-model="form.nd" placeholder="请选择年度" style="width: 100%">
|
||||
<el-select v-model="form.nd" placeholder="请选择年度" filterable style="width: 100%">
|
||||
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -624,11 +624,6 @@
|
||||
<el-form-item label="备注"><el-input v-model="stockForm.bz" type="textarea" :rows="2" placeholder="请输入" /></el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="JSONZD"><el-input v-model="stockForm.jsonzd" placeholder="请输入" /></el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
@@ -657,7 +652,6 @@
|
||||
<el-descriptions-item label="审批人编号">{{ stockDetailData.sprbh || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">{{ stockDetailData.zt || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注">{{ stockDetailData.bz || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="JSONZD">{{ stockDetailData.jsonzd || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{ fmtDateTime(stockDetailData.cjsj) || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="修改时间">{{ fmtDateTime(stockDetailData.xgsj) || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="提交时间">{{ fmtDateTime(stockDetailData.tjsj) || '-' }}</el-descriptions-item>
|
||||
@@ -720,11 +714,6 @@
|
||||
<el-form-item label="备注"><el-input v-model="detailForm.bz" type="textarea" :rows="2" placeholder="请输入" /></el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="JSONZD"><el-input v-model="detailForm.jsonzd" placeholder="请输入" /></el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
@@ -752,7 +741,6 @@
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="还回完毕时间">{{ fmtDateTime(detailViewData.hwbwsj) || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注">{{ detailViewData.bz || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="JSONZD">{{ detailViewData.jsonzd || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="快照_事务后库存数量">{{ fmtVal(detailViewData.kzswHkcsl) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="快照_事务后借出数量">{{ fmtVal(detailViewData.kzswHjcsl) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="快照_事务前库存数量">{{ fmtVal(detailViewData.kzswQkcsl) }}</el-descriptions-item>
|
||||
|
||||
Reference in New Issue
Block a user