feat: package docker deployment and publish flow

This commit is contained in:
theshy
2026-04-22 16:20:03 +08:00
parent 055474360e
commit 2146687dc6
178 changed files with 24318 additions and 20855 deletions

View File

@ -1,142 +1,142 @@
export function statusClass(status) {
if (["collection_synced", "published", "done", "resolved", "present"].includes(status)) return "good";
if (["failed_manual"].includes(status)) return "hot";
if (["failed_retryable", "pending", "running", "retry_now", "waiting_retry", "manual_now"].includes(status)) return "warn";
return "";
}
export function formatDate(value) {
if (!value) return "-";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return date.toLocaleString("zh-CN", { hour12: false });
}
export function summarizeAttention(task) {
if (task.status === "failed_manual") return "manual_now";
if (task.retry_state?.retry_due) return "retry_now";
if (task.status === "failed_retryable" && task.retry_state?.next_retry_at) return "waiting_retry";
if (task.status === "running") return "running";
return "stable";
}
export function attentionLabel(value) {
return {
manual_now: "需人工",
retry_now: "立即重试",
waiting_retry: "等待重试",
running: "处理中",
stable: "正常",
}[value] || value;
}
export function summarizeDelivery(delivery = {}) {
if (delivery.split_comment === "pending" || delivery.full_video_timeline_comment === "pending") return "pending_comment";
if (delivery.source_video_present === false || delivery.split_videos_present === false) return "cleanup_removed";
return "stable";
}
export function deliveryLabel(value) {
return {
done: "已发送",
pending: "待处理",
present: "保留",
removed: "已清理",
cleanup_removed: "已清理视频",
pending_comment: "评论待完成",
stable: "正常",
}[value] || value;
}
export function taskDisplayStatus(task) {
if (!task) return "-";
if (task.status === "failed_manual") return "需人工处理";
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") return "等待B站可见";
if (task.status === "failed_retryable") return "等待自动重试";
return {
created: "已接收",
transcribed: "已转录",
songs_detected: "已识歌",
split_done: "已切片",
published: "已上传",
commented: "评论完成",
collection_synced: "已完成",
running: "处理中",
}[task.status] || task.status || "-";
}
export function stepLabel(stepName) {
return {
ingest: "接收视频",
transcribe: "转录字幕",
song_detect: "识别歌曲",
split: "切分分P",
publish: "上传分P",
comment: "发布评论",
collection_a: "加入完整版合集",
collection_b: "加入分P合集",
}[stepName] || stepName || "-";
}
export function currentStepLabel(task, steps = []) {
const running = steps.find((step) => step.status === "running");
if (running) return stepLabel(running.step_name);
if (task?.retry_state?.step_name) return `${stepLabel(task.retry_state.step_name)} · ${taskDisplayStatus(task)}`;
const pending = steps.find((step) => step.status === "pending");
if (pending) return stepLabel(pending.step_name);
return {
created: "转录字幕",
transcribed: "识别歌曲",
songs_detected: "切分分P",
split_done: "上传分P",
published: "评论与合集",
commented: "同步合集",
collection_synced: "链路完成",
}[task?.status] || "-";
}
export function taskPrimaryActionLabel(task) {
if (!task) return "执行";
if (task.status === "failed_manual") return "人工重跑";
if (task.retry_state?.retry_due) return "立即重试";
if (task.status === "failed_retryable") return "继续处理";
if (task.status === "collection_synced") return "查看";
return "执行";
}
export function actionAdvice(task) {
if (!task) return "";
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") {
return "B站通常需要一段时间完成转码和审核系统会自动重试评论。";
}
if (task.status === "failed_retryable") {
return "当前错误可自动恢复,等到重试时间或手工触发即可。";
}
if (task.status === "failed_manual") {
return "先看错误信息,再决定是重试步骤还是绑定完整版 BV。";
}
if (task.status === "collection_synced") {
return "链路已完成可以直接打开分P或完整版链接检查结果。";
}
return "系统会继续推进后续步骤,必要时可在这里手工干预。";
}
export function recommendedAction(task) {
if (!task) return { label: "查看任务", detail: "先打开详情,确认当前步骤和最近动作。", action: "open" };
if (task.status === "failed_manual") {
return { label: "处理失败步骤", detail: "这是需要人工介入的任务,优先查看错误并决定是否重试。", action: "retry" };
}
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") {
return { label: "等待平台可见", detail: "B站通常需要转码和审核暂时不需要人工操作。", action: "wait" };
}
if (task.retry_state?.retry_due) {
return { label: "立即重试", detail: "已经到达重试窗口,可以立即推进当前步骤。", action: "retry" };
}
if (task.status === "published") {
return { label: "检查评论与合集", detail: "上传已经完成,下一步是确认评论和合集同步。", action: "open" };
}
if (task.status === "collection_synced") {
return { label: "检查最终结果", detail: "链路已经完成,可直接打开视频或做清理确认。", action: "open" };
}
return { label: "继续观察", detail: "当前任务仍在正常推进,必要时可手工执行一轮。", action: "open" };
}
export function statusClass(status) {
if (["collection_synced", "published", "done", "resolved", "present"].includes(status)) return "good";
if (["failed_manual"].includes(status)) return "hot";
if (["failed_retryable", "pending", "running", "retry_now", "waiting_retry", "manual_now"].includes(status)) return "warn";
return "";
}
export function formatDate(value) {
if (!value) return "-";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return date.toLocaleString("zh-CN", { hour12: false });
}
export function summarizeAttention(task) {
if (task.status === "failed_manual") return "manual_now";
if (task.retry_state?.retry_due) return "retry_now";
if (task.status === "failed_retryable" && task.retry_state?.next_retry_at) return "waiting_retry";
if (task.status === "running") return "running";
return "stable";
}
export function attentionLabel(value) {
return {
manual_now: "需人工",
retry_now: "立即重试",
waiting_retry: "等待重试",
running: "处理中",
stable: "正常",
}[value] || value;
}
export function summarizeDelivery(delivery = {}) {
if (delivery.split_comment === "pending" || delivery.full_video_timeline_comment === "pending") return "pending_comment";
if (delivery.source_video_present === false || delivery.split_videos_present === false) return "cleanup_removed";
return "stable";
}
export function deliveryLabel(value) {
return {
done: "已发送",
pending: "待处理",
present: "保留",
removed: "已清理",
cleanup_removed: "已清理视频",
pending_comment: "评论待完成",
stable: "正常",
}[value] || value;
}
export function taskDisplayStatus(task) {
if (!task) return "-";
if (task.status === "failed_manual") return "需人工处理";
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") return "等待B站可见";
if (task.status === "failed_retryable") return "等待自动重试";
return {
created: "已接收",
transcribed: "已转录",
songs_detected: "已识歌",
split_done: "已切片",
published: "已上传",
commented: "评论完成",
collection_synced: "已完成",
running: "处理中",
}[task.status] || task.status || "-";
}
export function stepLabel(stepName) {
return {
ingest: "接收视频",
transcribe: "转录字幕",
song_detect: "识别歌曲",
split: "切分分P",
publish: "上传分P",
comment: "发布评论",
collection_a: "加入完整版合集",
collection_b: "加入分P合集",
}[stepName] || stepName || "-";
}
export function currentStepLabel(task, steps = []) {
const running = steps.find((step) => step.status === "running");
if (running) return stepLabel(running.step_name);
if (task?.retry_state?.step_name) return `${stepLabel(task.retry_state.step_name)} · ${taskDisplayStatus(task)}`;
const pending = steps.find((step) => step.status === "pending");
if (pending) return stepLabel(pending.step_name);
return {
created: "转录字幕",
transcribed: "识别歌曲",
songs_detected: "切分分P",
split_done: "上传分P",
published: "评论与合集",
commented: "同步合集",
collection_synced: "链路完成",
}[task?.status] || "-";
}
export function taskPrimaryActionLabel(task) {
if (!task) return "执行";
if (task.status === "failed_manual") return "人工重跑";
if (task.retry_state?.retry_due) return "立即重试";
if (task.status === "failed_retryable") return "继续处理";
if (task.status === "collection_synced") return "查看";
return "执行";
}
export function actionAdvice(task) {
if (!task) return "";
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") {
return "B站通常需要一段时间完成转码和审核系统会自动重试评论。";
}
if (task.status === "failed_retryable") {
return "当前错误可自动恢复,等到重试时间或手工触发即可。";
}
if (task.status === "failed_manual") {
return "先看错误信息,再决定是重试步骤还是绑定完整版 BV。";
}
if (task.status === "collection_synced") {
return "链路已完成可以直接打开分P或完整版链接检查结果。";
}
return "系统会继续推进后续步骤,必要时可在这里手工干预。";
}
export function recommendedAction(task) {
if (!task) return { label: "查看任务", detail: "先打开详情,确认当前步骤和最近动作。", action: "open" };
if (task.status === "failed_manual") {
return { label: "处理失败步骤", detail: "这是需要人工介入的任务,优先查看错误并决定是否重试。", action: "retry" };
}
if (task.status === "failed_retryable" && task.retry_state?.step_name === "comment") {
return { label: "等待平台可见", detail: "B站通常需要转码和审核暂时不需要人工操作。", action: "wait" };
}
if (task.retry_state?.retry_due) {
return { label: "立即重试", detail: "已经到达重试窗口,可以立即推进当前步骤。", action: "retry" };
}
if (task.status === "published") {
return { label: "检查评论与合集", detail: "上传已经完成,下一步是确认评论和合集同步。", action: "open" };
}
if (task.status === "collection_synced") {
return { label: "检查最终结果", detail: "链路已经完成,可直接打开视频或做清理确认。", action: "open" };
}
return { label: "继续观察", detail: "当前任务仍在正常推进,必要时可手工执行一轮。", action: "open" };
}