后端代码
This commit is contained in:
@@ -1,540 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- ==================== 2. 查询条件区域 ==================== -->
|
||||
<div class="section-card query-card">
|
||||
<el-form>
|
||||
<el-row :gutter="32">
|
||||
<!-- 左栏 -->
|
||||
<el-col :xs="24" :md="12">
|
||||
<div class="query-field">
|
||||
<span class="q-label no-check">授课教员</span>
|
||||
<el-input v-model="searchForm.js" placeholder="请输入授课教员" clearable class="q-control" />
|
||||
</div>
|
||||
<div class="query-field">
|
||||
<span class="q-label no-check">可选班次年级</span>
|
||||
<el-input v-model="searchForm.kbcnj" placeholder="请输入可选班次年级" clearable class="q-control" />
|
||||
</div>
|
||||
<div class="query-field">
|
||||
<el-checkbox v-model="searchForm.xxkztEnabled" />
|
||||
<span class="q-label">选修课状态</span>
|
||||
<el-select v-model="searchForm.xxkzt" class="q-control" :disabled="!searchForm.xxkztEnabled">
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右栏 -->
|
||||
<el-col :xs="24" :md="12">
|
||||
<div class="query-field">
|
||||
<span class="q-label no-check">课程科目名称</span>
|
||||
<el-input v-model="searchForm.kckmmc" placeholder="请输入课程科目名称" clearable class="q-control" />
|
||||
</div>
|
||||
<div class="query-field">
|
||||
<span class="q-label no-check">选修班名称</span>
|
||||
<el-input v-model="searchForm.xxbmc" placeholder="请输入选修班名称" clearable class="q-control" />
|
||||
</div>
|
||||
<div class="query-field">
|
||||
<el-checkbox v-model="searchForm.pxccEnabled" />
|
||||
<span class="q-label">培训层次</span>
|
||||
<el-select v-model="searchForm.pxcc" class="q-control" :disabled="!searchForm.pxccEnabled">
|
||||
<el-option v-for="item in pxccOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="query-footer">
|
||||
<el-button class="gray-btn" @click="handleQuery">查询</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 3. 导出按钮区域 ==================== -->
|
||||
<div class="section-card export-card">
|
||||
<div class="export-bar">
|
||||
<el-button type="primary" @click="handleDownloadList">下载选修班列表</el-button>
|
||||
<el-button type="primary" @click="handleDownloadWord">下载选修班学员名单Word</el-button>
|
||||
<el-button type="primary" @click="handleDownloadExcel">下载选修班学员名单Excel</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 4. 操作按钮区域 ==================== -->
|
||||
<div class="section-card action-card">
|
||||
<div class="action-row">
|
||||
<el-button type="primary" @click="handleOpenNew">新建选修课</el-button>
|
||||
<el-button type="primary" @click="handleOpenEarly">所选批量开放报名</el-button>
|
||||
<el-button type="primary" @click="handleCancelEarly">所选批量取消开放报名</el-button>
|
||||
<el-button type="primary" @click="handleStopSignup">批量停止报名</el-button>
|
||||
<el-button type="primary" @click="handleReverseRange">所选批量根据学员反向确定班次范围</el-button>
|
||||
</div>
|
||||
<div class="action-row">
|
||||
<el-button type="primary" @click="handleDownloadTemplate">【选修课数据文件模板】下载</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 5. 文件上传区域 ==================== -->
|
||||
<div class="section-card upload-card">
|
||||
<div class="upload-row">
|
||||
<div class="upload-left">
|
||||
<el-button @click="handleSelectFile">选择文件</el-button>
|
||||
<span class="file-name" :class="{ 'has-file': selectedFile }">{{ fileName }}</span>
|
||||
<input ref="fileInputRef" type="file" style="display: none" @change="handleFileChange" />
|
||||
</div>
|
||||
<div class="upload-right">
|
||||
<el-button type="primary" @click="handleUpload">上传数据</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 6. 数据表格区域 ==================== -->
|
||||
<div class="section-card table-card">
|
||||
<el-table v-loading="loading" :data="tableData" border stripe class="main-table" @selection-change="handleSelectionChange">
|
||||
<template slot="empty">
|
||||
<span>无数据!</span>
|
||||
</template>
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" :index="tableIndex" />
|
||||
<el-table-column prop="kmc" label="课程" min-width="110" show-overflow-tooltip />
|
||||
<el-table-column prop="jcmc" label="教材" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="jyxm" label="实施教员" width="90" align="center" />
|
||||
<el-table-column prop="jsmc" label="教学场地" width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="kxdlbc" label="显示可选队别班次" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="计划学时/运行学时/学分" width="130" align="center">
|
||||
<template slot="header">
|
||||
<div class="triple-header">
|
||||
<span>计划学时</span>
|
||||
<span>运行学时</span>
|
||||
<span>学分</span>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row }">
|
||||
<div class="triple-cell">
|
||||
<span>{{ row.jhyxxsxf }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开课结课日期" min-width="150" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
{{ row.kkjkrq }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报名日期" min-width="140" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
{{ row.bmrq }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jhrs" label="计划人数" width="90" align="center" />
|
||||
<el-table-column prop="yqsm" label="要求说明" min-width="120" show-overflow-tooltip />
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-wrap">
|
||||
<el-pagination
|
||||
background
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:current-page="currentPage"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新建选修课弹窗 -->
|
||||
<el-dialog
|
||||
:visible="dialogVisible"
|
||||
title="新建选修课"
|
||||
width="560px"
|
||||
@update:visible="val => (dialogVisible = val)"
|
||||
>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
|
||||
<el-form-item label="课程名称" prop="kcmc">
|
||||
<el-input v-model="form.kcmc" placeholder="请输入课程名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="实施教员" prop="js">
|
||||
<el-input v-model="form.js" placeholder="请输入实施教员" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="教材">
|
||||
<el-input v-model="form.jc" placeholder="请输入教材" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="教学场地">
|
||||
<el-input v-model="form.jxcd" placeholder="请输入教学场地" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="计划学时">
|
||||
<el-input-number v-model="form.jhsxs" :min="0" :precision="0" class="w-full" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运行学时">
|
||||
<el-input-number v-model="form.yxsxs" :min="0" :precision="0" class="w-full" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学分">
|
||||
<el-input-number v-model="form.xf" :min="0" :precision="1" class="w-full" />
|
||||
</el-form-item>
|
||||
<el-form-item label="计划人数">
|
||||
<el-input-number v-model="form.jh" :min="0" :precision="0" class="w-full" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleNewConfirm">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listElective,
|
||||
batchOpenElective,
|
||||
batchCancelOpenElective,
|
||||
batchStopElective,
|
||||
exportElectiveList,
|
||||
exportElectiveStudentsExcel,
|
||||
exportElectiveStudentsWord
|
||||
} from '@/api/teachOffice/elective'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
name: 'Elective',
|
||||
data() {
|
||||
return {
|
||||
// ==================== 下拉选项 ====================
|
||||
statusOptions: ['拟制', '开放报名', '停止报名', '已开课'],
|
||||
pxccOptions: ['无', '本科', '硕士', '博士'],
|
||||
|
||||
// ==================== 查询条件 ====================
|
||||
searchForm: {
|
||||
js: '',
|
||||
kbcnj: '',
|
||||
xxkztEnabled: false,
|
||||
xxkzt: '拟制',
|
||||
kckmmc: '',
|
||||
xxbmc: '',
|
||||
pxccEnabled: false,
|
||||
pxcc: '无'
|
||||
},
|
||||
|
||||
// ==================== 数据表格 ====================
|
||||
tableData: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
selectedRows: [],
|
||||
|
||||
// ==================== 文件上传 ====================
|
||||
selectedFile: null,
|
||||
|
||||
// ==================== 新建选修课弹窗 ====================
|
||||
dialogVisible: false,
|
||||
form: {
|
||||
kcmc: '',
|
||||
js: '',
|
||||
jc: '',
|
||||
jxcd: '',
|
||||
jhsxs: 0,
|
||||
yxsxs: 0,
|
||||
xf: 0,
|
||||
jh: 0
|
||||
},
|
||||
rules: {
|
||||
kcmc: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
||||
js: [{ required: true, message: '请输入实施教员', trigger: 'blur' }]
|
||||
},
|
||||
|
||||
// ==================== 分页 ====================
|
||||
currentPage: 1,
|
||||
pageSize: 20
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fileName() {
|
||||
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadList()
|
||||
},
|
||||
methods: {
|
||||
// 组装查询过滤条件(列表与导出共用,导出不含分页参数)
|
||||
buildFilter() {
|
||||
const q = {}
|
||||
if (this.searchForm.js) q.jyxm = this.searchForm.js
|
||||
if (this.searchForm.kbcnj) q.kxbcnj = this.searchForm.kbcnj
|
||||
if (this.searchForm.kckmmc) q.kmc = this.searchForm.kckmmc
|
||||
if (this.searchForm.xxbmc) q.xxbmc = this.searchForm.xxbmc
|
||||
if (this.searchForm.xxkztEnabled) q.xkzt = this.searchForm.xxkzt
|
||||
if (this.searchForm.pxccEnabled) q.pxcc = this.searchForm.pxcc
|
||||
return q
|
||||
},
|
||||
|
||||
// ==================== 查询 ====================
|
||||
handleQuery() {
|
||||
this.currentPage = 1
|
||||
this.loadList()
|
||||
},
|
||||
loadList() {
|
||||
this.loading = true
|
||||
const params = Object.assign({ pageNum: this.currentPage, pageSize: this.pageSize }, this.buildFilter())
|
||||
listElective(params)
|
||||
.then(res => {
|
||||
const data = (res && res.data) || {}
|
||||
this.tableData = data.records || []
|
||||
this.total = data.total || 0
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
// ==================== 导出 ====================
|
||||
handleDownloadList() {
|
||||
exportElectiveList(this.buildFilter())
|
||||
.then(blob => {
|
||||
saveAs(blob, '选修班列表.xlsx')
|
||||
this.$message.success('选修班列表已下载')
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleDownloadWord() {
|
||||
const bhList = this.selectedRows.map(row => row.bh)
|
||||
if (bhList.length === 0) {
|
||||
this.$message.warning('请先选择选修班')
|
||||
return
|
||||
}
|
||||
exportElectiveStudentsWord(bhList)
|
||||
.then(blob => {
|
||||
saveAs(blob, '选修班学员名单.docx')
|
||||
this.$message.success('选修班学员名单Word已下载')
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleDownloadExcel() {
|
||||
const bhList = this.selectedRows.map(row => row.bh)
|
||||
if (bhList.length === 0) {
|
||||
this.$message.warning('请先选择选修班')
|
||||
return
|
||||
}
|
||||
exportElectiveStudentsExcel(bhList)
|
||||
.then(blob => {
|
||||
saveAs(blob, '选修班学员名单.xlsx')
|
||||
this.$message.success('选修班学员名单Excel已下载')
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
|
||||
// ==================== 操作按钮 ====================
|
||||
handleOpenEarly() {
|
||||
const bhList = this.selectedRows.map(row => row.bh)
|
||||
if (bhList.length === 0) {
|
||||
this.$message.warning('请先选择选修班')
|
||||
return
|
||||
}
|
||||
batchOpenElective(bhList)
|
||||
.then(() => {
|
||||
this.$message.success('所选班已开放报名')
|
||||
this.loadList()
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleCancelEarly() {
|
||||
const bhList = this.selectedRows.map(row => row.bh)
|
||||
if (bhList.length === 0) {
|
||||
this.$message.warning('请先选择选修班')
|
||||
return
|
||||
}
|
||||
batchCancelOpenElective(bhList)
|
||||
.then(() => {
|
||||
this.$message.success('所选班已取消开放报名')
|
||||
this.loadList()
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleStopSignup() {
|
||||
const bhList = this.selectedRows.map(row => row.bh)
|
||||
if (bhList.length === 0) {
|
||||
this.$message.warning('请先选择选修班')
|
||||
return
|
||||
}
|
||||
batchStopElective(bhList)
|
||||
.then(() => {
|
||||
this.$message.success('已批量停止报名')
|
||||
this.loadList()
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleReverseRange() {
|
||||
this.$message.warning('后端暂未提供该接口')
|
||||
},
|
||||
handleDownloadTemplate() {
|
||||
this.$message.warning('后端暂未提供该接口')
|
||||
},
|
||||
|
||||
// ==================== 文件上传 ====================
|
||||
handleSelectFile() {
|
||||
this.$refs.fileInputRef && this.$refs.fileInputRef.click()
|
||||
},
|
||||
handleFileChange(e) {
|
||||
this.selectedFile = e.target.files[0] || null
|
||||
},
|
||||
handleUpload() {
|
||||
if (!this.selectedFile) {
|
||||
this.$message.warning('请先选择文件')
|
||||
return
|
||||
}
|
||||
this.$message.warning('后端暂未提供该接口')
|
||||
},
|
||||
|
||||
// ==================== 表格多选 ====================
|
||||
handleSelectionChange(rows) {
|
||||
this.selectedRows = rows
|
||||
},
|
||||
|
||||
// ==================== 新建选修课弹窗 ====================
|
||||
handleOpenNew() {
|
||||
this.$message.warning('后端暂未提供该接口')
|
||||
},
|
||||
handleNewConfirm() {
|
||||
if (!this.$refs.formRef) return
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (!valid) return
|
||||
console.log('新建选修课:', JSON.parse(JSON.stringify(this.form)))
|
||||
this.$message.success('新建选修课成功(前端模拟)')
|
||||
this.dialogVisible = false
|
||||
})
|
||||
},
|
||||
|
||||
// ==================== 分页 ====================
|
||||
handlePageChange(page) {
|
||||
this.currentPage = page
|
||||
this.loadList()
|
||||
},
|
||||
|
||||
// 表格序号(跨页连续)
|
||||
tableIndex(index) {
|
||||
return (this.currentPage - 1) * this.pageSize + index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// ==================== 2. 查询条件区域 ====================
|
||||
.query-card {
|
||||
.query-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
min-height: 32px;
|
||||
|
||||
::v-deep .el-checkbox {
|
||||
margin-right: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.q-label {
|
||||
width: 120px;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
color: #303133;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
white-space: nowrap;
|
||||
|
||||
&.no-check {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.q-control {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notice {
|
||||
font-size: 12px;
|
||||
color: #f56c6c;
|
||||
margin-top: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.query-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 4. 操作按钮区域 ====================
|
||||
.action-card {
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 5. 文件上传区域 ====================
|
||||
.upload-card {
|
||||
.upload-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
|
||||
.upload-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.file-name {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
|
||||
&.has-file {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 6. 数据表格区域 ====================
|
||||
.table-card {
|
||||
.main-table {
|
||||
::v-deep .cell {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.triple-header,
|
||||
.triple-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 按钮样式 ====================
|
||||
.gray-btn {
|
||||
height: 28px;
|
||||
padding: 2px 16px;
|
||||
font-size: 12px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #c0c4cc;
|
||||
color: #333;
|
||||
border-radius: 2px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: #ebebeb;
|
||||
border-color: #c0c4cc;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user