WEB/src/pages/Site/Shop/Layout.tsx

185 lines
5.8 KiB
TypeScript

import { sitecontrollerAll } from '@/servers/api/site';
import { EditOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { Outlet, history, request, useLocation, useParams } from '@umijs/max';
import { Button, Col, Menu, Row, Select, Spin, message } from 'antd';
import Sider from 'antd/es/layout/Sider';
import React, { useEffect, useState } from 'react';
import type { SiteItem } from '../List/index';
import EditSiteForm from './EditSiteForm';
const ShopLayout: React.FC = () => {
const [sites, setSites] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const { siteId } = useParams<{ siteId: string }>();
const location = useLocation();
const [editModalOpen, setEditModalOpen] = useState(false);
const [editingSite, setEditingSite] = useState<SiteItem & { areas: string[] } | null>(null);
const fetchSites = async () => {
try {
setEditingSiteLoading(true);
const { data = [] } = await sitecontrollerAll();
setSites(data);
if (!siteId && data.length > 0) {
history.replace(`/site/shop/${data[0].id}/products`);
}
} catch (error) {
console.error('Failed to fetch sites', error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchSites();
}, []);
const handleSiteChange = (value: number) => {
const currentPath = location.pathname;
const parts = currentPath.split('/');
if (parts.length >= 5) {
parts[3] = String(value);
history.push(parts.join('/'));
} else {
history.push(`/site/shop/${value}/products`);
}
};
const handleMenuClick = (e: { key: string }) => {
if (!siteId) return;
history.push(`/site/shop/${siteId}/${e.key}`);
};
const getSelectedKey = () => {
const parts = location.pathname.split('/');
if (parts.length >= 5) {
return parts[4];
}
return 'products';
};
if (loading) {
return (
<Spin
size="large"
style={{ display: 'flex', justifyContent: 'center', marginTop: 100 }}
/>
);
}
const handleFinish = async (values: any) => {
if (!editingSite) {
message.error('未找到要编辑的站点');
return false;
}
try {
await request(`/site/${editingSite.id}`, {
method: 'PUT',
data: values,
});
message.success('更新成功');
setEditModalOpen(false);
fetchSites(); // 重新获取站点列表以更新数据
return true;
} catch (error: any) {
message.error(error.message || '操作失败');
return false;
}
};
return (
<PageContainer header={{ title: null, breadcrumb: undefined }}>
<Row gutter={16} style={{ height: 'calc(100vh - 100px)' }}>
<Col span={4} style={{ height: '100%' }}>
<Sider
style={{ background: 'white', height: '100%', overflow: 'hidden' }}
>
<div style={{ padding: '0 10px 16px' }}>
<div
style={{
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: '4px'
}}
>
<Select
style={{ flex: 1 }}
placeholder="请选择店铺"
options={sites?.map?.((site) => ({
label: site.name,
value: site.id,
}))}
value={siteId ? Number(siteId) : undefined}
onChange={handleSiteChange}
showSearch
optionFilterProp="label"
/>
<Button
icon={<EditOutlined />}
onClick={() => {
const currentSite = sites.find(
(site) => site.id === Number(siteId),
);
if (currentSite) {
function normalizeEditing (site: SiteItem){
return {
...site,
areas: site.areas?.map(area=>area.code) || [],
}
}
setEditingSite(normalizeEditing(currentSite));
setEditModalOpen(true);
} else {
message.warning('请先选择一个店铺');
}
}}
/>
</div>
</div>
<div style={{ flex: 1, overflowY: 'auto' }}>
<Menu
mode="inline"
selectedKeys={[getSelectedKey()]}
onClick={handleMenuClick}
style={{ borderRight: 0 }}
items={[
{ key: 'products', label: '产品管理' },
{ key: 'orders', label: '订单管理' },
{ key: 'subscriptions', label: '订阅管理' },
{ key: 'media', label: '媒体管理' },
{ key: 'customers', label: '客户管理' },
{ key: 'reviews', label: '评论管理' },
{ key: 'webhooks', label: 'Webhooks管理' },
{ key: 'links', label: '链接管理' },
]}
/>
</div>
</Sider>
</Col>
<Col span={20} style={{ height: '100%', overflowY: 'auto' }}>
{siteId ? <Outlet /> : <div></div>}
</Col>
</Row>
<EditSiteForm
open={editModalOpen}
onOpenChange={(visible: boolean) => {
setEditModalOpen(visible);
if (!visible) {
setEditingSite(null);
}
}}
initialValues={editingSite}
isEdit={!!editingSite}
onFinish={handleFinish}
/>
</PageContainer>
);
};
export default ShopLayout;