Files
school-developer/src/views/stuwork/stuleaveapply/form.vue
2026-02-08 23:47:54 +08:00

328 lines
8.7 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>
<el-dialog
title="新增"
v-model="visible"
:close-on-click-modal="false"
draggable
width="800px">
<el-form
ref="dataFormRef"
:model="form"
:rules="dataRules"
label-width="120px"
v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="班级" prop="classCode">
<el-select
v-model="form.classCode"
placeholder="请选择班级"
clearable
filterable
style="width: 100%"
@change="handleClassChange">
<el-option
v-for="item in classList"
:key="item.classCode"
:label="item.classNo"
:value="item.classCode">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="学号" prop="stuNo">
<el-select
v-model="form.stuNo"
placeholder="请选择学生"
clearable
filterable
style="width: 100%"
:disabled="!form.classCode"
@change="handleStudentChange">
<el-option
v-for="item in studentList"
:key="item.stuNo"
:label="`${item.realName} (${item.stuNo})`"
:value="item.stuNo">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="请假时间" prop="leaveTime">
<el-date-picker
v-model="form.leaveTime"
type="datetimerange"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="请假类型" prop="leaveType">
<el-select
v-model="form.leaveType"
placeholder="请选择请假类型"
clearable
style="width: 100%">
<el-option
v-for="item in leaveTypeList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="是否住宿" prop="stayDorm">
<el-switch
v-model="form.stayDorm"
active-value="1"
inactive-value="0"
active-text=""
inactive-text="" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="是否发热" prop="isFever">
<el-switch
v-model="form.isFever"
active-value="1"
inactive-value="0"
active-text=""
inactive-text="" />
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item label="请假事由" prop="reason">
<el-input
v-model="form.reason"
type="textarea"
:rows="4"
placeholder="请输入请假事由" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false"> </el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="StuLeaveApplyFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj } from '/@/api/stuwork/stuleaveapply'
import { getDicts } from '/@/api/admin/dict'
import { getClassListByRole } from '/@/api/basic/basicclass'
import { queryStudentListByClass } from '/@/api/basic/basicstudent'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const classList = ref<any[]>([])
const studentList = ref<any[]>([])
const leaveTypeList = ref<any[]>([])
const yesNoList = ref<any[]>([])
// 提交表单数据
const form = reactive({
classCode: '',
stuNo: '',
leaveTime: null as [string, string] | null,
leaveType: '',
reason: '',
stayDorm: '',
isFever: ''
})
// 定义校验规则
const dataRules = {
classCode: [
{ required: true, message: '请选择班级', trigger: 'change' }
],
stuNo: [
{ required: true, message: '请选择学生', trigger: 'change' }
],
leaveTime: [
{ required: true, message: '请选择请假时间', trigger: 'change', type: 'array', min: 2 }
],
leaveType: [
{ required: true, message: '请选择请假类型', trigger: 'change' }
],
reason: [
{ required: true, message: '请输入请假事由', trigger: 'blur' }
],
stayDorm: [
{ required: true, message: '请选择是否住宿', trigger: 'change' }
],
isFever: [
{ required: true, message: '请选择是否发热', trigger: 'change' }
]
}
// 班级变化时获取学生列表
const handleClassChange = async (classCode: string) => {
form.stuNo = ''
studentList.value = []
if (!classCode) {
return
}
try {
// 接口文档GET 仅 classCode返回 data 为数组
const res = await queryStudentListByClass({ classCode })
const data = res?.data
if (Array.isArray(data)) {
studentList.value = data
} else if (data?.records && Array.isArray(data.records)) {
studentList.value = data.records
} else {
studentList.value = []
}
} catch (err) {
studentList.value = []
}
}
// 学生变化
const handleStudentChange = (stuNo: string) => {
// 可以在这里处理学生变化后的逻辑
}
// 打开弹窗
const openDialog = async () => {
visible.value = true
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.classCode = ''
form.stuNo = ''
form.leaveTime = null
form.leaveType = ''
form.reason = ''
form.stayDorm = '0'
form.isFever = '0'
studentList.value = []
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
// 验证请假时间范围
if (!form.leaveTime || form.leaveTime.length !== 2) {
useMessage().error('请选择请假时间范围')
return
}
const [startTime, endTime] = form.leaveTime
const start = new Date(startTime)
const end = new Date(endTime)
if (end <= start) {
useMessage().error('请假结束时间必须大于开始时间')
return
}
loading.value = true
try {
await addObj({
classCode: form.classCode,
stuNo: form.stuNo,
startTime: startTime,
endTime: endTime,
leaveType: form.leaveType,
reason: form.reason,
stayDorm: form.stayDorm,
isFever: form.isFever
})
useMessage().success('新增成功')
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || '新增失败')
} finally {
loading.value = false
}
})
}
// 获取班级列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
classList.value = []
}
}
// 获取请假类型字典
const getLeaveTypeDict = async () => {
try {
const res = await getDicts('leave_type')
if (res.data) {
leaveTypeList.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) {
leaveTypeList.value = []
}
}
// 获取是否字典
const getYesNoDict = async () => {
try {
const res = await getDicts('yes_no')
if (res.data) {
yesNoList.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) {
yesNoList.value = []
}
}
// 初始化
onMounted(() => {
getClassListData()
getLeaveTypeDict()
getYesNoDict()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>