求职者管理增加收藏功能、面试邀请、人才库功能开发
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled

This commit is contained in:
francis-fh
2026-07-16 19:34:40 +08:00
parent e4c413baad
commit 03a0f7fd29
7 changed files with 527 additions and 2 deletions

View File

@@ -0,0 +1,212 @@
import React, { Fragment, useEffect, useRef, useState } from 'react';
import { useAccess } from '@umijs/max';
import { Button, FormInstance, message, Tag } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { StarFilled } from '@ant-design/icons';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import { delHrTalentCollect, getHrTalentCollectList } from '@/services/mobileusers/list';
function TalentCollectList() {
const access = useAccess();
const formTableRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const [educationEnum, setEducationEnum] = useState<any>({});
const [areaEnum, setAreaEnum] = useState<any>({});
const [sexEnum, setSexEnum] = useState<any>({});
useEffect(() => {
getDictValueEnum('education', true, true).then((data) => setEducationEnum(data));
getDictValueEnum('area', true, true).then((data) => setAreaEnum(data));
getDictValueEnum('sys_user_sex', false).then((data) => setSexEnum(data));
}, []);
// 取消收藏
const handleCancelCollect = async (record: API.TalentCollect.ListRow) => {
if (!record.userId) return;
try {
const res = await delHrTalentCollect(String(record.userId));
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: 120,
render: (_, record) => [
<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;
});
}}
/>
</div>
</Fragment>
);
}
export default TalentCollectList;