diff --git a/Cunkebao/app/workspace/moments-sync/[id]/page.tsx b/Cunkebao/app/workspace/moments-sync/[id]/page.tsx index 685c2fb2..badd0812 100644 --- a/Cunkebao/app/workspace/moments-sync/[id]/page.tsx +++ b/Cunkebao/app/workspace/moments-sync/[id]/page.tsx @@ -51,6 +51,19 @@ interface SyncHistory { errorMessage?: string } +// 新增朋友圈发布记录类型 +type MomentRecord = { + id: number + workbenchId: number + publishTime: number + contentType: number // 1文本 2视频 3图片 + content: string + resUrls: string[] + urls: string[] + operatorName: string + operatorAvatar: string +} + export default function MomentsSyncDetailPage({ params }: { params: { id: string } }) { const router = useRouter() const [taskDetail, setTaskDetail] = useState(null) @@ -58,13 +71,15 @@ export default function MomentsSyncDetailPage({ params }: { params: { id: string const [isLoading, setIsLoading] = useState(true) const [activeTab, setActiveTab] = useState("overview") const [showDeleteAlert, setShowDeleteAlert] = useState(false) + const [momentRecords, setMomentRecords] = useState([]) + const [isMomentLoading, setIsMomentLoading] = useState(false) // 获取任务详情 useEffect(() => { const fetchTaskDetail = async () => { setIsLoading(true) try { - const response = await api.get(`/v1/workbench/detail?id=${params.id}`) + const response = await api.get(`/v1/workbench/moments-records?workbenchId=${params.id}`) if (response.code === 200 && response.data) { setTaskDetail(response.data) @@ -103,12 +118,33 @@ export default function MomentsSyncDetailPage({ params }: { params: { id: string } } + // 获取朋友圈发布记录 + type MomentsApiResponse = { code: number; msg: string; data: { list: MomentRecord[] } } + const fetchMomentRecords = async () => { + setIsMomentLoading(true) + try { + const response = await api.get(`/v1/workbench/moments-records?workbenchId=${params.id}`) + if (response.code === 200 && response.data) { + setMomentRecords(response.data.list || []) + } else { + setMomentRecords([]) + } + } catch (error) { + setMomentRecords([]) + } finally { + setIsMomentLoading(false) + } + } + // 切换Tab时加载数据 const handleTabChange = (value: string) => { setActiveTab(value) if (value === "history" && syncHistory.length === 0) { fetchSyncHistory() } + if (value === "moments" && momentRecords.length === 0) { + fetchMomentRecords() + } } // 切换任务状态 @@ -275,10 +311,11 @@ export default function MomentsSyncDetailPage({ params }: { params: { id: string - + 基本信息 设备列表 同步历史 + 发布记录 @@ -385,6 +422,65 @@ export default function MomentsSyncDetailPage({ params }: { params: { id: string )} + + + +
+

朋友圈发布记录

