Commit f6f15916 authored by 刘斌's avatar 刘斌

fix: 增加兼职模块

parent 2d2dc236
......@@ -425,19 +425,47 @@ export namespace EmployeeInfoApi {
* 离职申请状态
*/
resignationApplyStatus?: number;
resignationApplyStatusName?: number;
resignationApplyStatusName?: string;
/**
* 入职审批状态
*/
entryApplyStatus?: number;
entryApplyStatusName?: number;
entryApplyStatusName?: string;
/**
* 调配申请状态
*/
transferApplyStatus?: number;
transferApplyStatusName?: number;
transferApplyStatusName?: string;
/**
* 状态
*/
status?: number;
statusName?: string;
/**
* 签订兼职协议
*/
partTimeAgreement?: string;
partTimeAgreementName?: string;
/**
* 协议主体
*/
agreementEntity?: string;
/**
* 协议期限
*/
agreementPeriod?: string;
/**
* 协议开始时间
*/
agreementStartDate?: string;
/**
* 协议截止时间
*/
agreementEndDate?: string;
}
export interface EmployeeApplyBaseBo {
......
import type { BaseModel, PageQuery } from '#/api/baseModel';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
export namespace PartTimeInfoApi {
export interface PartTimeInfo extends BaseModel {
/**
* 板块
*/
plate?: string;
/**
* 一级部门
*/
firstLevelDepartment?: string;
/**
* 二级部门
*/
secondLevelDepartment?: string;
/**
* 三级部门
*/
thirdLevelDepartment?: string;
/**
* 部门ID
*/
deptId?: number;
/**
* 岗位类型
*/
positionType?: string;
/**
* 主岗位
*/
position?: string;
/**
* 姓名
*/
name?: string;
/**
* 性别
*/
gender?: string;
/**
* 身份证号码
*/
idCardNumber?: number;
/**
* 照片ID
*/
ossId?: number;
/**
* 出生日期
*/
birthDate?: string;
/**
* 年龄
*/
age?: number;
/**
* 籍贯
*/
nativePlace?: string;
/**
* 民族
*/
ethnicity?: string;
/**
* 婚姻状况
*/
maritalStatus?: string;
/**
* 政治面貌
*/
politicalStatus?: string;
/**
* 手机号码
*/
phoneNumber?: string;
/**
* 紧急联系人
*/
emergencyContact?: string;
/**
* 紧急联系人电话
*/
emergencyContactPhone?: string;
/**
* 家庭地址
*/
homeAddress?: string;
/**
* 入职时间
*/
entryDate?: string;
/**
* 全日制学历
*/
fulltimeEducation?: string;
/**
* 全日制毕业院校
*/
fulltimeSchool?: string;
/**
* 全日制专业
*/
fulltimeMajor?: string;
/**
* 全日制毕业日期
*/
fulltimeGraduationDate?: string;
/**
* 全日制学位
*/
fulltimeDegree?: string;
/**
* 用工形式
*/
employmentForm?: string;
/**
* 是否兼职
*/
partTimeFlag?: string;
/**
* 签订兼职协议
*/
partTimeAgreement?: string;
/**
* 协议主体
*/
agreementEntity?: string;
/**
* 协议期限
*/
agreementPeriod?: string;
/**
* 协议开始时间
*/
agreementStartDate?: string;
/**
* 协议截止时间
*/
agreementEndDate?: string;
/**
* 备注
*/
remarks?: string;
/**
* 银行卡号
*/
bankCardNumber?: string;
/**
* 开户行
*/
bankName?: string;
/**
* 公司内是否有亲属关系
*/
hasRelativeInCompany?: string;
/**
* 亲属姓名
*/
relativeName?: string;
/**
* 介绍人
*/
introducer?: string;
/**
* 介绍人关系
*/
introducerRelation?: string;
/**
* 工资发放地
*/
salaryLocation?: string;
/**
* 成本费用所属
*/
costOfDept?: string;
/**
* 状态
*/
status?: number;
statusName?: string;
}
}
/**
* 查询兼职员工信息列表
* @param params
* @returns {*} page
*/
export function apiPage(params: PageQuery) {
return requestClient.get('/employee/partTimeInfo/page', { params });
}
/**
* 查询兼职员工信息详细
* @param id
*/
export function apiDetail(id: number) {
return requestClient.get(`/employee/partTimeInfo/${id}`);
}
/**
* 展示员工信息详细
* @param id
*/
export function apiInfoDetail(id: number) {
return requestClient.get(`/employee/partTimeInfo/detail/${id}`);
}
/**
* 新增兼职员工信息
* @param data
*/
export function apiAdd(data: PartTimeInfoApi.PartTimeInfo) {
return requestClient.post('/employee/partTimeInfo', data);
}
/**
* 修改兼职员工信息
* @param data
*/
export function apiUpdate(data: PartTimeInfoApi.PartTimeInfo) {
return requestClient.put('/employee/partTimeInfo', data);
}
/**
* 删除兼职员工信息
* @param id
*/
export function apiDelete(id: Array<number> | number) {
return requestClient.delete(`/employee/partTimeInfo/${id}`);
}
/**
* 导出兼职员工信息
* @param params
*/
export function apiExport(params: PageQuery) {
return commonExport('/employee/partTimeInfo/export', params);
}
/**
* 下载用户导入模板
* @returns blob
*/
export function downloadImportTemplate() {
return commonExport('/employee/partTimeInfo/importTemplate', {});
}
/**
* 从excel导入用户
* @param file
* @returns void
*/
export function employeePartTimeImportData(file: Blob) {
return requestClient.post<{ errMessage: string; success: boolean }>(
'/employee/partTimeInfo/import',
{ file },
{
headers: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
},
isTransformResponse: false,
responseReturn: 'body',
timeout: 300_000,
},
);
}
......@@ -36,6 +36,18 @@ const routes: RouteRecordRaw[] = [
componentPath: '#/views/hr/resignEmployee/list.vue',
},
},
{
path: '/hr/partTimeInfo/list',
name: 'EmployeePartTimeInfoList',
component: () => import('#/views/hr/partTimeInfo/list.vue'),
meta: {
title: '兼职员工列表',
icon: 'fluent:people-star-48-regular',
keepAlive: true,
permission: ['dashboard'],
componentPath: '#/views/hr/partTimeInfo/list.vue',
},
},
{
path: '/hr/phoneBook/list',
name: 'PhoneBookList',
......@@ -91,7 +103,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/hr/training/list.vue'),
meta: {
title: '员工培训档案',
icon: 'streamline-plump:contact-phonebook',
icon: 'si:archive-line',
keepAlive: true,
permission: ['dashboard'],
componentPath: '#/views/hr/training/list.vue',
......@@ -103,7 +115,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/hr/interviewProfile/list.vue'),
meta: {
title: '面试档案',
icon: 'streamline-plump:contact-phonebook',
icon: 'solar:archive-check-linear',
keepAlive: true,
permission: ['dashboard'],
componentPath: '#/views/hr/interviewProfile/list.vue',
......@@ -115,7 +127,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/hr/laborCost/list.vue'),
meta: {
title: '人工成本档案',
icon: 'streamline-plump:contact-phonebook',
icon: 'solar:archive-up-linear',
keepAlive: true,
permission: ['dashboard'],
componentPath: '#/views/hr/laborCost/list.vue',
......
......@@ -14,7 +14,8 @@ import {
} from 'ant-design-vue';
import { apiInfoDetail } from '#/api/hr/employeeInfo';
import { apiInfoDetail as resignInfoDetail } from '#/api/hr/resignEmployee';
// import { apiInfoDetail as partTimeInfoDetail } from '#/api/hr/partTimeInfo';
// import { apiInfoDetail as resignInfoDetail } from '#/api/hr/resignEmployee';
const [BasicDrawer, drawerApi] = useVbenDrawer({
onOpenChange: handleOpenChange,
......@@ -26,24 +27,32 @@ const [BasicDrawer, drawerApi] = useVbenDrawer({
const currentEmployee = shallowRef<EmployeeInfoApi.Employee | null>(null);
const loading = ref(false);
const isResign = ref(false);
const isPartTime = ref(false);
async function handleOpenChange(open: boolean) {
if (!open) {
return null;
}
const { id, resignFlag } = drawerApi.getData() as {
const { id } = drawerApi.getData() as {
id?: number;
resignFlag?: boolean;
};
if (!id) {
return null;
}
isResign.value = !!resignFlag;
const data = await (isResign.value
? resignInfoDetail(id)
: apiInfoDetail(id));
// const data = await apiInfoDetail(id);
// let data;
// if (isResign.value) {
// data = await resignInfoDetail(id);
// } else if (isPartTime.value) {
// data = await partTimeInfoDetail(id);
// } else {
// const data = await apiInfoDetail(id);
// }
const data = await apiInfoDetail(id);
currentEmployee.value = data;
if (data) {
isResign.value = data.status === 8;
isPartTime.value = data.partTimeFlag === 'Y';
}
}
// const actionInfo = computed(() => {
......@@ -78,47 +87,47 @@ async function handleOpenChange(open: boolean) {
<DescriptionsItem label="板块">
{{ currentEmployee.plate }}
</DescriptionsItem>
<DescriptionsItem label="兼岗板块">
{{ currentEmployee.concurrentPlate }}
</DescriptionsItem>
<DescriptionsItem label="一级部门">
{{ currentEmployee.firstLevelDepartment }}
</DescriptionsItem>
<DescriptionsItem label="兼岗一级部门">
{{ currentEmployee.concurrentFirstDept }}
</DescriptionsItem>
<DescriptionsItem label="二级部门">
{{ currentEmployee.secondLevelDepartment }}
</DescriptionsItem>
<DescriptionsItem label="兼岗二级部门">
{{ currentEmployee.concurrentSecondDept }}
</DescriptionsItem>
<DescriptionsItem label="三级部门">
{{ currentEmployee.thirdLevelDepartment }}
</DescriptionsItem>
<DescriptionsItem label="工号">
{{ currentEmployee.employeeNo }}
</DescriptionsItem>
<DescriptionsItem label="职级">
{{ currentEmployee.jobLevel }}
<DescriptionsItem label="兼岗三级部门">
{{ currentEmployee.concurrentThirdDept }}
</DescriptionsItem>
<DescriptionsItem label="主岗位">
{{ currentEmployee.position }}
</DescriptionsItem>
<DescriptionsItem label="兼岗岗位">
{{ currentEmployee.concurrentPosition }}
</DescriptionsItem>
<DescriptionsItem label="岗位类型">
{{ currentEmployee.positionTypeName }}
</DescriptionsItem>
<DescriptionsItem label="序列">
{{ currentEmployee.sequenceName }}
</DescriptionsItem>
<DescriptionsItem label="兼岗板块">
{{ currentEmployee.concurrentPlate }}
</DescriptionsItem>
<DescriptionsItem label="兼岗一级部门">
{{ currentEmployee.concurrentFirstDept }}
</DescriptionsItem>
<DescriptionsItem label="兼岗二级部门">
{{ currentEmployee.concurrentSecondDept }}
<DescriptionsItem label="兼岗岗位类型">
{{ currentEmployee.concurrentPositionTypeName }}
</DescriptionsItem>
<DescriptionsItem label="兼岗三级部门">
{{ currentEmployee.concurrentThirdDept }}
<DescriptionsItem label="工号">
{{ currentEmployee.employeeNo }}
</DescriptionsItem>
<DescriptionsItem label="兼岗岗位">
{{ currentEmployee.concurrentPosition }}
<DescriptionsItem label="职级">
{{ currentEmployee.jobLevel }}
</DescriptionsItem>
<DescriptionsItem label="兼岗岗位类型">
{{ currentEmployee.concurrentPositionTypeName }}
<DescriptionsItem label="序列">
{{ currentEmployee.sequenceName }}
</DescriptionsItem>
</Descriptions>
<Descriptions
......@@ -215,30 +224,30 @@ async function handleOpenChange(open: boolean) {
<DescriptionsItem label="全日制学历">
{{ currentEmployee.fulltimeEducation }}
</DescriptionsItem>
<DescriptionsItem label="全日制毕业院校">
{{ currentEmployee.fulltimeSchool }}
</DescriptionsItem>
<DescriptionsItem label="全日制专业">
{{ currentEmployee.fulltimeMajor }}
</DescriptionsItem>
<DescriptionsItem label="全日制毕业日期">
{{ currentEmployee.fulltimeGraduationDate }}
</DescriptionsItem>
<DescriptionsItem label="全日制学位">
{{ currentEmployee.fulltimeDegree }}
</DescriptionsItem>
<DescriptionsItem label="非全日制学历">
{{ currentEmployee.nonFulltimeEducation }}
</DescriptionsItem>
<DescriptionsItem label="全日制毕业院校">
{{ currentEmployee.fulltimeSchool }}
</DescriptionsItem>
<DescriptionsItem label="非全日制毕业院校">
{{ currentEmployee.nonFulltimeSchool }}
</DescriptionsItem>
<DescriptionsItem label="全日制专业">
{{ currentEmployee.fulltimeMajor }}
</DescriptionsItem>
<DescriptionsItem label="非全日制专业">
{{ currentEmployee.nonFulltimeMajor }}
</DescriptionsItem>
<DescriptionsItem label="全日制毕业日期">
{{ currentEmployee.fulltimeGraduationDate }}
</DescriptionsItem>
<DescriptionsItem label="非全日制毕业日期">
{{ currentEmployee.nonFulltimeGraduationDate }}
</DescriptionsItem>
<DescriptionsItem label="全日制学位">
{{ currentEmployee.fulltimeDegree }}
</DescriptionsItem>
<DescriptionsItem label="非全日制学位">
{{ currentEmployee.nonFulltimeDegree }}
</DescriptionsItem>
......@@ -298,7 +307,7 @@ async function handleOpenChange(open: boolean) {
</Descriptions>
<Descriptions
v-show="!loading"
v-if="currentEmployee"
v-if="currentEmployee && !isPartTime"
size="small"
bordered
:column="2"
......@@ -352,6 +361,38 @@ async function handleOpenChange(open: boolean) {
{{ currentEmployee.contractSigningStatus }}
</DescriptionsItem>
</Descriptions>
<Descriptions
v-show="!loading"
v-if="isPartTime && currentEmployee"
size="small"
bordered
:column="2"
class="mb-1"
:label-style="{
width: '140px',
fontWeight: 500,
backgroundColor: '#75e0e0',
}"
>
<template #title>
<div class="text-center">兼职信息</div>
</template>
<DescriptionsItem label="签订兼职协议">
{{ currentEmployee.partTimeAgreementName }}
</DescriptionsItem>
<DescriptionsItem label="协议主体">
{{ currentEmployee.agreementEntity }}
</DescriptionsItem>
<DescriptionsItem label="协议期限">
{{ currentEmployee.agreementPeriod }}
</DescriptionsItem>
<DescriptionsItem label="协议开始时间">
{{ currentEmployee.agreementStartDate }}
</DescriptionsItem>
<DescriptionsItem label="协议截止时间" :span="2">
{{ currentEmployee.agreementEndDate }}
</DescriptionsItem>
</Descriptions>
<Descriptions
v-show="!loading"
v-if="currentEmployee"
......@@ -488,10 +529,13 @@ async function handleOpenChange(open: boolean) {
<DescriptionsItem label="离职类型">
{{ currentEmployee.resignationTypeName }}
</DescriptionsItem>
<DescriptionsItem label="离职类别">
{{ currentEmployee.resignationCategoryName }}
</DescriptionsItem>
<DescriptionsItem label="离职时间">
{{ currentEmployee.resignationDate }}
</DescriptionsItem>
<DescriptionsItem label="最后结薪日" :span="2">
<DescriptionsItem label="最后结薪日">
{{ currentEmployee.finalPayDate }}
</DescriptionsItem>
<DescriptionsItem label="离职原因" :span="2">
......
......@@ -380,7 +380,7 @@ const formSchema: VbenFormSchema[] = [
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '职业信息',
default: () => '工作信息',
}),
},
{
......
......@@ -191,7 +191,7 @@ async function handleCompleteOrCancel() {
gridApi.query();
}
function handleDownloadExcel(row: EmployeeInfoApi.Employee) {
commonDownloadExcel(apiExport, '员工信息', row.id);
commonDownloadExcel(apiExport, '简历信息', row.id);
}
function handleDownloadEmployeeList() {
commonDownloadExcel(
......
......@@ -54,7 +54,7 @@ export function useColumns(
{
code: 'edit',
accessCode: ['employee:laborCost:edit'],
name: '查看',
text: '查看',
}, // 默认的编辑按钮
{
code: 'delete',
......
......@@ -7,57 +7,6 @@ import { Base64 } from 'js-base64';
import { ossInfo } from '#/api/system/oss';
// const emit = defineEmits<{
// success: [];
// }>();
// const formData = ref<LaborCostApi.LaborCost>();
// const formSchema: VbenFormSchema[] = [
// {
// component: 'DatePicker',
// fieldName: 'recordDate',
// label: '记录时间',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'ossId',
// label: '文件ID',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'fileKey',
// label: '文件Key',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'remark',
// label: '备注',
// rules: 'required',
// },
// ];
// const [BasicForm, formApi] = useVbenForm({
// commonConfig: {
// componentProps: {
// class: 'w-full',
// },
// formItemClass: 'col-span-2',
// labelWidth: 90,
// },
// schema: formSchema,
// showDefaultActions: false,
// wrapperClass: 'grid-cols-2',
// });
// const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
// {
// initializedGetter: defaultFormValueGetter(formApi),
// currentGetter: defaultFormValueGetter(formApi),
// },
// );
const url = ref('');
const [BasicModal, modalApi] = useVbenModal({
......@@ -78,17 +27,12 @@ const [BasicModal, modalApi] = useVbenModal({
// 'http://cdn.hr.antaikeji.top',
// '/oss-proxy',
// );
// console.log('[ossData.url)]', ossData.url);
const base64 = encodeURIComponent(Base64.encode(ossData.url));
// console.log('[base64]', base64);
url.value = `/file-preview/onlinePreview?url=${base64}`;
// url.value = `http://119.184.127.215:18010/file-preview/onlinePreview?url=${base64}`;
// url.value = `http://172.16.200.110:8012/onlinePreview?url=${base64}`;
// console.log('[url.value]', url.value);
// formData.value = data;
// await formApi.setValues(formData.value);
}
// await markInitialized();
modalApi.modalLoading(false);
},
......@@ -96,21 +40,6 @@ const [BasicModal, modalApi] = useVbenModal({
async function onSubmit() {
modalApi.close();
// const { valid } = await formApi.validate();
// if (valid) {
// modalApi.lock();
// const data = await formApi.getValues<LaborCostApi.LaborCost>();
// try {
// await (formData.value?.id
// ? apiUpdate({ id: formData.value.id, ...data })
// : apiAdd(data));
// resetInitialized();
// emit('success');
// modalApi.close();
// } finally {
// modalApi.unlock();
// }
// }
}
// async function handleClosed() {
......
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { PartTimeInfoApi } from '#/api/hr/partTimeInfo';
export const querySchema: VbenFormSchema[] = [
// {
// component: 'Input',
// fieldName: 'plate',
// label: '板块',
// },
// {
// component: 'Input',
// fieldName: 'firstLevelDepartment',
// label: '一级部门',
// },
// {
// component: 'Input',
// fieldName: 'secondLevelDepartment',
// label: '二级部门',
// },
// {
// component: 'Input',
// fieldName: 'thirdLevelDepartment',
// label: '三级部门',
// },
// {
// component: 'Input',
// fieldName: 'deptId',
// label: '部门ID',
// },
{
component: 'Input',
fieldName: 'position',
label: '主岗位',
},
{
component: 'Input',
fieldName: 'name',
label: '姓名',
},
{
component: 'Input',
fieldName: 'gender',
label: '性别',
},
{
component: 'Input',
fieldName: 'idCardNumber',
label: '身份证号码',
},
// {
// component: 'Input',
// fieldName: 'ossId',
// label: '照片ID',
// },
// {
// component: 'DatePicker',
// fieldName: 'birthDate',
// label: '出生日期',
// },
// {
// component: 'Input',
// fieldName: 'age',
// 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: 'DatePicker',
fieldName: 'entryDate',
label: '入职时间',
},
{
component: 'Input',
fieldName: 'fulltimeEducation',
label: '全日制学历',
},
{
component: 'Input',
fieldName: 'fulltimeSchool',
label: '全日制毕业院校',
},
{
component: 'Input',
fieldName: 'fulltimeMajor',
label: '全日制专业',
},
// {
// component: 'DatePicker',
// fieldName: 'fulltimeGraduationDate',
// label: '全日制毕业日期',
// },
// {
// component: 'Input',
// fieldName: 'fulltimeDegree',
// label: '全日制学位',
// },
{
component: 'Input',
fieldName: 'employmentForm',
label: '用工形式',
},
// {
// component: 'Input',
// fieldName: 'partTimeFlag',
// label: '是否兼职',
// },
{
component: 'Input',
fieldName: 'partTimeAgreement',
label: '签订兼职协议',
},
// {
// component: 'Input',
// fieldName: 'agreementEntity',
// label: '协议主体',
// },
// {
// component: 'Input',
// fieldName: 'agreementPeriod',
// label: '协议期限',
// },
{
component: 'DatePicker',
fieldName: 'agreementStartDate',
label: '协议开始时间',
},
{
component: 'DatePicker',
fieldName: 'agreementEndDate',
label: '协议截止时间',
},
// {
// component: 'Input',
// fieldName: 'remarks',
// label: '备注',
// },
// {
// component: 'Input',
// fieldName: 'bankCardNumber',
// label: '银行卡号',
// },
// {
// component: 'Input',
// fieldName: 'bankName',
// label: '开户行',
// },
// {
// component: 'Input',
// fieldName: 'hasRelativeInCompany',
// label: '公司内是否有亲属关系',
// },
// {
// component: 'Input',
// fieldName: 'relativeName',
// label: '亲属姓名',
// },
// {
// component: 'Input',
// fieldName: 'introducer',
// label: '介绍人',
// },
// {
// component: 'Input',
// fieldName: 'introducerRelation',
// label: '介绍人关系',
// },
// {
// component: 'Input',
// fieldName: 'salaryLocation',
// label: '工资发放地',
// },
{
component: 'Input',
fieldName: 'costOfDept',
label: '成本费用所属',
},
];
export function useColumns(): VxeTableGridOptions<PartTimeInfoApi.PartTimeInfo>['columns'] {
return [
{ title: '序号', type: 'seq', width: 50 },
{
title: '板块',
field: 'plate',
width: 80,
},
{
title: '一级部门',
field: 'firstLevelDepartment',
width: 90,
},
{
title: '二级部门',
field: 'secondLevelDepartment',
width: 100,
},
{
title: '三级部门',
field: 'thirdLevelDepartment',
width: 120,
},
// {
// title: '部门ID',
// field: 'deptId',
// },
{
title: '岗位类型',
field: 'positionTypeName',
width: 100,
// cellRender: { name: 'CellTag', options: [getTagDicts(DictEnum.HR_POSITION_TYPE)] },
},
{
title: '主岗位',
field: 'positionName',
width: 100,
},
{
title: '姓名',
field: 'name',
width: 100,
},
{
title: '性别',
field: 'genderName',
width: 80,
},
{
title: '身份证号码',
field: 'idCardNumber',
width: 130,
},
// {
// title: '照片ID',
// field: 'ossId',
// },
{
title: '出生日期',
field: 'birthDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '年龄',
field: 'age',
width: 80,
},
{
title: '籍贯',
field: 'nativePlace',
width: 120,
},
{
title: '民族',
field: 'ethnicity',
width: 80,
},
{
title: '婚姻状况',
field: 'maritalStatusName',
width: 80,
},
{
title: '政治面貌',
field: 'politicalStatusName',
width: 80,
},
{
title: '手机号码',
field: 'phoneNumber',
width: 110,
},
{
title: '紧急联系人',
field: 'emergencyContact',
width: 100,
},
{
title: '紧急联系人电话',
field: 'emergencyContactPhone',
width: 110,
},
{
title: '家庭地址',
field: 'homeAddress',
width: 120,
},
{
title: '入职时间',
field: 'entryDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '全日制学历',
field: 'fulltimeEducation',
width: 100,
},
{
title: '全日制毕业院校',
field: 'fulltimeSchool',
width: 100,
},
{
title: '全日制专业',
field: 'fulltimeMajor',
width: 90,
},
{
title: '全日制毕业日期',
field: 'fulltimeGraduationDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '全日制学位',
field: 'fulltimeDegree',
width: 100,
},
{
title: '用工形式',
field: 'employmentFormName',
width: 100,
},
// {
// title: '是否兼职',
// field: 'partTimeFlag',
// },
{
title: '签订兼职协议',
field: 'partTimeAgreement',
width: 100,
},
{
title: '协议主体',
field: 'agreementEntity',
width: 80,
},
{
title: '协议期限',
field: 'agreementPeriod',
width: 80,
},
{
title: '协议开始时间',
field: 'agreementStartDate',
width: 100,
// formatter: 'formatDateTime',
},
{
title: '协议截止时间',
field: 'agreementEndDate',
width: 100,
// formatter: 'formatDateTime',
},
{
title: '银行卡号',
field: 'bankCardNumber',
width: 110,
},
{
title: '开户行',
field: 'bankName',
width: 110,
},
{
title: '公司内是否有亲属关系',
field: 'hasRelativeInCompanyName',
width: 90,
},
{
title: '亲属姓名',
field: 'relativeName',
width: 90,
},
{
title: '介绍人',
field: 'introducer',
width: 90,
},
{
title: '介绍人关系',
field: 'introducerRelation',
width: 90,
},
{
title: '工资发放地',
field: 'salaryLocation',
width: 100,
},
{
title: '成本费用所属',
field: 'costOfDept',
width: 110,
},
// {
// title: '备注',
// field: 'remarks',
// },
{
align: 'right',
slots: { default: 'action' },
// cellRender: {
// attrs: {
// nameField: 'name',
// nameTitle: '兼职员工信息',
// onClick: onActionClick,
// },
// name: 'CellOperation',
// options: [
// {
// code: 'edit',
// accessCode: ['employee:partTimeInfo:edit'],
// }, // 默认的编辑按钮
// {
// code: 'delete',
// accessCode: ['employee:partTimeInfo:remove'],
// }, // 默认的删除按钮
// ],
// },
field: 'action',
fixed: 'right',
headerAlign: 'center',
resizable: false,
showOverflow: false,
title: '操作',
width: 'auto',
},
];
}
<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { PartTimeInfoApi } from '#/api/hr/partTimeInfo';
import { computed, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { addFullName, getVxePopupContainer } from '@vben/utils';
import { Skeleton } from 'ant-design-vue';
import { useVbenForm, z } from '#/adapter/form';
import { treeList } from '#/api/auth/dept';
import { apiAdd, apiDetail, apiUpdate } from '#/api/hr/partTimeInfo';
import { getDictOptions } from '#/utils/dict';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { idCardSchema } from '../../../utils/validator';
import { HrDictEnum } from '../dict-enum';
const emit = defineEmits<{
success: [];
}>();
const loading = ref(false);
const isUpdate = ref(false);
const formSchema: VbenFormSchema[] = [
{
component: 'Input',
dependencies: {
show: () => false,
triggerFields: [''],
},
fieldName: 'id',
label: 'id',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '部门信息',
}),
},
{
component: 'TreeSelect',
// 在onOpenChange里更新 这里不需要默认的componentProps
defaultValue: undefined,
fieldName: 'deptId',
label: '所属部门',
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'position',
label: '主岗位',
rules: 'required',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(HrDictEnum.HR_POSITION_TYPE),
getVxePopupContainer,
},
fieldName: 'positionType',
label: '岗位类型',
// rules: 'selectRequired',
},
{
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: 'ImageUpload',
componentProps: {
maxCount: 1,
},
fieldName: 'ossId',
label: '照片',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'phoneNumber',
label: '手机号码',
rules: z
.string()
.regex(/^1[3-9]\d{9}$/, { message: '请输入正确的联系电话' }),
},
{
component: 'Input',
fieldName: 'idCardNumber',
label: '身份证号码',
rules: idCardSchema,
},
{
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
getVxePopupContainer,
},
fieldName: 'birthDate',
label: '出生日期',
rules: 'required',
},
{
component: 'InputNumber',
fieldName: 'age',
label: '年龄',
rules: z.number().gt(0, '年龄不能小于0').lt(100, '年龄不能大于100'),
},
{
component: 'Input',
fieldName: 'homeAddress',
label: '家庭地址',
rules: 'required',
},
// {
// component: 'Input',
// fieldName: 'ageGroup',
// label: '年龄段',
// rules: 'required',
// },
{
component: 'Input',
fieldName: 'ethnicity',
label: '民族',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'nativePlace',
label: '籍贯',
// rules: 'required',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(HrDictEnum.HR_MARITAL_STATUS),
},
fieldName: 'maritalStatus',
label: '婚姻状况',
// rules: 'selectRequired',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(HrDictEnum.HR_POLITICAL_STATUS),
},
fieldName: 'politicalStatus',
label: '政治面貌',
// rules: 'selectRequired',
},
// {
// component: 'Input',
// fieldName: 'householdRegistrationAddress',
// label: '户口所在地',
// // rules: 'required',
// },
{
component: 'Input',
fieldName: 'emergencyContact',
label: '紧急联系人',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'emergencyContactPhone',
label: '紧急联系人电话',
rules: z
.string()
.regex(/^1[3-9]\d{9}$/, '请输入正确的手机号码')
.optional()
.or(z.literal('')),
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '教育信息',
}),
},
{
component: 'Input',
fieldName: 'fulltimeEducation',
label: '全日制学历',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'fulltimeSchool',
label: '全日制毕业院校',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'fulltimeMajor',
label: '全日制专业',
// rules: 'required',
},
{
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
getVxePopupContainer,
},
fieldName: 'fulltimeGraduationDate',
label: '全日制毕业日期',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'fulltimeDegree',
label: '全日制学位',
// rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '工作信息',
}),
},
{
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
getVxePopupContainer,
},
fieldName: 'entryDate',
label: '入职时间',
// rules: 'required',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(HrDictEnum.HR_EMPLOYMENT_FORM),
},
defaultValue: '4',
fieldName: 'employmentForm',
label: '用工形式',
// rules: 'selectRequired',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '合同信息',
}),
},
// {
// component: 'Input',
// fieldName: 'partTimeFlag',
// label: '是否兼职',
// rules: 'required',
// },
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(DictEnum.SYS_YES_NO),
},
fieldName: 'partTimeAgreement',
label: '签订兼职协议',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'agreementEntity',
label: '协议主体',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'agreementPeriod',
label: '协议期限',
// rules: 'required',
},
{
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
getVxePopupContainer,
},
fieldName: 'agreementStartDate',
label: '协议开始时间',
// rules: 'required',
},
{
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
getVxePopupContainer,
},
fieldName: 'agreementEndDate',
label: '协议截止时间',
// rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
formItemClass: 'col-span-2',
hideLabel: true,
renderComponentContent: () => ({
default: () => '其他信息',
}),
},
{
component: 'Input',
fieldName: 'bankCardNumber',
label: '银行卡号',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'bankName',
label: '开户行',
// rules: 'required',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
optionType: 'button',
options: getDictOptions(DictEnum.SYS_YES_NO),
},
fieldName: 'hasRelativeInCompany',
label: '是否有亲属关系',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'relativeName',
label: '亲属姓名',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'introducer',
label: '介绍人',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'introducerRelation',
label: '介绍人关系',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'salaryLocation',
label: '工资发放地',
// rules: 'required',
},
{
component: 'Input',
fieldName: 'costOfDept',
label: '成本费用所属',
// rules: 'required',
},
{
component: 'Textarea',
fieldName: 'remarks',
label: '备注',
// rules: 'required',
},
];
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
},
formItemClass: 'col-span-1',
labelWidth: 130,
},
schema: formSchema,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
async function setupDeptSelect() {
const deptArray = await treeList();
// const deptTree = genDeptTree(deptArray);
addFullName(deptArray, 'label', ' / ');
formApi.updateSchema([
{
componentProps: (formModel) => ({
treeData: deptArray,
async onSelect(deptId: number | string, node: Record<string, any>) {
/** 根据部门Node获取部门等级数组 */
const result = node.fullName
.split('/')
.map((item: string) => item.trim())
.filter(Boolean);
/** 变化后需要重新设置部门信息 */
formModel.plate = result[0];
formModel.firstLevelDepartment = result[1];
formModel.secondLevelDepartment = result[2];
formModel.thirdLevelDepartment = result[3];
},
class: 'w-full',
treeLine: { showLeafIcon: false },
treeIcon: false,
// 筛选的字段
treeNodeFilterProp: 'label',
// 选中后显示在输入框的值
treeNodeLabelProp: 'fullName',
getVxePopupContainer,
fieldNames: { label: 'label', value: 'id' },
labelField: 'label',
showSearch: true,
treeDefaultExpandAll: true,
valueField: 'id',
childrenField: 'children',
}),
fieldName: 'deptId',
},
]);
}
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;
}
drawerApi.drawerLoading(true);
loading.value = true;
const { id } = drawerApi.getData() as { id?: number };
isUpdate.value = !!id;
// 初始化
await setupDeptSelect();
if (isUpdate.value && id) {
const data = await apiDetail(id);
data.ossId = data.ossId ? `${data.ossId}` : data.ossId;
await formApi.setValues(data);
} else {
await formApi.resetForm();
}
await markInitialized();
drawerApi.drawerLoading(false);
loading.value = false;
},
});
async function onSubmit() {
const { valid } = await formApi.validate();
if (valid) {
drawerApi.lock();
const data = await formApi.getValues<PartTimeInfoApi.PartTimeInfo>();
try {
await (isUpdate.value ? apiUpdate(data) : apiAdd(data));
resetInitialized();
emit('success');
drawerApi.close();
} finally {
drawerApi.unlock();
}
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
}
const getDrawerTitle = computed(() =>
isUpdate.value ? '修改兼职员工信息' : '新增兼职员工信息',
);
</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 { ExtendedModalApi, VbenFormProps } from '@vben/common-ui';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { PartTimeInfoApi } from '#/api/hr/partTimeInfo';
import { ref, shallowRef } from 'vue';
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons';
import { ExportOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { Button, Space } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { employeeDeptTreeSelect } from '#/api/hr/employeeInfo';
import { apiExport, apiPage } from '#/api/hr/partTimeInfo';
import { GhostButton } from '#/components/global/button';
import { commonDownloadExcel } from '#/utils/file/download';
import DeptTree from '#/views/auth/user/deptTree.vue';
import { applyModal } from '../../workflow/components';
import applyEntryModel from '../employeeInfo/apply-entry-model.vue';
import applyResignModel from '../employeeInfo/apply-resign-model.vue';
import applyTransferModel from '../employeeInfo/apply-transfer-model.vue';
import employeeDetailDrawer from '../employeeInfo/employee-detail-drawer.vue';
import { querySchema, useColumns } from './data';
import Form from './form.vue';
import partTimeEmployeeImportModal from './partTime-employee-import-modal.vue';
/**
* 导入
*/
const [PartTimeEmployeeImportModal, partTimeEmployeeImportModalApi] =
useVbenModal({
connectedComponent: partTimeEmployeeImportModal,
});
function handleImport() {
partTimeEmployeeImportModalApi.open();
}
const [ApplyModal, applyModalApi] = useVbenModal({
connectedComponent: applyModal,
});
const [ApplyEntryModel, applyEntryModelApi] = useVbenModal({
connectedComponent: applyEntryModel,
});
const [ApplyTransferModel, applyTransferModelApi] = useVbenModal({
connectedComponent: applyTransferModel,
});
const [ApplyResignModel, applyResignModelApi] = useVbenModal({
connectedComponent: applyResignModel,
});
const modalApi = shallowRef<ExtendedModalApi | null>(null);
// 左边部门用
const selectDeptId = ref<number[]>([]);
const formOptions: VbenFormProps = {
commonConfig: {
labelWidth: 80,
componentProps: {
allowClear: true,
},
},
collapsed: true,
schema: querySchema,
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
handleReset: async () => {
selectDeptId.value = [];
const { formApi, reload } = gridApi;
await formApi.resetForm();
const formValues = formApi.form.values;
formApi.setLatestSubmissionValues(formValues);
await reload(formValues);
},
};
const [EmployeeDetailDrawer, employeeDetailDrawerApi] = useVbenDrawer({
connectedComponent: employeeDetailDrawer,
});
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 = {}) => {
// 部门树选择处理
if (selectDeptId.value.length === 1) {
formValues.belongDeptId = selectDeptId.value[0];
} else {
Reflect.deleteProperty(formValues, 'belongDeptId');
}
return await apiPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
});
},
},
},
rowConfig: {
keyField: 'id',
// 高亮当前行
isCurrent: true,
},
} as VxeTableGridOptions,
});
// function onActionClick({
// code,
// row,
// }: OnActionClickParams<PartTimeInfoApi.PartTimeInfo>) {
// switch (code) {
// case 'delete': {
// onDelete(row);
// break;
// }
// case 'edit': {
// onEdit(row);
// break;
// }
// default: {
// break;
// }
// }
// }
function onRefresh() {
gridApi.query();
}
function onShowDetail(row: PartTimeInfoApi.PartTimeInfo) {
employeeDetailDrawerApi.setData({ id: row.id, partTimeFlag: true }).open();
}
function onEdit(row: PartTimeInfoApi.PartTimeInfo) {
formDrawerApi.setData(row).open();
}
function onCreate() {
formDrawerApi.setData({}).open();
}
// function onDelete(row: PartTimeInfoApi.PartTimeInfo) {
// 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 onEntryApply(row: PartTimeInfoApi.PartTimeInfo) {
modalApi.value = applyEntryModelApi;
applyEntryModelApi
.setData({
employeeId: row.id,
name: row.name,
deptName: `${row.plate} / ${row.firstLevelDepartment} / ${
row.secondLevelDepartment
} / ${row.thirdLevelDepartment}`,
applyModalApi,
})
.open();
}
function onResign(row: PartTimeInfoApi.PartTimeInfo) {
modalApi.value = applyResignModelApi;
applyResignModelApi
.setData({
employeeId: row.id,
name: row.name,
deptName: `${row.plate} / ${row.firstLevelDepartment} / ${
row.secondLevelDepartment
} / ${row.thirdLevelDepartment}`,
applyModalApi,
})
.open();
}
function onTransfer(row: PartTimeInfoApi.PartTimeInfo) {
modalApi.value = applyTransferModelApi;
applyTransferModelApi
.setData({
employeeId: row.id,
name: row.name,
oldDeptName: `${row.plate} / ${row.firstLevelDepartment} / ${
row.secondLevelDepartment
} / ${row.thirdLevelDepartment}`,
applyModalApi,
})
.open();
}
async function handleCompleteOrCancel() {
if (modalApi.value) {
modalApi.value.close();
}
gridApi.query();
}
function handleDownloadExcel() {
commonDownloadExcel(apiExport, '兼职员工信息', gridApi.formApi.form.values);
}
</script>
<template>
<Page auto-content-height content-class="flex gap-[8px] w-full">
<EmployeeDetailDrawer />
<FormDrawer @success="onRefresh" />
<DeptTree
v-model:select-dept-id="selectDeptId"
:api="employeeDeptTreeSelect"
class="w-[260px]"
@reload="() => gridApi.reload()"
@select="() => gridApi.reload()"
/>
<Grid class="flex-1 overflow-hidden" table-title="兼职员工信息列表">
<template #toolbar-tools>
<Space>
<Button
type="primary"
ghost
v-access:code="['employee:partTimeInfo:export']"
@click="handleDownloadExcel"
>
<template #icon>
<ExportOutlined />
</template>
导出
</Button>
<Button
v-access:code="['employee:partTimeInfo:import']"
@click="handleImport"
>
<template #icon>
<UploadOutlined />
</template>
导入
</Button>
<Button
v-access:code="['employee:partTimeInfo:add']"
type="primary"
@click="onCreate"
>
<Plus class="size-5" />
新增兼职
</Button>
</Space>
</template>
<template #action="{ row }">
<Space>
<GhostButton
v-access:code="['employee:partTimeInfo:query']"
@click.stop="onShowDetail(row)"
>
查看
</GhostButton>
<GhostButton
v-access:code="['employee:partTimeInfo:edit']"
@click.stop="onEdit(row)"
>
编辑
</GhostButton>
<GhostButton
v-if="[0].includes(row.status)"
v-access:code="['employee:info:add']"
@click.stop="onEntryApply(row)"
>
申请入职
</GhostButton>
<GhostButton
v-if="[1, 2].includes(row.status)"
v-access:code="['employee:info:edit']"
@click.stop="onTransfer(row)"
>
申请调配
</GhostButton>
<GhostButton
danger
v-if="[1, 2].includes(row.status)"
v-access:code="['employee:info:resign']"
@click.stop="onResign(row)"
>
申请离职
</GhostButton>
</Space>
</template>
</Grid>
<PartTimeEmployeeImportModal @reload="onRefresh" />
<ApplyEntryModel />
<ApplyTransferModel />
<ApplyResignModel />
<ApplyModal
@complete="handleCompleteOrCancel"
@cancel="handleCompleteOrCancel"
/>
</Page>
</template>
<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,
employeePartTimeImportData,
} from '#/api/hr/partTimeInfo';
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 employeePartTimeImportData(
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>
......@@ -264,224 +264,474 @@ export const querySchema: VbenFormSchema[] = [
export function useColumns(): VxeTableGridOptions<EmployeeInfoApi.Employee>['columns'] {
// onActionClick: OnActionClickFn<EmployeeInfoApi.Employee>,
return [
{ title: '序号', type: 'seq', width: 50 },
{
title: '板块',
field: 'plate',
width: 80,
},
{
title: '一级部门',
field: 'firstLevelDepartment',
width: 90,
},
{
title: '二级部门',
field: 'secondLevelDepartment',
width: 100,
},
{
title: '三级部门',
field: 'thirdLevelDepartment',
width: 120,
},
{
title: '离职类型',
field: 'resignationTypeName',
width: 100,
},
{
title: '离职类别',
field: 'resignationCategoryName',
width: 100,
},
{
title: '离职时间',
field: 'resignationDate',
width: 100,
},
{
title: '离职原因',
field: 'resignationReason',
width: 120,
},
{
title: '最后结薪日',
field: 'finalPayDate',
width: 120,
},
{
title: '工号',
field: 'employeeNo',
width: 80,
},
// {
// title: '职级',
// field: 'jobLevel',
// },
{
title: '主岗位',
field: 'position',
title: '职级',
field: 'jobLevel',
width: 80,
},
{
title: '岗位类型',
field: 'positionTypeName',
width: 100,
// cellRender: { name: 'CellTag', options: [getTagDicts(DictEnum.HR_POSITION_TYPE)] },
},
{
title: '序列',
field: 'sequenceName',
width: 80,
},
{
title: '主岗位',
field: 'positionName',
width: 100,
},
{
title: '姓名',
field: 'name',
width: 100,
},
{
title: '性别',
field: 'genderName',
// cellRender: {
// name: 'CellTag',
// options: [getTagDicts(HrDictEnum.HR_USER_SEX)],
// },
width: 80,
},
{
title: '身份证号码',
field: 'idCardNumber',
width: 120,
},
{
title: '出生日期',
field: 'birthDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '年龄',
field: 'age',
width: 80,
},
{
title: '年龄段',
field: 'ageGroupName',
width: 100,
},
{
title: '兼岗板块',
field: 'concurrentPlate',
width: 80,
},
{
title: '兼岗一级部门',
field: 'concurrentFirstDept',
width: 90,
},
{
title: '兼岗二级部门',
field: 'concurrentSecondDept',
width: 100,
},
{
title: '兼岗三级部门',
field: 'concurrentThirdDept',
width: 120,
},
{
title: '兼岗岗位',
field: 'concurrentPosition',
width: 100,
},
{
title: '兼岗岗位类型',
field: 'concurrentPositionTypeName',
width: 100,
},
{
title: '籍贯',
field: 'nativePlace',
width: 120,
},
{
title: '民族',
field: 'ethnicity',
width: 80,
},
{
title: '婚姻状况',
field: 'maritalStatusName',
width: 80,
},
{
title: '政治面貌',
field: 'politicalStatusName',
width: 80,
},
// {
// 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',
width: 110,
},
{
title: '紧急联系人',
field: 'emergencyContact',
width: 100,
},
{
title: '紧急联系人电话',
field: 'emergencyContactPhone',
width: 110,
},
{
title: '家庭地址',
field: 'homeAddress',
width: 120,
},
{
title: '户口所在地',
field: 'householdRegistrationAddress',
width: 120,
},
{
title: '参加工作时间',
field: 'workStartDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '入职时间',
field: 'entryDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '工龄',
field: 'yearsOfService',
width: 90,
},
{
title: '工龄段',
field: 'yearsOfServiceSegmentName',
width: 90,
},
// {
// 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: '学历',
{
title: '全日制学历',
field: 'fulltimeEducation',
width: 100,
},
{
title: '全日制毕业院校',
field: 'fulltimeSchool',
width: 100,
},
{
title: '全日制专业',
field: 'fulltimeMajor',
width: 90,
},
{
title: '全日制毕业日期',
field: 'fulltimeGraduationDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '全日制学位',
field: 'fulltimeDegree',
width: 100,
},
{
title: '非全日制学历',
field: 'nonFulltimeEducation',
width: 100,
},
{
title: '非全日制毕业院校',
field: 'nonFulltimeSchool',
width: 100,
},
{
title: '非全日制专业',
field: 'nonFulltimeMajor',
width: 90,
},
{
title: '非全日制毕业日期',
field: 'nonFulltimeGraduationDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '非全日制学位',
field: 'nonFulltimeDegree',
width: 100,
},
{
title: '学历分类',
field: 'educationCategoryName',
width: 90,
},
// {
// 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)],
// },
width: 90,
},
{
title: '职称情况',
field: 'professionalTitle',
width: 90,
},
{
title: '证书情况',
field: 'certificateStatusName',
width: 100,
},
{
title: '外部个人履历',
field: 'externalResume',
width: 120,
},
{
title: '内部个人履历',
field: 'internalResume',
width: 120,
},
// {
// title: '职称情况',
// field: 'professionalTitle',
// },
// {
// title: '简历',
// field: 'resume',
// },
{
title: '用工形式',
field: 'employmentFormName',
// cellRender: {
// name: 'CellTag',
// options: [getTagDicts(HrDictEnum.HR_EMPLOYMENT_FORM)],
// },
width: 100,
},
{
title: '合同形式',
field: 'contractFormName',
width: 100,
},
{
title: '劳动合同期限',
field: 'contractTerm',
width: 80,
},
{
title: '劳动合同开始时间',
field: 'contractStartDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '劳动合同截止时间',
field: 'contractEndDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '合同到期提醒',
field: 'contractExpirationReminder',
// formatter: 'formatDate',
width: 100,
},
{
title: '劳动合同签订情况',
field: 'contractSigningStatus',
width: 110,
},
{
title: '合同主体',
field: 'contractEntity',
width: 90,
},
{
title: '社保主体',
field: 'socialSecurityEntity',
width: 90,
},
{
title: '是否缴纳社保',
field: 'hasSocialSecurityPaidName',
width: 90,
},
{
title: '公积金主体',
field: 'providentFundEntity',
width: 90,
},
{
title: '是否缴纳公积金',
field: 'hasProvidentFundPaidName',
width: 90,
},
{
title: '是否缴纳雇主险',
field: 'hasEmployerInsurancePaidName',
width: 90,
},
{
title: '试用期',
field: 'probationPeriod',
width: 90,
},
{
title: '转正时间',
field: 'regularizationDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '预计转正时间',
field: 'expectedRegularDate',
// formatter: 'formatDate',
width: 100,
},
{
title: '奖励情况',
field: 'rewardStatusName',
width: 110,
},
{
title: '处罚情况',
field: 'punishmentStatusName',
width: 110,
},
{
title: '备注',
field: 'remarks',
width: 110,
},
{
title: '办公电话',
field: 'officePhone',
width: 110,
},
{
title: '短线',
field: 'shortLine',
width: 90,
},
{
title: '银行卡号',
field: 'bankCardNumber',
width: 110,
},
{
title: '开户行',
field: 'bankName',
width: 110,
},
{
title: '公司内是否有亲属关系',
field: 'hasRelativeInCompanyName',
width: 90,
},
{
title: '亲属姓名',
field: 'relativeName',
width: 90,
},
{
title: '介绍人',
field: 'introducer',
width: 90,
},
{
title: '介绍人关系',
field: 'introducerRelation',
width: 90,
},
{
title: '工资发放地',
field: 'salaryLocation',
width: 100,
},
{
title: '编制所在地',
field: 'staffingLocation',
width: 100,
},
{
title: '成本费用所属',
field: 'costOfDept',
width: 110,
},
{
title: '成本费用细分',
field: 'costType',
width: 110,
// cellRender: { name: 'CellTag', options: [getTagDicts()] },
},
{
title: '绩效比例',
field: 'performanceRatio',
width: 100,
},
{
title: '工装',
field: 'workwearDetail',
width: 110,
},
{
title: '内部购房优惠',
field: 'internalPurchaseDiscountsName',
width: 110,
},
{
title: '安泰业主',
field: 'antaiHomeownersName',
width: 80,
},
{
title: '小区具体信息',
field: 'antaiCommunityInfo',
width: 110,
},
// {
// 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' },
......
......@@ -26,7 +26,11 @@ const props = defineProps<{ businessId: number | string }>();
const data = shallowRef<EmployeeFlowApi.EmployeeFlowVo>();
onMounted(async () => {
const resp = await apiDetail(props.businessId);
const resp = await apiDetail(
typeof props.businessId === 'number'
? props.businessId
: Number.parseInt(props.businessId),
);
data.value = resp;
});
......
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