auto-save 2026-05-17 21:52 (~3)

This commit is contained in:
2026-05-17 21:52:55 +08:00
parent bd86140cf6
commit 358e051bed
3 changed files with 32 additions and 20 deletions

View File

@@ -1,18 +1,5 @@
{
"entries": [
{
"files_changed": 1,
"message": "Codex 会话活跃 · 最近命令codex · 1 项未提交变更 · 最近提交auto-save 2026-05-15 13:11 (~1)",
"ts": "2026-05-15T05:14:45Z",
"type": "session-heartbeat"
},
{
"files_changed": 1,
"hash": "37f10c7",
"message": "auto-save 2026-05-15 13:16 (~1)",
"ts": "2026-05-15T13:17:05+08:00",
"type": "commit"
},
{
"files_changed": 1,
"hash": "39ada53",
@@ -3260,6 +3247,19 @@
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令codex · 分支 main · 3 项未提交变更 · 最近提交auto-save 2026-05-17 21:36 (~4)",
"files_changed": 3
},
{
"ts": "2026-05-17T21:42:09+08:00",
"type": "commit",
"message": "auto-save 2026-05-17 21:42 (~3)",
"hash": "bd86140",
"files_changed": 3
},
{
"ts": "2026-05-17T13:48:30Z",
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令codex · 分支 main · 2 项未提交变更 · 最近提交auto-save 2026-05-17 21:42 (~3)",
"files_changed": 2
}
]
}

View File

