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',
},
];
}
This diff is collapsed.
<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>
......@@ -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