后端代码

This commit is contained in:
liumengyu
2026-08-24 17:48:55 +08:00
parent e0485f7366
commit aa4145fd33
419 changed files with 3684 additions and 53031 deletions
@@ -1,299 +0,0 @@
<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>