+ {/* 搜索和筛选 */}
+ {/* 任务列表 */}
- {isLoading ? (
-
加载中...
- ) : filteredTasks.length > 0 ? (
+ {filteredTasks.length === 0 ? (
+
+
+ 暂无建群任务
+ 创建您的第一个自动建群任务
+
+
+ ) : (
filteredTasks.map((task) => (
{task.name}
-
- {task.status === 1 ? '运行中' : '已暂停'}
+
+ {getStatusText(task.status)}
-
toggleTaskStatus(task.id, task.status)} />
+ toggleTaskStatus(task.id)}
+ disabled={task.status === 'completed'}
+ />
-
-
-
-
目标人群:{task.config.targetGroups.join(', ')}
+
+
+
+ 上次建群:{task.lastCreateTime}
+
+
+ 创建时间:{task.createTime}
+
+
+
+
+ {expandedTaskId === task.id && (
+
+
+
+
+
+
基本设置
+
+
+
+ 建群间隔:
+ {task.createInterval} 秒
+
+
+ 每日最大建群数:
+ {task.maxGroupsPerDay} 个
+
+
+ 执行时间段:
+
+ {task.timeRange.start} - {task.timeRange.end}
+
+
+
+ 群组规模:
+ {task.groupSize.min}-{task.groupSize.max} 人
+
+
+
+
+
+
+
+
目标人群
+
+
+
+ {task.targetTags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+
+
+
+
+
群组设置
+
+
+
+
群名称模板:
+
+ {task.groupNameTemplate}
+
+
+
+
群描述:
+
+ {task.groupDescription}
-
- ))
- ) : (
-
- {searchQuery ? '没有找到匹配的任务' : '暂无建群任务'}
- )}
- {/* 分页 */}
- {total > pageSize && (
-
-
-
-
第 {currentPage} 页
-
共 {Math.ceil(total / pageSize)} 页
+
+
+
+
执行进度
+
+
+
+ 今日已建群:
+
+ {task.createdGroups} / {task.maxGroupsPerDay}
+
+
+
+
+
+
-
+ )}
+
+ ))
+ )}
- )}
+
-
+
);
}
\ No newline at end of file
diff --git a/nkebao/src/pages/workspace/auto-like/AutoLike.tsx b/nkebao/src/pages/workspace/auto-like/AutoLike.tsx
index 9de1ba0b..f529b49f 100644
--- a/nkebao/src/pages/workspace/auto-like/AutoLike.tsx
+++ b/nkebao/src/pages/workspace/auto-like/AutoLike.tsx
@@ -1,16 +1,20 @@
-import React, { useState, useEffect } from 'react';
-import { useNavigate, Link } from 'react-router-dom';
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
import {
Plus,
Filter,
Search,
RefreshCw,
MoreVertical,
+ Clock,
Edit,
Trash2,
Eye,
Copy,
+ ChevronDown,
+ ChevronUp,
Settings,
+ Calendar,
Users,
ThumbsUp,
} from 'lucide-react';
@@ -18,281 +22,184 @@ import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
-import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Switch } from '@/components/ui/switch';
import { Progress } from '@/components/ui/progress';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import Layout from '@/components/Layout';
import PageHeader from '@/components/PageHeader';
+import BottomNav from '@/components/BottomNav';
import { useToast } from '@/components/ui/toast';
+import '@/components/Layout.css';
-interface TaskConfig {
- id: number;
- workbenchId: number;
- interval: number;
- maxLikes: number;
- friendMaxLikes?: number;
- startTime: string;
- endTime: string;
- contentTypes: string[];
- devices: number[];
- targetGroups: string[];
- tagOperator: number;
- createTime: string;
- updateTime: string;
- todayLikeCount?: number;
- totalLikeCount?: number;
- friends?: string[];
- enableFriendTags?: boolean;
- friendTags?: string;
-}
-
-interface Task {
- id: number;
+interface LikeTask {
+ id: string;
name: string;
- type: number;
- status: number;
- autoStart: number;
+ status: 'running' | 'paused';
+ deviceCount: number;
+ targetGroup: string;
+ likeCount: number;
+ lastLikeTime: string;
createTime: string;
- updateTime: string;
- config: TaskConfig;
-}
-
-interface TaskListResponse {
- code: number;
- msg: string;
- data: {
- list: Task[];
- total: number;
- };
-}
-
-interface ApiResponse {
- code: number;
- msg: string;
+ creator: string;
+ likeInterval: number;
+ maxLikesPerDay: number;
+ timeRange: { start: string; end: string };
+ contentTypes: string[];
+ targetTags: string[];
}
export default function AutoLike() {
const navigate = useNavigate();
const { toast } = useToast();
- const [expandedTaskId, setExpandedTaskId] = useState
(null);
- const [tasks, setTasks] = useState([]);
- const [loading, setLoading] = useState(false);
- const [searchName, setSearchName] = useState('');
- const [currentPage, setCurrentPage] = useState(1);
- const [total, setTotal] = useState(0);
- const pageSize = 10;
-
- // 模拟数据
- const mockTasks: Task[] = [
+ const [expandedTaskId, setExpandedTaskId] = useState(null);
+ const [searchTerm, setSearchTerm] = useState('');
+ const [tasks, setTasks] = useState([
{
- id: 1,
- name: '智能点赞任务1',
- type: 1,
- status: 1,
- autoStart: 1,
- createTime: '2024-03-18 10:00:00',
- updateTime: '2024-03-18 16:30:00',
- config: {
- id: 1,
- workbenchId: 1,
- interval: 30,
- maxLikes: 100,
- friendMaxLikes: 3,
- startTime: '09:00',
- endTime: '18:00',
- contentTypes: ['text', 'image'],
- devices: [1, 2, 3],
- targetGroups: ['VIP客户', '活跃用户'],
- tagOperator: 1,
- createTime: '2024-03-18 10:00:00',
- updateTime: '2024-03-18 16:30:00',
- todayLikeCount: 45,
- totalLikeCount: 1234,
- friends: ['friend1', 'friend2', 'friend3'],
- enableFriendTags: true,
- friendTags: '重要客户'
- }
+ id: '1',
+ name: '高频互动点赞',
+ deviceCount: 2,
+ targetGroup: '高频互动好友',
+ likeCount: 156,
+ lastLikeTime: '2025-02-06 13:12:35',
+ createTime: '2024-11-20 19:04:14',
+ creator: 'admin',
+ status: 'running',
+ likeInterval: 5,
+ maxLikesPerDay: 200,
+ timeRange: { start: '08:00', end: '22:00' },
+ contentTypes: ['text', 'image', 'video'],
+ targetTags: ['高频互动', '高意向', '男性'],
},
{
- id: 2,
- name: '自动点赞任务2',
- type: 1,
- status: 2,
- autoStart: 0,
- createTime: '2024-03-17 14:20:00',
- updateTime: '2024-03-18 12:15:00',
- config: {
- id: 2,
- workbenchId: 2,
- interval: 60,
- maxLikes: 50,
- friendMaxLikes: 2,
- startTime: '10:00',
- endTime: '20:00',
- contentTypes: ['video'],
- devices: [4, 5],
- targetGroups: ['新客户'],
- tagOperator: 2,
- createTime: '2024-03-17 14:20:00',
- updateTime: '2024-03-18 12:15:00',
- todayLikeCount: 0,
- totalLikeCount: 567,
- friends: ['friend4', 'friend5'],
- enableFriendTags: false
- }
- }
- ];
+ id: '2',
+ name: '潜在客户点赞',
+ deviceCount: 1,
+ targetGroup: '潜在客户',
+ likeCount: 89,
+ lastLikeTime: '2024-03-04 14:09:35',
+ createTime: '2024-03-04 14:29:04',
+ creator: 'manager',
+ status: 'paused',
+ likeInterval: 10,
+ maxLikesPerDay: 150,
+ timeRange: { start: '09:00', end: '21:00' },
+ contentTypes: ['image', 'video'],
+ targetTags: ['潜在客户', '中意向', '女性'],
+ },
+ ]);
- const fetchTasks = async (page: number, name?: string) => {
- setLoading(true);
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 1000));
-
- // 模拟搜索过滤
- let filteredTasks = mockTasks;
- if (name) {
- filteredTasks = mockTasks.filter(task =>
- task.name.toLowerCase().includes(name.toLowerCase())
- );
- }
-
- setTasks(filteredTasks);
- setTotal(filteredTasks.length);
- } catch (error: any) {
- console.error('获取任务列表失败:', error);
- toast({
- title: '获取失败',
- description: error?.message || '请检查网络连接',
- });
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- fetchTasks(currentPage, searchName);
- }, [currentPage]);
-
- const handleSearch = () => {
- setCurrentPage(1);
- fetchTasks(1, searchName);
- };
-
- const handleRefresh = () => {
- fetchTasks(currentPage, searchName);
- };
-
- const toggleExpand = (taskId: number) => {
+ const toggleExpand = (taskId: string) => {
setExpandedTaskId(expandedTaskId === taskId ? null : taskId);
};
- const handleDelete = async (taskId: number) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
+ const handleDelete = (taskId: string) => {
+ const taskToDelete = tasks.find((task) => task.id === taskId);
+ if (!taskToDelete) return;
+
+ if (!window.confirm(`确定要删除"${taskToDelete.name}"吗?`)) return;
- setTasks(tasks.filter(task => task.id !== taskId));
+ setTasks(tasks.filter((task) => task.id !== taskId));
toast({
title: '删除成功',
description: '已成功删除点赞任务',
});
- } catch (error: any) {
- console.error('删除任务失败:', error);
- toast({
- title: '删除失败',
- description: error?.message || '请检查网络连接',
- });
- }
};
- const handleEdit = (taskId: number) => {
+ const handleEdit = (taskId: string) => {
navigate(`/workspace/auto-like/${taskId}/edit`);
};
- const handleView = (taskId: number) => {
+ const handleView = (taskId: string) => {
navigate(`/workspace/auto-like/${taskId}`);
};
- const handleCopy = async (taskId: number) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
-
- const taskToCopy = tasks.find(task => task.id === taskId);
+ const handleCopy = (taskId: string) => {
+ const taskToCopy = tasks.find((task) => task.id === taskId);
if (taskToCopy) {
const newTask = {
...taskToCopy,
- id: Date.now(),
- name: `${taskToCopy.name} (副本)`,
- status: 2,
- createTime: new Date().toLocaleString(),
- updateTime: new Date().toLocaleString(),
- config: {
- ...taskToCopy.config,
- id: Date.now(),
- workbenchId: Date.now(),
- todayLikeCount: 0,
- totalLikeCount: 0,
- createTime: new Date().toLocaleString(),
- updateTime: new Date().toLocaleString(),
- }
+ id: `${Date.now()}`,
+ name: `${taskToCopy.name} (复制)`,
+ createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
};
- setTasks([newTask, ...tasks]);
+ setTasks([...tasks, newTask]);
toast({
title: '复制成功',
description: '已成功复制点赞任务',
});
}
- } catch (error: any) {
- console.error('复制任务失败:', error);
+ };
+
+ const toggleTaskStatus = (taskId: string) => {
+ const task = tasks.find((t) => t.id === taskId);
+ if (!task) return;
+
+ setTasks(
+ tasks.map((task) =>
+ task.id === taskId ? { ...task, status: task.status === 'running' ? 'paused' : 'running' } : task,
+ ),
+ );
+
toast({
- title: '复制失败',
- description: error?.message || '请检查网络连接',
+ title: task.status === 'running' ? '已暂停' : '已启动',
+ description: `${task.name}任务${task.status === 'running' ? '已暂停' : '已启动'}`,
});
+ };
+
+ const handleCreateNew = () => {
+ navigate('/workspace/auto-like/new');
+ };
+
+ const filteredTasks = tasks.filter((task) =>
+ task.name.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+
+ const getStatusColor = (status: string) => {
+ switch (status) {
+ case 'running':
+ return 'bg-green-100 text-green-800';
+ case 'paused':
+ return 'bg-gray-100 text-gray-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
}
};
- const toggleTaskStatus = async (taskId: number, currentStatus: number) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
-
- const newStatus = currentStatus === 1 ? 2 : 1;
- setTasks(tasks.map(task =>
- task.id === taskId
- ? { ...task, status: newStatus }
- : task
- ));
-
- toast({
- title: '状态更新成功',
- description: `任务${newStatus === 1 ? '已启动' : '已暂停'}`,
- });
- } catch (error: any) {
- console.error('更新任务状态失败:', error);
- toast({
- title: '更新失败',
- description: error?.message || '请检查网络连接',
- });
+ const getStatusText = (status: string) => {
+ switch (status) {
+ case 'running':
+ return '进行中';
+ case 'paused':
+ return '已暂停';
+ default:
+ return '未知';
}
};
return (
-
+
-
)}
- ))}
-
-
- {/* 分页 */}
- {total > pageSize && (
-
-
setCurrentPage(prev => Math.max(1, prev - 1))}
- disabled={currentPage === 1 || loading}
- >
- 上一页
-
-
- 第 {currentPage} 页
- 共 {Math.ceil(total / pageSize)} 页
-
-
setCurrentPage(prev => Math.min(Math.ceil(total / pageSize), prev + 1))}
- disabled={currentPage >= Math.ceil(total / pageSize) || loading}
- >
- 下一页
-
+ ))
+ )}
- )}
+
-
+
);
}
\ No newline at end of file
diff --git a/nkebao/src/pages/workspace/auto-like/NewAutoLike.tsx b/nkebao/src/pages/workspace/auto-like/NewAutoLike.tsx
new file mode 100644
index 00000000..4311db5c
--- /dev/null
+++ b/nkebao/src/pages/workspace/auto-like/NewAutoLike.tsx
@@ -0,0 +1,469 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Label } from '@/components/ui/label';
+import { Switch } from '@/components/ui/switch';
+import { Badge } from '@/components/ui/badge';
+import { Progress } from '@/components/ui/progress';
+import { Checkbox } from '@/components/ui/checkbox';
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
+import Layout from '@/components/Layout';
+import PageHeader from '@/components/PageHeader';
+import BottomNav from '@/components/BottomNav';
+import { useToast } from '@/components/ui/toast';
+import '@/components/Layout.css';
+
+interface Device {
+ id: string;
+ name: string;
+ status: 'online' | 'offline';
+ lastActive: string;
+}
+
+interface TargetGroup {
+ id: string;
+ name: string;
+ count: number;
+ tags: string[];
+}
+
+export default function NewAutoLike() {
+ const navigate = useNavigate();
+ const { toast } = useToast();
+ const [currentStep, setCurrentStep] = useState(1);
+ const [formData, setFormData] = useState({
+ name: '',
+ description: '',
+ likeInterval: 30,
+ maxLikesPerDay: 100,
+ startTime: '09:00',
+ endTime: '18:00',
+ contentTypes: ['text', 'image'],
+ selectedDevices: [] as string[],
+ selectedGroups: [] as string[],
+ targetTags: [] as string[],
+ enableFriendTags: false,
+ friendTags: '',
+ });
+
+ // 模拟设备数据
+ const devices: Device[] = [
+ { id: '1', name: 'iPhone 14 Pro', status: 'online', lastActive: '2024-03-18 15:30:00' },
+ { id: '2', name: 'iPhone 13', status: 'online', lastActive: '2024-03-18 15:25:00' },
+ { id: '3', name: 'iPhone 12', status: 'offline', lastActive: '2024-03-18 14:20:00' },
+ ];
+
+ // 模拟目标人群数据
+ const targetGroups: TargetGroup[] = [
+ { id: '1', name: 'VIP客户', count: 156, tags: ['VIP', '高价值'] },
+ { id: '2', name: '活跃用户', count: 234, tags: ['活跃', '互动'] },
+ { id: '3', name: '潜在客户', count: 89, tags: ['潜在', '新客户'] },
+ ];
+
+ // 可用标签
+ const availableTags = [
+ 'VIP', '高价值', '活跃', '互动', '潜在', '新客户', '男性', '女性', '青年', '中年', '高收入', '中收入'
+ ];
+
+ const handleInputChange = (field: string, value: any) => {
+ setFormData(prev => ({ ...prev, [field]: value }));
+ };
+
+ const handleDeviceToggle = (deviceId: string) => {
+ setFormData(prev => ({
+ ...prev,
+ selectedDevices: prev.selectedDevices.includes(deviceId)
+ ? prev.selectedDevices.filter(id => id !== deviceId)
+ : [...prev.selectedDevices, deviceId]
+ }));
+ };
+
+ const handleGroupToggle = (groupId: string) => {
+ setFormData(prev => ({
+ ...prev,
+ selectedGroups: prev.selectedGroups.includes(groupId)
+ ? prev.selectedGroups.filter(id => id !== groupId)
+ : [...prev.selectedGroups, groupId]
+ }));
+ };
+
+ const handleTagToggle = (tag: string) => {
+ setFormData(prev => ({
+ ...prev,
+ targetTags: prev.targetTags.includes(tag)
+ ? prev.targetTags.filter(t => t !== tag)
+ : [...prev.targetTags, tag]
+ }));
+ };
+
+ const handleContentTypeToggle = (type: string) => {
+ setFormData(prev => ({
+ ...prev,
+ contentTypes: prev.contentTypes.includes(type)
+ ? prev.contentTypes.filter(t => t !== type)
+ : [...prev.contentTypes, type]
+ }));
+ };
+
+ const handleNext = () => {
+ if (currentStep === 1 && (!formData.name || formData.selectedDevices.length === 0)) {
+ toast({
+ title: '请完善信息',
+ description: '请填写任务名称并选择至少一个设备',
+ variant: 'destructive',
+ });
+ return;
+ }
+ if (currentStep === 2 && formData.selectedGroups.length === 0) {
+ toast({
+ title: '请选择目标人群',
+ description: '请至少选择一个目标人群',
+ variant: 'destructive',
+ });
+ return;
+ }
+ setCurrentStep(prev => Math.min(prev + 1, 3));
+ };
+
+ const handlePrev = () => {
+ setCurrentStep(prev => Math.max(prev - 1, 1));
+ };
+
+ const handleSubmit = async () => {
+ try {
+ // 模拟API调用
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ toast({
+ title: '创建成功',
+ description: '自动点赞任务已创建',
+ });
+
+ navigate('/workspace/auto-like');
+ } catch (error) {
+ toast({
+ title: '创建失败',
+ description: '请检查网络连接后重试',
+ variant: 'destructive',
+ });
+ }
+ };
+
+ const steps = [
+ { title: '基本设置', description: '配置任务基本信息' },
+ { title: '目标人群', description: '选择点赞目标' },
+ { title: '高级设置', description: '配置高级参数' },
+ ];
+
+ return (
+
+ }
+ footer={
}
+ >
+
+
+ {/* 步骤指示器 */}
+
+
+
+ {steps.map((step, index) => (
+
+
+ {index + 1}
+
+
+
{step.title}
+
{step.description}
+
+ {index < steps.length - 1 && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* 步骤1: 基本设置 */}
+ {currentStep === 1 && (
+
+
+
+ 任务信息
+
+
+
+
+ handleInputChange('name', e.target.value)}
+ />
+
+
+
+ handleInputChange('description', e.target.value)}
+ />
+
+
+
+
+
+
+ 执行设备
+
+
+
+ {devices.map((device) => (
+
handleDeviceToggle(device.id)}
+ >
+
+
+
+
{device.name}
+
+ {device.status === 'online' ? '在线' : '离线'} ·
+ 最后活跃: {device.lastActive}
+
+
+
+
handleDeviceToggle(device.id)}
+ />
+
+ ))}
+
+
+
+
+ )}
+
+ {/* 步骤2: 目标人群 */}
+ {currentStep === 2 && (
+
+
+
+ 目标人群
+
+
+
+ {targetGroups.map((group) => (
+
handleGroupToggle(group.id)}
+ >
+
+
{group.name}
+
+ {group.count} 个好友
+
+
+ {group.tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
handleGroupToggle(group.id)}
+ />
+
+ ))}
+
+
+
+
+
+
+ 标签筛选
+
+
+
+ {availableTags.map((tag) => (
+ handleTagToggle(tag)}
+ >
+ {tag}
+
+ ))}
+
+
+
+
+ )}
+
+ {/* 步骤3: 高级设置 */}
+ {currentStep === 3 && (
+
+
+
+ 点赞设置
+
+
+
+
+
+
+
+
+
+ 内容类型
+
+
+
+ {[
+ { value: 'text', label: '文字' },
+ { value: 'image', label: '图片' },
+ { value: 'video', label: '视频' },
+ ].map((type) => (
+ handleContentTypeToggle(type.value)}
+ >
+ {type.label}
+
+ ))}
+
+
+
+
+
+
+ 任务预览
+
+
+
+
+ 任务名称:
+ {formData.name}
+
+
+ 执行设备:
+ {formData.selectedDevices.length} 个
+
+
+ 目标人群:
+ {formData.selectedGroups.length} 个
+
+
+ 点赞间隔:
+ {formData.likeInterval} 秒
+
+
+ 每日上限:
+ {formData.maxLikesPerDay} 次
+
+
+ 执行时间:
+ {formData.startTime} - {formData.endTime}
+
+
+
+
+
+ )}
+
+ {/* 底部按钮 */}
+
+
+ 上一步
+
+
+ {currentStep < 3 ? (
+
+ 下一步
+
+ ) : (
+
+ 创建任务
+
+ )}
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/nkebao/src/pages/workspace/group-push/GroupPush.tsx b/nkebao/src/pages/workspace/group-push/GroupPush.tsx
new file mode 100644
index 00000000..ce59bc65
--- /dev/null
+++ b/nkebao/src/pages/workspace/group-push/GroupPush.tsx
@@ -0,0 +1,474 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+ Plus,
+ Filter,
+ Search,
+ RefreshCw,
+ MoreVertical,
+ Clock,
+ Edit,
+ Trash2,
+ Eye,
+ Copy,
+ ChevronDown,
+ ChevronUp,
+ Settings,
+ Calendar,
+ Users,
+ Send,
+ CheckCircle,
+ XCircle,
+ MessageSquare,
+} from 'lucide-react';
+import { Card } from '@/components/ui/card';
+import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Badge } from '@/components/ui/badge';
+import { Switch } from '@/components/ui/switch';
+import { Progress } from '@/components/ui/progress';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import Layout from '@/components/Layout';
+import PageHeader from '@/components/PageHeader';
+import BottomNav from '@/components/BottomNav';
+import { useToast } from '@/components/ui/toast';
+import '@/components/Layout.css';
+
+interface PushTask {
+ id: string;
+ name: string;
+ status: 'running' | 'paused' | 'completed';
+ deviceCount: number;
+ targetGroups: string[];
+ pushCount: number;
+ successCount: number;
+ lastPushTime: string;
+ createTime: string;
+ creator: string;
+ pushInterval: number;
+ maxPushPerDay: number;
+ timeRange: { start: string; end: string };
+ messageType: 'text' | 'image' | 'video' | 'link';
+ messageContent: string;
+ targetTags: string[];
+ pushMode: 'immediate' | 'scheduled';
+ scheduledTime?: string;
+}
+
+export default function GroupPush() {
+ const navigate = useNavigate();
+ const { toast } = useToast();
+ const [expandedTaskId, setExpandedTaskId] = useState
(null);
+ const [searchTerm, setSearchTerm] = useState('');
+ const [tasks, setTasks] = useState([
+ {
+ id: '1',
+ name: '产品推广群发',
+ deviceCount: 2,
+ targetGroups: ['VIP客户群', '潜在客户群'],
+ pushCount: 156,
+ successCount: 142,
+ lastPushTime: '2025-02-06 13:12:35',
+ createTime: '2024-11-20 19:04:14',
+ creator: 'admin',
+ status: 'running',
+ pushInterval: 60,
+ maxPushPerDay: 200,
+ timeRange: { start: '09:00', end: '21:00' },
+ messageType: 'text',
+ messageContent: '新品上市,限时优惠!点击查看详情...',
+ targetTags: ['VIP客户', '高意向'],
+ pushMode: 'immediate',
+ },
+ {
+ id: '2',
+ name: '活动通知推送',
+ deviceCount: 1,
+ targetGroups: ['活动群', '推广群'],
+ pushCount: 89,
+ successCount: 78,
+ lastPushTime: '2024-03-04 14:09:35',
+ createTime: '2024-03-04 14:29:04',
+ creator: 'manager',
+ status: 'paused',
+ pushInterval: 120,
+ maxPushPerDay: 100,
+ timeRange: { start: '10:00', end: '20:00' },
+ messageType: 'image',
+ messageContent: '活动海报.jpg',
+ targetTags: ['活跃用户', '中意向'],
+ pushMode: 'scheduled',
+ scheduledTime: '2024-03-05 10:00:00',
+ },
+ ]);
+
+ const toggleExpand = (taskId: string) => {
+ setExpandedTaskId(expandedTaskId === taskId ? null : taskId);
+ };
+
+ const handleDelete = (taskId: string) => {
+ const taskToDelete = tasks.find((task) => task.id === taskId);
+ if (!taskToDelete) return;
+
+ if (!window.confirm(`确定要删除"${taskToDelete.name}"吗?`)) return;
+
+ setTasks(tasks.filter((task) => task.id !== taskId));
+ toast({
+ title: '删除成功',
+ description: '已成功删除推送任务',
+ });
+ };
+
+ const handleEdit = (taskId: string) => {
+ navigate(`/workspace/group-push/${taskId}/edit`);
+ };
+
+ const handleView = (taskId: string) => {
+ navigate(`/workspace/group-push/${taskId}`);
+ };
+
+ const handleCopy = (taskId: string) => {
+ const taskToCopy = tasks.find((task) => task.id === taskId);
+ if (taskToCopy) {
+ const newTask = {
+ ...taskToCopy,
+ id: `${Date.now()}`,
+ name: `${taskToCopy.name} (复制)`,
+ createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+ };
+ setTasks([...tasks, newTask]);
+ toast({
+ title: '复制成功',
+ description: '已成功复制推送任务',
+ });
+ }
+ };
+
+ const toggleTaskStatus = (taskId: string) => {
+ const task = tasks.find((t) => t.id === taskId);
+ if (!task) return;
+
+ setTasks(
+ tasks.map((task) =>
+ task.id === taskId ? { ...task, status: task.status === 'running' ? 'paused' : 'running' } : task,
+ ),
+ );
+
+ toast({
+ title: task.status === 'running' ? '已暂停' : '已启动',
+ description: `${task.name}任务${task.status === 'running' ? '已暂停' : '已启动'}`,
+ });
+ };
+
+ const handleCreateNew = () => {
+ navigate('/workspace/group-push/new');
+ };
+
+ const filteredTasks = tasks.filter((task) =>
+ task.name.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+
+ const getStatusColor = (status: string) => {
+ switch (status) {
+ case 'running':
+ return 'bg-green-100 text-green-800';
+ case 'paused':
+ return 'bg-gray-100 text-gray-800';
+ case 'completed':
+ return 'bg-blue-100 text-blue-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
+ }
+ };
+
+ const getStatusText = (status: string) => {
+ switch (status) {
+ case 'running':
+ return '进行中';
+ case 'paused':
+ return '已暂停';
+ case 'completed':
+ return '已完成';
+ default:
+ return '未知';
+ }
+ };
+
+ const getMessageTypeText = (type: string) => {
+ switch (type) {
+ case 'text':
+ return '文字';
+ case 'image':
+ return '图片';
+ case 'video':
+ return '视频';
+ case 'link':
+ return '链接';
+ default:
+ return '未知';
+ }
+ };
+
+ const getSuccessRate = (pushCount: number, successCount: number) => {
+ if (pushCount === 0) return 0;
+ return Math.round((successCount / pushCount) * 100);
+ };
+
+ return (
+
+
+ 新建任务
+
+ }
+ />
+ }
+ footer={}
+ >
+
+
+ {/* 搜索和筛选 */}
+
+
+
+
+ setSearchTerm(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+
+
+ {/* 任务列表 */}
+
+ {filteredTasks.length === 0 ? (
+
+
+ 暂无推送任务
+ 创建您的第一个群消息推送任务
+
+
+ 创建第一个任务
+
+
+ ) : (
+ filteredTasks.map((task) => (
+
+
+
+
{task.name}
+
+ {getStatusText(task.status)}
+
+
+
+ toggleTaskStatus(task.id)}
+ disabled={task.status === 'completed'}
+ />
+
+
+
+
+
+
+
+ handleView(task.id)}>
+
+ 查看
+
+ handleEdit(task.id)}>
+
+ 编辑
+
+ handleCopy(task.id)}>
+
+ 复制
+
+ handleDelete(task.id)}>
+
+ 删除
+
+
+
+
+
+
+
+
+
执行设备:{task.deviceCount} 个
+
目标群组:{task.targetGroups.length} 个
+
+
+
推送成功:{task.successCount}/{task.pushCount}
+
创建人:{task.creator}
+
+
+
+ {/* 成功率进度条 */}
+
+
+ 推送成功率
+ {getSuccessRate(task.pushCount, task.successCount)}%
+
+
+
+
+
+
+
+ 上次推送:{task.lastPushTime}
+
+
+ 创建时间:{task.createTime}
+ toggleExpand(task.id)}
+ >
+ {expandedTaskId === task.id ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {expandedTaskId === task.id && (
+
+
+
+
+
+
基本设置
+
+
+
+ 推送间隔:
+ {task.pushInterval} 秒
+
+
+ 每日最大推送数:
+ {task.maxPushPerDay} 条
+
+
+ 执行时间段:
+
+ {task.timeRange.start} - {task.timeRange.end}
+
+
+
+ 推送模式:
+ {task.pushMode === 'immediate' ? '立即推送' : '定时推送'}
+
+ {task.scheduledTime && (
+
+ 定时时间:
+ {task.scheduledTime}
+
+ )}
+
+
+
+
+
+
+
目标群组
+
+
+
+ {task.targetGroups.map((group) => (
+
+ {group}
+
+ ))}
+
+
+
+
+
+
+
+
消息内容
+
+
+
+ 消息类型:
+ {getMessageTypeText(task.messageType)}
+
+
+
消息内容:
+
+ {task.messageContent}
+
+
+
+
+
+
+
+
+
执行进度
+
+
+
+ 今日已推送:
+
+ {task.pushCount} / {task.maxPushPerDay}
+
+
+
+ {task.targetTags.length > 0 && (
+
+
目标标签:
+
+ {task.targetTags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+ )}
+
+
+
+
+ )}
+
+ ))
+ )}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx b/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx
index 21a79649..f5f4f3e6 100644
--- a/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx
+++ b/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx
@@ -1,236 +1,230 @@
-import React, { useState, useEffect } from 'react';
-import { useNavigate, Link } from 'react-router-dom';
-import { Plus, Search, RefreshCw, MoreVertical, Clock, Edit, Trash2, Eye, Copy } from 'lucide-react';
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+ Plus,
+ Filter,
+ Search,
+ RefreshCw,
+ MoreVertical,
+ Clock,
+ Edit,
+ Trash2,
+ Eye,
+ Copy,
+ ChevronDown,
+ ChevronUp,
+ Settings,
+ Calendar,
+ Users,
+ Share2,
+ CheckCircle,
+ XCircle,
+} from 'lucide-react';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
-import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Switch } from '@/components/ui/switch';
+import { Progress } from '@/components/ui/progress';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import Layout from '@/components/Layout';
import PageHeader from '@/components/PageHeader';
+import BottomNav from '@/components/BottomNav';
import { useToast } from '@/components/ui/toast';
+import '@/components/Layout.css';
interface SyncTask {
id: string;
name: string;
- status: number; // 1-运行中,0-暂停
+ status: 'running' | 'paused' | 'completed';
deviceCount: number;
- contentLib: string;
+ targetGroup: string;
syncCount: number;
lastSyncTime: string;
createTime: string;
creator: string;
- config: {
- devices: string[];
- contentLibraryNames: string[];
- };
- creatorName: string;
+ syncInterval: number;
+ maxSyncPerDay: number;
+ timeRange: { start: string; end: string };
+ contentTypes: string[];
+ targetTags: string[];
+ syncMode: 'auto' | 'manual';
+ filterKeywords: string[];
}
export default function MomentsSync() {
const navigate = useNavigate();
const { toast } = useToast();
- const [tasks, setTasks] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
- const [searchQuery, setSearchQuery] = useState('');
- const [currentPage, setCurrentPage] = useState(1);
- const [pageSize, setPageSize] = useState(10);
- const [total, setTotal] = useState(0);
-
- // 模拟数据
- const mockTasks: SyncTask[] = [
+ const [expandedTaskId, setExpandedTaskId] = useState(null);
+ const [searchTerm, setSearchTerm] = useState('');
+ const [tasks, setTasks] = useState([
{
id: '1',
- name: '朋友圈同步任务1',
- status: 1,
- deviceCount: 3,
- contentLib: '营销素材库',
- syncCount: 156,
- lastSyncTime: '2024-03-18 16:30:00',
- createTime: '2024-03-15 10:00:00',
+ name: '朋友圈自动同步',
+ deviceCount: 2,
+ targetGroup: '所有好友',
+ syncCount: 45,
+ lastSyncTime: '2025-02-06 13:12:35',
+ createTime: '2024-11-20 19:04:14',
creator: 'admin',
- creatorName: '管理员',
- config: {
- devices: ['device1', 'device2', 'device3'],
- contentLibraryNames: ['营销素材库', '产品介绍库']
- }
+ status: 'running',
+ syncInterval: 30,
+ maxSyncPerDay: 100,
+ timeRange: { start: '08:00', end: '22:00' },
+ contentTypes: ['text', 'image', 'video'],
+ targetTags: ['重要客户', '活跃用户'],
+ syncMode: 'auto',
+ filterKeywords: ['产品', '服务', '优惠'],
},
{
id: '2',
- name: '朋友圈同步任务2',
- status: 0,
- deviceCount: 2,
- contentLib: '产品介绍库',
- syncCount: 89,
- lastSyncTime: '2024-03-17 14:20:00',
- createTime: '2024-03-14 15:30:00',
- creator: 'user1',
- creatorName: '用户1',
- config: {
- devices: ['device4', 'device5'],
- contentLibraryNames: ['产品介绍库']
- }
- }
- ];
+ name: '营销内容同步',
+ deviceCount: 1,
+ targetGroup: '目标客户',
+ syncCount: 23,
+ lastSyncTime: '2024-03-04 14:09:35',
+ createTime: '2024-03-04 14:29:04',
+ creator: 'manager',
+ status: 'paused',
+ syncInterval: 60,
+ maxSyncPerDay: 50,
+ timeRange: { start: '09:00', end: '21:00' },
+ contentTypes: ['image', 'video'],
+ targetTags: ['潜在客户', '中意向'],
+ syncMode: 'manual',
+ filterKeywords: ['营销', '推广'],
+ },
+ ]);
- // 获取任务列表
- const fetchTasks = async () => {
- setIsLoading(true);
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 1000));
-
- // 模拟搜索过滤
- let filteredTasks = mockTasks;
- if (searchQuery) {
- filteredTasks = mockTasks.filter(task =>
- task.name.toLowerCase().includes(searchQuery.toLowerCase())
- );
- }
-
- setTasks(filteredTasks);
- setTotal(filteredTasks.length);
- } catch (error: any) {
- console.error('获取朋友圈同步任务列表失败:', error);
- toast({
- title: '获取失败',
- description: error?.message || '请检查网络连接',
- });
- } finally {
- setIsLoading(false);
- }
+ const toggleExpand = (taskId: string) => {
+ setExpandedTaskId(expandedTaskId === taskId ? null : taskId);
};
- // 组件加载时获取任务列表
- useEffect(() => {
- fetchTasks();
- }, [currentPage, pageSize]);
+ const handleDelete = (taskId: string) => {
+ const taskToDelete = tasks.find((task) => task.id === taskId);
+ if (!taskToDelete) return;
- // 处理页码变化
- const handlePageChange = (page: number) => {
- setCurrentPage(page);
- };
-
- // 处理每页条数变化
- const handlePageSizeChange = (size: number) => {
- setPageSize(size);
- setCurrentPage(1); // 重置到第一页
- };
-
- // 搜索任务
- const handleSearch = () => {
- fetchTasks();
- };
-
- // 切换任务状态
- const toggleTaskStatus = async (taskId: string, currentStatus: number) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
-
- const newStatus = currentStatus === 1 ? 0 : 1;
- setTasks(
- tasks.map((task) =>
- task.id === taskId ? { ...task, status: newStatus } : task
- )
- );
-
- toast({
- title: '状态更新成功',
- description: `任务已${newStatus === 1 ? '启用' : '暂停'}`,
- });
- } catch (error: any) {
- console.error('更新任务状态失败:', error);
- toast({
- title: '更新失败',
- description: error?.message || '更新任务状态失败',
- });
- }
- };
-
- // 执行删除
- const handleDelete = async (taskId: string) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
+ if (!window.confirm(`确定要删除"${taskToDelete.name}"吗?`)) return;
setTasks(tasks.filter((task) => task.id !== taskId));
toast({
title: '删除成功',
description: '已成功删除同步任务',
});
- } catch (error: any) {
- console.error('删除任务失败:', error);
- toast({
- title: '删除失败',
- description: error?.message || '删除任务失败',
- });
- }
};
- // 编辑任务
const handleEdit = (taskId: string) => {
navigate(`/workspace/moments-sync/${taskId}/edit`);
};
- // 查看任务详情
const handleView = (taskId: string) => {
navigate(`/workspace/moments-sync/${taskId}`);
};
- // 复制任务
- const handleCopy = async (taskId: string) => {
- try {
- // 模拟API调用
- await new Promise(resolve => setTimeout(resolve, 500));
-
- const taskToCopy = tasks.find(task => task.id === taskId);
+ const handleCopy = (taskId: string) => {
+ const taskToCopy = tasks.find((task) => task.id === taskId);
if (taskToCopy) {
const newTask = {
...taskToCopy,
- id: Date.now().toString(),
- name: `${taskToCopy.name} (副本)`,
- status: 0,
- createTime: new Date().toLocaleString(),
- syncCount: 0,
- lastSyncTime: '-'
+ id: `${Date.now()}`,
+ name: `${taskToCopy.name} (复制)`,
+ createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
};
- setTasks([newTask, ...tasks]);
+ setTasks([...tasks, newTask]);
toast({
title: '复制成功',
description: '已成功复制同步任务',
});
}
- } catch (error: any) {
- console.error('复制任务失败:', error);
+ };
+
+ const toggleTaskStatus = (taskId: string) => {
+ const task = tasks.find((t) => t.id === taskId);
+ if (!task) return;
+
+ setTasks(
+ tasks.map((task) =>
+ task.id === taskId ? { ...task, status: task.status === 'running' ? 'paused' : 'running' } : task,
+ ),
+ );
+
toast({
- title: '复制失败',
- description: error?.message || '复制任务失败',
+ title: task.status === 'running' ? '已暂停' : '已启动',
+ description: `${task.name}任务${task.status === 'running' ? '已暂停' : '已启动'}`,
});
+ };
+
+ const handleCreateNew = () => {
+ navigate('/workspace/moments-sync/new');
+ };
+
+ const filteredTasks = tasks.filter((task) =>
+ task.name.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+
+ const getStatusColor = (status: string) => {
+ switch (status) {
+ case 'running':
+ return 'bg-green-100 text-green-800';
+ case 'paused':
+ return 'bg-gray-100 text-gray-800';
+ case 'completed':
+ return 'bg-blue-100 text-blue-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
}
};
- // 过滤任务
- const filteredTasks = tasks.filter(
- (task) => task.name.toLowerCase().includes(searchQuery.toLowerCase())
- );
+ const getStatusText = (status: string) => {
+ switch (status) {
+ case 'running':
+ return '进行中';
+ case 'paused':
+ return '已暂停';
+ case 'completed':
+ return '已完成';
+ default:
+ return '未知';
+ }
+ };
+
+ const getStatusIcon = (status: string) => {
+ switch (status) {
+ case 'running':
+ return ;
+ case 'paused':
+ return ;
+ case 'completed':
+ return ;
+ default:
+ return ;
+ }
+ };
return (
-
+
-
+
新建任务
-
}
/>
-
+ }
+ footer={}
+ >
+
+ {/* 搜索和筛选 */}
+ {/* 任务列表 */}
- {isLoading ? (
-
加载中...
- ) : filteredTasks.length > 0 ? (
+ {filteredTasks.length === 0 ? (
+
+
+ 暂无同步任务
+ 创建您的第一个朋友圈同步任务
+
+
+ 创建第一个任务
+
+
+ ) : (
filteredTasks.map((task) => (
{task.name}
-
- {task.status === 1 ? '运行中' : '已暂停'}
+
+ {getStatusText(task.status)}
-
toggleTaskStatus(task.id, task.status)} />
+ toggleTaskStatus(task.id)}
+ disabled={task.status === 'completed'}
+ />
@@ -297,58 +303,138 @@ export default function MomentsSync() {
-
执行设备:{task.deviceCount} 个
-
内容库:{task.contentLib}
-
创建者:{task.creatorName}
+
执行设备:{task.deviceCount} 个
+
目标人群:{task.targetGroup}
-
同步次数:{task.syncCount} 次
-
最后同步:{task.lastSyncTime}
-
创建时间:{task.createTime}
+
已同步:{task.syncCount} 条
+
创建人:{task.creator}
+
-
-
-
-
- 配置的设备:{task.config.devices.join(', ')}
-
+
+
+
+ 上次同步:{task.lastSyncTime}
+
+
+ 创建时间:{task.createTime}
+ toggleExpand(task.id)}
+ >
+ {expandedTaskId === task.id ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {expandedTaskId === task.id && (
+
+
+
+
+
+
基本设置
+
+
+
+ 同步间隔:
+ {task.syncInterval} 秒
+
+
+ 每日最大同步数:
+ {task.maxSyncPerDay} 条
+
+
+ 执行时间段:
+
+ {task.timeRange.start} - {task.timeRange.end}
+
+
+
+ 同步模式:
+ {task.syncMode === 'auto' ? '自动' : '手动'}
+
+
+
+
+
+
+
+
目标人群
+
+
+
+ {task.targetTags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+
+
+
+
+
同步内容类型
+
+
+
+ {task.contentTypes.map((type) => (
+
+ {type === 'text' ? '文字' : type === 'image' ? '图片' : '视频'}
+
+ ))}
+
+
+
+
+
+
+
+
执行进度
+
+
+
+ 今日已同步:
+
+ {task.syncCount} / {task.maxSyncPerDay}
+
+
+
+ {task.filterKeywords.length > 0 && (
+
+
关键词过滤:
+
+ {task.filterKeywords.map((keyword) => (
+
+ {keyword}
+
+ ))}
-
- ))
- ) : (
-
- {searchQuery ? '没有找到匹配的任务' : '暂无同步任务'}
)}
-
- {/* 分页 */}
- {total > pageSize && (
-
-
handlePageChange(Math.max(1, currentPage - 1))}
- disabled={currentPage === 1 || isLoading}
- >
- 上一页
-
-
- 第 {currentPage} 页
- 共 {Math.ceil(total / pageSize)} 页
+
+
-
handlePageChange(Math.min(Math.ceil(total / pageSize), currentPage + 1))}
- disabled={currentPage >= Math.ceil(total / pageSize) || isLoading}
- >
- 下一页
-
+ )}
+
+ ))
+ )}
- )}
+
-
+
);
}
\ No newline at end of file
diff --git a/nkebao/src/pages/workspace/traffic-distribution/TrafficDistribution.tsx b/nkebao/src/pages/workspace/traffic-distribution/TrafficDistribution.tsx
index f7422f29..ef6bbd99 100644
--- a/nkebao/src/pages/workspace/traffic-distribution/TrafficDistribution.tsx
+++ b/nkebao/src/pages/workspace/traffic-distribution/TrafficDistribution.tsx
@@ -1,5 +1,462 @@
-import React from 'react';
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+ Plus,
+ Filter,
+ Search,
+ RefreshCw,
+ MoreVertical,
+ Clock,
+ Edit,
+ Trash2,
+ Eye,
+ Copy,
+ ChevronDown,
+ ChevronUp,
+ Settings,
+ Calendar,
+ Users,
+ Share2,
+ CheckCircle,
+ XCircle,
+ TrendingUp,
+} from 'lucide-react';
+import { Card } from '@/components/ui/card';
+import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Badge } from '@/components/ui/badge';
+import { Switch } from '@/components/ui/switch';
+import { Progress } from '@/components/ui/progress';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import Layout from '@/components/Layout';
+import PageHeader from '@/components/PageHeader';
+import BottomNav from '@/components/BottomNav';
+import { useToast } from '@/components/ui/toast';
+import '@/components/Layout.css';
+
+interface DistributionRule {
+ id: string;
+ name: string;
+ status: 'running' | 'paused' | 'completed';
+ deviceCount: number;
+ totalTraffic: number;
+ distributedTraffic: number;
+ lastDistributionTime: string;
+ createTime: string;
+ creator: string;
+ distributionInterval: number;
+ maxDistributionPerDay: number;
+ timeRange: { start: string; end: string };
+ targetChannels: string[];
+ distributionRatio: Record
;
+ priority: 'high' | 'medium' | 'low';
+ filterConditions: string[];
+}
export default function TrafficDistribution() {
- return 流量分配页
;
+ const navigate = useNavigate();
+ const { toast } = useToast();
+ const [expandedRuleId, setExpandedRuleId] = useState(null);
+ const [searchTerm, setSearchTerm] = useState('');
+ const [tasks, setTasks] = useState([
+ {
+ id: '1',
+ name: 'VIP客户流量分发',
+ deviceCount: 3,
+ totalTraffic: 1000,
+ distributedTraffic: 756,
+ lastDistributionTime: '2025-02-06 13:12:35',
+ createTime: '2024-11-20 19:04:14',
+ creator: 'admin',
+ status: 'running',
+ distributionInterval: 300,
+ maxDistributionPerDay: 2000,
+ timeRange: { start: '08:00', end: '22:00' },
+ targetChannels: ['抖音', '小红书', '公众号'],
+ distributionRatio: {
+ '抖音': 40,
+ '小红书': 35,
+ '公众号': 25,
+ },
+ priority: 'high',
+ filterConditions: ['VIP客户', '高价值'],
+ },
+ {
+ id: '2',
+ name: '新客户流量分发',
+ deviceCount: 2,
+ totalTraffic: 500,
+ distributedTraffic: 234,
+ lastDistributionTime: '2024-03-04 14:09:35',
+ createTime: '2024-03-04 14:29:04',
+ creator: 'manager',
+ status: 'paused',
+ distributionInterval: 600,
+ maxDistributionPerDay: 1000,
+ timeRange: { start: '09:00', end: '21:00' },
+ targetChannels: ['抖音', '快手'],
+ distributionRatio: {
+ '抖音': 60,
+ '快手': 40,
+ },
+ priority: 'medium',
+ filterConditions: ['新客户', '潜在客户'],
+ },
+ ]);
+
+ const toggleExpand = (ruleId: string) => {
+ setExpandedRuleId(expandedRuleId === ruleId ? null : ruleId);
+ };
+
+ const handleDelete = (ruleId: string) => {
+ const ruleToDelete = tasks.find((rule) => rule.id === ruleId);
+ if (!ruleToDelete) return;
+
+ if (!window.confirm(`确定要删除"${ruleToDelete.name}"吗?`)) return;
+
+ setTasks(tasks.filter((rule) => rule.id !== ruleId));
+ toast({
+ title: '删除成功',
+ description: '已成功删除分发规则',
+ });
+ };
+
+ const handleEdit = (ruleId: string) => {
+ navigate(`/workspace/traffic-distribution/${ruleId}/edit`);
+ };
+
+ const handleView = (ruleId: string) => {
+ navigate(`/workspace/traffic-distribution/${ruleId}`);
+ };
+
+ const handleCopy = (ruleId: string) => {
+ const ruleToCopy = tasks.find((rule) => rule.id === ruleId);
+ if (ruleToCopy) {
+ const newRule = {
+ ...ruleToCopy,
+ id: `${Date.now()}`,
+ name: `${ruleToCopy.name} (复制)`,
+ createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+ };
+ setTasks([...tasks, newRule]);
+ toast({
+ title: '复制成功',
+ description: '已成功复制分发规则',
+ });
+ }
+ };
+
+ const toggleRuleStatus = (ruleId: string) => {
+ const rule = tasks.find((r) => r.id === ruleId);
+ if (!rule) return;
+
+ setTasks(
+ tasks.map((rule) =>
+ rule.id === ruleId ? { ...rule, status: rule.status === 'running' ? 'paused' : 'running' } : rule,
+ ),
+ );
+
+ toast({
+ title: rule.status === 'running' ? '已暂停' : '已启动',
+ description: `${rule.name}规则${rule.status === 'running' ? '已暂停' : '已启动'}`,
+ });
+ };
+
+ const handleCreateNew = () => {
+ navigate('/workspace/traffic-distribution/new');
+ };
+
+ const filteredRules = tasks.filter((rule) =>
+ rule.name.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+
+ const getStatusColor = (status: string) => {
+ switch (status) {
+ case 'running':
+ return 'bg-green-100 text-green-800';
+ case 'paused':
+ return 'bg-gray-100 text-gray-800';
+ case 'completed':
+ return 'bg-blue-100 text-blue-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
+ }
+ };
+
+ const getStatusText = (status: string) => {
+ switch (status) {
+ case 'running':
+ return '进行中';
+ case 'paused':
+ return '已暂停';
+ case 'completed':
+ return '已完成';
+ default:
+ return '未知';
+ }
+ };
+
+ const getPriorityColor = (priority: string) => {
+ switch (priority) {
+ case 'high':
+ return 'bg-red-100 text-red-800';
+ case 'medium':
+ return 'bg-yellow-100 text-yellow-800';
+ case 'low':
+ return 'bg-green-100 text-green-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
+ }
+ };
+
+ const getPriorityText = (priority: string) => {
+ switch (priority) {
+ case 'high':
+ return '高';
+ case 'medium':
+ return '中';
+ case 'low':
+ return '低';
+ default:
+ return '未知';
+ }
+ };
+
+ return (
+
+
+ 新建规则
+
+ }
+ />
+ }
+ footer={}
+ >
+
+
+ {/* 搜索和筛选 */}
+
+
+
+
+ setSearchTerm(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+
+
+ {/* 规则列表 */}
+
+ {filteredRules.length === 0 ? (
+
+
+ 暂无分发规则
+ 创建您的第一个流量分发规则
+
+
+ 创建第一个规则
+
+
+ ) : (
+ filteredRules.map((rule) => (
+
+
+
+
{rule.name}
+
+ {getStatusText(rule.status)}
+
+
+ 优先级: {getPriorityText(rule.priority)}
+
+
+
+ toggleRuleStatus(rule.id)}
+ disabled={rule.status === 'completed'}
+ />
+
+
+
+
+
+
+
+ handleView(rule.id)}>
+
+ 查看
+
+ handleEdit(rule.id)}>
+
+ 编辑
+
+ handleCopy(rule.id)}>
+
+ 复制
+
+ handleDelete(rule.id)}>
+
+ 删除
+
+
+
+
+
+
+
+
+
执行设备:{rule.deviceCount} 个
+
目标渠道:{rule.targetChannels.length} 个
+
+
+
已分发:{rule.distributedTraffic}/{rule.totalTraffic}
+
创建人:{rule.creator}
+
+
+
+ {/* 分发进度 */}
+
+
+ 分发进度
+
+ {Math.round((rule.distributedTraffic / rule.totalTraffic) * 100)}%
+
+
+
+
+
+
+
+
+ 上次分发:{rule.lastDistributionTime}
+
+
+ 创建时间:{rule.createTime}
+ toggleExpand(rule.id)}
+ >
+ {expandedRuleId === rule.id ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {expandedRuleId === rule.id && (
+
+
+
+
+
+
基本设置
+
+
+
+ 分发间隔:
+ {rule.distributionInterval} 秒
+
+
+ 每日最大分发数:
+ {rule.maxDistributionPerDay}
+
+
+ 执行时间段:
+
+ {rule.timeRange.start} - {rule.timeRange.end}
+
+
+
+ 优先级:
+ {getPriorityText(rule.priority)}
+
+
+
+
+
+
+
+
分发渠道
+
+
+
+ {rule.targetChannels.map((channel) => (
+
+ {channel}
+
+ ))}
+
+
+
+
+
+
+
+
分发比例
+
+
+ {Object.entries(rule.distributionRatio).map(([channel, ratio]) => (
+
+ {channel}:
+ {ratio}%
+
+ ))}
+
+
+
+
+
+
+
筛选条件
+
+
+
+ {rule.filterConditions.map((condition) => (
+
+ {condition}
+
+ ))}
+
+
+
+
+
+ )}
+
+ ))
+ )}
+
+
+
+
+ );
}
\ No newline at end of file