"use client" import { use, useState, useEffect } from "react" import { Copy, Link, HelpCircle, Shield, ChevronLeft, Plus } from "lucide-react" import { Button } from "@/components/ui/button" import { useRouter } from "next/navigation" import { toast } from "@/components/ui/use-toast" import { ScenarioAcquisitionCard } from "@/app/components/acquisition/ScenarioAcquisitionCard" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { api, ApiResponse } from "@/lib/api" interface Task { id: string name: string status: "running" | "paused" | "completed" stats: { devices: number acquired: number added: number } lastUpdated: string executionTime: string nextExecutionTime: string trend: { date: string; customers: number }[] } interface DeviceStats { active: number } // API文档提示组件 function ApiDocumentationTooltip() { return (

计划接口允许您通过API将外部系统的客户数据直接导入到存客宝。支持多种编程语言和第三方平台集成。

) } // export default function ChannelPage({ params }: { params: { channel: string } }) { export default function ChannelPage({ params }: { params: Promise<{ channel: string }> }) { const router = useRouter() // const unwrappedParams = use(params) const resolvedParams = use(params) // const channel = params.channel // const channelName = getChannelName(params.channel) // const channel = unwrappedParams.channel // const channelName = getChannelName(unwrappedParams.channel) const channel = resolvedParams.channel const [channelName, setChannelName] = useState("") // 1. tasks 初始值设为 [] const [tasks, setTasks] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState("") const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(10) const [total, setTotal] = useState(0) useEffect(() => { api.get(`/v1/plan/scenes-detail?id=${channel}`) .then((res: ApiResponse) => { if (res.code === 200 && res.data?.name) { setChannelName(res.data.name) } else { setChannelName(channel) } }) .catch(() => setChannelName(channel)) }, [channel]) // 抽出请求列表的函数 const fetchTasks = () => { setLoading(true) setError("") api.get(`/v1/plan/list?sceneId=${channel}&page=${page}&pageSize=${pageSize}`) .then((res: ApiResponse) => { if (res.code === 200 && Array.isArray(res.data?.list)) { setTasks(res.data.list) setTotal(res.data.total || 0) } else { setError(res.msg || "接口返回异常") } }) .catch(err => setError(err?.message || "接口请求失败")) .finally(() => setLoading(false)) } useEffect(() => { fetchTasks() }, [channel, page, pageSize]) const [deviceStats, setDeviceStats] = useState({ active: 5, }) const [showApiDialog, setShowApiDialog] = useState(false) const [currentApiSettings, setCurrentApiSettings] = useState({ apiKey: "", webhookUrl: "", taskId: "", }) const handleEditPlan = (taskId: string) => { router.push(`/scenarios/${channel}/edit/${taskId}`) } const handleCopyPlan = (taskId: string) => { const taskToCopy = tasks.find((task) => task.id === taskId) if (!taskToCopy) return; api.get(`/v1/plan/copy?planId=${taskId}`) .then((res: ApiResponse) => { if (res.code === 200) { toast({ title: "计划已复制", description: `已成功复制"${taskToCopy.name}"`, variant: "default", }) setPage(1) fetchTasks() } else { toast({ title: "复制失败", description: res.msg || "复制计划失败,请重试", variant: "destructive", }) } }) .catch(err => { toast({ title: "复制失败", description: err?.message || "复制计划失败,请重试", variant: "destructive", }) }) } const handleDeletePlan = (taskId: string) => { const taskToDelete = tasks.find((t) => t.id === taskId) if (!taskToDelete) return; api.delete(`/v1/plan/delete?planId=${taskId}`) .then((res: ApiResponse) => { if (res.code === 200) { setTasks(tasks.filter((t) => t.id !== taskId)) toast({ title: "计划已删除", description: `已成功删除"${taskToDelete.name}"`, variant: "default", }) } else { toast({ title: "删除失败", description: res.msg || "删除计划失败,请重试", variant: "destructive", }) } }) .catch(err => { toast({ title: "删除失败", description: err?.message || "删除计划失败,请重试", variant: "destructive", }) }) } const handleStatusChange = (taskId: string, newStatus: "running" | "paused") => { setTasks(tasks.map((task) => (task.id === taskId ? { ...task, status: newStatus } : task))) toast({ title: newStatus === "running" ? "计划已启动" : "计划已暂停", description: `已${newStatus === "running" ? "启动" : "暂停"}获客计划`, variant: "default", }) } const handleOpenApiSettings = (taskId: string) => { const task = tasks.find((t) => t.id === taskId) if (task) { setCurrentApiSettings({ apiKey: `api_${taskId}_${Math.random().toString(36).substring(2, 10)}`, webhookUrl: `${window.location.origin}/api/scenarios/${channel}/${taskId}/webhook`, taskId, }) setShowApiDialog(true) } } const handleCopyApiUrl = (url: string, withParams = false) => { let copyUrl = url if (withParams) { copyUrl = `${url}?name=张三&phone=13800138000&source=外部系统&remark=测试数据` } navigator.clipboard.writeText(copyUrl) toast({ title: "已复制", description: withParams ? "接口地址(含示例参数)已复制到剪贴板" : "接口地址已复制到剪贴板", variant: "default", }) } const handleCreateNewPlan = () => { // router.push(`/plans/new?type=${channel}`) router.push(`/scenarios/new?type=${channel}`) } return (

{channelName}

{loading ? (
加载中...
) : error ? (
{error}
) : tasks.length > 0 ? ( <> {tasks.map((task) => (
handleEditPlan(task.id)} onCopy={handleCopyPlan} onDelete={handleDeletePlan} onStatusChange={handleStatusChange} onOpenSettings={handleOpenApiSettings} />
))}
第 {page} 页 / 共 {Math.max(1, Math.ceil(total / pageSize))} 页
) : (
暂无获客计划
)}
{/* API接口设置对话框 */}
计划接口
使用此接口直接导入客资到该获客计划,支持多种编程语言。
{/* API密钥部分 */}
用于接口身份验证
{/* 接口地址部分 */}

必要参数:name(姓名)、phone(电话)
可选参数:source(来源)、remark(备注)、tags(标签)

{/* 接口文档部分 */}
{/* 快速测试部分 */}

使用以下URL可以快速测试接口是否正常工作:

{`${currentApiSettings.webhookUrl}?name=测试客户&phone=13800138000`}
接口安全加密传输
) }