Files
shz-admin/src/pages/Jobfair/PublicJobFair/index.tsx
lapuda 4db3255997
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
CodeQL / Analyze (javascript) (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
feat: 完善招聘会统计页面
2026-07-24 09:46:54 +08:00

395 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useRef, useState, useEffect } from 'react';
import { useAccess, history } from '@umijs/max';
import { Button, FormInstance, message, Modal, Tag } from 'antd';
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import {
PlusOutlined,
DeleteOutlined,
FormOutlined,
ExportOutlined,
EyeOutlined,
} from '@ant-design/icons';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import {
getPublicJobFairList,
getPublicJobFairDetail,
signupPublicJobFair,
addPublicJobFair,
updatePublicJobFair,
deletePublicJobFair,
exportPublicJobFair,
} from '@/services/jobfair/publicJobFair';
import EditModal from './components/EditModal';
import CompanyJobManageModal from './components/CompanyJobManageModal';
import FairExportModal from '../components/FairExportModal';
import type { RecruitmentFairExportParams } from '@/services/jobfair/recruitmentFairExport';
const PublicJobFairList: React.FC = () => {
const access = useAccess();
const isEnterprise = Boolean(access.isEnterprise);
const formRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const [modalVisible, setModalVisible] = useState(false);
const [currentRow, setCurrentRow] = useState<API.PublicJobFair.JobFairItem>();
const [companyJobModalOpen, setCompanyJobModalOpen] = useState(false);
const [currentJobFair, setCurrentJobFair] = useState<API.PublicJobFair.JobFairItem>();
const [jobFairTypeEnum, setJobFairTypeEnum] = useState<any>({});
const [jobFairRegionTypeEnum, setJobFairRegionTypeEnum] = useState<any>({});
const [yesNoEnum, setYesNoEnum] = useState<any>({});
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const [exportModalOpen, setExportModalOpen] = useState(false);
useEffect(() => {
getDictValueEnum('job_fair_type', true).then(setJobFairTypeEnum);
getDictValueEnum('job_fair_region_type').then(setJobFairRegionTypeEnum);
getDictValueEnum('sys_yes_no').then(setYesNoEnum);
}, []);
const handleDelete = async (ids: string) => {
Modal.confirm({
title: '确认删除',
content: '确定要删除选中的招聘会吗?',
onOk: async () => {
const res = await deletePublicJobFair(ids);
if (res.code === 200) {
message.success('删除成功');
actionRef.current?.reload();
setSelectedRowKeys([]);
} else {
message.error(res.msg || '删除失败');
}
},
});
};
const handleSignup = (record: API.PublicJobFair.JobFairItem) => {
Modal.confirm({
title: '报名线上招聘会',
content: `确定报名「${record.jobFairTitle}」吗?报名后需要等待管理员审核。`,
onOk: async () => {
const res = await signupPublicJobFair(record.jobFairId);
if (res.code === 200) {
message.success('报名成功,请等待管理员审核');
actionRef.current?.reload();
} else {
message.error(res.msg || '报名失败');
}
},
});
};
const handleExport = async (params: RecruitmentFairExportParams) => {
message.loading('正在导出...');
try {
await exportPublicJobFair(params);
message.success('导出成功');
setExportModalOpen(false);
} catch {
message.error('导出失败');
}
};
const dictOptions = (valueEnum: Record<string, any>) =>
Object.entries(valueEnum).map(([value, item]) => ({
value,
label: item?.text || item?.label || value,
}));
const columns: ProColumns<API.PublicJobFair.JobFairItem>[] = [
{
title: '时间范围',
dataIndex: 'dateRange',
hideInTable: true,
valueType: 'dateRange',
fieldProps: {
format: 'YYYY-MM-DD',
},
search: {
transform: (value) => ({
startDate: value[0],
endDate: value[1],
}),
},
},
{
title: '招聘会标题',
dataIndex: 'jobFairTitle',
ellipsis: true,
},
{
title: '地址',
dataIndex: 'jobFairAddress',
hideInSearch: true,
ellipsis: true,
},
/* 暂时隐藏线上招聘会列表中的招聘会类型字段,保留原实现便于后续恢复。
{
title: '类型',
dataIndex: 'jobFairType',
valueType: 'select',
valueEnum: jobFairTypeEnum,
render: (_, record) => <DictTag enums={jobFairTypeEnum} value={record.jobFairType} />,
},
*/
{
title: '区域类型',
dataIndex: 'jobFairRegionType',
valueType: 'select',
valueEnum: jobFairRegionTypeEnum,
render: (_, record) => (
<DictTag enums={jobFairRegionTypeEnum} value={record.jobFairRegionType} />
),
},
{
title: '举办状态',
dataIndex: 'jobFairStatus',
hideInSearch: true,
render: (_, record) => {
const status = record.jobFairStatus;
if (!status) return '-';
const color = status === '未举办' ? 'blue' : status === '正在举办' ? 'green' : 'default';
return <Tag color={color}>{status}</Tag>;
},
},
{
title: '报名审核状态',
dataIndex: 'enterpriseReviewStatus',
hideInSearch: true,
hideInTable: !isEnterprise,
render: (_, record) => {
if (record.isSignUp === undefined) return '-';
if (record.isSignUp !== '1') return <Tag></Tag>;
const statusMap: Record<string, { text: string; color: string }> = {
'0': { text: '待审核', color: 'gold' },
'1': { text: '已通过', color: 'green' },
'2': { text: '已驳回', color: 'red' },
};
const status = statusMap[record.enterpriseReviewStatus || '0'] || statusMap['0'];
return (
<span>
<Tag color={status.color}>{status.text}</Tag>
{record.enterpriseReviewComments && (
<span title={record.enterpriseReviewComments} style={{ color: '#999' }}>
</span>
)}
</span>
);
},
},
{
title: '是否跨域',
dataIndex: 'isCrossDomain',
valueType: 'select',
valueEnum: yesNoEnum,
render: (_, record) => <DictTag enums={yesNoEnum} value={record.isCrossDomain} />,
},
{
title: '开始时间',
dataIndex: 'jobFairStartTime',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '结束时间',
dataIndex: 'jobFairEndTime',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '创建时间',
dataIndex: 'createTime',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '操作',
valueType: 'option',
width: 360,
fixed: 'right',
render: (_, record) => {
const canViewDetail = !isEnterprise && access.hasPerms('cms:publicJobFair:query');
const canSignUp =
isEnterprise &&
access.hasPerms('cms:publicJobFair:signup') &&
(record.canSignUp ?? (record.isSignUp !== '1' || record.enterpriseReviewStatus === '2'));
const canEditCompanyJobs =
isEnterprise &&
access.hasPerms('cms:publicJobFair:job:edit') &&
(record.canEditJobs ?? record.enterpriseReviewStatus === '1');
return [
canViewDetail && (
<Button
key="detail"
type="link"
size="small"
icon={<EyeOutlined />}
onClick={() => history.push(`/jobfair/public-job-fair/detail?id=${record.jobFairId}`)}
>
</Button>
),
canSignUp && (
<Button
key="signup"
type="link"
size="small"
icon={<PlusOutlined />}
onClick={() => handleSignup(record)}
>
</Button>
),
canEditCompanyJobs && (
<Button
key="companyJobs"
type="link"
size="small"
icon={<FormOutlined />}
onClick={() => {
setCurrentJobFair(record);
setCompanyJobModalOpen(true);
}}
>
</Button>
),
<Button
key="edit"
type="link"
size="small"
icon={<FormOutlined />}
hidden={!access.hasPerms('cms:publicJobFair:edit')}
onClick={async () => {
const res = await getPublicJobFairDetail(record.jobFairId);
if (res.code === 200) {
setCurrentRow(res.data);
setModalVisible(true);
}
}}
>
</Button>,
<Button
key="delete"
type="link"
size="small"
danger
icon={<DeleteOutlined />}
hidden={!access.hasPerms('cms:publicJobFair:remove')}
onClick={() => handleDelete(record.jobFairId)}
>
</Button>,
];
},
},
];
return (
<PageContainer>
<ProTable<API.PublicJobFair.JobFairItem>
headerTitle="公共招聘会列表"
actionRef={actionRef}
formRef={formRef}
rowKey="jobFairId"
columns={columns}
scroll={{ x: 'max-content' }}
rowSelection={{
selectedRowKeys,
onChange: setSelectedRowKeys,
}}
request={async (params) => {
const res = await getPublicJobFairList({
pageNum: params.current,
pageSize: params.pageSize,
jobFairTitle: params.jobFairTitle,
jobFairType: params.jobFairType,
jobFairRegionType: params.jobFairRegionType,
startDate: params.startDate,
endDate: params.endDate,
});
return { data: res.rows, total: res.total, success: true };
}}
toolBarRender={() => [
<Button
key="add"
type="primary"
icon={<PlusOutlined />}
hidden={!access.hasPerms('cms:publicJobFair:add')}
onClick={() => {
setCurrentRow(undefined);
setModalVisible(true);
}}
>
</Button>,
selectedRowKeys.length > 0 && (
<Button
key="batchDelete"
danger
icon={<DeleteOutlined />}
hidden={!access.hasPerms('cms:publicJobFair:remove')}
onClick={() => handleDelete(selectedRowKeys.join(','))}
>
</Button>
),
<Button
key="export"
icon={<ExportOutlined />}
hidden={!access.hasPerms('cms:publicJobFair:export')}
onClick={() => setExportModalOpen(true)}
>
</Button>,
]}
/>
<EditModal
open={modalVisible}
values={currentRow}
jobFairTypeEnum={jobFairTypeEnum}
jobFairRegionTypeEnum={jobFairRegionTypeEnum}
onCancel={() => {
setModalVisible(false);
setCurrentRow(undefined);
}}
onSubmit={async (values) => {
const res = values.jobFairId
? await updatePublicJobFair(values)
: await addPublicJobFair(values);
if (res.code === 200) {
message.success(values.jobFairId ? '修改成功' : '新增成功');
setModalVisible(false);
setCurrentRow(undefined);
actionRef.current?.reload();
} else {
message.error(res.msg || '操作失败');
}
}}
/>
<CompanyJobManageModal
open={companyJobModalOpen}
jobFairId={currentJobFair?.jobFairId || ''}
jobFairTitle={currentJobFair?.jobFairTitle}
onCancel={() => {
setCompanyJobModalOpen(false);
setCurrentJobFair(undefined);
}}
/>
<FairExportModal
open={exportModalOpen}
channel="online"
fairTypeOptions={dictOptions(jobFairTypeEnum)}
regionOptions={dictOptions(jobFairRegionTypeEnum)}
onCancel={() => setExportModalOpen(false)}
onExport={handleExport}
/>
</PageContainer>
);
};
export default PublicJobFairList;