import React, { useCallback, useEffect, useRef, useState } from 'react'; import { history, useAccess } from '@umijs/max'; import { Button, Card, Descriptions, List, Tag, message, Modal, Space } from 'antd'; import { ActionType, ProTable } from '@ant-design/pro-components'; import { PlusOutlined, DeleteOutlined, FormOutlined } from '@ant-design/icons'; import type { OutdoorFairDictForm, OutdoorFairItem } from '@/services/jobportal/outdoorFair'; import { addOutdoorFairDictOption, updateOutdoorFair } from '@/services/jobportal/outdoorFair'; import { getVenueInfoList } from '@/services/jobportal/venueInfo'; import { getDictSelectOption } from '@/services/system/dict'; import { getParticipatingCompanies, addParticipatingCompany, removeParticipatingCompany, addJobForCompany, updateJobForCompany, removeJobFromCompany, } from '@/services/jobportal/outdoorFairDetail'; import EditModal from '@/pages/Jobfair/Outdoorfair/components/EditModal'; import CompanyAddModal from './CompanyAddModal'; import JobEditModal from './JobEditModal'; const OUTDOOR_FAIR_TYPE_DICT = 'outdoor_fair_type'; const OUTDOOR_FAIR_REGION_DICT = 'outdoor_fair_region'; interface Props { fairId: number; fairInfo: OutdoorFairItem; refreshKey?: number; onFairUpdate: () => void; } const FairInfoTab: React.FC = ({ fairId, fairInfo, refreshKey, onFairUpdate }) => { const access = useAccess(); const actionRef = useRef(); const [editModalOpen, setEditModalOpen] = useState(false); const [companyModalOpen, setCompanyModalOpen] = useState(false); const [jobModalOpen, setJobModalOpen] = useState(false); const [selectedCompany, setSelectedCompany] = useState(null); const [editingJob, setEditingJob] = useState(null); const [fairTypeOptions, setFairTypeOptions] = useState([]); const [regionOptions, setRegionOptions] = useState([]); const [venueOptions, setVenueOptions] = useState([]); const refreshEditModalOptions = useCallback(async () => { const [typeOptions, regionSelectOptions, venueRes] = await Promise.all([ getDictSelectOption(OUTDOOR_FAIR_TYPE_DICT), getDictSelectOption(OUTDOOR_FAIR_REGION_DICT), getVenueInfoList({ current: 1, pageSize: 999 }), ]); setFairTypeOptions(typeOptions); setRegionOptions(regionSelectOptions); if (venueRes.code === 200) { setVenueOptions( (venueRes.rows || []).map((item) => ({ label: item.venueName, value: item.id, venueAddress: item.venueAddress, floorCount: item.floorCount, })), ); } }, []); useEffect(() => { refreshEditModalOptions(); }, [refreshEditModalOptions]); useEffect(() => { actionRef.current?.reload(); }, [refreshKey]); const handleCreateDictOption = async (values: OutdoorFairDictForm) => { const res = await addOutdoorFairDictOption(values); if (res.code === 200) { await refreshEditModalOptions(); message.success('字典项新增成功'); return true; } message.error(res.msg || '字典项新增失败'); return false; }; const fairTypeColors: Record = { 综合类: 'blue', 校园招聘: 'green', 行业专场: 'orange', 高新技术专场: 'purple', 智能制造专场: 'cyan', 文旅专场: 'magenta', 其他: 'default', }; return (
{/* 基本信息卡片 */} } hidden={!access.hasPerms('cms:outdoorFair:edit')} onClick={() => setEditModalOpen(true)} > 编辑信息 } style={{ marginBottom: 16 }} > {fairInfo.title} {fairInfo.hostUnit} {fairInfo.fairType} {fairInfo.region} {fairInfo.venueId && fairInfo.venueName ? ( ) : ( '--' )} {fairInfo.address} {fairInfo.boothCount} {fairInfo.holdTime} {fairInfo.endTime} {fairInfo.applyStartTime} {fairInfo.applyEndTime} {fairInfo.onlineApply ? '是' : '否'} {/* 参会企业及岗位 */} } onClick={() => setCompanyModalOpen(true)}> 添加企业 } > { const res = await getParticipatingCompanies(fairId, { current: params.current, pageSize: params.pageSize, companyName: params.companyName, }); return { data: res.rows, total: res.total, success: true }; }} expandable={{ expandedRowRender: (record) => (
{record.jobList.length === 0 ? (

暂无岗位

) : ( ( { setEditingJob(job); setSelectedCompany(record); setJobModalOpen(true); }} > 编辑 , , ]} > 薪资 {job.minSalary}-{job.maxSalary}K {job.education} {job.experience} 招聘 {job.vacancies} 人 {job.status === 'active' ? '在招' : '已关闭'} } /> )} /> )}
), }} columns={[ { title: '企业名称', dataIndex: 'companyName', ellipsis: true }, { title: '行业', dataIndex: 'industry', width: 100, hideInSearch: true, render: (_, r: any) => {r.industry}, }, { title: '规模', dataIndex: 'scale', width: 110, hideInSearch: true }, { title: '联系人', dataIndex: 'contactPerson', width: 100, hideInSearch: true }, { title: '联系电话', dataIndex: 'contactPhone', width: 130, hideInSearch: true }, { title: '展位号', dataIndex: 'boothNumber', width: 80, hideInSearch: true, render: (_, r: any) => r.boothNumber || '--', }, { title: '岗位数', width: 80, hideInSearch: true, render: (_, r: any) => r.jobList?.length || 0, }, { title: '操作', valueType: 'option', width: 200, render: (_, record: any) => [ , , ], }, ]} />
{/* 编辑招聘会基本信息弹窗 */} setEditModalOpen(false)} onSubmit={async (values) => { const res = await updateOutdoorFair(values as any); if (res.code === 200) { message.success('修改成功'); setEditModalOpen(false); onFairUpdate(); } else { message.error(res.msg || '操作失败'); } }} /> {/* 添加企业弹窗 */} setCompanyModalOpen(false)} onSuccess={() => { setCompanyModalOpen(false); actionRef.current?.reload(); }} /> {/* 添加/编辑岗位弹窗 */} { setJobModalOpen(false); setEditingJob(null); setSelectedCompany(null); }} onSuccess={() => { setJobModalOpen(false); setEditingJob(null); actionRef.current?.reload(); }} />
); }; export default FairInfoTab;