|
|
@@ -98,6 +98,7 @@ export function LedgerPage({ runId }: { runId: string }) {
|
|
|
{rows.map((row) => (
|
|
|
<QueryGroupRows key={row.id} runId={runId} row={row} />
|
|
|
))}
|
|
|
+ <DeducedSourceRows rows={rows} demand={ledger.demandSummary} />
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</section>
|
|
|
@@ -276,6 +277,45 @@ function sourceKindClass(kind: string): string {
|
|
|
return "unknown";
|
|
|
}
|
|
|
|
|
|
+// 首轮取词三源:需求池直出(seed_term)/ 票圈帖子的点(query_seed_point)/ 分类叶子(category_leaf_element)。
|
|
|
+const FIRST_ROUND_SOURCE_TYPES = ["seed_term", "query_seed_point", "category_leaf_element"];
|
|
|
+
|
|
|
+function sourceTypeHasMaterial(type: string, demand?: DemandSummary): boolean {
|
|
|
+ if (!demand) return false;
|
|
|
+ if (type === "seed_term") return demand.seedTerms.length > 0;
|
|
|
+ if (type === "category_leaf_element") return demand.categoryPaths.length > 0;
|
|
|
+ if (type === "query_seed_point") return demand.extractedPoints.length > 0;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+// CFA 取词时同一个词只搜一次,后命中的来源被去重丢弃(不入库),前端看不到。
|
|
|
+// 这里据需求素材补出"被去重的来源"占位行:那行留空 + 标注与前面哪些来源重复。
|
|
|
+function DeducedSourceRows({ rows, demand }: { rows: FlowLedgerRow[]; demand?: DemandSummary }) {
|
|
|
+ const present = new Set(rows.map((row) => row.source.sourceKind));
|
|
|
+ const shownLabels = FIRST_ROUND_SOURCE_TYPES.filter((type) => present.has(type)).map((type) => sourceLabel(type));
|
|
|
+ const deduped = FIRST_ROUND_SOURCE_TYPES.filter(
|
|
|
+ (type) => !present.has(type) && sourceTypeHasMaterial(type, demand)
|
|
|
+ );
|
|
|
+ if (!deduped.length) return null;
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ {deduped.map((type) => (
|
|
|
+ <tr className="ledger-row deduped-source-row" key={`deduped-${type}`}>
|
|
|
+ <td className="source-cell sticky-source">
|
|
|
+ <div className="cell-stack">
|
|
|
+ <span className={`source-kind-badge ${sourceKindClass(type)}`}>{sourceLabel(type)}</span>
|
|
|
+ <span className="muted">(此处留空)</span>
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ <td className="muted deduped-source-note" colSpan={4}>
|
|
|
+ 这是「{sourceLabel(type)}」来源,搜索词与前面的{shownLabels.join(" / ") || "已展示"}来源重复(同词只搜一次),所以此处不单独显示。
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ ))}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
function VideoDecisionCell({ video }: { video: VideoRef | null }) {
|
|
|
if (!video) {
|
|
|
return (
|