2025-11-06 17:26:57 +08:00
|
|
|
import React, { Fragment, useRef, useState, useEffect } from 'react';
|
|
|
|
|
import { useAccess } from '@umijs/max';
|
|
|
|
|
import { getResumeList, getResumeDetail } from '@/services/resumeLibrary/resumeList';
|
|
|
|
|
import { Button, FormInstance, message } from 'antd';
|
|
|
|
|
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
|
|
|
|
|
import { EyeOutlined } from '@ant-design/icons';
|
|
|
|
|
import { getDictValueEnum } from '@/services/system/dict';
|
|
|
|
|
import DictTag from '@/components/DictTag';
|
|
|
|
|
import ResumeDetail from './detail';
|
|
|
|
|
|
|
|
|
|
function ResumeList() {
|
|
|
|
|
const access = useAccess();
|
|
|
|
|
|
|
|
|
|
const formTableRef = useRef<FormInstance>();
|
|
|
|
|
const actionRef = useRef<ActionType>();
|
|
|
|
|
|
|
|
|
|
const [currentRow, setCurrentRow] = useState<API.AppUser.ResumeItem>();
|
|
|
|
|
const [modalVisible, setModalVisible] = useState<boolean>(false);
|
|
|
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
|
|
|
|
|
|
|
|
// 字典枚举值
|
|
|
|
|
const [sexEnum, setSexEnum] = useState<any>([]);
|
|
|
|
|
const [educationEnum, setEducationEnum] = useState<any>([]);
|
|
|
|
|
const [politicalEnum, setPoliticalEnum] = useState<any>([]);
|
|
|
|
|
const [statusEnum, setStatusEnum] = useState<any>([]);
|
|
|
|
|
const [areaEnum, setAreaEnum] = useState<any>([]);
|
|
|
|
|
|
|
|
|
|
// 获取字典数据
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
getDictValueEnum('sys_user_sex', true).then((data) => {
|
|
|
|
|
setSexEnum(data);
|
|
|
|
|
});
|
|
|
|
|
getDictValueEnum('education', true, true).then((data) => {
|
|
|
|
|
setEducationEnum(data);
|
|
|
|
|
});
|
|
|
|
|
getDictValueEnum('political_affiliation', true, true).then((data) => {
|
|
|
|
|
setPoliticalEnum(data);
|
|
|
|
|
});
|
|
|
|
|
getDictValueEnum('enable_status', true).then((data) => {
|
|
|
|
|
setStatusEnum(data);
|
|
|
|
|
});
|
|
|
|
|
getDictValueEnum('area', true, true).then((data) => {
|
|
|
|
|
setAreaEnum(data);
|
|
|
|
|
});
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
// 查看详情
|
|
|
|
|
const handleViewDetail = async (userId: any) => {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const res = await getResumeDetail(userId);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
setCurrentRow(res.data);
|
|
|
|
|
setModalVisible(true);
|
|
|
|
|
} else {
|
|
|
|
|
message.error(res.msg);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
message.error('获取详情失败');
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const columns: ProColumns<API.AppUser.ResumeItem>[] = [
|
|
|
|
|
// {
|
|
|
|
|
// title: '用户ID',
|
|
|
|
|
// dataIndex: 'userId',
|
|
|
|
|
// valueType: 'text',
|
|
|
|
|
// align: 'center',
|
|
|
|
|
// hideInSearch: true,
|
|
|
|
|
// },
|
|
|
|
|
{
|
|
|
|
|
title: '姓名',
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
valueType: 'text',
|
|
|
|
|
align: 'center',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '性别',
|
|
|
|
|
dataIndex: 'sex',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
align: 'center',
|
|
|
|
|
valueEnum: sexEnum,
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
return <DictTag enums={sexEnum} value={record.sex} />;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '年龄',
|
|
|
|
|
dataIndex: 'age',
|
|
|
|
|
valueType: 'digit',
|
|
|
|
|
align: 'center',
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
},
|
2025-11-07 11:19:09 +08:00
|
|
|
{
|
|
|
|
|
title: '手机号',
|
|
|
|
|
dataIndex: 'phone',
|
|
|
|
|
valueType: 'text',
|
|
|
|
|
align: 'center',
|
|
|
|
|
},
|
|
|
|
|
|
2025-11-06 17:26:57 +08:00
|
|
|
{
|
|
|
|
|
title: '出生日期',
|
|
|
|
|
dataIndex: 'birthDate',
|
|
|
|
|
valueType: 'date',
|
|
|
|
|
align: 'center',
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '学历',
|
|
|
|
|
dataIndex: 'education',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
align: 'center',
|
|
|
|
|
valueEnum: educationEnum,
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
return <DictTag enums={educationEnum} value={record.education} />;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '政治面貌',
|
|
|
|
|
dataIndex: 'politicalAffiliation',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
align: 'center',
|
|
|
|
|
valueEnum: politicalEnum,
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
return <DictTag enums={politicalEnum} value={record.politicalAffiliation} />;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '地区',
|
|
|
|
|
dataIndex: 'area',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
align: 'center',
|
|
|
|
|
valueEnum: areaEnum,
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
return <DictTag enums={areaEnum} value={record.area} />;
|
|
|
|
|
},
|
|
|
|
|
},
|
2025-11-07 11:19:09 +08:00
|
|
|
{
|
|
|
|
|
title: '期望薪资',
|
|
|
|
|
align: 'center',
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<span>
|
|
|
|
|
{record.salaryMin} - {record.salaryMax}
|
|
|
|
|
</span>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
|
2025-11-06 17:26:57 +08:00
|
|
|
{
|
|
|
|
|
title: '状态',
|
|
|
|
|
dataIndex: 'status',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
align: 'center',
|
|
|
|
|
valueEnum: statusEnum,
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
return <DictTag enums={statusEnum} value={record.status} />;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '最后登录',
|
|
|
|
|
dataIndex: 'loginDate',
|
|
|
|
|
valueType: 'dateTime',
|
|
|
|
|
align: 'center',
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
align: 'center',
|
|
|
|
|
dataIndex: 'userId',
|
|
|
|
|
width: 120,
|
|
|
|
|
render: (userId, record) => (
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'center', gap: 8 }}>
|
|
|
|
|
<Button
|
|
|
|
|
type="link"
|
|
|
|
|
size="small"
|
|
|
|
|
key="view"
|
|
|
|
|
icon={<EyeOutlined />}
|
|
|
|
|
loading={loading}
|
2025-11-06 17:45:39 +08:00
|
|
|
hidden={!access.hasPerms('resumeLibrary:resumeList:view')}
|
2025-11-06 17:26:57 +08:00
|
|
|
onClick={() => handleViewDetail(userId)}
|
|
|
|
|
>
|
2025-12-02 14:05:46 +08:00
|
|
|
查看人才信息
|
2025-11-06 17:26:57 +08:00
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Fragment>
|
|
|
|
|
<div style={{ width: '100%', float: 'right' }}>
|
|
|
|
|
<ProTable<API.AppUser.ResumeItem>
|
|
|
|
|
actionRef={actionRef}
|
|
|
|
|
formRef={formTableRef}
|
|
|
|
|
rowKey="userId"
|
|
|
|
|
key="resumeIndex"
|
|
|
|
|
columns={columns}
|
|
|
|
|
search={{
|
|
|
|
|
labelWidth: 120,
|
|
|
|
|
}}
|
|
|
|
|
request={async (
|
|
|
|
|
params: API.AppUser.ListParams & {
|
|
|
|
|
pageSize?: number;
|
|
|
|
|
current?: number;
|
|
|
|
|
},
|
|
|
|
|
) => {
|
|
|
|
|
const res = await getResumeList({ ...params } as API.AppUser.ListParams);
|
|
|
|
|
return {
|
|
|
|
|
data: res.rows,
|
|
|
|
|
total: res.total,
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<ResumeDetail
|
|
|
|
|
open={modalVisible}
|
|
|
|
|
values={currentRow}
|
|
|
|
|
onCancel={() => {
|
|
|
|
|
setModalVisible(false);
|
|
|
|
|
setCurrentRow(undefined);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Fragment>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default ResumeList;
|