diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1edf6c1 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,99 @@ +# Airshelf · 电商 AI 平台 · Codex 工程约定 + +> **本文件由 Codex 启动时自动加载。所有 AI 协作必须遵循以下规则。** + +--- + +## 项目简介 + +**Airshelf** · AI 短视频带货生成平台 · 5 阶段流水线(商品 → 故事板 → 镜头 → 生成 → 投放) + +- **设计代号:** Restraint · V2.1 · Firecrawl-aligned +- **主要工作目录:** [电商AI平台/](电商AI平台/) +- **Next.js 工程(独立):** [app/](app/) +- **V1 历史归档:** [v1/](v1/) +- **V2.1 归档(原 v2.1/):** [v2/](v2/) + +--- + +## ★ 设计规范铁律(每次涉及页面 / CSS / UI 必读) + +### 触发条件 +**只要任务涉及以下任一种,必须先 Read [电商AI平台/design.md](电商AI平台/design.md):** +- 修改 `.html` 文件 +- 修改 `assets/restraint.css` 或任何 `.css` +- 修改 inline `
- -
-
-

消息中心// 0 条未读 · 0 条总计

-
// 任务 · 团队 · 系统 · 计费 四类事件流
-
-
- - -
-
- - - - - -
- - -
- - -
-
- - -
- -
-
- // 显示 0 条 - -
-
-
- - -
-
-
- +
+
+
+

消息中心

