Files
education/frontend/src/views/classHour/subsidy/index.vue
T
2026-08-24 09:15:34 +08:00

300 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container subsidy-page">
<div class="list-title">课时补助核算</div>
<!-- ==================== Tab 切换 ==================== -->
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane label="课时统计" name="hour" />
<el-tab-pane label="课时费统计" name="fee" />
</el-tabs>
<!-- ==================== 1. 查询条件 ==================== -->
<!-- 课时统计 -->
<el-card v-if="activeTab === 'hour'" shadow="never" class="search-card">
<el-form :model="hourForm" label-width="100px" class="search-form" @submit.native.prevent>
<el-row :gutter="24">
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="学期年度">
<el-input v-model="hourForm.nd" placeholder="如 2026" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="学期序号">
<el-input v-model="hourForm.xq" placeholder="如 1" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="教员姓名">
<el-input v-model="hourForm.jyxm" placeholder="请输入教员姓名" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6" class="search-actions-col">
<div class="search-actions">
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button type="primary" plain @click="handleExport">导出 Excel</el-button>
</div>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 课时费统计 -->
<el-card v-else shadow="never" class="search-card">
<el-form :model="feeForm" label-width="100px" class="search-form" @submit.native.prevent>
<el-row :gutter="24">
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="学期年度">
<el-input v-model="feeForm.nd" placeholder="如 2026" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="学期序号">
<el-input v-model="feeForm.xq" placeholder="如 1" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="教员姓名">
<el-input v-model="feeForm.jyxm" placeholder="请输入教员姓名" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form-item label="标准编号">
<el-input v-model="feeForm.ksfbzbh" placeholder="课时费标准编号" clearable />
</el-form-item>
</el-col>
<el-col :span="24" class="search-actions-col">
<div class="search-actions">
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button type="primary" plain @click="handleExport">导出 Excel</el-button>
</div>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- ==================== 2. 数据表格 ==================== -->
<el-card shadow="never" class="table-card">
<div class="table-title">{{ activeTab === 'hour' ? '课时统计列表' : '课时费统计列表' }}</div>
<el-table v-loading="currentState.loading" :data="currentState.list" border stripe style="width: 100%">
<el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column prop="jysdh" label="教研室代号" width="100" align="center" show-overflow-tooltip />
<el-table-column prop="jysmc" label="教研室名称" width="120" show-overflow-tooltip />
<el-table-column prop="jybh" label="教员编号" width="110" align="center" show-overflow-tooltip />
<el-table-column prop="jyxm" label="教员姓名" width="100" align="center" show-overflow-tooltip />
<el-table-column prop="zc" label="职称" width="90" align="center" show-overflow-tooltip />
<el-table-column prop="nf" label="年份" width="70" align="center" />
<el-table-column prop="sbn" label="上半年" width="90" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.sbn) }}</template>
</el-table-column>
<el-table-column prop="xbn" label="下半年" width="90" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.xbn) }}</template>
</el-table-column>
<el-table-column prop="zj" label="总计" width="90" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.zj) }}</template>
</el-table-column>
<el-table-column prop="bzksl" label="标准课时量" width="100" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.bzksl) }}</template>
</el-table-column>
<el-table-column prop="cks" label="超课时" width="90" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.cks) }}</template>
</el-table-column>
<el-table-column prop="jsgs" label="计算过程" min-width="140" show-overflow-tooltip />
<el-table-column prop="jg" label="结果" width="90" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.jg) }}</template>
</el-table-column>
<el-table-column prop="ksfbzmc" label="课时费标准" width="110" align="center" show-overflow-tooltip />
<el-table-column prop="ksfbz" label="课时费单价" width="100" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.ksfbz) }}</template>
</el-table-column>
<el-table-column prop="clksfbz" label="超量课时费单价" width="110" align="right" header-align="center">
<template slot-scope="{ row }">{{ fmtValue(row.clksfbz) }}</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="currentState.pageNum"
:page-size="currentState.pageSize"
:total="currentState.total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
class="pagination"
@current-change="handlePageChange"
@size-change="handleSizeChange"
/>
</el-card>
</div>
</template>
<script>
import { saveAs } from 'file-saver'
import {
listHourStatistics,
exportHourStatistics,
listFeeStatistics,
exportFeeStatistics
} from '@/api/classHour/hourStat'
export default {
name: 'SubsidyIndex',
data() {
return {
// ==================== Tab ====================
activeTab: 'hour',
// ==================== 课时统计查询条件 ====================
hourForm: {
nd: '',
xq: '',
jyxm: ''
},
// ==================== 课时费统计查询条件 ====================
feeForm: {
nd: '',
xq: '',
jyxm: '',
ksfbzbh: ''
},
// ==================== 各 Tab 列表状态 ====================
hourState: this.createEmptyState(),
feeState: this.createEmptyState()
}
},
computed: {
currentForm() {
return this.activeTab === 'hour' ? this.hourForm : this.feeForm
},
currentState() {
return this.activeTab === 'hour' ? this.hourState : this.feeState
}
},
mounted() {
this.fetchList()
},
methods: {
createEmptyState() {
return { list: [], loading: false, pageNum: 1, pageSize: 20, total: 0 }
},
/** 构建查询参数,仅传非空字段(与后端 Query 字段一致) */
buildParams(form) {
const params = {}
if (form.nd && form.nd.trim()) params.nd = form.nd.trim()
if (form.xq && form.xq.trim()) params.xq = form.xq.trim()
if (form.jyxm && form.jyxm.trim()) params.jyxm = form.jyxm.trim()
if (form.ksfbzbh && form.ksfbzbh.trim()) params.ksfbzbh = form.ksfbzbh.trim()
return params
},
// ==================== 查询 ====================
fetchList() {
const state = this.currentState
const form = this.currentForm
const params = Object.assign(
{ pageNum: state.pageNum, pageSize: state.pageSize },
this.buildParams(form)
)
state.loading = true
const req = this.activeTab === 'hour' ? listHourStatistics(params) : listFeeStatistics(params)
req.then(res => {
const data = (res && res.data) || {}
state.list = data.records || []
state.total = data.total || 0
}).catch(() => {
state.list = []
state.total = 0
}).finally(() => {
state.loading = false
})
},
handleTabClick() {
this.currentState.pageNum = 1
this.fetchList()
},
handleQuery() {
this.currentState.pageNum = 1
this.fetchList()
},
handlePageChange(page) {
this.currentState.pageNum = page
this.fetchList()
},
handleSizeChange(size) {
this.currentState.pageSize = size
this.currentState.pageNum = 1
this.fetchList()
},
// ==================== 导出 ====================
handleExport() {
const clean = this.buildParams(this.currentForm)
const isHour = this.activeTab === 'hour'
const req = isHour ? exportHourStatistics(clean) : exportFeeStatistics(clean)
const fileName = isHour ? '课时统计.xlsx' : '课时费统计.xlsx'
req.then(blob => {
saveAs(blob, fileName)
this.$message.success('导出成功')
}).catch(() => {})
},
/** 数值空值显示为 '-'(保留 0 */
fmtValue(val) {
return val === null || val === undefined ? '-' : val
}
}
}
</script>
<style scoped lang="scss">
.app-container {
padding: 20px;
}
.subsidy-page {
.list-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 12px;
}
// ==================== 1. 查询条件区域 ====================
.search-card {
margin-bottom: 16px;
.search-form {
.search-actions-col {
display: flex;
align-items: center;
}
.search-actions {
display: flex;
gap: 12px;
}
}
}
// ==================== 2. 数据表格 ====================
.table-card {
.table-title {
font-size: 14px;
font-weight: 600;
color: #303133;
margin-bottom: 12px;
}
.pagination {
display: flex;
justify-content: flex-end;
margin-top: 12px;
}
}
}
</style>