This commit is contained in:
2026-08-26 14:12:30 +08:00
3 changed files with 160 additions and 42 deletions
@@ -86,7 +86,7 @@
<el-table-column prop="pxcc" label="培训层次" width="85" align="center" />
<el-table-column prop="zzmm" label="政治面貌" width="85" align="center" />
<el-table-column prop="mz" label="民族" width="55" align="center" />
<el-table-column prop="jg" label="籍贯" width="55" align="center" />
<el-table-column prop="jg" label="籍贯" width="90" align="center" show-overflow-tooltip />
<el-table-column prop="xw" label="学位" width="55" align="center" />
<el-table-column prop="zczt" label="注册状态" width="85" align="center" />
<el-table-column prop="xjyd" label="学籍异动状态" width="110" align="center" />
@@ -359,7 +359,7 @@ export default {
{ label: '已发回', value: 2 },
{ label: '已拒绝', value: 3 }
],
statCards: [],
statCards: this.createStatCards([0, 0, 0, 0]),
// 新增申请
addVisible: false,
addLoading: false,
@@ -397,7 +397,10 @@ export default {
}
},
created() {
this.loadYearOptions().then(() => this.loadList())
this.loadYearOptions().then(() => {
this.loadStatistics()
this.loadList()
})
},
methods: {
/* ---------- 年度下拉(数据来自 /semester/all ---------- */
@@ -458,12 +461,10 @@ export default {
const data = response.data || {}
this.tableData = data.records || []
this.total = data.total || 0
this.refreshStatCards()
this.loading = false
}).catch(() => {
this.tableData = []
this.total = 0
this.refreshStatCards()
this.loading = false
})
},
@@ -481,18 +482,56 @@ export default {
}
this.loadList()
},
refreshStatCards() {
const list = this.tableData
this.statCards = [
{ title: '本页申请', value: list.length, gradient: 'linear-gradient(135deg, #00875a 0%, #00b877 100%)', filter: undefined },
{ title: '教研室待审批', value: list.filter(i => i.jyspzzt === 0).length, gradient: 'linear-gradient(135deg, #e6a23c 0%, #f8b04c 100%)', filter: 0 },
{ title: '教研室已同意', value: list.filter(i => i.jyspzzt === 1).length, gradient: 'linear-gradient(135deg, #409eff 0%, #66b1ff 100%)', filter: 1 },
{ title: '教研室已拒绝', value: list.filter(i => i.jyspzzt === 3).length, gradient: 'linear-gradient(135deg, #f56c6c 0%, #f78989 100%)', filter: 3 }
loadStatistics() {
const baseParams = {
nd: this.defaultNd,
pageNum: 1,
pageSize: 1
}
const statusFilters = [undefined, 0, 1, 3]
const requests = statusFilters.map(status => {
const params = Object.assign({}, baseParams)
if (status !== undefined) {
params.jyspzzt = status
}
return listScheduleAdjust(params)
.then(response => Number((response.data && response.data.total) || 0))
.catch(() => 0)
})
return Promise.all(requests).then(counts => {
this.statCards = this.createStatCards(counts)
})
},
createStatCards(counts) {
return [
{
title: '本页申请',
value: counts[0],
gradient: 'linear-gradient(135deg, #00875a 0%, #00b877 100%)',
filter: undefined
},
{
title: '教研室待审批',
value: counts[1],
gradient: 'linear-gradient(135deg, #e6a23c 0%, #f8b04c 100%)',
filter: 0
},
{
title: '教研室已同意',
value: counts[2],
gradient: 'linear-gradient(135deg, #409eff 0%, #66b1ff 100%)',
filter: 1
},
{
title: '教研室已拒绝',
value: counts[3],
gradient: 'linear-gradient(135deg, #f56c6c 0%, #f78989 100%)',
filter: 3
}
]
},
handleStatClick(card) {
if (card.filter === undefined) return
this.queryParams.jyspzzt = this.queryParams.jyspzzt === card.filter ? undefined : card.filter
this.queryParams.jyspzzt = card.filter
this.handleQuery()
},
/* ---------- 新增申请 ---------- */
@@ -146,24 +146,27 @@
:close-on-click-modal="false">
<el-form ref="trainingForm" :model="dialog.form" :rules="rules" label-width="130px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="专业代号" prop="zydh">
<el-input v-model="dialog.form.zydh" placeholder="请输入专业代号" :disabled="dialog.isEdit" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="专业名称" prop="zymc">
<el-input v-model="dialog.form.zymc" placeholder="请输入专业名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="专业代码" prop="zydm">
<el-input v-model="dialog.form.zydm" placeholder="请输入专业代码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="专业方向">
<el-input v-model="dialog.form.zyfx" placeholder="请输入专业方向" />
<el-select
v-model="dialog.form.zyfx"
placeholder="请选择专业方向"
clearable
filterable
class="training-dict-select"
>
<el-option
v-for="item in majorDirectionOptions"
:key="item.dictCode || item.dictValue"
:label="item.dictLabel"
:value="item.dictLabel"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -207,7 +210,20 @@
</el-col>
<el-col :span="12">
<el-form-item label="学员类别">
<el-input v-model="dialog.form.xylb" placeholder="请输入学员类别" />
<el-select
v-model="dialog.form.xylb"
placeholder="请选择学员类别"
clearable
filterable
class="training-dict-select"
>
<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-col :span="12">
@@ -231,8 +247,21 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教学管理机构编号">
<el-input v-model="dialog.form.jxgljgbh" placeholder="请输入教学管理机构编号" />
<el-form-item label="教学管理机构">
<el-select
v-model="dialog.form.jxgljgbh"
placeholder="请选择教学管理机构"
clearable
filterable
class="training-dict-select"
>
<el-option
v-for="item in teachingOrganizationOptions"
:key="item.dictCode || item.dictValue"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -294,7 +323,7 @@
<el-descriptions-item label="专业版本">{{ fmtVal(detail.data.zybb) }}</el-descriptions-item>
<el-descriptions-item label="主干专业">{{ fmtYesNo(detail.data.zgzy) }}</el-descriptions-item>
<el-descriptions-item label="自定义分类">{{ fmtVal(detail.data.zdyfl) }}</el-descriptions-item>
<el-descriptions-item label="教学管理机构编号">{{ fmtVal(detail.data.jxgljgbh) }}</el-descriptions-item>
<el-descriptions-item label="教学管理机构">{{ fmtVal(detail.data.jxgljgbh) }}</el-descriptions-item>
<el-descriptions-item label="规范名称">{{ fmtVal(detail.data.gfmc) }}</el-descriptions-item>
<el-descriptions-item label="专业规范">{{ fmtVal(detail.data.zygf) }}</el-descriptions-item>
<el-descriptions-item label="简称">{{ fmtVal(detail.data.jc) }}</el-descriptions-item>
@@ -326,6 +355,7 @@ import {
listTraining
} from '@/api/teachBusiness/training'
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'
@@ -344,6 +374,9 @@ export default {
},
trainingTypeOptions: [],
trainingLevelOptions: [],
majorDirectionOptions: [],
studentCategoryOptions: [],
teachingOrganizationOptions: [],
// 列表
tableData: [],
total: 0,
@@ -367,9 +400,7 @@ export default {
data: {}
},
rules: {
zydh: [{ required: true, message: '请输入专业代号', trigger: 'blur' }],
zymc: [{ required: true, message: '请输入专业名称', trigger: 'blur' }],
zydm: [{ required: true, message: '请输入专业代码', trigger: 'blur' }],
pxcc: [{ required: true, message: '请选择培训层次', trigger: 'change' }],
pxlx: [{ required: true, message: '请选择培训类型', trigger: 'change' }]
}
@@ -381,19 +412,66 @@ export default {
},
methods: {
/**
* 从系统字典加载培训类型和培训层次,提交标签以匹配现有业务数据
* 从系统字典加载表单下拉选项;文本业务字段提交标签,机构字段提交编号
*/
loadTrainingDictionaries() {
return Promise.all([
getDicts(TRAINING_TYPE_DICT_CODE),
getDicts(TRAINING_LEVEL_DICT_CODE)
]).then(([typeResponse, levelResponse]) => {
this.trainingTypeOptions = typeResponse.data || []
this.trainingLevelOptions = levelResponse.data || []
}).catch(() => {
this.trainingTypeOptions = []
this.trainingLevelOptions = []
async loadTrainingDictionaries() {
const emptyResponse = { data: [] }
const [typeResponse, levelResponse, dictTypeResponse] = await Promise.all([
getDicts(TRAINING_TYPE_DICT_CODE).catch(() => emptyResponse),
getDicts(TRAINING_LEVEL_DICT_CODE).catch(() => emptyResponse),
optionselect().catch(() => emptyResponse)
])
this.trainingTypeOptions = typeResponse.data || []
this.trainingLevelOptions = levelResponse.data || []
const dictTypes = dictTypeResponse.data || []
const [directionOptions, categoryOptions, organizationOptions] = await Promise.all([
this.loadNamedDictionary(dictTypes, '专业方向'),
this.loadNamedDictionary(dictTypes, '学员类别'),
this.loadNamedDictionary(dictTypes, '教学管理机构')
])
this.majorDirectionOptions = directionOptions
this.studentCategoryOptions = categoryOptions
this.teachingOrganizationOptions = organizationOptions
this.mergeExistingSelectOptions()
},
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 []
}
},
mergeExistingSelectOptions() {
this.majorDirectionOptions = this.mergeTextOptions(this.majorDirectionOptions, 'zyfx', true)
this.studentCategoryOptions = this.mergeTextOptions(this.studentCategoryOptions, 'xylb', true)
this.teachingOrganizationOptions = this.mergeTextOptions(
this.teachingOrganizationOptions,
'jxgljgbh',
false
)
},
mergeTextOptions(dictionaryOptions, fieldName, usesLabel) {
const options = dictionaryOptions.slice()
const existingValues = new Set(options.map(item => String(usesLabel ? item.dictLabel : item.dictValue)))
this.tableData.forEach(row => {
const value = row[fieldName]
if (value === '' || value === null || value === undefined || existingValues.has(String(value))) {
return
}
options.push({
dictLabel: String(value),
dictValue: String(value)
})
existingValues.add(String(value))
})
return options
},
/* ---------- 列表加载 ---------- */
@@ -413,6 +491,7 @@ export default {
const data = response.data || {}
this.tableData = data.records || []
this.total = data.total || 0
this.mergeExistingSelectOptions()
}).catch(() => {
this.tableData = []
this.total = 0