班次学期信息管理

This commit is contained in:
2026-08-23 21:02:15 +08:00
parent 499518a2a6
commit 526b9082df
6 changed files with 1601 additions and 1504 deletions
@@ -1,148 +1,71 @@
<template>
<el-dialog
:visible="dialogVisible"
title="学员队选取"
width="90%"
top="5vh"
:title="title"
width="900px"
top="8vh"
:close-on-click-modal="false"
class="team-select-dialog"
@update:visible="val => dialogVisible = val"
>
<div class="team-select">
<!-- ==================== 1. 查询条件区域 ==================== -->
<!-- ==================== 操作说明 ==================== -->
<div v-if="excludeNote" class="note-bar">
<i class="el-icon-info"></i>
<span>{{ excludeNote }}</span>
</div>
<!-- ==================== 查询条件区域 ==================== -->
<div class="query-panel">
<el-form label-width="88px" class="query-form">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="专业">
<div class="check-field">
<el-checkbox v-model="queryForm.zyEnabled" />
<el-select v-model="queryForm.zy" :disabled="!queryForm.zyEnabled" style="flex: 1">
<el-option v-for="opt in zyOptions" :key="opt" :label="opt" :value="opt" />
</el-select>
</div>
</el-form-item>
<el-form-item label="年级">
<div class="check-field">
<el-checkbox v-model="queryForm.njEnabled" />
<el-input v-model="queryForm.nj" :disabled="!queryForm.njEnabled" placeholder="" />
</div>
</el-form-item>
<el-form-item label="在校状态">
<div class="check-field">
<el-checkbox v-model="queryForm.zxztEnabled" />
<el-select v-model="queryForm.zxzt" :disabled="!queryForm.zxztEnabled" style="flex: 1">
<el-option v-for="opt in zxztOptions" :key="opt" :label="opt" :value="opt" />
</el-select>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学员队名称">
<div class="check-field">
<el-checkbox v-model="queryForm.xydmcEnabled" />
<el-input v-model="queryForm.xydmc" :disabled="!queryForm.xydmcEnabled" placeholder="" />
</div>
</el-form-item>
<el-form-item label="任务类别">
<div class="check-field">
<el-checkbox v-model="queryForm.rwlbEnabled" />
<el-select v-model="queryForm.rwlb" :disabled="!queryForm.rwlbEnabled" style="flex: 1">
<el-option v-for="opt in rwlbOptions" :key="opt" :label="opt" :value="opt" />
</el-select>
</div>
</el-form-item>
</el-col>
</el-row>
<el-form :inline="true" class="query-form" @submit.native.prevent>
<el-form-item label="班次编号">
<el-input
v-model="queryForm.xydbh"
placeholder="请输入班次编号(模糊)"
clearable
style="width: 220px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">查询</el-button>
<el-button size="small" @click="handleResetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 分页控制区域 -->
<div class="pager-row">
<button type="button" class="gray-btn" @click="handleQuery">查询</button>
<button type="button" class="gray-btn" @click="handleFirst">首页</button>
<button type="button" class="gray-btn" @click="handlePrev">上页</button>
<button type="button" class="gray-btn" @click="handleNext">下页</button>
<button type="button" class="gray-btn" @click="handleLast">末页</button>
<el-input-number v-model="currentPage" :min="1" size="small" controls-position="right" style="width: 90px" />
<span class="pager-label">每页条数</span>
<el-select v-model="pageSize" size="small" style="width: 70px">
<el-option v-for="n in pageSizeOptions" :key="n" :label="String(n)" :value="n" />
</el-select>
<button type="button" class="gray-btn" @click="handleLocate">定位</button>
<el-select v-model="displaySize" size="small" style="width: 80px">
<el-option v-for="n in displaySizeOptions" :key="n" :label="String(n)" :value="n" />
</el-select>
<button type="button" class="blue-btn" @click="handleSetPageSize">设置页项数</button>
</div>
</div>
<!-- ==================== 2. 上方数据表格 ==================== -->
<!-- ==================== 目标班次学期表格 ==================== -->
<div class="table-panel">
<el-table
:data="teamList"
border
stripe
highlight-current-row
size="small"
class="team-table"
@selection-change="handleTopSelectionChange"
>
<el-table-column type="selection" width="40" align="center" />
<el-table-column prop="xzdbm" label="行政队别名称" width="100" align="center" show-overflow-tooltip />
<el-table-column prop="xydmc" label="学员队名称" width="90" align="center" show-overflow-tooltip />
<el-table-column prop="nj" label="年级" width="70" align="center" show-overflow-tooltip />
<el-table-column prop="zy" label="专业" width="80" align="center" show-overflow-tooltip />
<el-table-column label="人数" width="60" align="center">
<template slot-scope="{ row }">{{ row.rs }}人</template>
</el-table-column>
<el-table-column prop="zxzt" label="在校状态" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="rwlb" label="任务类别" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="zyjs" label="专用教室" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="rxrq" label="入学日期" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="byrq" label="毕业日期" width="120" align="center" show-overflow-tooltip />
</el-table>
</div>
<!-- ==================== 3. 中间操作按钮区域 ==================== -->
<div class="mid-actions">
<span class="mid-label">已选择列表项</span>
<button type="button" class="gray-btn" @click="handleAdd">加入</button>
<button type="button" class="gray-btn" @click="handleRemove">移除</button>
<button type="button" class="gray-btn" @click="handleClear">清除</button>
<button type="button" class="gray-btn" @click="handleReset">重置</button>
</div>
<!-- ==================== 4. 下方数据表格(已选学员队列表) ==================== -->
<div class="table-panel">
<el-table
:data="selectedList"
ref="tableRef"
v-loading="loading"
:data="filteredList"
border
stripe
size="small"
max-height="360"
class="team-table"
@selection-change="handleBottomSelectionChange"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="40" align="center" />
<el-table-column prop="zy" label="专业" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="xydmc" label="学员队名称" width="90" align="center" show-overflow-tooltip />
<el-table-column prop="nj" label="年级" width="70" align="center" show-overflow-tooltip />
<el-table-column label="人数" width="60" align="center">
<template slot-scope="{ row }">{{ row.rs }}人</template>
<el-table-column type="selection" width="44" align="center" reserve-selection />
<el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column prop="nd" label="年度" width="80" align="center" show-overflow-tooltip />
<el-table-column label="学期第次" width="90" align="center">
<template slot-scope="{ row }">{{ xqdcLabel(row.xqdc) }}</template>
</el-table-column>
<el-table-column prop="rwlb" label="任务类别" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="zxzt" label="在校状态" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="zyjs" label="专用教室" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="rxrq" label="入学日期" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="byrq" label="毕业日期" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="bz" label="备注" width="80" align="center" show-overflow-tooltip />
<el-table-column prop="xydbh" label="班次编号" min-width="150" align="left" header-align="center" show-overflow-tooltip />
<el-table-column prop="kxrq" label="开学日期" width="110" align="center" :formatter="fmtDate" />
<el-table-column prop="jsrq" label="结束日期" width="110" align="center" :formatter="fmtDate" />
<el-table-column prop="bz" label="备注" min-width="120" align="left" header-align="center" show-overflow-tooltip />
</el-table>
<el-empty v-if="!selectedList.length" description="暂无已选学员队,请从上方表格加入" :image-size="60" />
<el-empty v-if="!filteredList.length" description="暂无可选的目标班次学期" :image-size="60" />
</div>
<!-- ==================== 5. 底部按钮区域 ==================== -->
<!-- ==================== 底部按钮区域 ==================== -->
<div class="footer-actions">
<button type="button" class="gray-btn" @click="handleConfirm">确定</button>
<button type="button" class="gray-btn" @click="handleCancel">取消</button>
<span class="selected-count">已选择 {{ selection.length }} 个班次学期</span>
<el-button size="small" @click="dialogVisible = false">取消</el-button>
<el-button size="small" type="primary" :disabled="!selection.length" @click="handleConfirm">确定</el-button>
</div>
</div>
</el-dialog>
@@ -152,52 +75,21 @@
export default {
name: 'ClassTeamSelectDialog',
props: {
visible: { type: Boolean, default: false }
visible: { type: Boolean, default: false },
/** 标题(可选) */
title: { type: String, default: '目标班次学期选取' },
/** 可选的目标班次学期列表(含 bh/nd/xqdc/xydbh/kxrq/jsrq 等) */
semesterList: { type: Array, default: () => [] },
/** 需要排除的班次学期编号(当前班次学期,不可复制给自己) */
excludeBh: { type: String, default: '' },
/** 顶部操作说明 */
excludeNote: { type: String, default: '' }
},
data() {
return {
// ==================== 查询条件区域 ====================
queryForm: {
zyEnabled: false, // 专业启用复选框(未勾选)
zy: '专业219', // 专业(默认值)
njEnabled: true, // 年级启用复选框(已勾选)
nj: '', // 年级(空值)
zxztEnabled: false, // 在校状态启用复选框(未勾选)
zxzt: '毕业', // 在校状态(默认值)
xydmcEnabled: true, // 学员队名称启用复选框(已勾选)
xydmc: '', // 学员队名称(空值)
rwlbEnabled: false, // 任务类别启用复选框(未勾选)
rwlb: '规划内' // 任务类别(默认值)
},
zyOptions: ['专业219', '专业220', '专业221'],
zxztOptions: ['毕业', '在校'],
rwlbOptions: ['规划内', '规划外'],
// ==================== 分页控制区域 ====================
currentPage: 1,
pageSize: 1,
displaySize: 100,
pageSizeOptions: [1, 5, 10, 20],
displaySizeOptions: [50, 100, 200],
// ==================== 上方数据表格(可选学员队列表) ====================
teamList: [
{ xzdbm: '教学五系', xydmc: '班次0417', nj: '2016级', zy: '专业113', rs: 36, zxzt: '毕业', rwlb: '规划内', zyjs: '8-011', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0423', nj: '2016级', zy: '专业114', rs: 9, zxzt: '毕业', rwlb: '规划内', zyjs: '8-212(南楼)', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0411', nj: '2016级', zy: '专业112', rs: 38, zxzt: '毕业', rwlb: '规划内', zyjs: '6-203', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0405', nj: '2016级', zy: '专业111', rs: 34, zxzt: '毕业', rwlb: '规划内', zyjs: '8-007', rxrq: '2016年8月26日', byrq: '2018年1月21日' },
{ xzdbm: '教学五系', xydmc: '班次0429', nj: '2017级', zy: '专业117', rs: 43, zxzt: '毕业', rwlb: '规划内', zyjs: '6-202', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
{ xzdbm: '教学五系', xydmc: '班次0431', nj: '2017级', zy: '专业118', rs: 22, zxzt: '毕业', rwlb: '规划内', zyjs: '2-403', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0425', nj: '2017级', zy: '专业115', rs: 19, zxzt: '毕业', rwlb: '规划内', zyjs: '2-406', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0432', nj: '2017级', zy: '专业119', rs: 15, zxzt: '毕业', rwlb: '规划内', zyjs: '8-009(南楼)', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
{ xzdbm: '教学七系', xydmc: '班次0434', nj: '2017级', zy: '专业120', rs: 45, zxzt: '毕业', rwlb: '规划内', zyjs: '6-303', rxrq: '2017年8月24日', byrq: '2019年1月21日' },
{ xzdbm: '教学六系', xydmc: '班次0427', nj: '2017级', zy: '专业116', rs: 64, zxzt: '毕业', rwlb: '规划内', zyjs: '2-501', rxrq: '2017年8月24日', byrq: '2019年1月21日' }
],
/** 上方表格多选 */
topSelection: [],
/** 下方数据表格(已选学员队列表) */
selectedList: [],
bottomSelection: []
loading: false,
queryForm: { xydbh: '' },
selection: []
}
},
computed: {
@@ -208,105 +100,54 @@ export default {
set(val) {
this.$emit('update:visible', val)
}
},
/** 排除当前班次学期后的可选列表 */
availableList() {
const excludeBh = this.excludeBh || ''
return (this.semesterList || []).filter(item => item.bh && String(item.bh) !== String(excludeBh))
},
/** 本地过滤后的列表 */
filteredList() {
const kw = (this.queryForm.xydbh || '').trim()
if (!kw) return this.availableList
return this.availableList.filter(item => item.xydbh && String(item.xydbh).includes(kw))
}
},
watch: {
visible(val) {
if (val) {
this.selection = []
this.queryForm.xydbh = ''
this.$nextTick(() => {
if (this.$refs.tableRef) this.$refs.tableRef.clearSelection()
})
}
}
},
methods: {
handleTopSelectionChange(rows) {
this.topSelection = rows
fmtDate(val) {
if (!val) return '-'
return String(val).slice(0, 10)
},
handleBottomSelectionChange(rows) {
this.bottomSelection = rows
xqdcLabel(val) {
if (val === 1 || val === '1') return '第1学期'
if (val === 2 || val === '2') return '第2学期'
if (val === 3 || val === '3') return '第3学期'
return val !== undefined && val !== null && val !== '' ? `第${val}学期` : '-'
},
// ==================== 分页控制 ====================
handleQuery() {
this.$message.success('查询(前端演示)')
handleSelectionChange(rows) {
this.selection = rows
},
handleFirst() {
this.currentPage = 1
this.$message.success('已跳转首页')
handleQuery() {},
handleResetQuery() {
this.queryForm.xydbh = ''
},
handlePrev() {
if (this.currentPage > 1) this.currentPage--
},
handleNext() {
this.currentPage++
},
handleLast() {
this.currentPage = this.teamList.length || 1
},
handleLocate() {
this.$message.success(`已定位到第 ${this.currentPage} 页`)
},
handleSetPageSize() {
this.$message.success(`每页显示条数已设置为 ${this.displaySize}`)
},
// ==================== 中间操作按钮 ====================
/** 加入:将上方表格选中行加入已选列表(去重) */
handleAdd() {
if (!this.topSelection.length) {
this.$message.warning('请先在上方表格选择学员队')
return
}
const existing = new Set(this.selectedList.map((r) => r.xydmc))
let added = 0
this.topSelection.forEach((r) => {
if (!existing.has(r.xydmc)) {
this.selectedList.push({ ...r, bz: '' })
added++
}
})
if (added) this.$message.success(`已加入 ${added} 个学员队`)
else this.$message.info('所选学员队已在列表中')
},
/** 移除:将下方表格选中行移除 */
handleRemove() {
if (!this.bottomSelection.length) {
this.$message.warning('请先在下方表格选择要移除的学员队')
return
}
const removeKeys = new Set(this.bottomSelection.map((r) => r.xydmc))
this.selectedList = this.selectedList.filter((r) => !removeKeys.has(r.xydmc))
this.$message.success(`已移除 ${this.bottomSelection.length} 个学员队`)
},
/** 清除:清空已选列表 */
handleClear() {
if (!this.selectedList.length) {
this.$message.info('已选列表为空')
return
}
this.selectedList = []
this.$message.success('已清空已选列表')
},
/** 重置:清空已选列表并重置查询条件 */
handleReset() {
this.selectedList = []
Object.assign(this.queryForm, {
zyEnabled: false, zy: '专业219',
njEnabled: true, nj: '',
zxztEnabled: false, zxzt: '毕业',
xydmcEnabled: true, xydmc: '',
rwlbEnabled: false, rwlb: '规划内'
})
this.currentPage = 1
this.$message.success('已重置')
},
// ==================== 底部按钮 ====================
handleConfirm() {
if (!this.selectedList.length) {
this.$message.warning('请先选择要应用的学员队')
if (!this.selection.length) {
this.$message.warning('请先勾选目标班次学期')
return
}
this.$emit('confirm', this.selectedList.slice())
this.dialogVisible = false
this.$message.success(`选定区域设置已应用于 ${this.selectedList.length} 个班次`)
},
handleCancel() {
this.$emit('confirm', this.selection.slice())
this.dialogVisible = false
}
}
@@ -319,40 +160,34 @@ export default {
flex-direction: column;
gap: 12px;
// ========== 1. 查询条件区域 ==========
// ========== 操作说明 ==========
.note-bar {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
font-size: 13px;
color: #1e6fff;
background: #ecf5ff;
border: 1px solid #d9ecff;
border-radius: 4px;
}
// ========== 查询条件区域 ==========
.query-panel {
background: #fff;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 12px 16px 8px;
padding: 10px 12px 2px;
.query-form {
.check-field {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
}
}
.pager-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
padding-top: 10px;
border-top: 1px solid #ebeef5;
margin-top: 4px;
.pager-label {
font-size: 13px;
color: #606266;
white-space: nowrap;
::v-deep .el-form-item {
margin-bottom: 8px;
}
}
}
// ========== 2/4. 表格区域 ==========
// ========== 表格区域 ==========
.table-panel {
position: relative;
background: #fff;
@@ -370,69 +205,19 @@ export default {
}
}
// ========== 3. 中间操作按钮区域 ==========
.mid-actions {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
.mid-label {
font-size: 13px;
font-weight: 600;
color: #303133;
white-space: nowrap;
margin-right: 4px;
}
}
// ========== 5. 底部按钮区域 ==========
// ========== 底部按钮区域 ==========
.footer-actions {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 8px;
padding-top: 12px;
border-top: 1px solid #ebeef5;
}
// ========== 银灰色 / 蓝色边框按钮 ==========
.gray-btn {
min-width: 70px;
height: 28px;
padding: 0 14px;
font-size: 12px;
color: #000;
background: linear-gradient(180deg, #fdfdfd 0%, #ececec 50%, #dcdcdc 100%);
border: 1px solid #7a7a7a;
border-radius: 2px;
cursor: pointer;
&:hover {
background: linear-gradient(180deg, #ffffff 0%, #f4f4f4 50%, #e6e6e6 100%);
}
&:active {
background: #c8c8c8;
}
}
.blue-btn {
min-width: 110px;
height: 28px;
padding: 0 14px;
font-size: 12px;
color: #1e6fff;
background: #ecf5ff;
border: 1px solid #1e6fff;
border-radius: 2px;
cursor: pointer;
&:hover {
background: #d9ecff;
}
&:active {
background: #c6e2ff;
.selected-count {
flex: 1;
font-size: 13px;
color: #606266;
}
}
}