@@ -589,7 +589,7 @@
<tr><td><code>web/next.config.mjs</code></td><td>Next.js 构建配置:静态导出、图片不走优化、禁用开发环境左下角 Next Dev Indicator并移除 Next 16 已不支持的 <code>eslint</code> 顶层配置,避免本地 dev 出现配置 Issue 提示。</td></tr>
<tr><td><code>web/app/globals.css</code></td><td>全局主题变量、登录页视觉样式、ReactFlow 样式引用,以及本地开发态 <code>nextjs-portal</code> 遮挡隐藏规则。</td></tr>
<tr><td><code>web/app/page.tsx</code></td><td>产品工作台主状态jobs、activeJobId、生成任务状态主渲染为全屏素材输入列 + 信息流广告复刻工作表;“开始”编排状态只负责在下载完成后自动触发 <code>triggerTranscribe</code>不再默认触发抽帧、Vision 扫描或分镜初稿保存;底部吸附音频条不再从主界面渲染。</td></tr>
<tr><td><code>web/components/ad-recreation-board.tsx</code></td><td>信息流广告复刻工作表:左侧素材输入;右侧展示视频下载状态、默认折叠的音频文案依据,以及统一的音频解析结果面板;面板顶部是一行讲话人/节奏/背景音摘要,下方左侧为原视频播放器,中间为“关键帧 / 相似主角”,右侧为逐句时间轴,底部横向音频波形用参考图式的连续灰色包络显示响度、停顿和密集爆点。视频播放时通过 <code>requestAnimationFrame</code> 平滑驱动波形播放线,同时同步高亮并滚动当前句;点击音频波形或字幕行会跳转原视频时间。关键帧区一键按动作目标重新抽取 12 张源视频关键帧,人工勾选后调用 <code>generateSubjectAssets</code><code>source_actor + similar</code> 模式生成 6 张白底相似主角视图;这是新演员重构,不做像素提取或精确复刻源人物身份。音频结果下方是信息流复刻分镜工作台:顶部产品参考区是“同一产品素材池”,不限量上传产品图,不做不同产品身份判断;上传原图推荐长边 1200-2000px、短边至少 600px但后端会统一生成最长边 1600px、JPEG 92 的 AI 工作副本,并回显尺寸、自动转换和风险标注;上传后按“套在脖子上的 U 形肩颈按摩仪”进行同一产品批量识别,左/右按佩戴者身体左右、上/下按佩戴方向,额外标注内外侧、开口方向、局部结构点、背景类型、用途标签、生成风险和备注,用户只检查备注,鼠标悬停通过固定浮层显示大图预览,能盖过滚动容器和分镜框架;缺视角补图失败时保留重试入口。脚本区在分镜行上方提供“作者想法”和“整片改写”,每行新口播文案可直接编辑并可单段 AI 改写,原内容和新文案列压缩为紧凑脚本列;生成本条视频时使用当前编辑后的新口播文案。每条音频分镜纵向排列,行内从左到右串起原内容、新口播文案、画面规划/产品融入和 6 个候选视频槽;单条生成会从全局选中关键帧或 12 张关键帧中取最贴近本句时间点的参考帧。单条生成会从产品素材池按分镜角色、视角优先级、用途标签、置信度和风险自动挑选最多 6 张相关产品图,不会把全部产品图提交给生视频模型,然后把产品坐标系、视角标注、方向、结构点和风险写入 Seedance 提示。旧分镜卡、抽帧控制和视频生成组件仍保留在文件里,但当前主路径不渲染。</td></tr>
<tr><td><code>web/components/ad-recreation-board.tsx</code></td><td>信息流广告复刻工作表:左侧素材输入;右侧展示视频下载状态、默认折叠的音频文案依据,以及统一的音频解析结果面板;面板顶部是一行讲话人/节奏/背景音摘要,下方左侧为原视频播放器,中间为“关键帧 / 相似主角”,右侧为逐句时间轴,底部横向音频波形用参考图式的连续灰色包络显示响度、停顿和密集爆点。视频播放时通过 <code>requestAnimationFrame</code> 平滑驱动波形播放线,同时同步高亮并滚动当前句;点击音频波形或字幕行会跳转原视频时间。关键帧区一键按动作目标重新抽取 12 张源视频关键帧,人工勾选后调用 <code>generateSubjectAssets</code><code>source_actor + similar</code> 模式生成 6 张白底相似主角视图;这是新演员重构,不做像素提取或精确复刻源人物身份。音频结果下方是信息流复刻分镜工作台:顶部产品参考区是“同一产品素材池”,不限量上传产品图,不做不同产品身份判断;上传原图推荐长边 1200-2000px、短边至少 600px但后端会统一生成最长边 1600px、JPEG 92 的 AI 工作副本,并回显尺寸、自动转换和风险标注;上传后按“套在脖子上的 U 形肩颈按摩仪”进行同一产品批量识别,左/右按佩戴者身体左右、上/下按佩戴方向,额外标注内外侧、开口方向、局部结构点、背景类型、用途标签、生成风险和备注,用户只检查备注,鼠标悬停通过固定浮层显示大图预览,能盖过滚动容器和分镜框架;缺视角补图失败时保留重试入口。脚本区在分镜行上方提供“作者想法”和“整片改写”,每行新口播文案可直接编辑并可单段 AI 改写,分镜时间和原内容列压缩为窄摘要列,把横向空间留给新口播、画面规划和视频候选;生成本条视频时使用当前编辑后的新口播文案。每条音频分镜纵向排列,行内从左到右串起原内容、新口播文案、画面规划/产品融入和 6 个候选视频槽;候选视频槽在宽屏下一排显示 6 个竖版预览,避免前面空旷、后面拥挤。单条生成会从全局选中关键帧或 12 张关键帧中取最贴近本句时间点的参考帧。单条生成会从产品素材池按分镜角色、视角优先级、用途标签、置信度和风险自动挑选最多 6 张相关产品图,不会把全部产品图提交给生视频模型,然后把产品坐标系、视角标注、方向、结构点和风险写入 Seedance 提示。旧分镜卡、抽帧控制和视频生成组件仍保留在文件里,但当前主路径不渲染。</td></tr>
<tr><td><code>web/app/login/page.tsx</code></td><td>生产登录页:访问账号/访问密钥表单、保持登录、错误/成功状态;当前只在原版 Digital Oasis 动态背景上叠加一个组合登录框,桌面端左侧是动态角色,右侧是图标化登录表单;面板左上角展示官网 SKG 字标和中文“营销内容工作台”系统标识。</td></tr>
<tr><td><code>web/app/login/layout.tsx</code></td><td>登录路由专属 layout覆盖全站默认网页标题和描述为空避免 <code>/login</code> 继承工作台 metadata 后在页面源码里继续出现登录界面文字以外的文案。</td></tr>
<tr><td><code>web/components/login/oasis-canvas.tsx</code></td><td>登录页全屏动态视觉层:用 iframe 直接承载下载包 <code>web/public/oasis-source/index.html</code> 的原 WebGPU / Three.js 草场源码;父级登录页只覆盖自己的文案和表单,并在捕获阶段把全局鼠标坐标同时用原生事件和 <code>postMessage</code> 转发给 iframe避免登录面板或输入框遮挡时草地失去鼠标响应。</td></tr>
@@ -1002,6 +1002,18 @@ ProductRefStateItem {
<h2>变更记录</h2>
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
<div class="changelog">
<article class="change">
<header>
<h3>2026-05-17 · 分镜行前窄后宽重新分配</h3>
<span class="tag rose">UI</span>
<span class="tag cyan">Workflow</span>
</header>
<div class="body">
<p><strong>问题:</strong>分镜行前面的“分镜 / 原内容”信息量很少,却占了过多横向空间;右侧 6 个视频候选槽被压成拥挤的 2x3 小格。</p>
<p><strong>改动:</strong><code>AudioStoryboardPlanPanel</code> 的行 grid 改为前两列固定窄列,宽屏下视频列固定放大;<code>StoryboardVideoSlots</code> 从 3 列 2 行改为一排 6 个竖版候选预览。</p>
<p><strong>影响:</strong><code>web/components/ad-recreation-board.tsx</code><code>docs/source-analysis.html</code>。后续这个区域按“工作表高密度排版”处理,低信息字段不再占大列宽。</p>
</div>
</article>
<article class="change">
<header>
<h3>2026-05-17 · 产品素材池持久化到 job</h3>

View File

@@ -1816,17 +1816,17 @@ function AudioStoryboardPlanPanel({
return (
<article
key={row.index}
className="grid overflow-hidden rounded-md border border-white/10 bg-black/24 text-[11px] leading-snug text-white/64 xl:grid-cols-[64px_minmax(104px,0.54fr)_minmax(148px,0.72fr)_minmax(220px,1fr)_270px]"
className="grid overflow-hidden rounded-md border border-white/10 bg-black/24 text-[11px] leading-snug text-white/64 xl:grid-cols-[56px_140px_minmax(220px,0.75fr)_minmax(240px,0.8fr)_minmax(320px,1fr)] 2xl:grid-cols-[58px_170px_minmax(360px,0.8fr)_minmax(380px,1fr)_520px]"
>
<StoryboardPlanCell label="分镜">
<div className="font-mono text-[11px] text-white/40">{row.start.toFixed(1)}-{row.end.toFixed(1)}s</div>
<div className="mt-2 inline-flex max-w-full rounded-md border border-emerald-300/15 bg-emerald-300/[0.08] px-2 py-1 text-[11px] text-emerald-100/80">
<div className="mt-1.5 inline-flex max-w-full rounded-md border border-emerald-300/15 bg-emerald-300/[0.08] px-1.5 py-0.5 text-[10px] leading-tight text-emerald-100/80">
{row.role}
</div>
</StoryboardPlanCell>
<StoryboardPlanCell label="原内容">
<p className="line-clamp-3 text-[10.5px] leading-snug" title={row.source}>{row.source}</p>
<p className="line-clamp-2 text-[10.5px] leading-snug" title={row.source}>{row.source}</p>
</StoryboardPlanCell>
<StoryboardPlanCell label="新口播文案">
@@ -2038,12 +2038,12 @@ function StoryboardVideoSlots({ job, videos, enabled }: { job: Job; videos: Gene
const emptyCount = Math.max(0, 6 - visible.length)
return (
<div>
<div className="grid grid-cols-3 gap-1.5">
<div className="grid grid-cols-6 gap-1.5">
{visible.map((video) => (
<StoryboardVideoPreview key={video.id} job={job} video={video} className="h-[74px] w-full" />
<StoryboardVideoPreview key={video.id} job={job} video={video} className="aspect-[9/16] min-h-[86px] w-full" />
))}
{Array.from({ length: emptyCount }).map((_, index) => (
<div key={`empty-video-${index}`} className="flex h-[74px] min-w-0 items-center justify-center rounded border border-dashed border-white/12 bg-black/25 px-1 text-center text-[10px] leading-tight text-white/26">
<div key={`empty-video-${index}`} className="flex aspect-[9/16] min-h-[86px] min-w-0 items-center justify-center rounded border border-dashed border-white/12 bg-black/25 px-1 text-center text-[9.5px] leading-tight text-white/26">
{enabled ? `候选 ${visible.length + index + 1}` : "先抽 12 帧"}
</div>
))}