Files
school-developer/src/views/stuwork/stutemleaveapply/index.vue
2026-01-29 16:38:09 +08:00

346 lines
11 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="modern-page-container">
<div class="page-wrapper">
<!-- æ<EFBFBD>œç´¢è¡¨å<EFBFBD>å<EFBFBD>¡ç -->
<el-card v-show="showSearch" class="search-card" shadow="never">
<template #header>
<div class="card-header">
<span class="card-title">
<el-icon class="title-icon"><Search /></el-icon>
ç­éæ<EFBFBD>¡ä»?
</span>
</div>
</template>
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch" class="search-form">
<el-form-item label="系部代ç <C3A7>" prop="deptCode">
<el-select
v-model="searchForm.deptCode"
placeholder="请选择系部"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in deptList"
:key="item.deptCode"
:label="item.deptName"
:value="item.deptCode">
</el-option>
</el-select>
</el-form-item>
<el-form-item label=<>­çº§ä»£ç <C3A7>" prop="classCode">
<el-select
v-model="searchForm.classCode"
placeholder="请选æ©ç<C2A9>­çº§"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in classList"
:key="item.classCode"
:label="item.classNo"
:value="item.classCode">
</el-option>
</el-select>
</el-form-item>
<el-form-item label=­¦å<C2A6>·" prop="stuNo">
<el-input
v-model="searchForm.stuNo"
placeholder="请输入学å<C2A6>?
clearable
style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button>
<el-button icon="Refresh" @click="handleReset">é<EFBFBD>ç½®</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- å容å<EFBFBD>¡ç -->
<el-card class="content-card" shadow="never">
<template #header>
<div class="card-header">
<span class="card-title">
<el-icon class="title-icon"><Document /></el-icon>
å­¦çŸä¸´æè¯·å<EFBFBD>åˆè¡¨
</span>
<div class="header-actions">
<el-button
icon="Plus"
type="primary"
@click="formDialogRef.openDialog()">
æ°å¢ž
</el-button>
<right-toolbar
v-model:showSearch="showSearch"
class="ml10"
@queryTable="getDataList">
<TableColumnControl
ref="columnControlRef"
:columns="tableColumns"
v-model="visibleColumns"
trigger-type="default"
trigger-circle
@change="handleColumnChange"
@order-change="handleColumnOrderChange"
>
<template #trigger>
<el-tooltip class="item" effect="dark" content="列设� placement="top">
<el-button circle style="margin-left: 0;">
<el-icon><Menu /></el-icon>
</el-button>
</el-tooltip>
</template>
</TableColumnControl>
</right-toolbar>
</div>
</div>
</template>
<!-- 表格 -->
<el-table
:data="state.dataList"
v-loading="state.loading"
stripe
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
class="modern-table">
<el-table-column type="index" label="åº<C3A5>å<EFBFBD>·" width="70" align="center">
<template #header>
<el-icon><List /></el-icon>
</template>
<template #default="{ $index }">
{{ $index + 1 + ((state.pagination?.current || 1) - 1) * (state.pagination?.size || 10) }}
</template>
</el-table-column>
<template v-for="col in visibleColumnsSorted" :key="col.prop || col.label">
<el-table-column
v-if="checkColumnVisible(col.prop || '') && col.prop !== 'æ“<C3A6>作'"
:prop="col.prop"
:label="col.label"
:width="col.width"
:min-width="col.minWidth"
:show-overflow-tooltip="col.showOverflowTooltip !== false"
:align="col.align || 'center'">
<template #header>
<el-icon v-if="col.icon"><component :is="col.icon" /></el-icon>
<span :style="{ marginLeft: col.icon ? '4px' : '0' }">{{ col.label }}</span>
</template>
<template #default="scope" v-if="col.prop === 'schoolTerm'">
<el-tag size="small" type="primary" effect="plain">
{{ formatSchoolTerm(scope.row.schoolTerm) }}
</el-tag>
</template>
<template #default="scope" v-else-if="col.prop === 'startTime'">
<span>{{ scope.row.startTime ? formatDateTime(scope.row.startTime) : '-' }}</span>
</template>
<template #default="scope" v-else-if="col.prop === 'endTime'">
<span>{{ scope.row.endTime ? formatDateTime(scope.row.endTime) : '-' }}</span>
</template>
</el-table-column>
</template>
<el-table-column label="æ“<C3A6>作" width="100" align="center" fixed="right">
<template #header>
<el-icon><Setting /></el-icon>
<span style="margin-left: 4px">æ<EFBFBD>作</span>
</template>
<template #default="scope">
<el-button
icon="Delete"
link
type="danger"
@click="handleDelete(scope.row)">
删é¤
</el-button>
</template>
</el-table-column>
</el-table>
<!-- åˆé¡µ -->
<div class="pagination-wrapper">
<pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
</el-card>
</div>
<!-- æ°å¢žè¡¨å<EFBFBD>å¼¹çª -->
<form-dialog ref="formDialogRef" @refresh="getDataList" />
</div>
</template>
<script setup lang="ts" name="StuTemLeaveApply">
import { reactive, ref, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObj } from "/@/api/stuwork/stutemleaveapply";
import { getDicts } from "/@/api/admin/dict";
import { getDeptListByLevelTwo } from "/@/api/basic/basicdept";
import { getClassListByRole } from "/@/api/basic/basicclass";
import { useMessage, useMessageBox } from "/@/hooks/message";
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
import FormDialog from './form.vue'
import { List, Calendar, Clock, OfficeBuilding, Grid, CreditCard, Avatar, Document, UserFilled, Phone, EditPen, Setting, Menu, Search } from '@element-plus/icons-vue'
import { useTableColumnControl } from '/@/hooks/tableColumnControl'
// 定义å<E280B0>˜é‡<C3A9>内容
const route = useRoute()
const searchFormRef = ref()
const columnControlRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const classList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const formDialogRef = ref()
// 表格列é…<C3A9>ç½?
const tableColumns = [
{ prop: 'schoolYear', label: '学年', icon: Calendar },
{ prop: 'schoolTerm', label: '学期', icon: Clock },
{ prop: 'deptCode', label: '系部代ç <C3A7>', icon: OfficeBuilding },
{ prop: 'classCode', label: <>­çº§ä»£ç <C3A7>', icon: Grid },
{ prop: 'stuNo', label: ­¦å<C2A6>·', icon: CreditCard },
{ prop: 'realName', label: 'å§“å<E2809C><C3A5>', icon: Avatar },
{ prop: 'startTime', label: '请å<C2B7>‡å¼€å§æ—¶é—?, icon: Calendar, width: 180 },
{ prop: 'endTime', label: '请å<EFBFBD>ç»æ<EFBFBD>Ÿæé´', icon: Calendar, width: 180 },
{ prop: 'reason', label: '请å<EFBFBD>äºç±', icon: Document, minWidth: 150 },
{ prop: 'classTeach', label: 'ç<EFBFBD>­ä¸»ä»?, icon: UserFilled },
{ prop: 'stuPhote', label: <>”ç³»æ¹å¼<C3A5>', icon: Phone },
{ prop: 'remarks', label: '备注', icon: EditPen, minWidth: 150 }
]
// 使用表格列控制hook
const {
visibleColumns,
visibleColumnsSorted,
checkColumnVisible,
handleColumnChange,
handleColumnOrderChange
} = useTableColumnControl(tableColumns, route.path)
// æ<>œç´¢è¡¨å<C2A8>
const searchForm = reactive({
deptCode: '',
classCode: '',
stuNo: ''
})
// é…<C3A9>ç½® useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle
} = useTable(state)
// æ ¼å¼<C3A5>åŒå­¦æœ?
const formatSchoolTerm = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = schoolTermList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// æ ¼å¼<C3A5>åŒæ—¥æœŸæ—¶é—?
const formatDateTime = (dateTime: string) => {
if (!dateTime) return '-'
// 妿žœåŒ…å<E280A6>«æ—¶é—´éƒ¨åˆ†ï¼Œå<C592>ªæ˜¾ç¤ºæ—¥æœŸåŒæ—¶é—?
if (dateTime.includes(' ')) {
return dateTime.split('.')[0] // 移除毫秒部分
}
return dateTime
}
// 查询
const handleSearch = () => {
getDataList()
}
// é‡<C3A9>ç½®
const handleReset = () => {
searchFormRef.value?.resetFields()
getDataList()
}
// 删除
const handleDelete = async (row: any) => {
const { confirm } = useMessageBox()
try {
await confirm('确定è¦<C3A8>删除该临时请å<C2B7>‡è®°å½•å<E280A2>—?')
await delObj([row.id])
useMessage().success(ˆ é™¤æˆ<C3A6>功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 获å<C2B7>系部列表
const getDeptListData = async () => {
try {
const res = await getDeptListByLevelTwo()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
deptList.value = []
}
}
// 获å<C2B7>ç<E28093>­çº§åˆ—表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
classList.value = []
}
}
// 获å<C2B7>学期字典
const getSchoolTermDict = async () => {
try {
const res = await getDicts('school_term')
if (res.data) {
schoolTermList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
schoolTermList.value = []
}
}
// åˆ<C3A5>å§åŒ?
onMounted(() => {
getDeptListData()
getClassListData()
getSchoolTermDict()
})
</script>
<style scoped lang="scss">
@import '/@/assets/styles/modern-page.scss';
</style>