Files
school-developer/src/views/professional/teachersalary/index.vue
zhoutianchi 9fcbfb0fd7 薪资
2026-01-12 14:55:38 +08:00

411 lines
12 KiB
Vue
Executable File

<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<search-form
v-show="showSearch"
:model="search"
ref="searchFormRef"
@keyup-enter="handleFilter"
>
<template #default="{ visible }">
<template v-if="visible">
<el-form-item label="工号" prop="teacherNo">
<el-input
v-model="search.teacherNo"
placeholder="请输入工号"
clearable
style="width: 200px"
/>
</el-form-item>
<el-form-item label="姓名" prop="realName">
<el-input
v-model="search.realName"
placeholder="请输入姓名"
clearable
style="width: 200px"
/>
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input
v-model="search.idCard"
placeholder="请输入身份证号"
clearable
style="width: 200px"
/>
</el-form-item>
<el-form-item label="年份" prop="nf">
<el-date-picker
v-model="search.nf"
type="year"
format="YYYY"
value-format="YYYY"
placeholder="请选择年份"
clearable
style="width: 200px"
/>
</el-form-item>
<el-form-item label="月份" prop="yf">
<el-date-picker
v-model="search.yf"
type="month"
format="M"
value-format="M"
placeholder="请选择月份"
clearable
style="width: 200px"
/>
</el-form-item>
<el-form-item label="岗位类别" prop="stationTypeId">
<el-select
v-model="search.stationTypeId"
filterable
clearable
placeholder="请选择岗位类别"
style="width: 200px"
>
<el-option
v-for="item in stationLevelList"
:key="item.id"
:label="item.levelName"
:value="item.id"
/>
</el-select>
</el-form-item>
</template>
</template>
<!-- 查询和重置按钮 -->
<template #actions>
<el-form-item>
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
</el-form-item>
</template>
</search-form>
<!-- 操作按钮 -->
<el-row>
<div class="mb15">
<el-button
type="primary"
plain
icon="UploadFilled"
v-if="permissions.professional_salary_import"
@click="handleImportBaseSalary">人事薪资导入
</el-button>
<el-button
type="warning"
plain
icon="Download"
class="ml10"
v-if="permissions.professional_salary_finance_import"
@click="handleExportSalart">薪资导出
</el-button>
<el-button
type="primary"
plain
icon="UploadFilled"
class="ml10"
v-if="permissions.professional_salary_finance_import"
@click="handleImportTaxSalary">税金导入
</el-button>
<el-button
icon="View"
class="ml10"
v-if="permissions.professional_seach_auth"
@click="canSearch(1)">设置可查询
</el-button>
<el-button
icon="Hide"
class="ml10"
v-if="permissions.professional_seach_auth"
@click="canSearch(0)">设置不可查询
</el-button>
<el-button
type="danger"
plain
icon="Delete"
class="ml10"
v-if="permissions.professional_professionalsalaries_del"
@click="delbatch">批量删除
</el-button>
</div>
</el-row>
<!-- 表格 -->
<el-table
ref="tableRef"
:data="state.dataList"
v-loading="state.loading"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
class="data-table"
@selection-change="selectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="姓名/工号" min-width="150" align="center">
<template #default="scope">
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
</template>
</el-table-column>
<el-table-column prop="postSalary" label="岗位工资" min-width="120" align="center" show-overflow-tooltip />
<el-table-column prop="nf" label="年份" width="100" align="center" />
<el-table-column prop="yf" label="月份" width="100" align="center" />
<el-table-column prop="idCard" label="身份证号" min-width="180" align="center" show-overflow-tooltip />
<el-table-column prop="shouldPay" label="应发工资" min-width="120" align="center" show-overflow-tooltip />
<el-table-column prop="realWage" label="实发工资" width="120" align="center" show-overflow-tooltip />
<el-table-column prop="normalView" label="职工查看" width="120" align="center">
<template #default="scope">
<el-tag :type="scope.row.normalView === '1' ? 'success' : 'info'">
{{ scope.row.normalView === '1' ? '可查询' : '不可查询' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" min-width="80" align="center" fixed="right">
<template #default="scope">
<el-button
icon="document"
link
type="primary"
@click="handleEdit(scope.row)">查看
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-bind="state.pagination"
@current-change="currentChangeHandle"
@size-change="sizeChangeHandle"
/>
<!-- 子组件 -->
<salary-info ref="salaryInfoRef" />
<import-base-salary ref="importBaseSalaryRef" @refreshData="handleFilter" />
<export-base-salary ref="exportBaseSalaryRef" />
<import-tax-salary ref="importTaxSalaryRef" @refreshData="handleFilter" />
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { defineAsyncComponent } from 'vue'
import { storeToRefs } from 'pinia'
import { useUserInfo } from '/@/stores/userInfo'
import { BasicTableProps, useTable } from '/@/hooks/table'
import { useMessage, useMessageBox } from '/@/hooks/message'
import { fetchList, delBatch, setCanSearch, checkAuth } from '/@/api/professional/salaries/teachersalary'
import { getStationLevelList } from '/@/api/professional/professionalstationlevelconfig'
import SalaryInfo from './salaryInfo.vue'
import ImportBaseSalary from './importBaseSalary.vue'
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
import ExportBaseSalary from './exportBaseSalary.vue'
import ImportTaxSalary from './importTaxSalary.vue'
// 使用 Pinia store
const userInfoStore = useUserInfo()
const { userInfos } = storeToRefs(userInfoStore)
// 创建权限对象
const permissions = computed(() => {
const perms: Record<string, boolean> = {}
userInfos.value.authBtnList.forEach((perm: string) => {
perms[perm] = true
})
return perms
})
// 消息提示 hooks
const message = useMessage()
const messageBox = useMessageBox()
// 表格引用
const tableRef = ref()
const searchFormRef = ref()
const salaryInfoRef = ref()
const importBaseSalaryRef = ref()
const exportBaseSalaryRef = ref()
const importTaxSalaryRef = ref()
// 搜索表单显示状态
const showSearch = ref(true)
// 岗位类别列表
const stationLevelList = ref<any[]>([])
// 选中的行
const selectList = ref<any[]>([])
// 搜索表单数据
const search = reactive({
teacherNo: '',
realName: '',
idCard: '',
nf: '',
yf: '',
stationTypeId: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
pageList: async (params: any) => {
const response = await fetchList(params)
return {
data: {
records: response.data.records || [],
total: response.data.total || 0
}
}
},
queryForm: search
})
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
// 初始化
onMounted(() => {
init()
})
// 初始化数据
const init = async () => {
try {
const [stationRes, authRes] = await Promise.all([
getStationLevelList(),
checkAuth()
])
stationLevelList.value = stationRes.data || []
// 根据权限设置表格选项(如果需要)
// if (authRes.data.data === false) {
// // 设置普通表格选项
// }
} catch (error) {
// 初始化失败
}
}
// 查询
const handleFilter = () => {
getDataList() // 查询后跳转到第一页
}
// 重置
const resetQuery = () => {
searchFormRef.value?.formRef?.resetFields()
Object.assign(search, {
teacherNo: '',
realName: '',
idCard: '',
nf: '',
yf: '',
stationTypeId: ''
})
handleFilter()
}
// 选择变化
const selectionChange = (selection: any[]) => {
selectList.value = selection
}
// 查看
const handleEdit = (row: any) => {
salaryInfoRef.value?.init(row)
}
// 导入人事薪资
const handleImportBaseSalary = () => {
importBaseSalaryRef.value?.init()
}
// 导入税金
const handleImportTaxSalary = () => {
importTaxSalaryRef.value?.init()
}
// 导出薪资
const handleExportSalart = () => {
exportBaseSalaryRef.value?.init()
}
// 批量删除
const delbatch = () => {
if (selectList.value.length === 0) {
message.warning("请至少选择一名人员")
return
}
messageBox.confirm(`确认删除当前${selectList.value.length}条记录`).then(async () => {
try {
const data = { selectList: selectList.value }
const response = await delBatch(data)
if (response.data.code == -1) {
message.error(response.data.data)
} else {
message.success("删除成功")
getDataList(false) // 删除后保持当前页
}
} catch (error: any) {
message.error(error?.msg || '删除失败')
}
}).catch(() => {
// 用户取消
})
}
// 设置可查询/不可查询
const canSearch = (val: number) => {
if (selectList.value.length === 0) {
message.warning("请至少选择一名人员")
return
}
const params = {
canSearch: val,
selectList: selectList.value
}
messageBox.confirm('确认设置?').then(async () => {
try {
await setCanSearch(params)
message.success("设置成功")
getDataList(false) // 设置后保持当前页
} catch (error: any) {
message.error(error?.msg || '设置失败')
}
}).catch(() => {
// 用户取消
})
}
</script>
<style lang="scss" scoped>
.data-table {
width: 100% !important;
}
</style>