Files
klp-oa/klp-ui/src/views/wms/hrm/employeeInfo/index.vue
砂糖 ea73305ebb feat(员工信息): 添加时间范围筛选功能并新增员工报表页面
在员工信息各页面添加入职/转正/调岗/离职时间范围筛选功能
新增员工报表页面,包含统计卡片、图表和数据表格
2026-03-21 17:45:37 +08:00

629 lines
24 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>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="60px">
<el-form-item label="部门" prop="deptId">
<el-select v-model="queryParams.dept" placeholder="请选择部门" clearable @keyup.enter.native="handleQuery">
<el-option v-for="item in deptList" :value="item.deptName" :label="item.deptName" :key="item.deptId" />
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="queryParams.idCard" placeholder="请输入身份证号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model="queryParams.age" placeholder="请输入年龄" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select v-model="queryParams.gender" placeholder="请选择性别" clearable @change="handleQuery">
<el-option label="男" value="男" />
<el-option label="女" value="女" />
</el-select>
<!-- <el-input v-model="queryParams.gender" placeholder="请输入性别" clearable @keyup.enter.native="handleQuery" /> -->
</el-form-item>
<el-form-item label="学历" prop="education">
<el-select v-model="queryParams.education" placeholder="请选择学历" clearable @change="handleQuery">
<el-option v-for="item in dict.type.hrm_employee_education" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="转正情况" prop="isRegular">
<el-select v-model="queryParams.isRegular" placeholder="请选择转正情况" clearable @change="handleQuery">
<el-option label="已转正" value="1" />
<el-option label="未转正" value="0" />
</el-select>
</el-form-item>
<el-form-item label="入职时间">
<el-date-picker
v-model="queryParams.entryTimeRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 240px"
/>
</el-form-item>
<el-form-item label="在职情况" prop="isLeave">
<el-select v-model="queryParams.isLeave" placeholder="请选择在职情况" clearable @change="handleQuery">
<el-option label="已离职" value="1" />
<el-option label="在职" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">入职</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
@click="handleUpdate">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
@click="handleDelete">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="employeeInfoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="infoId" v-if="false" />
<el-table-column label="部门" align="center" prop="dept" />
<el-table-column label="岗位工种" align="center" prop="jobType" />
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="身份证号" align="center" prop="idCard" />
<el-table-column label="年龄" align="center" prop="age" />
<el-table-column label="性别" align="center" prop="gender" />
<el-table-column label="学历" align="center" prop="education" />
<el-table-column label="家庭住址" align="center" prop="homeAddress" />
<el-table-column label="联系电话" align="center" prop="phone" />
<el-table-column label="入职时间" align="center" prop="entryTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.entryTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="在职天数" align="center">
<template slot-scope="scope">
<el-tag :type="getRegularStatus(scope.row.entryTime, scope.row.isRegular).type">
{{ getRegularStatus(scope.row.entryTime, scope.row.isRegular).days }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="紧急联系人" align="center" prop="emergencyContact" />
<el-table-column label="关系" align="center" prop="relationship" />
<el-table-column label="紧急联系电话" align="center" prop="emergencyContactPhone" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="在职状态" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.isLeave === 0 ? 'success' : 'danger'">
{{ scope.row.isLeave === 0 ? '在职' : '已离职' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
<el-button v-if="scope.row.isLeave === 0" size="mini" type="text" icon="el-icon-switch-button"
@click="handleResignation(scope.row)">离职</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 添加或修改员工信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- 公司内信息 -->
<el-card class="mb-4" shadow="never">
<template slot="header">
<div class="card-header">
<span>在职信息</span>
</div>
</template>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="部门" prop="dept">
<!-- <el-input v-model="form.dept" placeholder="请输入部门" /> -->
<el-select v-model="form.dept" placeholder="请选择部门">
<el-option v-for="item in deptList" :value="item.deptName" :label="item.deptName"
:key="item.deptId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="岗位工种" prop="jobType">
<el-input v-model="form.jobType" placeholder="请输入岗位工种" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入职时间" prop="entryTime">
<el-date-picker clearable v-model="form.entryTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择入职时间" style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.infoRemark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 员工个人信息 -->
<el-card class="mb-4" shadow="never">
<template slot="header">
<div class="card-header">
<span>员工信息</span>
</div>
</template>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入身份证号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年龄" prop="age">
<el-input v-model="form.age" placeholder="请输入年龄" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="gender">
<!-- <el-input v-model="form.gender" placeholder="请输入性别" /> -->
<el-radio-group v-model="form.gender" size="small" mode="button">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学历" prop="education">
<!-- <el-input v-model="form.education" placeholder="请输入学历" /> -->
<el-select v-model="form.education" placeholder="请选择学历">
<el-option v-for="item in dict.type.hrm_employee_education" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="家庭住址" prop="homeAddress">
<el-input v-model="form.homeAddress" placeholder="请输入家庭住址" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 紧急联系信息 -->
<el-card class="mb-4" shadow="never">
<template slot="header">
<div class="card-header">
<span>紧急联系信息</span>
</div>
</template>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="紧急联系人" prop="emergencyContact">
<el-input v-model="form.emergencyContact" placeholder="请输入紧急联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="关系" prop="relationship">
<el-input v-model="form.relationship" placeholder="请输入关系" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="紧急联系电话" prop="emergencyContactPhone">
<el-input v-model="form.emergencyContactPhone" placeholder="请输入紧急联系人电话" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 备注和附件 -->
<el-card class="mb-4" shadow="hover">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="!form.infoId">
<el-form-item label="附件" prop="attachment">
<file-upload v-model="attachment"></file-upload>
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 员工离职对话框 -->
<el-dialog :title="resignationTitle" :visible.sync="resignationOpen" width="500px" append-to-body>
<el-form ref="resignationForm" :model="resignationForm" :rules="resignationRules" label-width="80px">
<el-form-item label="员工姓名" prop="name">
<el-input v-model="resignationForm.name" disabled />
</el-form-item>
<el-form-item label="异动类型" prop="changeType">
<el-input v-model="resignationForm.changeType" disabled />
</el-form-item>
<el-form-item label="离职时间" prop="changeTime">
<el-date-picker clearable v-model="resignationForm.changeTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择离职时间" />
</el-form-item>
<el-form-item label="离职原因" prop="changeReason" required>
<el-input v-model="resignationForm.changeReason" type="textarea" placeholder="请输入离职原因" />
</el-form-item>
<el-form-item label="负责人" prop="changeHandler">
<el-input v-model="resignationForm.changeHandler" disabled />
</el-form-item>
<el-form-item label="附件" prop="attachment">
<file-upload v-model="resignationAttachment"></file-upload>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="resignationForm.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitResignation"> </el-button>
<el-button @click="cancelResignation"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listEmployeeInfo, getEmployeeInfo, delEmployeeInfo, updateEmployeeInfo } from "@/api/wms/employeeInfo";
import { listDept } from "@/api/wms/dept";
import { employeeEntry, employeeLeave } from '@/api/wms/employeeChange'
export default {
name: "EmployeeInfo",
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 员工信息表格数据
employeeInfoList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
dept: undefined,
jobType: undefined,
name: undefined,
idCard: undefined,
age: undefined,
gender: undefined,
education: undefined,
isRegular: undefined,
isLeave: undefined,
entryStartTime: undefined,
entryEndTime: undefined,
entryTimeRange: [],
},
// 表单参数
form: {},
// 表单校验
rules: {
},
// 附件
attachment: undefined,
// 部门列表
deptList: [],
// 离职对话框相关
resignationTitle: "员工离职",
resignationOpen: false,
resignationForm: {
infoId: undefined,
name: undefined,
changeType: "离职",
changeTime: undefined,
changeReason: undefined,
changeHandler: undefined,
remark: undefined
},
resignationRules: {
changeTime: [
{
required: true,
message: "请选择离职时间",
trigger: "change"
}
],
changeReason: [
{
required: true,
message: "请输入离职原因",
trigger: "blur"
}
]
},
resignationAttachment: undefined
};
},
dicts: ['hrm_employee_education'],
created() {
this.getList();
this.getDeptList();
},
methods: {
/** 查询员工信息列表 */
getList() {
this.loading = true;
listEmployeeInfo(this.queryParams).then(response => {
this.employeeInfoList = response.rows;
this.total = response.total;
this.loading = false;
});
},
getDeptList() {
listDept().then(response => {
this.deptList = response.data;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
infoId: undefined,
serialNumber: undefined,
dept: undefined,
jobType: undefined,
name: undefined,
idCard: undefined,
age: undefined,
gender: undefined,
education: undefined,
homeAddress: undefined,
phone: undefined,
entryTime: undefined,
emergencyContact: undefined,
relationship: undefined,
emergencyContactPhone: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
delFlag: undefined,
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
// 处理时间范围
if (this.queryParams.entryTimeRange && this.queryParams.entryTimeRange.length === 2) {
this.queryParams.entryStartTime = this.queryParams.entryTimeRange[0];
this.queryParams.entryEndTime = this.queryParams.entryTimeRange[1];
} else {
this.queryParams.entryStartTime = undefined;
this.queryParams.entryEndTime = undefined;
}
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams.entryTimeRange = [];
this.queryParams.entryStartTime = undefined;
this.queryParams.entryEndTime = undefined;
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.infoId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "员工入职";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const infoId = row.infoId || this.ids
getEmployeeInfo(infoId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改员工信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.infoId != null) {
updateEmployeeInfo(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
employeeEntry({
changeType: 0,
changeTime: this.form.entryTime,
changeHandler: this.$store.getters.nickName,
attachment: this.attachment,
...this.form
}).then(response => {
this.$modal.msgSuccess("员工入职成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const infoIds = row.infoId || this.ids;
this.$modal.confirm('是否确认删除员工信息编号为"' + infoIds + '"的数据项?').then(() => {
this.loading = true;
return delEmployeeInfo(infoIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/employeeInfo/export', {
...this.queryParams
}, `employeeInfo_${new Date().getTime()}.xlsx`)
},
/** 离职按钮操作 */
handleResignation(row) {
// 获取北京时间UTC+8
const now = new Date();
const formattedDate = this.parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}')
this.resignationForm = {
infoId: row.infoId,
name: row.name,
changeType: "离职",
changeTime: formattedDate,
changeReason: undefined,
changeHandler: this.$store.getters.nickName,
remark: undefined
};
this.resignationAttachment = undefined;
this.resignationOpen = true;
},
/** 取消离职按钮操作 */
cancelResignation() {
this.resignationOpen = false;
this.resignationForm = {
infoId: undefined,
name: undefined,
changeType: "1",
changeTime: undefined,
changeReason: undefined,
changeHandler: undefined,
remark: undefined
};
this.resignationAttachment = undefined;
this.resetForm("resignationForm");
},
/** 提交离职表单 */
submitResignation() {
this.$refs["resignationForm"].validate(valid => {
if (valid) {
this.$modal.confirm('是否确认提交员工离职申请?').then(() => {
this.buttonLoading = true;
employeeLeave({
changeType: 1,
changeTime: this.resignationForm.changeTime,
changeReason: this.resignationForm.changeReason,
changeHandler: this.resignationForm.changeHandler,
attachment: this.resignationAttachment,
remark: this.resignationForm.remark,
infoId: this.resignationForm.infoId
}).then(response => {
this.$modal.msgSuccess("员工离职成功");
this.resignationOpen = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
});
}
});
},
/** 计算入职天数和转正状态 */
getRegularStatus(entryTime, isRegular) {
if (!entryTime) return { days: 0, type: '', status: 0 };
const entryDate = new Date(entryTime);
const now = new Date();
const diffTime = now - entryDate;
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
let type = '';
let status = isRegular || 0;
if (status === 0) {
// 未转正
if (diffDays < 60) {
// 2个月内未转正
type = 'warning';
} else if (diffDays < 90) {
// 3个月内未转正
type = 'info';
} else if (diffDays >= 90) {
// 3个月以上未转正
type = 'danger';
}
} else {
// 已转正
type = 'success';
}
return { days: diffDays, type, status };
}
}
};
</script>