Files
shz-admin/src/pages/Management/List/ResumeRecommend/index.tsx

248 lines
6.8 KiB
TypeScript
Raw Normal View History

2026-06-27 17:57:45 +08:00
import React, { Fragment, useEffect, useRef, useState } from 'react';
import { useAccess, useParams } from '@umijs/max';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { Button, message } from 'antd';
import { AlignLeftOutlined, SendOutlined } from '@ant-design/icons';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import { getRecommendByJobId, getCmsJobIds } from '@/services/Management/list';
import ResumeDetail from './ResumeDetail';
import InterviewInvite from './InterviewInvite';
function ResumeRecommend() {
const access = useAccess();
const actionRef = useRef<ActionType>();
const [educationEnum, setEducationEnum] = useState<any>([]);
const [areaEnum, setAreaEnum] = useState<any>([]);
const [sexEnum, setSexEnum] = useState<any>([]);
const [politicalEnum, setPoliticalEnum] = useState<any>([]);
const [currentRow, setCurrentRow] = useState<API.ManagementList.RecommendUser>();
const [detailVisible, setDetailVisible] = useState<boolean>(false);
const [inviteVisible, setInviteVisible] = useState<boolean>(false);
const [jobInfo, setJobInfo] = useState<any>({});
const params = useParams();
const jobId = params.id || '0';
useEffect(() => {
getDictValueEnum('education', true, true).then((data) => {
setEducationEnum(data);
});
getDictValueEnum('area', true, true).then((data) => {
setAreaEnum(data);
});
getDictValueEnum('sys_user_sex', true).then((data) => {
setSexEnum(data);
});
getDictValueEnum('political_affiliation', true, true).then((data) => {
setPoliticalEnum(data);
});
getJobInfo(jobId);
}, [jobId]);
const getJobInfo = async (id: string) => {
try {
const resData = await getCmsJobIds(id);
if (resData.code === 200 && resData.data) {
const data = resData.data as any;
setJobInfo({
jobTitle: data.jobTitle || '',
companyId: data.companyId,
});
}
} catch (error) {
console.error('获取岗位信息失败:', error);
}
};
const columns: ProColumns<API.ManagementList.RecommendUser>[] = [
{
title: '用户名',
dataIndex: 'name',
valueType: 'text',
align: 'center',
},
{
title: '期望薪资',
dataIndex: 'minSalary',
valueType: 'text',
hideInSearch: true,
align: 'center',
render: (_, record) => (
<>
{record.salaryMin}-{record.salaryMax}
</>
),
},
{
title: '出生日期',
dataIndex: 'birthDate',
valueType: 'text',
align: 'center',
hideInSearch: true,
},
{
title: '学历要求',
dataIndex: 'education',
valueType: 'select',
align: 'center',
valueEnum: educationEnum,
render: (_, record) => {
return <DictTag enums={educationEnum} value={record.education} />;
},
},
{
title: '区域',
dataIndex: 'area',
valueType: 'select',
align: 'center',
valueEnum: areaEnum,
render: (_, record) => {
return <DictTag enums={areaEnum} value={record.area} />;
},
},
{
title: '性别',
dataIndex: 'sex',
valueType: 'select',
align: 'center',
valueEnum: sexEnum,
render: (_, record) => {
return <DictTag enums={sexEnum} value={record.sex} />;
},
},
{
title: '政治面貌',
dataIndex: 'politicalAffiliation',
valueType: 'select',
align: 'center',
valueEnum: politicalEnum,
render: (_, record) => {
return <DictTag enums={politicalEnum} value={record.politicalAffiliation} />;
},
},
{
title: '手机号码',
dataIndex: 'phone',
valueType: 'text',
align: 'center',
hideInSearch: true,
},
{
title: '匹配级别',
dataIndex: 'matchLevelDesc',
valueType: 'text',
align: 'center',
hideInSearch: true,
width: 200,
},
{
title: '操作',
hideInSearch: true,
align: 'center',
dataIndex: 'userId',
width: 200,
render: (_, record) => [
<div key="actions" style={{ display: 'flex', justifyContent: 'center', gap: 8 }}>
<Button
type="link"
size="small"
key="view-resume"
icon={<AlignLeftOutlined />}
onClick={() => {
setCurrentRow(record);
setDetailVisible(true);
}}
>
</Button>
<Button
type="link"
size="small"
key="invite-interview"
icon={<SendOutlined />}
hidden={!access.hasPerms('cms:interview:add')}
onClick={() => {
setCurrentRow(record);
setInviteVisible(true);
}}
>
</Button>
</div>,
],
},
];
return (
<Fragment>
<div style={{ width: '100%', float: 'right' }}>
<ProTable<API.ManagementList.RecommendUser>
actionRef={actionRef}
rowKey="userId"
key="index"
headerTitle={`简历推荐${jobInfo.jobTitle ? ` - ${jobInfo.jobTitle}` : ''}`}
columns={columns}
request={async () => {
try {
const res = await getRecommendByJobId(jobId);
if (res.code === 200) {
const data = res.data || [];
return {
data,
total: data.length,
success: true,
};
} else {
message.error(res.msg || '获取推荐简历失败');
return {
data: [],
total: 0,
success: false,
};
}
} catch (error) {
message.error('获取推荐简历失败');
return {
data: [],
total: 0,
success: false,
};
}
}}
search={false}
pagination={{ pageSize: 10 }}
/>
</div>
<ResumeDetail
values={currentRow}
open={detailVisible}
jobId={jobId}
onClose={() => {
setDetailVisible(false);
setCurrentRow(undefined);
}}
/>
<InterviewInvite
open={inviteVisible}
userId={currentRow?.userId}
userName={currentRow?.name}
jobId={jobId}
companyId={jobInfo.companyId}
jobName={jobInfo.jobTitle}
onClose={(needRefresh) => {
setInviteVisible(false);
setCurrentRow(undefined);
if (needRefresh) {
actionRef.current?.reload();
}
}}
/>
</Fragment>
);
}
export default ResumeRecommend;