- Added `react-rnd` for draggable booth positioning in the booth management interface. - Implemented booth booking, cancellation, and swapping features. - Updated `BoothTab` component to fetch and display booth data with enhanced UI for booth interactions. - Introduced modal dialogs for booking and managing booth assignments. - Enhanced venue information service to support booth-related API calls. - Updated `VenueInfoDetail` to allow for booth layout management and generation. - Improved overall user experience with better state management and loading indicators.
258 lines
7.2 KiB
TypeScript
258 lines
7.2 KiB
TypeScript
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
import { history, useAccess, useModel } from '@umijs/max';
|
|
import { Button, message, Modal } from 'antd';
|
|
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
|
|
import { AppstoreOutlined, DeleteOutlined, FormOutlined, PlusOutlined } from '@ant-design/icons';
|
|
import {
|
|
addVenueInfo,
|
|
addVenueInfoDictOption,
|
|
deleteVenueInfo,
|
|
getVenueInfoList,
|
|
updateVenueInfo,
|
|
} from '@/services/jobportal/venueInfo';
|
|
import type {
|
|
VenueInfoDictForm,
|
|
VenueInfoForm,
|
|
VenueInfoItem,
|
|
VenueInfoListParams,
|
|
} from '@/services/jobportal/venueInfo';
|
|
import { getCmsLineList } from '@/services/area/subway';
|
|
import { getDictSelectOption, getDictValueEnum } from '@/services/system/dict';
|
|
import EditModal from './components/EditModal';
|
|
|
|
const VENUE_TYPE_DICT = 'venue_info_type';
|
|
|
|
const VenueInfoList: React.FC = () => {
|
|
const access = useAccess();
|
|
const { initialState } = useModel('@@initialState');
|
|
const actionRef = useRef<ActionType>();
|
|
const [modalVisible, setModalVisible] = useState(false);
|
|
const [currentRow, setCurrentRow] = useState<VenueInfoItem>();
|
|
const [venueTypeValueEnum, setVenueTypeValueEnum] = useState<Record<string, any>>({});
|
|
const [venueTypeOptions, setVenueTypeOptions] = useState<any[]>([]);
|
|
const [lineOptions, setLineOptions] = useState<any[]>([]);
|
|
|
|
const defaultHandler =
|
|
initialState?.currentUser?.nickName || initialState?.currentUser?.userName || undefined;
|
|
|
|
const refreshVenueTypeOptions = useCallback(async () => {
|
|
const [valueEnum, options] = await Promise.all([
|
|
getDictValueEnum(VENUE_TYPE_DICT),
|
|
getDictSelectOption(VENUE_TYPE_DICT),
|
|
]);
|
|
setVenueTypeValueEnum(valueEnum);
|
|
setVenueTypeOptions(options);
|
|
}, []);
|
|
|
|
const refreshLineOptions = useCallback(async () => {
|
|
const res = await getCmsLineList({ current: '1', pageSize: '999' } as any);
|
|
if (res.code === 200) {
|
|
setLineOptions(
|
|
(res.rows || []).map((item) => ({
|
|
label: item.lineName,
|
|
value: String(item.lineId),
|
|
})),
|
|
);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
refreshVenueTypeOptions();
|
|
refreshLineOptions();
|
|
}, [refreshVenueTypeOptions, refreshLineOptions]);
|
|
|
|
const handleCreateDictOption = async (values: VenueInfoDictForm) => {
|
|
const res = await addVenueInfoDictOption(values);
|
|
if (res.code === 200) {
|
|
await refreshVenueTypeOptions();
|
|
message.success('场地类型新增成功');
|
|
return true;
|
|
}
|
|
message.error(res.msg || '场地类型新增失败');
|
|
return false;
|
|
};
|
|
|
|
const handleDelete = async (id: number) => {
|
|
Modal.confirm({
|
|
title: '确认删除',
|
|
content: '确定要删除该场地信息吗?',
|
|
onOk: async () => {
|
|
const res = await deleteVenueInfo(id);
|
|
if (res.code === 200) {
|
|
message.success('删除成功');
|
|
actionRef.current?.reload();
|
|
} else {
|
|
message.error(res.msg || '删除失败');
|
|
}
|
|
},
|
|
});
|
|
};
|
|
|
|
const columns: ProColumns<VenueInfoItem>[] = [
|
|
{
|
|
title: '场地类型',
|
|
dataIndex: 'venueType',
|
|
ellipsis: true,
|
|
valueType: 'select',
|
|
valueEnum: venueTypeValueEnum,
|
|
},
|
|
{
|
|
title: '场地名称',
|
|
dataIndex: 'venueName',
|
|
ellipsis: true,
|
|
},
|
|
{
|
|
title: '场地面积',
|
|
dataIndex: 'venueArea',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '展位数量',
|
|
dataIndex: 'floorCount',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '场地地址',
|
|
dataIndex: 'venueAddress',
|
|
ellipsis: true,
|
|
},
|
|
{
|
|
title: '联系电话',
|
|
dataIndex: 'contactPhone',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '乘坐线路',
|
|
dataIndex: 'routeLineNames',
|
|
ellipsis: true,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '经办日期',
|
|
dataIndex: 'handleDate',
|
|
valueType: 'date',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '经办机构',
|
|
dataIndex: 'handleOrg',
|
|
ellipsis: true,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '经办人',
|
|
dataIndex: 'handler',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '备注',
|
|
dataIndex: 'remark',
|
|
ellipsis: true,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '操作',
|
|
valueType: 'option',
|
|
width: 220,
|
|
fixed: 'right',
|
|
render: (_, record) => [
|
|
<Button
|
|
key="boothMap"
|
|
type="link"
|
|
size="small"
|
|
icon={<AppstoreOutlined />}
|
|
hidden={!access.hasPerms('cms:venueInfo:query')}
|
|
onClick={() => history.push(`/jobfair/venue-info/detail?id=${record.id}`)}
|
|
>
|
|
展位图
|
|
</Button>,
|
|
<Button
|
|
key="edit"
|
|
type="link"
|
|
size="small"
|
|
icon={<FormOutlined />}
|
|
hidden={!access.hasPerms('cms:venueInfo:edit')}
|
|
onClick={() => {
|
|
setCurrentRow(record);
|
|
setModalVisible(true);
|
|
}}
|
|
>
|
|
编辑
|
|
</Button>,
|
|
<Button
|
|
key="delete"
|
|
type="link"
|
|
size="small"
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
hidden={!access.hasPerms('cms:venueInfo:remove')}
|
|
onClick={() => handleDelete(record.id)}
|
|
>
|
|
删除
|
|
</Button>,
|
|
],
|
|
},
|
|
];
|
|
|
|
return (
|
|
<PageContainer>
|
|
<ProTable<VenueInfoItem>
|
|
headerTitle="场地信息维护列表"
|
|
actionRef={actionRef}
|
|
rowKey="id"
|
|
columns={columns}
|
|
scroll={{ x: 'max-content' }}
|
|
request={async (params) => {
|
|
const res = await getVenueInfoList({
|
|
current: params.current,
|
|
pageSize: params.pageSize,
|
|
venueType: params.venueType,
|
|
venueName: params.venueName,
|
|
venueAddress: params.venueAddress,
|
|
} as VenueInfoListParams);
|
|
return { data: res.rows, total: res.total, success: true };
|
|
}}
|
|
toolBarRender={() => [
|
|
<Button
|
|
key="add"
|
|
type="primary"
|
|
icon={<PlusOutlined />}
|
|
hidden={!access.hasPerms('cms:venueInfo:add')}
|
|
onClick={() => {
|
|
setCurrentRow(undefined);
|
|
setModalVisible(true);
|
|
}}
|
|
>
|
|
新增
|
|
</Button>,
|
|
]}
|
|
/>
|
|
<EditModal
|
|
open={modalVisible}
|
|
values={currentRow}
|
|
venueTypeOptions={venueTypeOptions}
|
|
lineOptions={lineOptions}
|
|
defaultHandler={defaultHandler}
|
|
onCreateDictOption={handleCreateDictOption}
|
|
onCancel={() => {
|
|
setModalVisible(false);
|
|
setCurrentRow(undefined);
|
|
}}
|
|
onSubmit={async (values: VenueInfoForm) => {
|
|
const res = values.id ? await updateVenueInfo(values) : await addVenueInfo(values);
|
|
if (res.code === 200) {
|
|
message.success(values.id ? '修改成功' : '新增成功');
|
|
setModalVisible(false);
|
|
setCurrentRow(undefined);
|
|
actionRef.current?.reload();
|
|
} else {
|
|
message.error(res.msg || '操作失败');
|
|
}
|
|
}}
|
|
/>
|
|
</PageContainer>
|
|
);
|
|
};
|
|
|
|
export default VenueInfoList;
|