## ADDED Requirements ### Requirement: 剩余 Gradio Tab 提取为独立 UI 模块 系统 SHALL 将 `ui/app.py` 中所有 Gradio Tab 按如下顺序排列,且顶部 SHALL 不存在任何全局设置折叠块(`gr.Accordion`): | 序号 | Tab 名称 | 模块/说明 | |------|----------|-----------| | 0 | ✍️ 内容创作 | `ui/tab_create.py` | | 1 | 📅 内容排期 | 内联或 `ui/tab_queue.py` | | 2 | 🔥 热点探测 | 内联或 `ui/tab_hotspot.py` | | 3 | 💬 评论管家 | 内联或 `ui/tab_engage.py` | | 4 | 📊 数据看板 | 内联或 `ui/tab_analytics.py` | | 5 | 🧠 智能学习 | 内联或 `ui/tab_learn.py` | | 6 | 🤖 自动运营 | 内联或 `ui/tab_auto.py` | | 7 | 🔐 账号登录 | 内联或 `ui/tab_profile.py` | | 8 | ⚙️ 配置 | 内联(含原全局设置所有组件) | 每个 Tab 模块 SHALL 暴露 `build_tab(...)` 函数,接受所需组件引用和回调函数作为参数。 #### Scenario: 每个 Tab 模块暴露 build_tab 函数 - **WHEN** `ui/app.py` 执行 `from ui.tab_create import build_tab` - **THEN** 调用 `build_tab(...)` 后 SHALL 返回包含需跨 Tab 共享组件的 dict #### Scenario: build_tab 接收回调而非直接导入 services - **WHEN** `build_tab(...)` 内部需要调用业务函数时 - **THEN** 业务函数 SHALL 通过 `fn_*` 参数传入,不在 `ui/tab_*.py` 内直接 `import services.*` #### Scenario: 事件绑定在 build_tab 内完成 - **WHEN** `build_tab(...)` 被调用 - **THEN** 本 Tab 所有 Gradio 组件的 `.click()`、`.change()` 等事件绑定 SHALL 在函数内完成 #### Scenario: 内容创作 Tab 为首个 Tab(索引 0) - **WHEN** 用户打开应用 - **THEN** 默认激活的 Tab SHALL 为「✍️ 内容创作」,用户无需额外点击即可开始创作工作流 #### Scenario: 配置和账号 Tab 位于末尾 - **WHEN** 用户查看 Tab 导航栏 - **THEN** 「🔐 账号登录」SHALL 位于倒数第二位,「⚙️ 配置」SHALL 位于最末位,低频操作不干扰主工作区