Filter MoneyPrinter Comfy video templates

This commit is contained in:
boos
2026-06-03 11:29:55 +08:00
parent dbc8b715d1
commit 18c039eff3
+71 -4
View File
@@ -146,6 +146,67 @@ function templateLabel(workflow: WorkflowSummary) {
return '私有工作流'; return '私有工作流';
} }
function workflowTimestampLabel(workflow: WorkflowSummary) {
const value = workflow.updatedAt || workflow.createdAt;
if (!value) return '';
const date = new Date(value);
if (Number.isNaN(date.getTime())) return '';
return date.toLocaleString('zh-CN', {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
});
}
function workflowOptionLabel(workflow: WorkflowSummary) {
const name = workflow.name?.trim() || '未命名工作流';
const time = workflowTimestampLabel(workflow);
const suffix = workflow.publicId ? workflow.publicId.slice(0, 8) : String(workflow.id);
return `${name} · ${templateLabel(workflow)}${time ? ` · ${time}` : ''} · ${suffix}`;
}
function workflowLooksVideoCapable(workflow: WorkflowSummary) {
const graphText = JSON.stringify(workflow.graph || {}).toLowerCase();
return [
'video',
'wan',
'ltx',
'seedance',
'kling',
'runway',
'hailuo',
'pixverse',
'image_to_video',
'text_to_video',
'savevideo',
'video combine',
'vhs_videocombine',
'output.preview_video',
'boosapi.text_to_video',
'boosapi.image_to_video',
].some((keyword) => graphText.includes(keyword));
}
function moneyPrinterWorkflows(items: WorkflowSummary[]) {
const seen = new Set<string>();
return items
.filter((workflow) => workflowLooksVideoCapable(workflow))
.filter((workflow) => {
const key = workflow.publicId || String(workflow.id);
if (seen.has(key)) return false;
seen.add(key);
return true;
})
.sort((a, b) => {
const aTemplate = a.isTemplate || a.visibility === 'template' || a.visibility === 'public';
const bTemplate = b.isTemplate || b.visibility === 'template' || b.visibility === 'public';
if (aTemplate !== bTemplate) return aTemplate ? -1 : 1;
return String(b.updatedAt || b.createdAt || '').localeCompare(String(a.updatedAt || a.createdAt || ''));
});
}
export default function MoneyPrinter() { export default function MoneyPrinter() {
const location = useLocation(); const location = useLocation();
const audience: SessionAudience = location.pathname.startsWith('/user/') ? 'user' : 'admin'; const audience: SessionAudience = location.pathname.startsWith('/user/') ? 'user' : 'admin';
@@ -178,8 +239,14 @@ export default function MoneyPrinter() {
const loadWorkflows = useCallback(async () => { const loadWorkflows = useCallback(async () => {
const payload = await client.getWorkflows({ include_public: true }); const payload = await client.getWorkflows({ include_public: true });
const items = Array.isArray(payload.items) ? payload.items : []; const items = Array.isArray(payload.items) ? payload.items : [];
setWorkflows(items); const videoItems = moneyPrinterWorkflows(items);
setTemplateId((current) => current || items.find((item) => item.isTemplate || item.visibility === 'template' || item.visibility === 'public')?.publicId || ''); setWorkflows(videoItems);
setTemplateId((current) => {
if (current && videoItems.some((item) => item.publicId === current)) return current;
return videoItems.find((item) => item.isTemplate || item.visibility === 'template' || item.visibility === 'public')?.publicId
|| videoItems[0]?.publicId
|| '';
});
}, [client]); }, [client]);
useEffect(() => { useEffect(() => {
@@ -354,7 +421,7 @@ export default function MoneyPrinter() {
<div className="money-printer-section-head"> <div className="money-printer-section-head">
<div> <div>
<h2>Comfy API 工作流</h2> <h2>Comfy API 工作流</h2>
<p>请选择真实 Comfy/Cloud 支持的视频工作流模板。系统只注入提示词、画幅、分辨率和时长,不再提交 BoosAPI 自定义节点。</p> <p>Comfy/Comfy Cloud 使用原生 /api/prompt 工作流接口,不是 OpenAI /v1 兼容接口。请选择真实视频模板,系统只注入提示词、画幅、分辨率和时长。</p>
</div> </div>
</div> </div>
<label className="money-printer-field"> <label className="money-printer-field">
@@ -363,7 +430,7 @@ export default function MoneyPrinter() {
<option value="">请选择模板</option> <option value="">请选择模板</option>
{workflows.map((workflow) => ( {workflows.map((workflow) => (
<option key={workflow.publicId} value={workflow.publicId}> <option key={workflow.publicId} value={workflow.publicId}>
{workflow.name} · {templateLabel(workflow)} {workflowOptionLabel(workflow)}
</option> </option>
))} ))}
</select> </select>