feat: gx-人员请假申请

This commit is contained in:
TianyangZhang 2026-01-07 16:01:51 +08:00
parent cbc940b8df
commit f475974d49
3 changed files with 387 additions and 0 deletions

View File

@ -266,4 +266,39 @@ export default {
}
},
},
leave: {
list: {
name: "人员请假",
req: async function(data){
return await http.get(
`${config.API_URL}/hrm/leave/`,
data
);
}
},
item: {
name: "人员请假申请",
req: async function(id){
return await http.get(
`${config.API_URL}/hrm/leave/${id}/`,
);
}
},
create: {
name: "人员请假新增",
req: async function(data){
return await http.post(
`${config.API_URL}/hrm/leave/`,
data);
}
},
delete: {
name: "人员请假删除",
req: async function(id){
return await http.delete(
`${config.API_URL}/hrm/leave/${id}/`
);
}
},
},
}

134
src/views/hrm/leave.vue Normal file
View File

@ -0,0 +1,134 @@
<template>
<el-container>
<el-header>
<div class="left-panel">
<el-button type="primary" @click="handleAdd">新增</el-button>
</div>
<div class="right-panel">
<el-select
v-model="query.leave_type"
placeholder="请假类型"
@change="handleQuery"
clearable
style="margin-left: 2px; width: 120px"
>
<el-option
v-for="item in leaveOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
<el-cascader
v-model="query.employee__belong_dept"
:options="deptData"
clearable
placeholder="部门/单位"
@change="handleQuery"
:show-all-levels="false"
:props="{ emitPath: false, checkStrictly: true }"
style="margin-left: 4px; width: 150px"
/>
<el-button
type="primary"
icon="el-icon-search"
@click="handleQuery"
></el-button>
</div>
</el-header>
<el-main class="nopadding">
<scTable
ref="table"
:apiObj="this.$API.hrm.leave.list"
row-key="id"
stripe
:query="query"
@row-click="(row)=>{t_id=row.id;mode='show';drawerVisible=true;}"
>
<el-table-column label="部门" prop="dept_need_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="姓名" prop="employee_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="岗位" prop="post_name" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="审批状态" width="200" show-overflow-tooltip>
<template #default="scope">
<el-tag :type="actStateEnum[scope.row.ticket_?.act_state]?.type">
{{ actStateEnum[scope.row.ticket_?.act_state]?.text }}
</el-tag>
<el-tag type="info" effect="plain">{{ scope.row.ticket_?.state_.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="请假类型" prop="leave_type" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="开始时间" prop="start_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="结束时间" prop="end_date" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="请假小时数" prop="hour" width="80" show-overflow-tooltip></el-table-column>
<el-table-column label="请假事由" prop="reason" width="150" show-overflow-tooltip></el-table-column>
</scTable>
</el-main>
</el-container>
<el-drawer title="请假审批" v-model="drawerVisible" :size="'50%'" destroy-on-close>
<div style="display: flex; height: calc(100% - 60px);">
<div style="flex: 1; padding-right: 20px; overflow-y: auto;">
<leave_form
:mode="mode"
:t_id="t_id"
@success="()=>{handleQuery(); drawerVisible = false}"
@closed="drawerVisible = false"
/>
</div>
</div>
</el-drawer>
</template>
<script>
import leave_form from './leave_form.vue'
import { actStateEnum, interveneTypeEnum } from "@/utils/enum.js";
import { genTree } from "@/utils/verificate";
export default {
name: "hrm.leave",
components: {
leave_form,
},
data() {
return {
actStateEnum, interveneTypeEnum,
drawerVisible: false,
mode: 'show',
t_id: null,
deptData: [],
query: {},
leaveOptions:[
{ label: "事假", value: 10 },
{ label: "病假", value: 20 },
{ label: "婚假", value: 30 },
{ label: "丧假", value: 40 },
{ label: "公假", value: 50 },
{ label: "工伤", value: 60 },
{ label: "产假", value: 70 },
{ label: "护理假", value: 80 },
{ label: "其他", value: 90 }
],
};
},
mounted() {
this.getDept();
},
methods: {
handleAdd() {
this.mode = 'add';
this.t_id = null;
this.drawerVisible = true;
},
handleQuery() {
this.$refs.table.queryData(this.query);
},
async getDept() {
let res = await this.$API.system.dept.list.req({
page: 0,
type__in: "dept,rparty",
});
this.deptData = genTree(res);
},
},
};
</script>

View File

@ -0,0 +1,218 @@
<template>
<el-container>
<el-main class="nopadding">
<el-form label-width="80px" :rules="rules" :model="formData" style="padding: 20px;" :disabled="localMode === 'show'">
<el-form-item label="员工信息" required>
{{ formData.employee_name }}{{ formData.belong_dept_name }} - {{ formData.post_name }}
</el-form-item>
<el-form-item label="请假类型" required>
<el-select
v-model="formData.leave_type"
placeholder="请选择请假类型"
clearable
style="width: 200px"
@change="handleTypeChange"
>
<el-option label="事假" :value="10" />
<el-option label="病假" :value="20" />
<el-option label="婚假" :value="30" />
<el-option label="丧假" :value="40" />
<el-option label="公假" :value="50" />
<el-option label="工伤" :value="60" />
<el-option label="产假" :value="70" />
<el-option label="护理假" :value="80" />
<el-option label="其他" :value="90" />
</el-select>
</el-form-item>
<el-form-item label="开始日期" required>
<el-date-picker
v-model="formData.start_date"
type="datetime"
placeholder="请假开始日期"
value-format="YYYY-MM-DD HH:mm:ss"
:readonly="localMode === 'show'"
style="width: 200px"
></el-date-picker>
</el-form-item>
<el-form-item label="结束日期" required>
<el-date-picker
v-model="formData.end_date"
type="datetime"
placeholder="请假结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
:readonly="localMode === 'show'"
style="width: 200px"
></el-date-picker>
</el-form-item>
<el-form-item label="请假时长一天8h计算" label-width="180px" required>
<el-input v-model="formData.hour" type="number" min="1" style="width: 160px">
<template #append>小时</template>
</el-input>
</el-form-item>
<el-form-item label="上传附件"
v-if = "showUpload"
prop="file">
<sc-upload-file
v-model="formData.file"
:multiple="false"
:limit="1"
:accept="['.xlsx', '.xls','.pdf','.docx', '.doc', '.jpg', '.png', '.jpeg']"
@success = "fileUPSuccess"
:disabled="localMode ==='show'"
>
<el-button type="primary" icon="el-icon-upload"> </el-button>
</sc-upload-file>
</el-form-item>
<el-form-item label="申请理由" required>
<el-input v-model="formData.reason" type="textarea" rows="3" style="width: 400px" placeholder="请输入请假理由"></el-input>
</el-form-item>
</el-form>
<el-footer>
<el-button type="danger"
v-if="localMode=='edit'"
style="margin-right: 4px;"
@click="handleDel"
:loading="saveLoading"
>删除</el-button>
<ticketd_b
v-if = "formData.ticket_ && localMode=='show'"
:t_id="formData.id"
:ticket_="formData.ticket_"
:ticket_data="ticket_data"
@success="$emit('success', localMode)"
ref="ticketd_b"
></ticketd_b>
<el-button
v-if="localMode!='show'"
type="primary"
style="margin-right: 4px;"
@click="handleSave"
:loading="saveLoading"
>提交审批</el-button>
</el-footer>
</el-main>
<el-aside width="20%" v-if="formData.ticket_">
<ticketd :ticket_="formData.ticket_" @success="$emit('success')"></ticketd>
</el-aside>
</el-container>
</template>
<script>
import ticketd_b from "@/views/wf/ticketd_b.vue";
import ticketd from '@/views/wf/ticketd.vue'
export default {
components: {
ticketd_b,
ticketd
},
props: {
mode: {
type: String,
default: 'show'
},
t_id: {
type: String,
default: ""
}
},
computed: {
showUpload() {
return [20, 30, 40, 70].includes(this.formData.leave_type)
},
},
data() {
return {
formData: {},
ticket_data: {},
localMode: this.mode,
saveLoading: false,
rules: {
leave_type: [{ required: true, message: "请输入请假类型", trigger: "blur" }],
start_date: [{ required: true, message: "请选择开始时间", trigger: "blur" }],
end_date: [{ required: true, message: "请选择结束时间", trigger: "blur" }],
hour: [{ required: true, message: "请输入请假时长", trigger: "blur" }],
file: [{ required: true, message: "请上传附件", trigger: "blur" }],
reason: [{ required: true, message: "请输入请假理由", trigger: "blur" }],
},
}
},
watch: {
mode(val) {
this.localMode = val;
},
},
mounted() {
if (this.t_id) {
this.getTid();
}else {
this.initFormData();
}
},
methods: {
async getTid() {
try {
let res = await this.$API.hrm.leave.item.req(this.t_id);
this.formData = res;
if (res.ticket_ && res.ticket_.state_.type == 1 && res.create_by == this.$TOOL.data.get("USER_INFO").id) {
this.localMode = "edit";
}
} catch (error) {
console.error('获取请假数据失败:', error);
}
},
async initFormData() {
try {
let res = await this.$API.hrm.employee.read.req();
this.formData.employee_name = res.name;
this.formData.belong_dept_name = res.belong_dept_name;
this.formData.post_name = res.post_name;
this.formData.employee = res.id;
this.localMode = "add";
} catch (error) {
console.error('初始化表单数据失败:', error);
}
},
handleTypeChange(val) {
const map = {
10: '事假',
20: '病假',
30: '婚假',
40: '丧假',
50: '公假',
60: '工伤',
70: '产假',
80: '护理假',
90: '其他',
}
this.formData.leave_type_name = map[val] || ''
},
handleDel() {
this.$confirm(`确定删除吗?`, "提示", {
type: "warning",
})
.then(()=>{
this.$API.hrm.leave.delete.req(this.formData.id).then(res=>{
this.$message.success("删除成功");
this.$emit('success');
})
})
},
async handleSave() {
if (this.localMode == "add") {
try {
let res = await this.$API.hrm.leave.create.req(this.formData);
this.$message.success("提交成功");
this.$emit('success', this.localMode);
} catch (error) {
console.error('请假需求申请失败:', error);
throw error;
}
} else if (this.localMode == "edit") {
this.$message.error("不支持编辑");
}
},
},
};
</script>