forked from liweijie/education
课时补助核算两个tab页
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// ======================== 课时补助核算:课时统计 / 课时费统计 ========================
|
||||||
|
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks;返回行为 HourStatisticsVO。
|
||||||
|
|
||||||
|
// 分页查询课时统计(支持 nd 年度、xq 学期序号、jyxm 教员姓名)
|
||||||
|
export function listHourStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/hour-stat/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出课时统计 Excel(返回 Blob,文件名 课时统计.xlsx)
|
||||||
|
export function exportHourStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/hour-stat/export',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页查询课时费统计(支持 nd、xq、jyxm、ksfbzbh 课时费标准编号)
|
||||||
|
export function listFeeStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-stat/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出课时费统计 Excel(返回 Blob,文件名 课时费统计.xlsx)
|
||||||
|
export function exportFeeStatistics(query) {
|
||||||
|
return request({
|
||||||
|
url: '/ks/fee-stat/export',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,21 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
* 全局视口等比缩放 —— 让整个系统在不同大小屏幕(桌面 1280~1920)下布局不崩塌。
|
* 全局视口等比缩放 —— 让整个系统在不同大小屏幕(桌面 1280~4K)下布局不崩塌。
|
||||||
*
|
*
|
||||||
* 原理:
|
* 原理:
|
||||||
* 以 DESIGN_WIDTH 为设计基准宽度(视觉稿基准)。当视口宽度小于该值时,
|
* 以 DESIGN_WIDTH(1920)为设计基准宽度。将视口宽度与设计宽的比值作为缩放倍数,
|
||||||
* 对整个文档根节点 <html> 应用 zoom = 视口宽度 / DESIGN_WIDTH(不超过 1),
|
* 作用到文档根节点 <html> 的 zoom 上:
|
||||||
* 使页面内部所有元素(含 Element UI 挂载到 body 的弹窗/提示/下拉等)等比缩小,
|
* - 视口 < 设计宽(如 1280):zoom < 1,整体等比缩小,避免窄屏布局被撑破;
|
||||||
* 从而在保持原有表格/表单固定布局不塌陷的前提下,整体适配到当前屏幕。
|
* - 视口 = 设计宽(1920):zoom = 1,原生 1:1 显示;
|
||||||
|
* - 视口 > 设计宽(如 4K 3840):zoom = 2,整体等比放大,大屏不再留白/字小。
|
||||||
|
* 缩放倍数被限制在 MIN_SCALE ~ MAX_SCALE 之间,MAX_SCALE=2 恰好覆盖 4K(3840/1920)。
|
||||||
*
|
*
|
||||||
* 说明:
|
* 采用 zoom 挂在 documentElement 上,可覆盖包括 Element UI 挂载到 body 的
|
||||||
* 1. 仅在“需要缩小”时写入 zoom,宽度 ≥ 设计宽时清除,保证大屏原生 1:1 显示;
|
* 弹窗/提示/下拉选择在内的所有内容,保证整套界面一致缩放、不塌陷。
|
||||||
* 2. zoom 挂在 documentElement 上,能覆盖包括 Element 弹层在内的所有内容;
|
*
|
||||||
* 3. modern Chromium / Edge / Safari 及 Firefox(≥126) 均支持 zoom。
|
* 兼容性:modern Chromium / Edge / Safari 以及 Firefox(≥126) 均支持 zoom。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let initialized = false
|
let initialized = false
|
||||||
|
|
||||||
export const DEFAULT_DESIGN_WIDTH = 1920
|
export const DEFAULT_DESIGN_WIDTH = 1920
|
||||||
|
// 最小缩放倍数:极窄视口的安全下限,避免文字过小/布局异常
|
||||||
|
export const MIN_SCALE = 0.5
|
||||||
|
// 最大缩放倍数:2 对应 4K(3840/1920=2),更高分辨率也封顶在此,避免过度放大
|
||||||
|
export const MAX_SCALE = 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化全局自适应。可在任意入口调用,重复调用幂等。
|
* 初始化全局自适应。可在任意入口调用,重复调用幂等。
|
||||||
@@ -31,12 +37,14 @@ export function initAdaptive(designWidth = DEFAULT_DESIGN_WIDTH) {
|
|||||||
|
|
||||||
const applyScale = () => {
|
const applyScale = () => {
|
||||||
const root = document.documentElement
|
const root = document.documentElement
|
||||||
const width = (root && root.clientWidth) || window.innerWidth
|
if (!root) {
|
||||||
const scale = Math.min(1, width / designWidth)
|
return
|
||||||
// 小于设计宽才缩放,否则清除,避免触发整页缩放动画/重置
|
|
||||||
if (root) {
|
|
||||||
root.style.zoom = scale < 1 ? String(scale) : ''
|
|
||||||
}
|
}
|
||||||
|
const width = root.clientWidth || window.innerWidth
|
||||||
|
const ratio = width / designWidth
|
||||||
|
// 收敛到 [MIN_SCALE, MAX_SCALE],规避极端宽高的异常比例
|
||||||
|
const scale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, ratio))
|
||||||
|
root.style.zoom = scale === 1 ? '' : String(scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onResize = () => {
|
const onResize = () => {
|
||||||
|
|||||||
@@ -1,223 +1,250 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container subsidy-page">
|
<div class="app-container subsidy-page">
|
||||||
<div class="list-title">课时补助核算</div>
|
<div class="list-title">课时补助核算</div>
|
||||||
<div class="top-tip">{{ tipText }}</div>
|
|
||||||
|
|
||||||
<!-- ==================== 1. 新增核算区域 ==================== -->
|
<!-- ==================== Tab 切换 ==================== -->
|
||||||
<el-card shadow="never" class="search-card">
|
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||||
<div class="form-title">新增</div>
|
<el-tab-pane label="课时统计" name="hour" />
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="search-form">
|
<el-tab-pane label="课时费统计" name="fee" />
|
||||||
<el-row :gutter="0">
|
</el-tabs>
|
||||||
<!-- 左栏 -->
|
|
||||||
<el-col :span="12">
|
<!-- ==================== 1. 查询条件 ==================== -->
|
||||||
<el-form-item label="学期名称" prop="semesterName">
|
<!-- 课时统计 -->
|
||||||
<el-input v-model="form.semesterName" placeholder="请输入学期名称" clearable />
|
<el-card v-if="activeTab === 'hour'" shadow="never" class="search-card">
|
||||||
</el-form-item>
|
<el-form :model="hourForm" label-width="100px" class="search-form" @submit.native.prevent>
|
||||||
<el-form-item label="开始日期" prop="startDate">
|
<el-row :gutter="24">
|
||||||
<el-input v-model="form.startDate" placeholder="如:2016-03-01" clearable />
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
</el-form-item>
|
<el-form-item label="学期年度">
|
||||||
<el-form-item label="课时补助标准">
|
<el-input v-model="hourForm.nd" placeholder="如 2026" clearable />
|
||||||
<el-select v-model="form.subsidyStandard" placeholder="请选择" class="w-full">
|
|
||||||
<el-option v-for="item in subsidyStandardOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
<!-- 右栏 -->
|
<el-form-item label="学期序号">
|
||||||
<el-col :span="12">
|
<el-input v-model="hourForm.xq" placeholder="如 1" clearable />
|
||||||
<el-form-item label="任务类别">
|
|
||||||
<el-radio-group v-model="form.taskCategory">
|
|
||||||
<el-radio v-for="item in taskCategoryOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结束日期" prop="endDate">
|
</el-col>
|
||||||
<el-input v-model="form.endDate" placeholder="如:2016-08-31" clearable />
|
<el-col :xs="24" :sm="12" :md="6">
|
||||||
</el-form-item>
|
<el-form-item label="教员姓名">
|
||||||
<el-form-item label="课时核算标准">
|
<el-input v-model="hourForm.jyxm" placeholder="请输入教员姓名" clearable @keyup.enter.native="handleQuery" />
|
||||||
<el-select v-model="form.accountStandard" placeholder="请选择" class="w-full">
|
|
||||||
<el-option v-for="item in accountStandardOptions" :key="item" :label="item" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</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-row>
|
||||||
<div class="search-actions">
|
|
||||||
<el-button type="primary" :loading="addLoading" @click="handleAdd">添加</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 2. 数据表格 ==================== -->
|
<!-- ==================== 2. 数据表格 ==================== -->
|
||||||
<el-card shadow="never" class="table-card">
|
<el-card shadow="never" class="table-card">
|
||||||
<el-table v-loading="queryLoading" :data="tableData" border stripe style="width: 100%">
|
<div class="table-title">{{ activeTab === 'hour' ? '课时统计列表' : '课时费统计列表' }}</div>
|
||||||
<el-table-column label="详细" width="80" fixed align="center">
|
<el-table v-loading="currentState.loading" :data="currentState.list" border stripe style="width: 100%">
|
||||||
<template slot-scope="{ row }">
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-button type="text" @click="handleDetail(row)">详细</el-button>
|
<el-table-column prop="jysdh" label="教研室代号" width="100" align="center" show-overflow-tooltip />
|
||||||
</template>
|
<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">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.sbn) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="semesterName" label="学期名称" width="120" />
|
<el-table-column prop="xbn" label="下半年" width="90" align="right">
|
||||||
<el-table-column prop="taskCategory" label="任务类别" width="180" />
|
<template slot-scope="{ row }">{{ fmtValue(row.xbn) }}</template>
|
||||||
<el-table-column prop="startDate" label="核算开始日期" width="120" />
|
</el-table-column>
|
||||||
<el-table-column prop="endDate" label="核算结束日期" width="120" />
|
<el-table-column prop="zj" label="总计" width="90" align="right">
|
||||||
<el-table-column prop="totalHours" label="总课时量" width="100" align="right" />
|
<template slot-scope="{ row }">{{ fmtValue(row.zj) }}</template>
|
||||||
<el-table-column prop="qualityHours" label="优质课时量" width="100" align="right" />
|
</el-table-column>
|
||||||
<el-table-column prop="qualityRatio" label="优质课时量比例" width="120" align="right" />
|
<el-table-column prop="bzksl" label="标准课时量" width="100" align="right">
|
||||||
<el-table-column prop="totalSubsidy" label="总补助金额" width="120" align="right" />
|
<template slot-scope="{ row }">{{ fmtValue(row.bzksl) }}</template>
|
||||||
<el-table-column prop="accountStandard" label="课时核算标准" show-overflow-tooltip />
|
</el-table-column>
|
||||||
<el-table-column prop="subsidyStandard" label="课时补助标准" width="180" show-overflow-tooltip />
|
<el-table-column prop="cks" label="超课时" width="90" align="right">
|
||||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
<template slot-scope="{ row }">{{ fmtValue(row.cks) }}</template>
|
||||||
<template slot-scope="{ row }">
|
</el-table-column>
|
||||||
<span :class="row.status === '已核算' ? 'status-done' : 'status-doing'">
|
<el-table-column prop="jsgs" label="计算过程" min-width="140" show-overflow-tooltip />
|
||||||
{{ row.status }}
|
<el-table-column prop="jg" label="结果" width="90" align="right">
|
||||||
</span>
|
<template slot-scope="{ row }">{{ fmtValue(row.jg) }}</template>
|
||||||
</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">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.ksfbz) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="clksfbz" label="超量课时费单价" width="110" align="right">
|
||||||
|
<template slot-scope="{ row }">{{ fmtValue(row.clksfbz) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="table-footer">
|
<el-pagination
|
||||||
<span>总记录数:{{ tableData.length }} 条</span>
|
:current-page="currentState.pageNum"
|
||||||
<span>总课时量:{{ totalHours }}</span>
|
:page-size="currentState.pageSize"
|
||||||
<span>优质课时量:{{ totalQualityHours }}</span>
|
:total="currentState.total"
|
||||||
<span>总补助金额:{{ totalSubsidy }} 元</span>
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
</div>
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
class="pagination"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- ==================== 3. 详情对话框 ==================== -->
|
|
||||||
<el-dialog
|
|
||||||
:visible="detailVisible"
|
|
||||||
title="课时补助核算详情"
|
|
||||||
width="560px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
@update:visible="val => detailVisible = val"
|
|
||||||
>
|
|
||||||
<el-descriptions v-if="detailRow" :column="1" border>
|
|
||||||
<el-descriptions-item label="学期名称">{{ detailRow.semesterName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="任务类别">{{ detailRow.taskCategory }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="核算开始日期">{{ detailRow.startDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="核算结束日期">{{ detailRow.endDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="总课时量">{{ detailRow.totalHours }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="优质课时量">{{ detailRow.qualityHours }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="优质课时量比例">{{ detailRow.qualityRatio }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="总补助金额">{{ detailRow.totalSubsidy }} 元</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="课时核算标准">{{ detailRow.accountStandard }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="课时补助标准">{{ detailRow.subsidyStandard }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="状态">{{ detailRow.status }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
<div slot="footer">
|
|
||||||
<el-button @click="detailVisible = false">关闭</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 模拟核算列表数据(后端接口未提供,接口就绪后可删除并改为接口加载)
|
import { saveAs } from 'file-saver'
|
||||||
const mockSummaryData = [
|
import {
|
||||||
{ bh: 'H001', mc: '2022年秋季学期课时补助核算', rwlb: '全军院校训练规划内任务', hsksrq: '2022-09-01T00:00:00', hsjsrq: '2023-01-15T00:00:00', zksl: 1200, yzksl: 800, yzkslbl: 0.6667, zbzje: 24000, zt: '已核算' },
|
listHourStatistics,
|
||||||
{ bh: 'H002', mc: '2022年春季学期课时补助核算', rwlb: '其他任务(含研究生导师指导)', hsksrq: '2022-03-01T00:00:00', hsjsrq: '2022-08-31T00:00:00', zksl: 900, yzksl: 540, yzkslbl: 0.6, zbzje: 18000, zt: '核算中' },
|
exportHourStatistics,
|
||||||
{ bh: 'H003', mc: '2021年秋季学期课时补助核算', rwlb: '全军院校训练规划内任务', hsksrq: '2021-09-01T00:00:00', hsjsrq: '2022-01-15T00:00:00', zksl: 1100, yzksl: 770, yzkslbl: 0.7, zbzje: 22000, zt: '已核算' }
|
listFeeStatistics,
|
||||||
]
|
exportFeeStatistics
|
||||||
|
} from '@/api/classHour/hourStat'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SubsidyIndex',
|
name: 'SubsidyIndex',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// ==================== 顶部提示条 ====================
|
// ==================== Tab ====================
|
||||||
tipText: '提示:"课时核算"和"补助核算"要花费稍微长一点时间,操作后请耐心等待系统"操作成功"的提示!',
|
activeTab: 'hour',
|
||||||
|
|
||||||
// ==================== 下拉选项 ====================
|
// ==================== 课时统计查询条件 ====================
|
||||||
subsidyStandardOptions: ['2022年秋季学期', '2022年春季学期', '2021年秋季学期', '2021年春季学期'],
|
hourForm: {
|
||||||
accountStandardOptions: ['2022年秋季学期课时补助核算', '2022年春季学期课时补助核算', '2021年秋季学期课时补助核算', '2021年春季学期课时补助核算'],
|
nd: '',
|
||||||
taskCategoryOptions: [
|
xq: '',
|
||||||
{ label: '全军院校训练规划内任务', value: '全军院校训练规划内任务' },
|
jyxm: ''
|
||||||
{ label: '其他任务(含研究生导师指导)', value: '其他任务(含研究生导师指导)' }
|
|
||||||
],
|
|
||||||
|
|
||||||
// ==================== 新增表单 ====================
|
|
||||||
form: {
|
|
||||||
semesterName: '',
|
|
||||||
taskCategory: '全军院校训练规划内任务',
|
|
||||||
startDate: '',
|
|
||||||
endDate: '',
|
|
||||||
subsidyStandard: '2022年秋季学期',
|
|
||||||
accountStandard: '2022年秋季学期课时补助核算'
|
|
||||||
},
|
},
|
||||||
rules: {
|
|
||||||
semesterName: [{ required: true, message: '请输入学期名称', trigger: 'blur' }],
|
// ==================== 课时费统计查询条件 ====================
|
||||||
startDate: [{ required: true, message: '请输入开始日期', trigger: 'blur' }],
|
feeForm: {
|
||||||
endDate: [{ required: true, message: '请输入结束日期', trigger: 'blur' }]
|
nd: '',
|
||||||
|
xq: '',
|
||||||
|
jyxm: '',
|
||||||
|
ksfbzbh: ''
|
||||||
},
|
},
|
||||||
addLoading: false,
|
|
||||||
|
|
||||||
// ==================== 表格数据 ====================
|
// ==================== 各 Tab 列表状态 ====================
|
||||||
tableData: [],
|
hourState: this.createEmptyState(),
|
||||||
queryLoading: false,
|
feeState: this.createEmptyState()
|
||||||
|
|
||||||
// ==================== 详情对话框 ====================
|
|
||||||
detailVisible: false,
|
|
||||||
detailRow: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
totalHours() {
|
currentForm() {
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.totalHours || 0), 0)
|
return this.activeTab === 'hour' ? this.hourForm : this.feeForm
|
||||||
},
|
},
|
||||||
totalQualityHours() {
|
currentState() {
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.qualityHours || 0), 0)
|
return this.activeTab === 'hour' ? this.hourState : this.feeState
|
||||||
},
|
|
||||||
totalSubsidy() {
|
|
||||||
return this.tableData.reduce((sum, r) => sum + Number(r.totalSubsidy || 0), 0)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.handleQuery()
|
this.fetchList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ==================== 查询核算列表 ====================
|
createEmptyState() {
|
||||||
// TODO: 后端接口未提供,暂用模拟数据;接口就绪后替换为 /log/summary/list
|
return { list: [], loading: false, pageNum: 1, pageSize: 20, total: 0 }
|
||||||
handleQuery() {
|
|
||||||
this.queryLoading = true
|
|
||||||
setTimeout(() => {
|
|
||||||
this.tableData = mockSummaryData.map((item, idx) => ({
|
|
||||||
id: idx + 1,
|
|
||||||
_bh: item.bh || '',
|
|
||||||
semesterName: item.mc || '-',
|
|
||||||
taskCategory: item.rwlb || '-',
|
|
||||||
startDate: (item.hsksrq || '').substring(0, 10) || '-',
|
|
||||||
endDate: (item.hsjsrq || '').substring(0, 10) || '-',
|
|
||||||
totalHours: item.zksl || 0,
|
|
||||||
qualityHours: item.yzksl || 0,
|
|
||||||
qualityRatio: item.zksl > 0 ? ((item.yzkslbl || 0) * 100).toFixed(2) + '%' : '0.00%',
|
|
||||||
totalSubsidy: item.zbzje || 0,
|
|
||||||
accountStandard: item.mc || '-',
|
|
||||||
subsidyStandard: '-',
|
|
||||||
status: item.zt || '-'
|
|
||||||
}))
|
|
||||||
this.$message.success(`查询完成,共 ${this.tableData.length} 条记录(前端模拟)`)
|
|
||||||
this.queryLoading = false
|
|
||||||
}, 200)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ==================== 添加 ====================
|
/** 构建查询参数,仅传非空字段(与后端 Query 字段一致) */
|
||||||
// TODO: 后端接口未提供,提交为前端模拟;接口就绪后替换为 /log/subsidy-project/add
|
buildParams(form) {
|
||||||
handleAdd() {
|
const params = {}
|
||||||
this.$refs.formRef.validate((valid) => {
|
if (form.nd && form.nd.trim()) params.nd = form.nd.trim()
|
||||||
if (!valid) {
|
if (form.xq && form.xq.trim()) params.xq = form.xq.trim()
|
||||||
this.$message.warning('请完善必填项后再提交')
|
if (form.jyxm && form.jyxm.trim()) params.jyxm = form.jyxm.trim()
|
||||||
return
|
if (form.ksfbzbh && form.ksfbzbh.trim()) params.ksfbzbh = form.ksfbzbh.trim()
|
||||||
}
|
return params
|
||||||
this.addLoading = true
|
},
|
||||||
setTimeout(() => {
|
|
||||||
this.$message.success('核算提交成功(前端模拟)')
|
// ==================== 查询 ====================
|
||||||
this.handleQuery()
|
fetchList() {
|
||||||
this.addLoading = false
|
const state = this.currentState
|
||||||
}, 300)
|
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() {
|
||||||
handleDetail(row) {
|
this.currentState.pageNum = 1
|
||||||
this.detailRow = row
|
this.fetchList()
|
||||||
this.detailVisible = true
|
},
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,63 +263,37 @@ export default {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-tip {
|
// ==================== 1. 查询条件区域 ====================
|
||||||
color: #f56c6c;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
.form-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
.w-full {
|
.search-actions-col {
|
||||||
width: 100%;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-actions {
|
.search-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
gap: 12px;
|
||||||
margin-top: 8px;
|
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 2. 数据表格 ====================
|
||||||
.table-card {
|
.table-card {
|
||||||
.el-table {
|
.table-title {
|
||||||
width: 100%;
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-footer {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
justify-content: flex-end;
|
||||||
gap: 24px;
|
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-done {
|
|
||||||
color: #67c23a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-doing {
|
|
||||||
color: #e6a23c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user