Files
shz-admin/src/pages/Mobileusers/Rencai/index.tsx

252 lines
7.3 KiB
TypeScript
Raw Normal View History

import React, { Fragment, useEffect, useRef, useState } from 'react';
import { useAccess, useNavigate } from '@umijs/max';
import { Button, FormInstance, message, Tag } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { StarFilled, FileTextOutlined, SendOutlined } from '@ant-design/icons';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import { delHrTalentCollect, getHrTalentCollectList } from '@/services/mobileusers/list';
import InterviewInvite from '@/pages/Management/List/ResumeRecommend/InterviewInvite';
function TalentCollectList() {
const access = useAccess();
const navigate = useNavigate();
const formTableRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const [educationEnum, setEducationEnum] = useState<any>({});
const [areaEnum, setAreaEnum] = useState<any>({});
const [sexEnum, setSexEnum] = useState<any>({});
const [inviteVisible, setInviteVisible] = useState<boolean>(false);
const [currentRow, setCurrentRow] = useState<API.TalentCollect.ListRow>();
useEffect(() => {
2026-07-16 20:15:25 +08:00
getDictValueEnum('education', false, true).then((data) => setEducationEnum(data));
getDictValueEnum('area', false, true).then((data) => setAreaEnum(data));
getDictValueEnum('sys_user_sex', false).then((data) => setSexEnum(data));
}, []);
// 取消收藏接口路径参数为收藏记录主键id
const handleCancelCollect = async (record: API.TalentCollect.ListRow) => {
if (!record.id) return;
try {
const res = await delHrTalentCollect(String(record.id));
if (res.code === 200) {
message.success('已取消收藏');
actionRef.current?.reload();
} else {
message.error(res.msg || '取消收藏失败');
}
} catch (error: any) {
message.error(error?.response?.data?.msg || error?.message || '取消收藏失败');
}
};
const intentionLevelMap: Record<string, { text: string; color: string }> = {
'1': { text: '高意向', color: 'red' },
'2': { text: '中等意向', color: 'blue' },
'3': { text: '低意向', color: 'default' },
};
const sourceTypeMap: Record<string, string> = {
'1': '简历搜索',
'2': '投递记录',
'3': '邀约面试',
'4': '手动录入',
};
const columns: ProColumns<API.TalentCollect.ListRow>[] = [
{
title: '用户名',
dataIndex: 'name',
valueType: 'text',
align: 'center',
},
{
title: '联系方式',
dataIndex: 'phone',
valueType: 'text',
align: 'center',
},
{
title: '意向等级',
dataIndex: 'intentionLevel',
valueType: 'select',
align: 'center',
valueEnum: {
'1': '高意向',
'2': '中等意向',
'3': '低意向',
},
render: (_, record) => {
const info = intentionLevelMap[record.intentionLevel || ''];
if (!info) return '-';
return <Tag color={info.color}>{info.text}</Tag>;
},
},
{
title: '人才标签',
dataIndex: 'collectTags',
valueType: 'text',
align: 'center',
render: (_, record) => {
if (!record.collectTags) return '-';
const tags = record.collectTags.split(',').filter(Boolean);
return (
<>
{tags.map((tag) => (
<Tag key={tag} color="blue">
{tag.trim()}
</Tag>
))}
</>
);
},
},
{
title: '收藏来源',
dataIndex: 'sourceType',
valueType: 'select',
align: 'center',
valueEnum: {
'1': '简历搜索',
'2': '投递记录',
'3': '邀约面试',
'4': '手动录入',
},
render: (_, record) => sourceTypeMap[record.sourceType || ''] || '-',
},
{
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: 'createTime',
valueType: 'dateTime',
align: 'center',
hideInSearch: true,
},
{
title: '操作',
hideInSearch: true,
align: 'center',
dataIndex: 'userId',
width: 280,
render: (_, record) => [
<Button
type="link"
size="small"
key="resume"
icon={<FileTextOutlined />}
onClick={() => navigate(`/usermgmt/appuser/resume/${record.userId}?readOnly=1`)}
>
</Button>,
<Button
type="link"
size="small"
key="invite-interview"
icon={<SendOutlined />}
hidden={!access.hasPerms('cms:interview:add')}
onClick={() => {
setCurrentRow(record);
setInviteVisible(true);
}}
>
</Button>,
<Button
type="link"
size="small"
key="cancel-collect"
icon={<StarFilled style={{ color: '#faad14' }} />}
hidden={!access.hasPerms('cms:hrTalentCollect:remove')}
onClick={() => handleCancelCollect(record)}
>
</Button>,
],
},
];
return (
<Fragment>
<div style={{ width: '100%', float: 'right' }}>
<ProTable<API.TalentCollect.ListRow>
search={{ labelWidth: 'auto' }}
actionRef={actionRef}
formRef={formTableRef}
rowKey="id"
key="talentCollect"
columns={columns}
request={(params) => {
const { current, pageSize, ...searchParams } = params;
const filteredParams: Record<string, any> = {};
Object.keys(searchParams).forEach((key) => {
const val = (searchParams as any)[key];
if (val !== undefined && val !== null && val !== '') {
filteredParams[key] = val;
}
});
return getHrTalentCollectList({
pageNum: current,
pageSize,
...filteredParams,
}).then((res: any) => {
const result = {
data: res.rows,
total: res.total,
success: true,
};
return result;
});
}}
/>
<InterviewInvite
open={inviteVisible}
userId={currentRow?.userId}
userName={currentRow?.name}
companyId={currentRow?.companyId}
onClose={(needRefresh) => {
setInviteVisible(false);
setCurrentRow(undefined);
if (needRefresh) {
actionRef.current?.reload();
}
}}
/>
</div>
</Fragment>
);
}
export default TalentCollectList;