+ +
+ {isMomentLoading ? ( +
加载中...
+ ) : momentRecords.length === 0 ? ( +
暂无发布记录
+ ) : ( +
+ {momentRecords.map((rec) => ( +
+ + {rec.operatorAvatar ? ( + {rec.operatorName} + ) : ( +
+ {rec.operatorName?.charAt(0) || "?"} +
+ )} +
+
+
+ {rec.operatorName} + {rec.publishTime ? new Date(rec.publishTime * 1000).toLocaleString() : "-"} +
+
+ {rec.contentType === 1 && rec.content} + {rec.contentType === 3 && rec.content} +
+ {/* 图片展示 */} + {rec.contentType === 3 && rec.resUrls && rec.resUrls.length > 0 && ( +
+ {rec.resUrls.map((url, idx) => ( + 图片 + ))} +
+ )} + {/* 视频展示 */} + {rec.contentType === 2 && rec.urls && rec.urls.length > 0 && ( +
+ {rec.urls.map((url, idx) => ( +
+ )} +
+
+ ))} +
+ )} +
+
diff --git a/Cunkebao/app/workspace/traffic-distribution/[id]/edit/page.tsx b/Cunkebao/app/workspace/traffic-distribution/[id]/edit/page.tsx index 224d6f83..c5eb14c2 100644 --- a/Cunkebao/app/workspace/traffic-distribution/[id]/edit/page.tsx +++ b/Cunkebao/app/workspace/traffic-distribution/[id]/edit/page.tsx @@ -1,514 +1,89 @@ "use client" +import type React from "react" + import { useState, useEffect } from "react" import { useRouter } from "next/navigation" -import { ChevronLeft, Info, Users, Target, Settings, ArrowRight, ArrowLeft } from "lucide-react" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Textarea } from "@/components/ui/textarea" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" -import { Switch } from "@/components/ui/switch" -import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs" -import { Slider } from "@/components/ui/slider" -import { Badge } from "@/components/ui/badge" -import { TrafficPoolSelector } from "@/app/components/traffic-pool-selector" -import { toast } from "@/components/ui/use-toast" +import { useToast } from "@/components/ui/use-toast" // 模拟数据 -const planDetails = { +const mockDistributionRule = { id: "1", name: "抖音直播引流计划", description: "从抖音直播间获取的潜在客户流量分发", status: "active", - source: "douyin", - sourceIcon: "🎬", - distributionMethod: "even", - targetGroups: ["新客户", "潜在客户"], - devices: ["iPhone 13", "华为 P40", "小米 11"], - totalUsers: 1250, - dailyAverage: 85, - weeklyData: [42, 56, 78, 64, 85, 92, 76], - createdAt: "2024-03-10T08:30:00Z", - lastUpdated: "2024-03-18T10:30:00Z", - rules: { - maxPerDay: 50, - timeRestriction: "custom", - customTimeStart: "09:00", - customTimeEnd: "21:00", - userFilters: [], - excludeTags: [], - }, - selectedUsers: [], + dailyDistributionLimit: 85, + deviceIds: ["dev1", "dev2", "dev3"], + trafficPoolIds: ["pool1", "pool2"], + distributionStrategy: "even", + autoAdjust: true, } export default function EditTrafficDistributionPage({ params }: { params: { id: string } }) { const router = useRouter() - const [currentStep, setCurrentStep] = useState(1) + const { toast } = useToast() + const [loading, setLoading] = useState(true) + const [isDeviceDialogOpen, setIsDeviceDialogOpen] = useState(false) + const [isPoolDialogOpen, setIsPoolDialogOpen] = useState(false) + const [isSubmitting, setIsSubmitting] = useState(false) + const [formData, setFormData] = useState({ + id: "", name: "", description: "", - source: "", - distributionMethod: "even", // even, priority, ratio - targetGroups: [] as string[], - targetDevices: [] as string[], - autoTag: true, - activeStatus: true, - priorityOrder: [] as string[], - ratioSettings: {} as Record, - rules: { - maxPerDay: 50, - timeRestriction: "all", // all, custom - customTimeStart: "09:00", - customTimeEnd: "21:00", - userFilters: [] as string[], - excludeTags: [] as string[], - }, - selectedUsers: [], - isPoolSelectorOpen: false, + status: "active", + dailyDistributionLimit: 100, + deviceIds: [] as string[], + trafficPoolIds: [] as string[], + distributionStrategy: "even", // even, weighted, priority + autoAdjust: true, }) - // 加载计划详情 useEffect(() => { - // 模拟API请求 - setFormData({ - name: planDetails.name, - description: planDetails.description || "", - source: planDetails.source, - distributionMethod: planDetails.distributionMethod, - targetGroups: planDetails.targetGroups, - targetDevices: planDetails.devices, - autoTag: true, - activeStatus: planDetails.status === "active", - priorityOrder: planDetails.targetGroups, - ratioSettings: planDetails.targetGroups.reduce( - (acc, group, index, arr) => { - acc[group] = Math.floor(100 / arr.length) - return acc - }, - {} as Record, - ), - rules: planDetails.rules, - selectedUsers: planDetails.selectedUsers || [], - isPoolSelectorOpen: false, - }) - }, [params.id]) + // 模拟API请求获取计划详情 + const fetchData = async () => { + try { + // 实际项目中应从API获取数据 + // const response = await fetch(`/api/traffic-distribution/${params.id}`) + // const data = await response.json() + // setFormData(data) - const updateFormData = (field: string, value: any) => { - setFormData((prev) => { - if (field.includes(".")) { - const [parent, child] = field.split(".") - return { - ...prev, - [parent]: { - ...prev[parent as keyof typeof prev], - [child]: value, - }, - } - } - return { ...prev, [field]: value } - }) - } - - const handleNext = () => { - setCurrentStep((prev) => prev + 1) - } - - const handleBack = () => { - if (currentStep > 1) { - setCurrentStep((prev) => prev - 1) - } else { - router.back() - } - } - - const handleSubmit = async (formData: any) => { - try { - const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/v1/api/traffic-distribution/${params.id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${localStorage.getItem('token')}` - }, - body: JSON.stringify(formData) - }); - - const data = await response.json(); - if (data.code === 200) { + // 使用模拟数据 + setTimeout(() => { + setFormData({ + ...mockDistributionRule, + id: params.id, + }) + setLoading(false) + }, 500) + } catch (error) { + console.error("获取分发规则失败:", error) toast({ - title: "保存成功", - description: "流量分配计划已更新", - }); - router.push('/workspace/traffic-distribution'); - } else { - toast({ - title: "保存失败", - description: data.msg || "请稍后重试", + title: "加载失败", + description: "无法加载分发规则详情", variant: "destructive", - }); + }) + setLoading(false) } - } catch (error) { - toast({ - title: "保存失败", - description: "网络错误,请稍后重试", - variant: "destructive", - }); } - }; - const isStep1Valid = formData.name && formData.source - const isStep2Valid = formData.targetGroups.length > 0 || formData.targetDevices.length > 0 - const isStep3Valid = true // 规则设置可以有默认值 + fetchData() + }, [params.id, toast]) - return ( -
-
-
-
- -

编辑流量分发

-
-
-
+ const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target + setFormData((prev) => ({ ...prev, [name]: value })) + } -
- {/* 步骤指示器 */} -
-
- {[ - { step: 1, title: "基本信息", icon: }, - { step: 2, title: "目标设置", icon: }, - { step: 3, title: "规则配置", icon: }, - ].map(({ step, title, icon }) => ( -
-
- {step < currentStep ? "✓" : icon} -
- {title} -
- ))} -
-
-
-
-
-
+ const handleSwitchChange = (checked: boolean, name: string) => { + setFormData((prev) => ({ ...prev, [name]: checked })) + } - {/* 步骤1:基本信息 */} - {currentStep === 1 && ( - - - 基本信息 - 设置流量分发计划的基本信息 - - -
- - updateFormData("name", e.target.value)} - /> -
+ const handleSelectChange = (value: string, name: string) => { + setFormData((prev) => ({ ...prev, [name]: value })) + } -
- -