From f3ea088c75f4ef5ac930c536bfb4ac31356c1b30 Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Sat, 10 Oct 2026 15:13:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(monitor):=20=E4=BB=8E=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E4=B8=8A=E5=BB=BA=E7=9A=84=E4=BB=BB=E5=8A=A1=E6=B0=B8=E8=BF=9C?= =?UTF-8?q?=E6=98=AF=E5=B0=8F=E7=BA=A2=E4=B9=A6=E4=BB=BB=E5=8A=A1=EF=BC=8C?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E4=BB=8E=E6=B2=A1=E8=A2=AB=E4=BC=A0=E4=B8=8A?= =?UTF-8?q?=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:站在抖音页面上新建任务,任务跑到小红书列表里去了;界面上还写着「笔记」。 根因在前端:TaskCreatePayload 里**根本没有 platform 字段**,handleSubmit 拼的 payload 自然也不带它,而后端是 `payload.get("platform") or PLATFORM_XHS` —— 于是不管在哪个 平台标签下建任务,落下来的都是小红书任务。以前只支持小红书,两边都看不出问题。 * TaskCreatePayload 补上 platform(并在注释里写明为什么它是必填),handleSubmit 带上 当前平台。 * 更新任务时不带 platform:平台创建后不可更改,带着会让「平台能改」看起来像真的。 * 三处写死的「笔记」改成按平台取措辞(能力矩阵的 target_hints.note_label): · 任务编辑器的类型选择项「笔记(批量监控指定内容)」 · 「笔记模式下此项不生效」那句提示 · 任务卡片上的类型徽章 —— 它按**任务自己的**平台取词,不是当前平台,因为卡片未必 只出现在同平台的列表里 抖音管它们叫「作品」,小红书叫「笔记」,写死一个对另一个就是错的。 测试 +1:后端这一半也守住 —— 建任务时显式给了平台,就必须落到那个平台,且不得出现在 另一个平台的列表里。前端那半边是 UI,测不了,但后端守住能挡住「给了不用」这类退化。 注意:这次是纯前端漏传,后端那个「缺省回退小红书」的行为本身没变(有测试断言它是 有意为之的兼容行为)。要彻底消灭这类静默错误,可以把缺省值去掉、让 platform 必填 —— 那会破坏 API 兼容性,目前没有任何别的调用方,需要的话说一声。 --- tests/test_platforms.py | 23 +++++++++++++++++++ webui/src/components/monitor/TaskCard.tsx | 9 +++++++- .../components/monitor/TaskEditorDialog.tsx | 15 ++++++++---- webui/src/types/monitor.ts | 7 ++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/tests/test_platforms.py b/tests/test_platforms.py index 355ab54..43235eb 100644 --- a/tests/test_platforms.py +++ b/tests/test_platforms.py @@ -177,6 +177,29 @@ class TestTaskCreationGuard: tasks = (await client.get("/api/monitor/tasks")).json()["tasks"] assert {t["platform"] for t in tasks} == {"xhs"} + @pytest.mark.asyncio + async def test_an_explicit_platform_is_honoured_on_create(self, client): + """建任务时给的平台必须落到那个平台。 + + 缺省值是小红的(接口早期的兼容行为),所以「在抖音页面建任务」如果没有显式 + 带上 platform,就会安安静静地变成一个小红书任务 —— 不报错,只是出现在另一 + 个列表里。前端那半边已经改成必传;这里守住后端这一半:给了就必须用。 + """ + sec_uid = "MS4wLjABAAAATJPY7LAlaa5X-c8uNdWkvz0jUGgpw4eeXIwu_8BhvqE" + created = await client.post( + "/api/monitor/tasks", + json={"name": "抖音任务", "mode": "creator", "platform": "dy", "targets": [sec_uid]}, + ) + assert created.status_code == 201 + + assert (await client.get("/api/monitor/tasks", params={"platform": "xhs"})).json()[ + "tasks" + ] == [] + dy_tasks = ( + await client.get("/api/monitor/tasks", params={"platform": "dy"}) + ).json()["tasks"] + assert [t["name"] for t in dy_tasks] == ["抖音任务"] + class TestPlatformScoping: async def _seed_two_platforms(self, client): diff --git a/webui/src/components/monitor/TaskCard.tsx b/webui/src/components/monitor/TaskCard.tsx index e370813..43e453d 100644 --- a/webui/src/components/monitor/TaskCard.tsx +++ b/webui/src/components/monitor/TaskCard.tsx @@ -3,6 +3,7 @@ import { Bell, CalendarClock, Pencil, Play, Trash2 } from 'lucide-react' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { useDeleteTask, useRunTaskNow, useUpdateTask } from '@/hooks/useMonitor' +import { useCurrentPlatform } from '@/hooks/usePlatform' import { formatRelative } from '@/lib/monitorFormat' import type { MonitorTask } from '@/types/monitor' @@ -46,6 +47,12 @@ export function TaskCard({ task, selected, onSelect, onEdit }: TaskCardProps) { const updateTask = useUpdateTask() const deleteTask = useDeleteTask() const runNow = useRunTaskNow() + // 按**任务自己的**平台取措辞,而不是当前平台 —— 卡片未必只出现在同平台的列表里。 + // 抖音管它们叫「作品」,小红书叫「笔记」,写死一个对另一个就是错的。 + const { platforms } = useCurrentPlatform() + const noteNoun = + platforms.find((entry) => entry.value === task.platform)?.target_hints?.note_label ?? + '笔记' // A suspected cookie failure surfaces here so it is visible without opening // the event feed. @@ -65,7 +72,7 @@ export function TaskCard({ task, selected, onSelect, onEdit }: TaskCardProps) {
- 笔记模式下此项不生效:你列出的每个链接都会被逐条抓取。 + {hints?.note_label ?? '笔记'}模式下此项不生效:你列出的每个链接都会被逐条抓取。
)}