+
// INBOX 任务提醒 · 团队协作 · 计费与系统公告
-
从左侧选择一条消息查看详情
-
// 点击列表项 · 自动标为已读
+
+ + +
+
+ +
+
+
+ 收件箱 + // 0 条 +
+
+ +
+
+ +
+
+ +
+ // 消息保留 90 天 · 高风险任务会同时进入工作台队列 + 管理通知策略 →
-
- - 消息默认保留 90 天,任务类消息可在「通知设置」中按类别静音或转发到团队邮箱。 - 前往设置 → -
- -
diff --git a/电商AI平台/model-photo.html b/电商AI平台/model-photo.html index dc53649..fb15aef 100644 --- a/电商AI平台/model-photo.html +++ b/电商AI平台/model-photo.html @@ -15,9 +15,12 @@ flex: 1; min-height: 0; display: grid; grid-template-columns: 260px 1fr; + transition: grid-template-columns var(--t-base); } + .mp-layout.side-collapsed { grid-template-columns: 0 1fr; } @media (max-width: 1280px) { .mp-layout { grid-template-columns: 240px 1fr; } + .mp-layout.side-collapsed { grid-template-columns: 0 1fr; } } /* ─── 主区: flat 双区 (头部 + body) · 无 card · 用 border 分隔 ─── */ @@ -55,6 +58,23 @@ color: var(--black-alpha-48); } .mp-main-h .spacer { flex: 1; } + .mp-main-h .side-restore-btn { + height: 32px; + padding: 0 10px; + display: inline-flex; + align-items: center; + gap: 6px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + color: var(--black-alpha-72); + font-family: inherit; + font-size: 12.5px; + cursor: pointer; + } + .mp-main-h .side-restore-btn:hover { border-color: var(--heat-20); color: var(--heat); } + .mp-main-h .side-restore-btn[hidden] { display: none; } + .mp-main-h .side-restore-btn svg { width: 14px; height: 14px; } .mp-main-h .search-btn { width: 32px; height: 32px; background: var(--surface); @@ -177,6 +197,12 @@ display: flex; flex-direction: column; min-height: 0; overflow: hidden; + transition: opacity var(--t-base), transform var(--t-base); + } + .mp-layout.side-collapsed .mp-prod-space { + opacity: 0; + transform: translateX(-8px); + pointer-events: none; } /* 顶部工具栏: 返回 + 折叠 (跟 image-optimize 视觉一致) */ .mp-side-top { @@ -2224,6 +2250,10 @@
+
// 商品空间 未选择 · 请在左侧商品空间选一个 @@ -4737,6 +4767,22 @@ document.getElementById('pv-swap').addEventListener('click', () => { tasks = load(); })(); +/* ---------- 商品空间折叠 / 展开 ---------- */ +(function () { + const layout = document.querySelector('.mp-layout'); + const foldBtn = document.querySelector('.mp-side-top .fold'); + const restoreBtn = document.getElementById('mp-side-restore'); + function setSideCollapsed(collapsed) { + layout?.classList.toggle('side-collapsed', collapsed); + if (restoreBtn) restoreBtn.hidden = !collapsed; + if (foldBtn) foldBtn.setAttribute('aria-expanded', collapsed ? 'false' : 'true'); + try { localStorage.setItem('fs-mp-side-collapsed', collapsed ? '1' : '0'); } catch (e) {} + } + foldBtn?.addEventListener('click', () => setSideCollapsed(true)); + restoreBtn?.addEventListener('click', () => setSideCollapsed(false)); + try { setSideCollapsed(localStorage.getItem('fs-mp-side-collapsed') === '1'); } catch (e) {} +})(); + // 初始化 renderProdSpace(); renderSelectedProds(); diff --git a/电商AI平台/platform-cover.html b/电商AI平台/platform-cover.html index 589f8f2..ef18135 100644 --- a/电商AI平台/platform-cover.html +++ b/电商AI平台/platform-cover.html @@ -14,9 +14,12 @@ flex: 1; min-height: 0; display: grid; grid-template-columns: 260px 1fr; + transition: grid-template-columns var(--t-base); } + .pc-layout.side-collapsed { grid-template-columns: 0 1fr; } @media (max-width: 1280px) { .pc-layout { grid-template-columns: 240px 1fr; } + .pc-layout.side-collapsed { grid-template-columns: 0 1fr; } } /* ─── 主区: flat 双区 · 用 border 分隔 ─── */ @@ -53,6 +56,23 @@ color: var(--black-alpha-48); } .pc-main-h .spacer { flex: 1; } + .pc-main-h .side-restore-btn { + height: 32px; + padding: 0 10px; + display: inline-flex; + align-items: center; + gap: 6px; + background: var(--surface); + border: 1px solid var(--border-faint); + border-radius: var(--r-sm); + color: var(--black-alpha-72); + font-family: inherit; + font-size: 12.5px; + cursor: pointer; + } + .pc-main-h .side-restore-btn:hover { border-color: var(--heat-20); color: var(--heat); } + .pc-main-h .side-restore-btn[hidden] { display: none; } + .pc-main-h .side-restore-btn svg { width: 14px; height: 14px; } .pc-main-h .search-btn { width: 32px; height: 32px; background: var(--surface); @@ -170,6 +190,12 @@ display: flex; flex-direction: column; min-height: 0; overflow: hidden; + transition: opacity var(--t-base), transform var(--t-base); + } + .pc-layout.side-collapsed .pc-prod-space { + opacity: 0; + transform: translateX(-8px); + pointer-events: none; } /* 顶部工具栏: 返回 + 折叠 (跟 image-optimize 视觉一致) */ .pc-side-top { @@ -1159,6 +1185,10 @@
+
// 商品空间 未选择 · 请在左侧商品空间选一个 @@ -2297,6 +2327,22 @@ document.addEventListener('click', e => { tasks = load(); })(); +/* ---------- 商品空间折叠 / 展开 ---------- */ +(function () { + const layout = document.querySelector('.pc-layout'); + const foldBtn = document.querySelector('.pc-side-top .fold'); + const restoreBtn = document.getElementById('pc-side-restore'); + function setSideCollapsed(collapsed) { + layout?.classList.toggle('side-collapsed', collapsed); + if (restoreBtn) restoreBtn.hidden = !collapsed; + if (foldBtn) foldBtn.setAttribute('aria-expanded', collapsed ? 'false' : 'true'); + try { localStorage.setItem('fs-pc-side-collapsed', collapsed ? '1' : '0'); } catch (e) {} + } + foldBtn?.addEventListener('click', () => setSideCollapsed(true)); + restoreBtn?.addEventListener('click', () => setSideCollapsed(false)); + try { setSideCollapsed(localStorage.getItem('fs-pc-side-collapsed') === '1'); } catch (e) {} +})(); + // 初始 renderProdSpace(); renderSelectedProds(); diff --git a/电商AI平台/product-create.html b/电商AI平台/product-create.html index cc46da2..60528e2 100644 --- a/电商AI平台/product-create.html +++ b/电商AI平台/product-create.html @@ -24,7 +24,7 @@ /* ============================================================ 新建商品 · 重定向 stub ---------------------------------------------------------- - 旧版本是一个 3883 行的全屏 drawer 页(legacy 备份在 product-create.legacy.html)。 + 旧版本是一个 3883 行的全屏 drawer 页(legacy 已归档到 _archive/deprecated-pages-20260528/)。 现在「新建商品」改为 drawer 形态在原页面弹出,直接访问此 URL 没有意义。 行为: diff --git a/电商AI平台/projects.html b/电商AI平台/projects.html index 49d65a9..e6e9730 100644 --- a/电商AI平台/projects.html +++ b/电商AI平台/projects.html @@ -147,7 +147,6 @@
进行中 0
已完成 0
失败 0
-
已归档 0
@@ -216,7 +215,7 @@ 3/5
- 故事板 待确认 + 故事板生成中 12 分钟前
@@ -339,25 +338,6 @@ 5 月 4 日 - - -
-
9:16
-
补水面膜 · 痛点种草 · v1
6 镜 · 0-15s
-
- - 透真补水面膜 - AI 全生 - -
-
- 5/5 -
- - 已归档 - 4 月 28 日 - -
@@ -379,7 +359,7 @@ 3/5
- 故事板 待确认 + 故事板生成中 12 分钟前
@@ -505,25 +485,6 @@
-
- - -
9:16 · 5/5 ✓
-
-
-
补水面膜 · 痛点种草 · v1
-
透真补水面膜 · 6 镜
-
-
-
- 5/5 -
-
- 已归档 - 4 月 28 日 -
-
-
@@ -665,7 +626,7 @@ Shell.render({ active: 'projects', crumbs: [{ label: '工作台', href: 'index.h // ============== 从 DOM 实算项目计数,同步副标题 + tab 角标 ============== const allRows = document.querySelectorAll('#list-tbody tr'); -const counts = { total: allRows.length, wip: 0, done: 0, fail: 0, archived: 0 }; +const counts = { total: allRows.length, wip: 0, done: 0, fail: 0 }; allRows.forEach(r => { const s = r.dataset.status; if (counts[s] !== undefined) counts[s]++; }); document.getElementById('sub-total').textContent = counts.total; @@ -901,13 +862,13 @@ document.getElementById('search-input').addEventListener('input', e => { applyFilter(); }); -// 从 URL ?filter=wip|done|fail|archived|all 接收外部跳转 (例如工作台 stat 卡) +// 从 URL ?filter=wip|done|fail|all 接收外部跳转 (例如工作台 stat 卡) (function applyUrlFilter() { try { const q = new URLSearchParams(location.search); const f = q.get('filter'); if (!f) return; - const valid = ['all', 'wip', 'done', 'fail', 'archived']; + const valid = ['all', 'wip', 'done', 'fail']; if (!valid.includes(f)) return; state.filter = f; document.querySelectorAll('#status-tabs .tab').forEach(t => diff --git a/电商AI平台/team.html b/电商AI平台/team.html index 9ba7670..c78dabc 100644 --- a/电商AI平台/team.html +++ b/电商AI平台/team.html @@ -111,9 +111,9 @@ .members-table tr.pending .nm::after { content: '· 待激活'; font-size: 11px; color: var(--black-alpha-48); margin-left: 6px; font-weight: 400; font-family: var(--font-mono); } /* ─── 角色权限矩阵 ─── */ - .perm-table { width: 100%; border-collapse: collapse; font-size: 12.5px; } - .perm-table th, .perm-table td { padding: 8px 4px; border-bottom: 1px solid var(--border-faint); } - .perm-table th { font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--black-alpha-48); letter-spacing: .04em; text-transform: uppercase; text-align: left; } + .perm-table { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--surface); border: 1px solid var(--border-muted); border-radius: var(--r-md); overflow: hidden; font-size: 12.5px; } + .perm-table th, .perm-table td { padding: 8px 10px; border-bottom: 0; } + .perm-table th { border-bottom: 1px solid var(--border-muted); background: var(--background-lighter); font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--black-alpha-48); letter-spacing: .04em; text-transform: uppercase; text-align: left; } .perm-table th:not(:first-child), .perm-table td:not(:first-child) { text-align: center; } .perm-table tbody td:first-child { color: var(--accent-black); } .perm-table .yes { color: var(--accent-forest); font-weight: 600; } diff --git a/电商AI平台/页面流程定稿.md b/电商AI平台/页面流程定稿.md new file mode 100644 index 0000000..33030dc --- /dev/null +++ b/电商AI平台/页面流程定稿.md @@ -0,0 +1,400 @@ +# Airshelf 页面流程定稿记录 + +> 本文件用于记录和用户逐页确认后的产品页面流程。 +> PRD 只作为功能边界参考,页面布局与交互以本文件后续定稿为准。 + +维护日期:2026-05-28 + +--- + +## 0. 总体原则 + +- 创作视频是产品主线任务。 +- 当前版本单条生成视频的时长上限是 15s。 +- AI 图片创作是附加能力,用于辅助商品图、人物、场景等素材生产,不抢视频主线。 +- 页面跳转尽量少,能在当前页面完成的操作尽量不跳转。 +- 操作尽量简单,第一次使用 AI 产品的用户也应该能理解。 +- 5 个 Stage 是步骤引导,不是强制锁定流程。 +- 用户可以在脚本、基础资产、故事板、视频、拼接导出之间自由跳转。 +- 如果某个 Stage 缺少前置内容,页面给提示和快捷补全入口,不做硬锁死。 +- 暂不做复制项目、归档、审核、待审核、待我确认等复杂项目管理概念。 + +--- + +## 1. 视频项目页 `/projects` + +### 页面定位 + +视频项目页是视频生产任务列表,帮助用户看清每个视频项目做到哪一步,以及下一步能点什么。 + +### 不做内容 + +- 不做复制项目。 +- 不做归档。 +- 不做审核 / 待审核 / 待我确认。 +- 不做草稿分类。 +- 不做复杂批量操作。 +- AI 图片创作不作为顶部主按钮。 + +### 状态分类 + +只保留: + +- 全部 +- 进行中 +- 生成中 +- 已完成 +- 失败 + +### 页面结构 + +1. Page Head + - 标题:视频项目 + - 主按钮:新建视频项目 + +2. 状态概览 / Tab + - 全部 + - 进行中 + - 生成中 + - 已完成 + - 失败 + +3. 工具栏 + - 搜索项目 / 商品名 + - 商品筛选 + - 状态筛选 + - 最近更新排序 + - 可选:列表 / 卡片视图切换 + +4. 项目列表 + - 默认列表行,不默认大卡片。 + - 每行展示: + - 9:16 缩略图 + - 项目名 + - 关联商品 + - 当前阶段 + - 5 段进度:脚本 / 资产 / 故事板 / 视频 / 导出 + - 更新时间 + - 状态 + - 主操作:继续 / 查看进度 / 查看成片 / 重试 + +5. 空状态 + - 没有商品:引导新建商品。 + - 有商品但没有项目:引导新建视频项目。 + +--- + +## 2. 新建视频项目页 `/projects/new` + +### 页面定位 + +新建项目页只负责创建项目壳子,并绑定商品。 +脚本怎么生成、脚本风格、任务设定等全部放到 Stage 1 脚本页。 + +### 交互原则 + +- 一个页面内完成,不做多步跳转。 +- 只问用户:为哪个商品创建视频。 +- 创建后直接进入项目流水线的 Stage 1 脚本页。 + +### 字段 + +必选: + +- 商品 + +可选: + +- 项目名称 + - 默认自动生成,例如:商品名 + 短视频 + 日期。 + +不展示: + +- 创作方式 +- 脚本风格 +- 任务设定 +- 商品卖点选择 +- 预估消耗 + +### 卖点选择归属 + +商品卖点不放在新建项目页。 +商品卖点选择放到 Stage 1 脚本页,作为“本条视频重点”配置项,从商品库自动带出。 + +--- + +## 3. Stage 1 脚本页 + +### 页面定位 + +脚本页是 AI 脚本工作台。 +用户通过 AI 输入和启动卡片完成脚本来源选择、卖点选择、风格设定、任务设定,并在中间区域查看完整读秒流分镜脚本。 + +### 核心原则 + +- 脚本是用户最关注的内容,必须放在中间最大区域。 +- 脚本不按 15s 大段展示。 +- 脚本按完整读秒流分镜展示,适合短视频细看。 +- AI 聊天不是主内容,而是脚本修改和生成记录。 +- AI 输入框放页面底部固定,作为当前 Stage 的全局指令入口。 + +### 页面布局 + +顶部: + +- 项目面包屑 +- 商品名 / 项目名 +- 5 Stage 自由切换导航:脚本 / 基础资产 / 故事板 / 视频 / 拼接导出 + +主体: + +- 左侧窄栏:商品信息 / 卖点 / 人物 / 场景等辅助信息 +- 中间主栏:读秒流分镜脚本 +- 右侧窄栏:AI 对话记录 / 操作历史 + +底部固定栏: + +- AI 输入框 +- 页面操作按钮,例如重新生成全部、进入下一步 + +### 空状态引导 + +脚本来源不做 Tab。 +脚本未生成时,中间主区域展示启动卡片: + +- AI 帮我写 + 根据商品信息自动生成完整读秒流分镜。 + +- 我有脚本 + 粘贴已有口播稿,AI 帮你整理成分镜结构。 + +- 一句话生成 + 输入一句视频方向,AI 生成完整分镜。 + +- 复刻爆款 + 暂未开放或后续版本处理。 + +用户选择后进入对应模式。生成脚本后,中间区域切换为完整读秒流分镜。 + +### 读秒流分镜结构 + +每个分镜以卡片 / 行卡展示: + +- 镜头编号 +- 时间段,例如 0-5s、5-10s +- 画面描述 +- 对白 / 旁白 +- 可选:镜头类型、场景、人物 + +用户可以: + +- 直接编辑某个分镜文字。 +- 用底部 AI 输入框修改某个分镜。 +- 重新生成全部。 +- 调整整体时长、口吻、卖点重点等。 + +### 商品卖点 + +- 从商品库自动带出。 +- 在脚本页展示为“本条视频重点”。 +- 默认选中前 2-3 个,或默认使用全部卖点。 +- 用户可点选 / 取消。 +- 用户也可以直接在 AI 输入框里说重点突出哪些卖点。 + +--- + +## 4. Stage 2 基础资产页 + +### 页面定位 + +基础资产页用于为当前视频准备视觉资产。 +它不是资产库,也不是完整 AI 图片创作页。 + +### 总体原则 + +- 默认 AI 自动生成,用户只在效果不好时调整。 +- 脚本确定后,AI 自动识别需要的商品、人物、场景,并生成图片提示词。 +- 页面优先让用户看默认生成效果。 +- 不满意时再修改提示词、上传参考图、从资产库选择或重新生成。 +- 商品是最重要的,优先展示商品资产。 + +### 页面布局 + +- 左侧:资产清单 +- 中间:当前资产工作台 / 生成结果 +- 右侧:AI 操作记录 / 生成记录 +- 底部:AI 输入框 + +### 资产顺序 + +1. 商品资产 +2. 人物 +3. 场景 + +### 商品资产 + +商品三视图是一张 16:9 图,包含正面、侧面、背面。 +它不是三张图,也不拆分成三个槽位。 + +不提供: + +- 上传三视图 +- 使用现有商品图 + +原因: + +- 用户一般不会有适合生成视频的白底三视图。 +- 如果不生成三视图,系统本来就只能默认使用商品图继续,不需要多给一个“使用现有商品图”的操作。 + +推荐交互: + +- 展示当前商品图。 +- 展示商品三视图状态:未生成 / 生成中 / 已生成。 +- 说明:生成 16:9 商品三视图可以提升商品角度稳定性。 +- 主操作:生成商品三视图。 +- 不生成三视图也可以继续,只做弱提示。 + +生成规则: + +- 商品三视图属于结构转换型。 +- 默认一次生成 1 张。 +- 不满意可重新生成或用 AI 输入框调整提示词。 +- 商品三视图支持保留历史版本,用户可以在历史版本中选择满意的一版采用。 + +### 人物资产 + +命名为“人物”,不叫“模特”。 +人物指脚本中需要出现的角色,用户要确定这个角色的形象。 + +默认流程: + +1. AI 根据脚本自动识别人物。 +2. AI 为每个人物自动生成图片提示词。 +3. 默认生成 4 张人物立绘候选。 +4. 用户选择 1 张满意的立绘。 +5. AI 基于选中的立绘生成 1 张 16:9 人物三视图。 +6. 用户采用此人物资产。 + +不满意时,用户可以: + +- 修改描述。 +- 上传自己的模特 / 参考图。 +- 从人物库选择。 +- 重新生成立绘。 +- 从历史立绘里再选一张生成三视图。 +- 重新生成人物三视图。 +- 从人物三视图历史版本中选择满意的一版采用。 + +人物调整不放抽屉。 +点击人物后,中间区域直接切换为人物工作台。 + +人物工作台需要一步到位承载: + +- 人物库选择 +- 上传参考图 +- 描述生成 +- 直接使用自己的模特 +- AI 生成多张立绘 +- 从立绘生成三视图 +- 从历史立绘再选再生成三视图 + +### 场景资产 + +默认流程: + +1. AI 根据脚本识别场景。 +2. AI 自动生成场景图提示词。 +3. 默认一次生成 4 张候选。 +4. 用户选择 1 张。 + +不满意时,用户可以: + +- 修改描述。 +- 重新生成。 +- 上传替换。 + +### 候选生成规则 + +创意选择型:一次生成 4 张。 + +- 人物立绘 +- 场景图 + +结构转换型:一次生成 1 张。 + +- 商品三视图 +- 人物三视图 + +三视图版本规则: + +- 商品三视图和人物三视图都可以重跑。 +- 每次重跑产生一个历史版本。 +- 用户可以在历史版本中回选满意的一版。 +- 采用某一版后,该版本成为当前项目使用版本。 + +### 资产复用 + +人物默认是项目内资产,不自动进入团队人物库,避免资产库变乱。 + +采用人物时可以勾选: + +- 保存到人物库 + +保存后: + +- 进入团队共享人物库。 +- 后续项目可复用。 +- 记录来源:项目内生成 / AI 生成 / 上传参考图等。 + +--- + +## 5. 待继续确认页面 + +- Stage 4 视频页 +- Stage 5 拼接导出页 +- 商品库 / 商品详情 +- 资产库 +- AI 图片创作 +- 人物库 +- 工作台 +- 团队 +- 消费 +- 设置 + +--- + +## 5. Stage 3 故事板页 + +### 页面定位 + +故事板页用于在生成视频前,让用户清晰看到接下来这条 15s 视频的大致内容和画面走向。 + +### 核心原则 + +- 不做分镜级故事板。 +- 不按每个镜头单独生成故事板。 +- 故事板按照“一条视频”的完整时长来展示。 +- 当前版本单条视频上限是 15s,因此故事板就是这条 15s 视频的整体视觉预览。 +- 故事板需要让用户一眼明白:等下这条视频会讲什么、画面如何推进、商品如何出现。 + +### 与脚本页的关系 + +- Stage 1 脚本页仍然可以按读秒流分镜展示,方便用户细看脚本。 +- Stage 3 故事板页不继承“每个分镜一张图”的结构。 +- 故事板应总结整条 15s 视频,而不是把脚本分镜逐张拆开。 + +### 初步页面方向 + +主体重点应放在一张完整故事板 / 故事板预览上。 + +页面需要展示: + +- 当前视频脚本摘要 +- 使用的商品资产、人物资产、场景资产 +- 故事板整体预览 +- 生成状态 +- 重新生成 / 调整提示词 / 采用当前版本 +- 历史版本回选 + +故事板可重跑。 +每次重跑保留历史版本,用户可以在历史版本中选择满意的一版。