163 lines
7.3 KiB
TypeScript
163 lines
7.3 KiB
TypeScript
|
|
import React, { useState } from 'react';
|
|||
|
|
import { Modal, Tag, Space, Card, Row, Col, Button, message } from 'antd';
|
|||
|
|
import { CloseOutlined, CheckOutlined } from '@ant-design/icons';
|
|||
|
|
import type { VenueItem } from '@/services/jobportal/indoorJobFair';
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
venue: VenueItem | null;
|
|||
|
|
open: boolean;
|
|||
|
|
onClose: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const VENUE_LAYOUT_DATA = [
|
|||
|
|
// A区
|
|||
|
|
{ id: 1, area: 'A', row: 1, col: 1, boothNumber: 'A01', status: 'reserved', companyName: '新疆天业(集团)有限公司' },
|
|||
|
|
{ id: 2, area: 'A', row: 1, col: 2, boothNumber: 'A02', status: 'fixed', companyName: '石河子经济技术开发区管委会' },
|
|||
|
|
{ id: 3, area: 'A', row: 1, col: 3, boothNumber: 'A03', status: 'available', companyName: '' },
|
|||
|
|
{ id: 4, area: 'A', row: 1, col: 4, boothNumber: 'A04', status: 'reserved', companyName: '新疆西部牧业股份有限公司' },
|
|||
|
|
{ id: 5, area: 'A', row: 2, col: 1, boothNumber: 'A05', status: 'available', companyName: '' },
|
|||
|
|
{ id: 6, area: 'A', row: 2, col: 2, boothNumber: 'A06', status: 'locked', companyName: '' },
|
|||
|
|
{ id: 7, area: 'A', row: 2, col: 3, boothNumber: 'A07', status: 'available', companyName: '' },
|
|||
|
|
{ id: 8, area: 'A', row: 2, col: 4, boothNumber: 'A08', status: 'reserved', companyName: '兵团水利水电工程集团' },
|
|||
|
|
// B区
|
|||
|
|
{ id: 9, area: 'B', row: 1, col: 1, boothNumber: 'B01', status: 'available', companyName: '' },
|
|||
|
|
{ id: 10, area: 'B', row: 1, col: 2, boothNumber: 'B02', status: 'fixed', companyName: '阿拉尔新爵纺织有限公司' },
|
|||
|
|
{ id: 11, area: 'B', row: 1, col: 3, boothNumber: 'B03', status: 'locked', companyName: '' },
|
|||
|
|
{ id: 12, area: 'B', row: 1, col: 4, boothNumber: 'B04', status: 'available', companyName: '' },
|
|||
|
|
{ id: 13, area: 'B', row: 2, col: 1, boothNumber: 'B05', status: 'reserved', companyName: '新疆通用航空有限责任公司' },
|
|||
|
|
{ id: 14, area: 'B', row: 2, col: 2, boothNumber: 'B06', status: 'available', companyName: '' },
|
|||
|
|
{ id: 15, area: 'B', row: 2, col: 3, boothNumber: 'B07', status: 'reserved', companyName: '石河子市商业银行' },
|
|||
|
|
{ id: 16, area: 'B', row: 2, col: 4, boothNumber: 'B08', status: 'available', companyName: '' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const statusMap: Record<string, { text: string; color: string }> = {
|
|||
|
|
available: { text: '可用', color: '#52c41a' },
|
|||
|
|
fixed: { text: '固定', color: '#1890ff' },
|
|||
|
|
reserved: { text: '预留', color: '#fa8c16' },
|
|||
|
|
locked: { text: '锁定', color: '#ff4d4f' },
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const VenueLayoutModal: React.FC<Props> = ({ venue, open, onClose }) => {
|
|||
|
|
const [selectedBooth, setSelectedBooth] = useState<typeof VENUE_LAYOUT_DATA[0] | null>(null);
|
|||
|
|
|
|||
|
|
if (!venue) return null;
|
|||
|
|
|
|||
|
|
const areas = ['A', 'B'];
|
|||
|
|
|
|||
|
|
const handleBoothClick = (booth: typeof VENUE_LAYOUT_DATA[0]) => {
|
|||
|
|
setSelectedBooth(booth);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const getBoothStyle = (status: string) => {
|
|||
|
|
switch (status) {
|
|||
|
|
case 'available':
|
|||
|
|
return { backgroundColor: '#f6ffed', borderColor: '#52c41a' };
|
|||
|
|
case 'fixed':
|
|||
|
|
return { backgroundColor: '#e6f7ff', borderColor: '#1890ff' };
|
|||
|
|
case 'reserved':
|
|||
|
|
return { backgroundColor: '#fff7e6', borderColor: '#fa8c16' };
|
|||
|
|
case 'locked':
|
|||
|
|
return { backgroundColor: '#fff1f0', borderColor: '#ff4d4f' };
|
|||
|
|
default:
|
|||
|
|
return {};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Modal
|
|||
|
|
title={`场地布局 - ${venue.venueName}`}
|
|||
|
|
open={open}
|
|||
|
|
onCancel={onClose}
|
|||
|
|
footer={null}
|
|||
|
|
width={900}
|
|||
|
|
destroyOnClose
|
|||
|
|
>
|
|||
|
|
<div style={{ marginBottom: 16 }}>
|
|||
|
|
<Space>
|
|||
|
|
<Tag color="#52c41a">可用</Tag>
|
|||
|
|
<Tag color="#1890ff">固定</Tag>
|
|||
|
|
<Tag color="#fa8c16">预留</Tag>
|
|||
|
|
<Tag color="#ff4d4f">锁定</Tag>
|
|||
|
|
</Space>
|
|||
|
|
<span style={{ marginLeft: 24, color: '#888' }}>
|
|||
|
|
共 {venue.boothCount} 个展位 | 已使用 {VENUE_LAYOUT_DATA.filter(b => b.status !== 'available').length} 个 | 可用 {VENUE_LAYOUT_DATA.filter(b => b.status === 'available').length} 个
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<Row gutter={16}>
|
|||
|
|
<Col span={16}>
|
|||
|
|
<Card size="small" title="平面布局图" style={{ marginBottom: 16 }}>
|
|||
|
|
{areas.map((area) => (
|
|||
|
|
<div key={area} style={{ marginBottom: 16 }}>
|
|||
|
|
<div style={{ fontWeight: 'bold', marginBottom: 8 }}>【{area}区】</div>
|
|||
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
|
|||
|
|
{VENUE_LAYOUT_DATA.filter(b => b.area === area).map((booth) => (
|
|||
|
|
<div
|
|||
|
|
key={booth.id}
|
|||
|
|
onClick={() => handleBoothClick(booth)}
|
|||
|
|
style={{
|
|||
|
|
...getBoothStyle(booth.status),
|
|||
|
|
border: '1px solid',
|
|||
|
|
borderRadius: 4,
|
|||
|
|
padding: '8px 4px',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
cursor: 'pointer',
|
|||
|
|
minHeight: 60,
|
|||
|
|
display: 'flex',
|
|||
|
|
flexDirection: 'column',
|
|||
|
|
justifyContent: 'center',
|
|||
|
|
alignItems: 'center',
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
<div style={{ fontSize: 12, fontWeight: 'bold' }}>{booth.boothNumber}</div>
|
|||
|
|
{booth.companyName ? (
|
|||
|
|
<div style={{ fontSize: 10, color: '#666', marginTop: 2, maxWidth: 80, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
|||
|
|
{booth.companyName}
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div style={{ fontSize: 10, color: '#999' }}>{statusMap[booth.status].text}</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
|
|||
|
|
<Col span={8}>
|
|||
|
|
<Card size="small" title="展位详情">
|
|||
|
|
{selectedBooth ? (
|
|||
|
|
<div>
|
|||
|
|
<p><strong>展位号:</strong>{selectedBooth.boothNumber}</p>
|
|||
|
|
<p><strong>状态:</strong><Tag color={statusMap[selectedBooth.status].color}>{statusMap[selectedBooth.status].text}</Tag></p>
|
|||
|
|
<p><strong>区域:</strong>{selectedBooth.area}区 {selectedBooth.row}排 {selectedBooth.col}列</p>
|
|||
|
|
<p><strong>企业名称:</strong>{selectedBooth.companyName || '--'}</p>
|
|||
|
|
<Space style={{ marginTop: 16 }}>
|
|||
|
|
<Button size="small" icon={<CheckOutlined />}>设为固定</Button>
|
|||
|
|
<Button size="small" icon={<CloseOutlined />}>设为锁定</Button>
|
|||
|
|
</Space>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div style={{ color: '#999', textAlign: 'center', padding: 20 }}>
|
|||
|
|
点击左侧展位查看详情
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</Card>
|
|||
|
|
|
|||
|
|
<Card size="small" title="场地信息" style={{ marginTop: 16 }}>
|
|||
|
|
<p><strong>场地名称:</strong>{venue.venueName}</p>
|
|||
|
|
<p><strong>就业机构:</strong>{venue.employmentAgency}</p>
|
|||
|
|
<p><strong>场地类型:</strong>{venue.venueType}</p>
|
|||
|
|
<p><strong>场地地址:</strong>{venue.venueAddress}</p>
|
|||
|
|
<p><strong>联系人:</strong>{venue.contactPerson}</p>
|
|||
|
|
<p><strong>联系电话:</strong>{venue.contactPhone}</p>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
</Row>
|
|||
|
|
</Modal>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default VenueLayoutModal;
|