From ab3a544eece92b30e370f334c14a1339ad7a55af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=AB=E5=87=A4=E8=90=8D?= Date: Wed, 19 Aug 2026 15:08:17 +0800 Subject: [PATCH] feat: add MCP creator screenshot metrics recognition --- app/admin-app.tsx | 38 ++++++++-- app/api/creator-screenshot/route.ts | 15 +++- app/api/partner-upload/route.ts | 44 ++++++++++- app/api/upload/route.ts | 34 ++++++++- koc-portal/app/page.tsx | 41 ++++++---- koc-portal/tests/rendered-html.test.mjs | 4 +- lib/collection-service.ts | 32 +++++++- lib/creator-screenshot-access.ts | 60 +++++++++++++++ lib/mcp-collection-client.ts | 99 +++++++++++++++++++++++-- tests/date-utils.test.mjs | 2 +- tests/mcp-collection-client.test.mjs | 2 +- tests/rendered-html.test.mjs | 7 +- 12 files changed, 342 insertions(+), 36 deletions(-) create mode 100644 lib/creator-screenshot-access.ts diff --git a/app/admin-app.tsx b/app/admin-app.tsx index 7eaf551..7b6aff6 100644 --- a/app/admin-app.tsx +++ b/app/admin-app.tsx @@ -494,6 +494,9 @@ export default function Home({ currentUser }: { currentUser: AuthUser }) { const [activeNav, setActiveNav] = useState("overview"); const [loading, setLoading] = useState(true); const [working, setWorking] = useState(false); + const [collectingDistributionIds, setCollectingDistributionIds] = useState>( + new Set(), + ); const [error, setError] = useState(""); const [toast, setToast] = useState(""); const [menuOpen, setMenuOpen] = useState(false); @@ -762,10 +765,23 @@ export default function Home({ currentUser }: { currentUser: AuthUser }) { }; const collectMetrics = async (distribution: Distribution) => { - await runAction( - { action: "collect_now", distributionId: distribution.id }, - "公开数据已更新", - ); + setCollectingDistributionIds((current) => { + const next = new Set(current); + next.add(distribution.id); + return next; + }); + try { + await runAction( + { action: "collect_now", distributionId: distribution.id }, + "公开数据已更新", + ); + } finally { + setCollectingDistributionIds((current) => { + const next = new Set(current); + next.delete(distribution.id); + return next; + }); + } }; const updateDistributionPublishUrl = async ( @@ -1123,6 +1139,7 @@ export default function Home({ currentUser }: { currentUser: AuthUser }) { tasks={data.tasks} distributions={data.distributions} working={working} + collectingDistributionIds={collectingDistributionIds} canUpdatePublishUrl={isManager} onCollect={collectMetrics} onUpdatePublishUrl={updateDistributionPublishUrl} @@ -2815,6 +2832,7 @@ function RecoveryPage({ tasks, distributions, working, + collectingDistributionIds, canUpdatePublishUrl, onCollect, onUpdatePublishUrl, @@ -2829,6 +2847,7 @@ function RecoveryPage({ tasks: Task[]; distributions: Distribution[]; working: boolean; + collectingDistributionIds: ReadonlySet; canUpdatePublishUrl: boolean; onCollect: (distribution: Distribution) => void; onUpdatePublishUrl: (distribution: Distribution) => void; @@ -3116,7 +3135,9 @@ function RecoveryPage({ ) : item.screenshot_key ? ( - 待KOC填写数据 + {item.ocr_status === "processing" + ? "正在识别数据" + : "识别失败,请手动填写"} ) : null} {item.screenshot_key && @@ -3139,7 +3160,12 @@ function RecoveryPage({ ) : (