Commit bf1ac72a authored by 刘斌's avatar 刘斌

feat: 增加人事管理-预览

parent 3ed4afd8
import type { BaseModel, PageQuery } from '#/api/baseModel';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
export namespace EmployeeInfoApi {
export interface Employee extends BaseModel {
/**
* 板块
*/
plate?: string;
/**
* 项目
*/
project?: string;
/**
* 一级部门
*/
firstLevelDepartment?: string;
/**
* 二级部门
*/
secondLevelDepartment?: string;
/**
* 工号
*/
employeeId?: number;
/**
* 职级
*/
jobLevel?: string;
/**
* 岗位
*/
position?: string;
/**
* 职务
*/
post?: string;
/**
* 姓名
*/
name?: string;
/**
* 性别
*/
gender?: string;
/**
* 身份证号码
*/
idCardNumber?: number;
/**
* 出生日期
*/
birthDate?: string;
/**
* 年龄
*/
age?: number;
/**
* 年龄段
*/
ageGroup?: string;
/**
* 籍贯
*/
nativePlace?: string;
/**
* 民族
*/
ethnicity?: string;
/**
* 婚姻状况
*/
maritalStatus?: string;
/**
* 政治面貌
*/
politicalStatus?: string;
/**
* 手机号码
*/
phoneNumber?: string;
/**
* 紧急联系人
*/
emergencyContact?: string;
/**
* 紧急联系人电话
*/
emergencyContactPhone?: string;
/**
* 家庭地址
*/
homeAddress?: string;
/**
* 户口所在地
*/
householdRegistrationAddress?: string;
/**
* 参加工作时间
*/
workStartDate?: string;
/**
* 入职时间
*/
entryDate?: string;
/**
* 工龄
*/
yearsOfService?: number;
/**
* 工龄段
*/
yearsOfServiceSegment?: string;
/**
* 学历
*/
education?: string;
/**
* 学位
*/
degree?: string;
/**
* 毕业时间
*/
graduationDate?: string;
/**
* 专业
*/
major?: string;
/**
* 毕业院校
*/
graduateSchool?: string;
/**
* 员工类型
*/
employeeType?: string;
/**
* 职称情况
*/
professionalTitle?: string;
/**
* 简历
*/
resume?: string;
/**
* 用工形式
*/
employmentForm?: string;
/**
* 劳动合同期限
*/
contractTerm?: string;
/**
* 劳动合同开始时间
*/
contractStartDate?: string;
/**
* 劳动合同截止时间
*/
contractEndDate?: string;
/**
* 合同到期提醒
*/
contractExpirationReminder?: string;
/**
* 劳动合同签订情况
*/
contractSigningStatus?: string;
/**
* 合同主体
*/
contractEntity?: string;
/**
* 转正时间
*/
regularizationDate?: string;
/**
* 异动情况
*/
transferStatus?: string;
/**
* 奖惩情况
*/
rewardPunishmentStatus?: string;
/**
* 备注
*/
remarks?: string;
/**
* 离职时间
*/
resignationDate?: string;
/**
* 离职原因
*/
resignationReason?: string;
}
}
/**
* 查询员工信息列表
* @param params
* @returns {*} page
*/
export function apiPage(params: PageQuery) {
return requestClient.get('/employee/info/page', { params });
}
/**
* 查询员工信息详细
* @param id
*/
export function apiDetail(id: number) {
return requestClient.get(`/employee/info/${id}`);
}
/**
* 新增员工信息
* @param data
*/
export function apiAdd(data: EmployeeInfoApi.Employee) {
return requestClient.post('/employee/info', data);
}
/**
* 修改员工信息
* @param data
*/
export function apiUpdate(data: EmployeeInfoApi.Employee) {
return requestClient.put('/employee/info', data);
}
/**
* 删除员工信息
* @param id
*/
export function apiDelete(id: Array<number> | number) {
return requestClient.delete(`/employee/info/${id}`);
}
/**
* 导出员工信息
* @param params
*/
export function apiExport(id: number) {
return commonExport(`/employee/info/export/${id}`, {});
}
/**
* 下载用户导入模板
* @returns blob
*/
export function downloadImportTemplate() {
return commonExport('/employee/info/importTemplate', {});
}
/**
* 从excel导入用户
* @param file
* @returns void
*/
export function employeeImportData(file: Blob) {
return requestClient.post<{ errMessage: string; success: boolean }>(
'/employee/info/excel/import',
{ file },
{
headers: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
},
isTransformResponse: false,
responseReturn: 'body',
},
);
}
...@@ -79,7 +79,7 @@ function hasPermission(menuSet: Set<string>, route: RouteRecordRaw) { ...@@ -79,7 +79,7 @@ function hasPermission(menuSet: Set<string>, route: RouteRecordRaw) {
async function generateAccess(options: GenerateMenuAndRoutesOptions) { async function generateAccess(options: GenerateMenuAndRoutesOptions) {
const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
console.warn('[pageMap]', pageMap); // console.warn('[pageMap]', pageMap);
const layoutMap: ComponentRecordType = { const layoutMap: ComponentRecordType = {
BasicLayout, BasicLayout,
......
import type { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
// 人事管理
{
path: '/hr',
name: 'HrManagement',
meta: {
title: '人事管理',
keepAlive: true,
icon: 'streamline-ultimate:human-resources-hierarchy-1',
permission: ['dashboard'],
},
children: [
{
path: '/hr/employee/list',
name: 'EmployeeInfoList',
component: () => import('#/views/hr/employeeInfo/list.vue'),
meta: {
title: '员工信息列表',
icon: 'clarity:employee-line',
keepAlive: true,
permission: ['dashboard'],
componentPath: '#/views/hr/employeeInfo/list.vue',
},
},
],
},
];
export default routes;
export const HrDictEnum = {
HR_USER_SEX: 'hr_user_sex',
HR_AGE_GROUP: 'hr_age_group',
HR_MARITAL_STATUS: 'hr_marital_status', // 设备类型
HR_POLITICAL_STATUS: 'hr_political_status', // 授权类型
HR_YEARS_SERVICE_SEGMENT: 'hr_years_service_segment',
HR_EDUCATION: 'hr_education', // 通知状态
HR_EMPLOYEE_TYPE: 'hr_employee_type', // 通知类型
HR_EMPLOYMENT_FORM: 'hr_employment_form', // 操作类型
// SYS_JOB_TYPE: 'sys_job_type', // 定时任务类型
// SYS_JOB_STATUS: 'sys_job_status', // 定时任务状态
// SYS_OSS_ACCESS_POLICY: 'oss_access_policy', // oss权限桶类型
// SYS_SHOW_HIDE: 'sys_show_hide', // 显示状态
// SYS_USER_SEX: 'sys_user_sex', // 性别
// SYS_YES_NO: 'sys_yes_no', // 是否
// WF_BUSINESS_STATUS: 'wf_business_status', // 业务状态
// WF_FORM_TYPE: 'wf_form_type', // 表单类型
// WF_TASK_STATUS: 'wf_task_status', // 任务状态
} as const;
export type HrDictEnumKey = keyof typeof HrDictEnum;
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { EmployeeInfoApi } from '#/api/hr/employeeInfo';
import { getDictOptions } from '#/utils/dict';
import { HrDictEnum } from '../dict-enum';
export const querySchema: VbenFormSchema[] = [
{
component: 'Input',
fieldName: 'plate',
label: '板块',
},
{
component: 'Input',
fieldName: 'project',
label: '项目',
},
{
component: 'Input',
fieldName: 'firstLevelDepartment',
label: '一级部门',
},
{
component: 'Input',
fieldName: 'secondLevelDepartment',
label: '二级部门',
},
{
component: 'Input',
fieldName: 'employeeId',
label: '工号',
},
{
component: 'Input',
fieldName: 'jobLevel',
label: '职级',
},
{
component: 'Input',
fieldName: 'position',
label: '岗位',
},
{
component: 'Input',
fieldName: 'post',
label: '职务',
},
{
component: 'Input',
fieldName: 'name',
label: '姓名',
},
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_USER_SEX),
},
fieldName: 'gender',
label: '性别',
},
// {
// component: 'Input',
// fieldName: 'idCardNumber',
// label: '身份证号码',
// },
// {
// component: 'DatePicker',
// fieldName: 'birthDate',
// label: '出生日期',
// },
// {
// component: 'Input',
// fieldName: 'age',
// label: '年龄',
// },
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_AGE_GROUP),
},
fieldName: 'ageGroup',
label: '年龄段',
},
// {
// component: 'Input',
// fieldName: 'nativePlace',
// label: '籍贯',
// },
// {
// component: 'Input',
// fieldName: 'ethnicity',
// label: '民族',
// },
{
component: 'Input',
fieldName: 'phoneNumber',
label: '手机号码',
},
// {
// component: 'Input',
// fieldName: 'emergencyContact',
// label: '紧急联系人',
// },
// {
// component: 'Input',
// fieldName: 'emergencyContactPhone',
// label: '紧急联系人电话',
// },
// {
// component: 'Input',
// fieldName: 'homeAddress',
// label: '家庭地址',
// },
// {
// component: 'Input',
// fieldName: 'householdRegistrationAddress',
// label: '户口所在地',
// },
// {
// component: 'DatePicker',
// fieldName: 'workStartDate',
// label: '参加工作',
// },
{
component: 'RangePicker',
fieldName: 'entryDate',
label: '入职时间',
componentProps: {
valueFormat: 'YYYY-MM-DD',
},
},
// {
// component: 'Input',
// fieldName: 'yearsOfService',
// label: '工龄',
// },
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_YEARS_SERVICE_SEGMENT),
},
fieldName: 'yearsOfServiceSegment',
label: '工龄段',
},
// {
// component: 'Input',
// fieldName: 'education',
// label: '学历',
// },
// {
// component: 'Input',
// fieldName: 'degree',
// label: '学位',
// },
// {
// component: 'DatePicker',
// fieldName: 'graduationDate',
// label: '毕业时间',
// },
// {
// component: 'Input',
// fieldName: 'major',
// label: '专业',
// },
// {
// component: 'Input',
// fieldName: 'graduateSchool',
// label: '毕业院校',
// },
// {
// component: 'Input',
// fieldName: 'professionalTitle',
// label: '职称情况',
// },
// {
// component: 'Input',
// fieldName: 'resume',
// label: '简历',
// },
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_EMPLOYMENT_FORM),
},
fieldName: 'employmentForm',
label: '用工形式',
},
// {
// component: 'Input',
// fieldName: 'contractTerm',
// label: '劳动合同期限',
// },
// {
// component: 'DatePicker',
// fieldName: 'contractStartDate',
// label: '劳动合同开始时间',
// },
// {
// component: 'DatePicker',
// fieldName: 'contractEndDate',
// label: '劳动合同截止时间',
// },
// {
// component: 'DatePicker',
// fieldName: 'contractExpirationReminder',
// label: '合同到期提醒',
// },
// {
// component: 'Input',
// fieldName: 'contractEntity',
// label: '合同主体',
// },
// {
// component: 'DatePicker',
// fieldName: 'regularizationDate',
// label: '转正时间',
// },
// {
// component: 'Input',
// fieldName: 'remarks',
// label: '备注',
// },
// {
// component: 'DatePicker',
// fieldName: 'resignationDate',
// label: '离职时间',
// },
// {
// component: 'Input',
// fieldName: 'resignationReason',
// label: '离职原因',
// },
];
export function useColumns(): VxeTableGridOptions<EmployeeInfoApi.Employee>['columns'] {
// onActionClick: OnActionClickFn<EmployeeInfoApi.Employee>,
return [
{
title: '板块',
field: 'plate',
},
{
title: '项目',
field: 'project',
},
{
title: '一级部门',
field: 'firstLevelDepartment',
},
{
title: '二级部门',
field: 'secondLevelDepartment',
},
{
title: '工号',
field: 'employeeId',
},
// {
// title: '职级',
// field: 'jobLevel',
// },
{
title: '岗位',
field: 'position',
},
{
title: '职务',
field: 'post',
},
{
title: '姓名',
field: 'name',
},
{
title: '性别',
field: 'genderName',
// cellRender: {
// name: 'CellTag',
// options: [getTagDicts(HrDictEnum.HR_USER_SEX)],
// },
},
// {
// title: '身份证号码',
// field: 'idCardNumber',
// },
// {
// title: '出生日期',
// field: 'birthDate',
// formatter: 'formatDateTime',
// },
// {
// title: '年龄',
// field: 'age',
// },
// {
// title: '年龄段',
// field: 'ageGroup',
// },
// {
// title: '籍贯',
// field: 'nativePlace',
// },
// {
// title: '民族',
// field: 'ethnicity',
// },
// {
// title: '婚姻状况',
// field: 'maritalStatus',
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
// },
// {
// title: '政治面貌',
// field: 'politicalStatus',
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
// },
{
title: '手机号码',
field: 'phoneNumber',
},
// {
// title: '紧急联系人',
// field: 'emergencyContact',
// },
// {
// title: '紧急联系人电话',
// field: 'emergencyContactPhone',
// },
// {
// title: '家庭地址',
// field: 'homeAddress',
// },
// {
// title: '户口所在地',
// field: 'householdRegistrationAddress',
// },
// {
// title: '参加工作时间',
// field: 'workStartDate',
// formatter: 'formatDateTime',
// },
// {
// title: '入职时间',
// field: 'entryDate',
// formatter: 'formatDateTime',
// },
// {
// title: '工龄',
// field: 'yearsOfService',
// },
// {
// title: '工龄段',
// field: 'yearsOfServiceSegment',
// },
{
title: '学历',
field: 'education',
},
// {
// title: '学位',
// field: 'degree',
// },
// {
// title: '毕业时间',
// field: 'graduationDate',
// formatter: 'formatDateTime',
// },
// {
// title: '专业',
// field: 'major',
// },
// {
// title: '毕业院校',
// field: 'graduateSchool',
// },
{
title: '员工类型',
field: 'employeeTypeName',
// cellRender: {
// name: 'CellTag',
// options: [getTagDicts(HrDictEnum.HR_EMPLOYEE_TYPE)],
// },
},
// {
// title: '职称情况',
// field: 'professionalTitle',
// },
// {
// title: '简历',
// field: 'resume',
// },
{
title: '用工形式',
field: 'employmentFormName',
// cellRender: {
// name: 'CellTag',
// options: [getTagDicts(HrDictEnum.HR_EMPLOYMENT_FORM)],
// },
},
{
title: '劳动合同期限',
field: 'contractTerm',
},
// {
// title: '劳动合同开始时间',
// field: 'contractStartDate',
// formatter: 'formatDateTime',
// },
// {
// title: '劳动合同截止时间',
// field: 'contractEndDate',
// formatter: 'formatDateTime',
// },
// {
// title: '合同到期提醒',
// field: 'contractExpirationReminder',
// formatter: 'formatDateTime',
// },
// {
// title: '劳动合同签订情况',
// field: 'contractSigningStatus',
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
// },
// {
// title: '合同主体',
// field: 'contractEntity',
// },
// {
// title: '转正时间',
// field: 'regularizationDate',
// formatter: 'formatDateTime',
// },
// {
// title: '异动情况',
// field: 'transferStatus',
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
// },
// {
// title: '奖惩情况',
// field: 'rewardPunishmentStatus',
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
// },
// {
// title: '备注',
// field: 'remarks',
// },
// {
// title: '离职时间',
// field: 'resignationDate',
// formatter: 'formatDateTime',
// },
// {
// title: '离职原因',
// field: 'resignationReason',
// },
{
align: 'right',
slots: { default: 'action' },
// cellRender: {
// attrs: {
// nameField: 'name',
// nameTitle: '员工信息',
// onClick: onActionClick,
// },
// name: 'CellOperation',
// options: [
// {
// code: 'export',
// text: '导出简历',
// // disabled: (row: SysUserApi.User) => {
// // return !!(row.id === 1);
// // },
// accessCode: ['employee:info:export'],
// },
// {
// code: 'edit',
// accessCode: ['employee:info:edit'],
// }, // 默认的编辑按钮
// {
// code: 'delete',
// text: '离职',
// accessCode: ['employee:info:remove'],
// }, // 默认的删除按钮
// ],
// },
field: 'action',
fixed: 'right',
headerAlign: 'center',
resizable: false,
showOverflow: false,
title: '操作',
width: 'auto',
},
];
}
<script setup lang="ts">
import type { UploadFile } from 'ant-design-vue/es/upload/interface';
import { h, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { ExcelIcon, InBoxIcon } from '@vben/icons';
import { Button, Modal, Upload } from 'ant-design-vue';
import {
downloadImportTemplate,
employeeImportData,
} from '#/api/hr/employeeInfo';
import { commonDownloadExcel } from '#/utils/file/download';
const emit = defineEmits<{ reload: [] }>();
const UploadDragger = Upload.Dragger;
const [BasicModal, modalApi] = useVbenModal({
onCancel: handleCancel,
onConfirm: handleSubmit,
});
const fileList = ref<UploadFile[]>([]);
// const checked = ref(false);
async function handleSubmit() {
try {
modalApi.modalLoading(true);
if (fileList.value.length !== 1) {
handleCancel();
return;
}
// const data = {
// file: fileList.value[0]!.originFileObj as Blob,
// updateSupport: unref(checked),
// };
const { success, errMessage } = await employeeImportData(
fileList.value[0]!.originFileObj as Blob,
);
let modal = Modal.success;
if (success) {
emit('reload');
} else {
modal = Modal.error;
}
handleCancel();
modal({
content: h('div', {
class: 'max-h-[260px] overflow-y-auto',
innerHTML: errMessage, // 后台已经处理xss问题
}),
title: '提示',
});
} catch (error) {
console.warn(error);
modalApi.close();
} finally {
modalApi.modalLoading(false);
}
}
function handleCancel() {
modalApi.close();
fileList.value = [];
// checked.value = false;
}
</script>
<template>
<BasicModal
:close-on-click-modal="false"
:fullscreen-button="false"
title="员工信息导入"
>
<!-- z-index不设置会遮挡模板下载loading -->
<!-- 手动处理 而不是放入文件就上传 -->
<UploadDragger
v-model:file-list="fileList"
:before-upload="() => false"
:max-count="1"
:show-upload-list="true"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
>
<p class="ant-upload-drag-icon flex items-center justify-center">
<InBoxIcon class="text-primary size-[48px]" />
</p>
<p class="ant-upload-text">点击或者拖拽到此处上传文件</p>
</UploadDragger>
<div class="mt-2 flex flex-col gap-2">
<div class="flex items-center gap-2">
<span>允许导入xlsx, xls文件</span>
<Button
type="link"
@click="
commonDownloadExcel(downloadImportTemplate, '员工信息导入模板')
"
>
<div class="flex items-center gap-[4px]">
<ExcelIcon />
<span>下载模板</span>
</div>
</Button>
</div>
<!-- <div class="flex items-center gap-2">
<span :class="{ 'text-red-500': checked }">
是否更新/覆盖已存在的用户数据
</span>
<Switch v-model:checked="checked" />
</div> -->
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { EmployeeInfoApi } from '#/api/hr/employeeInfo';
import { computed, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { Skeleton } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { apiAdd, apiUpdate } from '#/api/hr/employeeInfo';
import { getDictOptions } from '#/utils/dict';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { HrDictEnum } from '../dict-enum';
const emit = defineEmits<{
success: [];
}>();
const formData = ref<EmployeeInfoApi.Employee>();
const loading = ref(false);
const formSchema: VbenFormSchema[] = [
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '部门信息',
}),
},
{
component: 'Input',
fieldName: 'plate',
label: '板块',
rules: 'required',
},
{
component: 'Input',
fieldName: 'project',
label: '项目',
rules: 'required',
},
{
component: 'Input',
fieldName: 'firstLevelDepartment',
label: '一级部门',
rules: 'required',
},
{
component: 'Input',
fieldName: 'secondLevelDepartment',
label: '二级部门',
rules: 'required',
},
{
component: 'Input',
fieldName: 'employeeId',
label: '工号',
rules: 'required',
},
{
component: 'Input',
fieldName: 'jobLevel',
label: '职级',
rules: 'required',
},
{
component: 'Input',
fieldName: 'position',
label: '岗位',
rules: 'required',
},
{
component: 'Input',
fieldName: 'post',
label: '职务',
rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '员工信息',
}),
},
{
component: 'Input',
fieldName: 'name',
label: '姓名',
rules: 'required',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(HrDictEnum.HR_USER_SEX),
},
defaultValue: '1',
fieldName: 'gender',
label: '性别',
rules: 'required',
},
{
component: 'Input',
fieldName: 'idCardNumber',
label: '身份证号码',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'birthDate',
label: '出生日期',
rules: 'required',
},
{
component: 'Input',
fieldName: 'age',
label: '年龄',
rules: 'required',
},
// {
// component: 'Input',
// fieldName: 'ageGroup',
// label: '年龄段',
// rules: 'required',
// },
{
component: 'Input',
fieldName: 'nativePlace',
label: '籍贯',
rules: 'required',
},
{
component: 'Input',
fieldName: 'ethnicity',
label: '民族',
rules: 'required',
},
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_MARITAL_STATUS),
},
fieldName: 'maritalStatus',
label: '婚姻状况',
rules: 'selectRequired',
},
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_POLITICAL_STATUS),
},
fieldName: 'politicalStatus',
label: '政治面貌',
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'phoneNumber',
label: '手机号码',
rules: 'required',
},
{
component: 'Input',
fieldName: 'emergencyContact',
label: '紧急联系人',
rules: 'required',
},
{
component: 'Input',
fieldName: 'emergencyContactPhone',
label: '紧急联系人电话',
rules: 'required',
},
{
component: 'Input',
fieldName: 'homeAddress',
label: '家庭地址',
rules: 'required',
},
{
component: 'Input',
fieldName: 'householdRegistrationAddress',
label: '户口所在地',
rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '教育信息',
}),
},
{
component: 'Input',
fieldName: 'education',
label: '学历',
rules: 'required',
},
{
component: 'Input',
fieldName: 'degree',
label: '学位',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'graduationDate',
label: '毕业时间',
rules: 'required',
},
{
component: 'Input',
fieldName: 'major',
label: '专业',
rules: 'required',
},
{
component: 'Input',
fieldName: 'graduateSchool',
label: '毕业院校',
rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '职业信息',
}),
},
{
component: 'DatePicker',
fieldName: 'workStartDate',
label: '参加工作时间',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'entryDate',
label: '入职时间',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'regularizationDate',
label: '转正时间',
rules: 'required',
},
{
component: 'Input',
fieldName: 'yearsOfService',
label: '工龄',
rules: 'required',
},
// {
// component: 'Input',
// fieldName: 'yearsOfServiceSegment',
// label: '工龄段',
// rules: 'required',
// },
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_EMPLOYEE_TYPE),
},
fieldName: 'employeeType',
label: '员工类型',
rules: 'selectRequired',
},
{
component: 'Select',
componentProps: {
options: getDictOptions(HrDictEnum.HR_EMPLOYMENT_FORM),
},
fieldName: 'employmentForm',
label: '用工形式',
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'professionalTitle',
label: '职称情况',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'resume',
label: '简历',
// rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '合同信息',
}),
},
{
component: 'Input',
fieldName: 'contractTerm',
label: '劳动合同期限',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'contractStartDate',
label: '劳动合同开始时间',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'contractEndDate',
label: '劳动合同截止时间',
rules: 'required',
},
{
component: 'DatePicker',
fieldName: 'contractExpirationReminder',
label: '合同到期提醒',
rules: 'required',
},
{
component: 'Input',
fieldName: 'contractEntity',
label: '合同主体',
rules: 'required',
},
{
component: 'Input',
// componentProps: {
// buttonStyle: 'solid',
// optionType: 'button',
// },
fieldName: 'contractSigningStatus',
label: '劳动合同签订情况',
formItemClass: 'col-span-2',
// rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '其他信息',
}),
},
{
component: 'Input',
// componentProps: {
// buttonStyle: 'solid',
// optionType: 'button',
// },
fieldName: 'transferStatus',
formItemClass: 'col-span-2',
label: '异动情况',
rules: 'required',
},
{
component: 'Input',
// componentProps: {
// buttonStyle: 'solid',
// optionType: 'button',
// },
fieldName: 'rewardPunishmentStatus',
formItemClass: 'col-span-2',
label: '奖惩情况',
rules: 'required',
},
{
component: 'Textarea',
fieldName: 'remarks',
formItemClass: 'col-span-2',
label: '备注',
// rules: 'required',
},
// {
// component: 'DatePicker',
// fieldName: 'resignationDate',
// label: '离职时间',
// rules: 'required',
// },
// {
// component: 'Textarea',
// fieldName: 'resignationReason',
// label: '离职原因',
// rules: 'required',
// },
];
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
formItemClass: 'col-span-1',
},
// formItemClass: 'col-span-2',
labelWidth: 130,
},
schema: formSchema,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
{
initializedGetter: defaultFormValueGetter(formApi),
currentGetter: defaultFormValueGetter(formApi),
},
);
const [Drawer, drawerApi] = useVbenDrawer({
onBeforeClose,
onClosed: handleClosed,
onConfirm: onSubmit,
async onOpenChange(isOpen) {
if (!isOpen) {
return null;
}
const data = drawerApi.getData<EmployeeInfoApi.Employee>();
if (data) {
formData.value = data;
await formApi.setValues(formData.value);
} else {
formApi.resetForm();
}
await markInitialized();
},
});
async function onSubmit() {
const { valid } = await formApi.validate();
if (valid) {
drawerApi.lock();
const data = await formApi.getValues<EmployeeInfoApi.Employee>();
try {
await (formData.value?.id
? apiUpdate({ id: formData.value.id, ...data })
: apiAdd(data));
resetInitialized();
emit('success');
drawerApi.close();
} finally {
drawerApi.unlock();
}
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
}
const getDrawerTitle = computed(() =>
formData.value?.id ? '修改员工信息' : '新增员工信息',
);
</script>
<template>
<Drawer class="w-full max-w-[900px]" :title="getDrawerTitle">
<Skeleton v-if="loading" active />
<BasicForm v-show="!loading" class="mx-4" />
</Drawer>
</template>
<script lang="ts" setup>
import type { VbenFormProps } from '@vben/common-ui';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { EmployeeInfoApi } from '#/api/hr/employeeInfo';
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons';
import { getVxePopupContainer } from '@vben/utils';
import { Button, message, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { apiDelete, apiExport, apiPage } from '#/api/hr/employeeInfo';
import { GhostButton } from '#/components/global/button';
import { commonDownloadExcel } from '#/utils/file/download';
import { querySchema, useColumns } from './data';
import employeeImportModal from './employee-import-modal.vue';
import Form from './form.vue';
/**
* 导入
*/
const [EmployeeImportModal, employeeImportModalApi] = useVbenModal({
connectedComponent: employeeImportModal,
});
function handleImport() {
employeeImportModalApi.open();
}
const formOptions: VbenFormProps = {
commonConfig: {
labelWidth: 80,
componentProps: {
allowClear: true,
},
},
schema: querySchema,
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
// 日期选择格式化
fieldMappingTime: [
[
'entryDate',
['params[entryBeginTime]', 'params[entryEndTime]'],
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
],
],
};
const [FormDrawer, formDrawerApi] = useVbenDrawer({
connectedComponent: Form,
});
const [Grid, gridApi] = useVbenVxeGrid({
formOptions,
gridOptions: {
columns: useColumns(),
height: 'auto',
keepSource: true,
pagerConfig: {
enabled: true,
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues = {}) => {
return await apiPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
rowConfig: {
keyField: 'id',
// 高亮当前行
isCurrent: true,
},
} as VxeTableGridOptions,
});
// function onActionClick({
// code,
// row,
// }: OnActionClickParams<EmployeeInfoApi.Employee>) {
// switch (code) {
// case 'delete': {
// onResign(row);
// break;
// }
// case 'edit': {
// onEdit(row);
// break;
// }
// case 'export': {
// handleDownloadExcel(row);
// break;
// }
// default: {
// break;
// }
// }
// }
function onRefresh() {
gridApi.query();
}
function onEdit(row: EmployeeInfoApi.Employee) {
formDrawerApi.setData(row).open();
}
function onCreate() {
formDrawerApi.setData({}).open();
}
function onResign(row: EmployeeInfoApi.Employee) {
const hideLoading = message.loading({
content: `正在处理${row.name}的离职...`,
duration: 0,
key: 'action_process_msg',
});
apiDelete(row.id || 0)
.then(() => {
message.success({
content: `${row.name}离职申请成功`,
key: 'action_process_msg',
});
onRefresh();
})
.catch(() => {
hideLoading();
});
}
function handleDownloadExcel(row: EmployeeInfoApi.Employee) {
commonDownloadExcel(apiExport, '员工信息', row.id);
}
</script>
<template>
<Page auto-content-height>
<FormDrawer @success="onRefresh" />
<Grid table-title="员工信息列表">
<template #toolbar-tools>
<Space>
<Button
v-access:code="['employee:info:import']"
@click="handleImport"
>
导入
</Button>
<!-- <Button
v-access:code="['employee:info:export']"
@click="handleDownloadExcel"
>
导出
</Button> -->
<Button
v-access:code="['employee:info:add']"
type="primary"
@click="onCreate"
>
<Plus class="size-5" />
入职
</Button>
</Space>
</template>
<template #action="{ row }">
<!-- 租户管理员不可修改admin角色 防止误操作 -->
<!-- 超级管理员可通过租户切换来操作租户管理员角色 -->
<!-- -->
<!-- <template
v-if="!row.superAdmin && (row.roleKey !== 'admin' || isSuperAdmin)"
> -->
<Space>
<GhostButton
v-access:code="['employee:info:export']"
@click.stop="handleDownloadExcel(row)"
>
导出简历
</GhostButton>
<GhostButton
v-access:code="['employee:info:edit']"
@click.stop="onEdit(row)"
>
编辑
</GhostButton>
<!-- <GhostButton
v-access:code="['auth:role:edit']"
@click.stop="onAssignRole(row)"
>
分配
</GhostButton> -->
<Popconfirm
:get-popup-container="getVxePopupContainer"
placement="left"
:title="`确认离职【${row.name}】?`"
@confirm="onResign(row)"
>
<GhostButton
danger
v-access:code="['employee:info:resign']"
@click.stop=""
>
离职
</GhostButton>
</Popconfirm>
</Space>
<!-- </template> -->
</template>
</Grid>
<EmployeeImportModal @reload="onRefresh" />
</Page>
</template>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment