feat: 添加前端页面和业务说明书

refactor(server): 重构服务层代码结构
feat(server): 添加基础设施、跨境电商、AI决策等核心服务
docs: 完善前端业务说明书和开发进度文档
style: 格式化代码和文档
This commit is contained in:
2026-03-18 19:12:38 +08:00
parent c932a67be2
commit 6d0d2b6157
140 changed files with 23859 additions and 5833 deletions

View File

@@ -0,0 +1,281 @@
import React, { useState, useEffect } from 'react';
import { Table, Button, Input, Select, DatePicker, message, Card, Tabs } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined, PlayCircleOutlined, PauseCircleOutlined } from '@ant-design/icons';
const { Option } = Select;
const { RangePicker } = DatePicker;
const { Search } = Input;
const { TabPane } = Tabs;
interface Ad {
id: string;
name: string;
platform: string;
campaign: string;
status: 'active' | 'paused' | 'completed';
budget: number;
spend: number;
impressions: number;
clicks: number;
conversions: number;
roi: number;
startDate: string;
endDate: string;
}
const Ads: React.FC = () => {
const [ads, setAds] = useState<Ad[]>([]);
const [loading, setLoading] = useState(false);
const [filters, setFilters] = useState({
platform: '',
status: '',
search: '',
dateRange: null as any,
});
useEffect(() => {
fetchAds();
}, [filters]);
const fetchAds = async () => {
setLoading(true);
// 模拟API调用
setTimeout(() => {
const mockAds: Ad[] = [
{
id: '1',
name: 'Summer Sale',
platform: 'Facebook',
campaign: 'Summer Campaign',
status: 'active',
budget: 10000,
spend: 5000,
impressions: 100000,
clicks: 5000,
conversions: 250,
roi: 3.5,
startDate: '2026-06-01',
endDate: '2026-06-30',
},
{
id: '2',
name: 'Back to School',
platform: 'Google',
campaign: 'Back to School Campaign',
status: 'active',
budget: 15000,
spend: 8000,
impressions: 150000,
clicks: 7500,
conversions: 375,
roi: 4.0,
startDate: '2026-07-01',
endDate: '2026-08-31',
},
{
id: '3',
name: 'Holiday Special',
platform: 'Instagram',
campaign: 'Holiday Campaign',
status: 'paused',
budget: 20000,
spend: 10000,
impressions: 200000,
clicks: 10000,
conversions: 500,
roi: 3.0,
startDate: '2026-11-01',
endDate: '2026-12-31',
},
];
setAds(mockAds);
setLoading(false);
}, 500);
};
const handleStartAd = (id: string) => {
message.success('广告已启动');
fetchAds();
};
const handlePauseAd = (id: string) => {
message.success('广告已暂停');
fetchAds();
};
const handleEditAd = (id: string) => {
message.info('编辑广告功能开发中');
};
const handleDeleteAd = (id: string) => {
message.success('广告已删除');
fetchAds();
};
const columns = [
{
title: '广告名称',
dataIndex: 'name',
key: 'name',
},
{
title: '平台',
dataIndex: 'platform',
key: 'platform',
},
{
title: '活动',
dataIndex: 'campaign',
key: 'campaign',
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
render: (status: string) => {
const statusMap = {
active: '活跃',
paused: '暂停',
completed: '已完成',
};
return statusMap[status] || status;
},
},
{
title: '预算',
dataIndex: 'budget',
key: 'budget',
render: (budget: number) => `$${budget.toFixed(2)}`,
},
{
title: '支出',
dataIndex: 'spend',
key: 'spend',
render: (spend: number) => `$${spend.toFixed(2)}`,
},
{
title: '点击量',
dataIndex: 'clicks',
key: 'clicks',
},
{
title: '转化数',
dataIndex: 'conversions',
key: 'conversions',
},
{
title: 'ROI',
dataIndex: 'roi',
key: 'roi',
render: (roi: number) => `${roi.toFixed(2)}x`,
},
{
title: '操作',
key: 'action',
render: (_: any, record: Ad) => (
<div>
{record.status === 'active' ? (
<Button
type="link"
icon={<PauseCircleOutlined />}
onClick={() => handlePauseAd(record.id)}
>
</Button>
) : (
<Button
type="link"
icon={<PlayCircleOutlined />}
onClick={() => handleStartAd(record.id)}
>
</Button>
)}
<Button
type="link"
icon={<EditOutlined />}
onClick={() => handleEditAd(record.id)}
>
</Button>
<Button
type="link"
danger
icon={<DeleteOutlined />}
onClick={() => handleDeleteAd(record.id)}
>
</Button>
</div>
),
},
];
return (
<div className="ads">
<div className="page-header">
<h1>广</h1>
<Button
type="primary"
icon={<PlusOutlined />}
>
广
</Button>
</div>
<div className="filter-section" style={{ marginBottom: 24, display: 'flex', gap: 16, flexWrap: 'wrap' }}>
<Search
placeholder="搜索广告名称或活动"
style={{ width: 300 }}
onChange={(e) => setFilters({ ...filters, search: e.target.value })}
/>
<Select
placeholder="平台"
style={{ width: 120 }}
onChange={(value) => setFilters({ ...filters, platform: value })}
>
<Option value=""></Option>
<Option value="Facebook">Facebook</Option>
<Option value="Google">Google</Option>
<Option value="Instagram">Instagram</Option>
<Option value="TikTok">TikTok</Option>
</Select>
<Select
placeholder="状态"
style={{ width: 120 }}
onChange={(value) => setFilters({ ...filters, status: value })}
>
<Option value=""></Option>
<Option value="active"></Option>
<Option value="paused"></Option>
<Option value="completed"></Option>
</Select>
<RangePicker
style={{ width: 300 }}
onChange={(dates) => setFilters({ ...filters, dateRange: dates })}
/>
<Button
icon={<SearchOutlined />}
onClick={fetchAds}
>
</Button>
</div>
<Card title="广告列表">
<Table
columns={columns}
dataSource={ads}
loading={loading}
rowKey="id"
pagination={{
pageSize: 10,
showSizeChanger: true,
}}
/>
</Card>
</div>
);
};
export default Ads;