Files
WorkBuddy eee042c855 ③段第八轮收口:功能入口卡按参照物对齐 + 导航按 tiaoyue 源站重建 + 密度 A 方案
原型(执行会话/目标-…-d85687/ui/mcn-workbench.html)
- 功能入口卡改三段纵向(图标/标题/描述各一行),68 → 111.19px,对齐 mcn-work-shop
  参考卡(同视口 1249×1277 实测 133px),补 --sh-L1 投影;主因是排布不是字号
- 左侧导航重建:由「纯图标 + 悬停提示」改为 64px 药丸浮栏,图标 24 在上、名字常驻在下
  (名字一律 2 字,说明走 data-tip);真值取自 tiaoyue 源站实测
  (栏 64/内衬 3/圆角 100/项 56×78/字 12px-500-行高 16)
- 密度 A 方案:≤1000 卡最小宽 200→160、≤820 统计条最小宽 132→96
  (两处 auto-fit 只在真装不下时才缩)⇒ 768/700/560 三处转绿,其余 10 个视口未动
- 移动档隐藏导航条横向滚动轨(16px 轨道曾吃掉 52px 条高的三成,还白吃 16px 主区)

取证通道
- _tools/cap.py 改为「只连不起」:只连 9223 常驻实例,视口走 Emulation.setDeviceMetricsOverride,
  不再自起 headless Chrome(顺带解除 500px 视口下限,390×844 可测)
- _tools/check_js.py 新增第 5 道门禁(node --check + 模板内注释反引号扫描)

文档
- 复盘-为什么第一版做得很差.md(新建):13 轮时间轴/四类反作用/三重归因/已修与仍欠
- 3d-审查报告.md:更正 §九 那条假 ✓(把「§5.5 五条逐条过完」记成机核,实际零覆盖,
  正是「五道闸门全绿却难看」的开关),补 §十二 功能入口卡高差、§十三 tiaoyue 导航逐条对照
- 3b-实测记录.md/DESIGN.md/3c-GPT 参考版与会诊/布局排版参考 ×2

机制与记忆
- .workbuddy/collab/collabctl.py:off --ws 不再全机扫描(原先一次杀掉他区+看板共 5 个进程)
- .workbuddy/memory/:本轮纪律与实测真值
- .gitignore:补排运行时噪音(ui/_scratch/__pycache__/浏览器取证临时目录/*.bak-*/一次性脚本)

闸门:语法全过/骨架八页 39 板块/变异对照 15-15/逐视口 14 绿(500×844 唯一红,缺口待拍板)/命名 2060-0-27
2026-10-08 22:21:42 +08:00

3844 lines
69 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3c GPT 参考版
> 工具:`browser-harness` 打开 `chatgpt.com`(独立实例,用户已登录);对话 URL:`https://chatgpt.com/c/6ac75440-fc60-83e8-b509-cdd6ec808200`
> 口径:按 ③段 `SKILL.md` §3c(2026-10-08 新)—— **内联②段需求与 `DESIGN.md` 定调/令牌,让 GPT 独立生成一版**;⛔ 未传我们的原型 HTML。
> 产出:模型独立生成的一版单文件 HTML(**48800 字符**),全文存 `_scratch/gpt-ref.html`;整页截图 `tmp/_bh_shots/gpt-ref-full.png`。
---
## 一、提问原文(内联给 GPT 的需求 + 风格)
```
你是资深产品设计师。请按下面这份「需求 + 设计风格」,独立设计并给出一个可运行的单文件 HTML(内联 CSS,不要外链任何资源),作为我们的参考版本。
## 一、需求
产品:**MCN 短视频整合营销工作台**。用户=管 10–50 个账号的矩阵运营团队(内容负责人 / 编导文案 / 剪辑投放),天天进来干活。**工具型产品,不是营销落地页。**
八页(格式:页 → 干什么 → 板块从上到下):
1、**P1 矩阵总览** —— 一屏回答每个账号今天该发什么、发了什么、效果如何。板块:今日待处理 / 账号矩阵 / 异常值提示 / 本月表现最好的一条 / 全局检索与随手记入口。
2、**P2 选题雷达** —— 找选题并推进下一步。板块:对标监控概览(在监控账号数 / 低粉爆款条数 / 异常值条数 / 近三天更新条数) / 对标内容(每条带「相对该账号平时水平的倍数」) / 评论区洞察 / 选题库(待做 · 在写 · 已用) / 灵感速记入口。
3、**P3 资产库** —— 把拆解结果存下来,下次直接拿。板块:分区切换(角度 / 结构 / 开场白 / 标题) / 资产条目 / 单条详情(原文 · 出处) / 引用入口。
4、**P4 创作台** —— 一条内容从选题走到成稿。板块:当前内容标识 / 环节进度(七个环节,可回退) / 当前环节工作区 / **AI 产出与采纳**(生成中 · 已生成 · 失败重试 + 采纳 · 驳回 · 改后再用) / 资产引用区 / 版本列表。
5、**P5 发布中心** —— 展开成各账号各平台版本,过闸,由人确认发出。板块:目标选择 / 各版本预览与逐版编辑 / 检查结果(哪几处硬拦、哪几处只提醒) / 确认发布(含二次确认) / 发布记录入口。
6、**P6 账号画像** —— 每个账号一份画像与记忆。板块:账号列表 / 画像六维(定位 · 风格 · 受众 · 平台 · 偏好与红线 · 长期记忆) / 记忆条目(只追加) / 关联内容。
7、**P7 复盘台** —— 把已发内容的表现读回来,写成这个账号的经验。板块:待复盘项 / 这一条的表现数据 / 归因结论(AI 给出,可编辑) / 确认与改判 / 回写目标提示 / 历史复盘。
8、**P8 记录与对账** —— 查发布留痕,核商单与收支。板块:发布记录 / 单条溯源 / 对账核对区 / 商单与收支。
导航:唯一入口 P1;一级导航三组 —— 找选题(P2 / P3)|走创作流水线(P4 / P5)|看矩阵复盘(P1 / P7 / P8);账号画像 P6 跨组。
## 二、设计风格(既定,请沿用)
定调:**极简纸感 + 品牌紫**。暖白纸底、白面、细线分隔、克制阴影。
令牌:
- 底色 `#faf9f5`(暖白纸感)|面 `#ffffff`|次级面 `#f7f6f1`
- 主文字 `#1a1a18`|次级 `#57564f`|三级 `#8a887f`
- 描边 `#e7e5dc`|弱描边 `#efeee7`
- 强调色 `#9E4CFF`(紫):占屏 ≤5%,只用于主按钮填充 / 当前项浅底 / 链接文字 / 焦点环
- 状态色:成功 `#3d7a4f`|错误 `#b4453a`|警告 `#8a5a00`
- 圆角:大容器 24 / 面板 16 / 行与小件 14 / 输入 9 / 按钮 26(药丸)
- 间距:主刻度 4 / 8 / 16 / 24 / 32 / 64;微网格 2 / 4 / 6 / 8 / 12
- 字阶:12 / 14 / 16 / 18 / 20 / 24 / 30(正文 14–16)
- 字体:正文=系统中文字体栈;**标题=展示体**(宋体系,与正文形成对照)
- 阴影:多层叠层(贴地一层 + 远而淡一层),⛔ 不用单层死黑
- 密度:密集(行高紧凑,一屏要多装行)
工具型纪律:⛔ 不做营销落地页那套(大标题 + 口号 + 三栏特性卡);⛔ 不用单侧彩色边条标状态;⛔ 不用星星 / 魔法棒 / 机器人表示 AI;状态用元素本身表达(底色 · 字重 · 状态词);一屏只有一个主角,其余退后。
## 三、重点参考(同类产品 —— 请重点参考它的布局与风格)
另一个同类产品「AI 内容工作台」(Obsidian 插件形态)与我们同品类,**请重点参考**:
- 外壳:**顶部横向 Tab 导航**(⛔ 不是左侧栏),十个 Tab 按创作工作流排序(首页 / 对标与热点 / 选题 / 拆解与沉淀 / 创作 / 发布与经营 / 计划 / 常用助手 / 画板 / 收支);主体是**居中的单列宽内容区**,顶部一个**全局搜索框**。
- 子层:**胶囊子 Tab**(如 精选总览 / 对标动态 / AI 热点 / Twitter 动态);创作台内是 聊思路 / 写文案 / 起标题 / 做封面 / 发布检查。
- 首页:**Hero 区**=问候 + 大钟 + 日期 + 手绘插画底;右侧一张**日历卡**;下方是本月最佳作品陈列。
- 数据:**指标卡一排**,四张等宽卡,每张一个色相,卡内=标签 + 大数字 + 单位小字。
- 资产:**三列表格**(文案原文(含标题) / 这类角度叫什么 / 原文怎么写)。
- 创作:顶部子 Tab 本身就是流水线;发布检查页给了**分步指示**「1 导入文案 → 2 检查问题 → 3 处理建议 → 4 复核后发布」;主体=左(表单与动作)+ 右(正文预览)。
- 它的视觉调性:深色底、多色强调、橙色主按钮、手绘插画。
⚠️ 取舍交给你判断:**布局手法**(顶部工作流 Tab、居中宽列 + 搜索、胶囊子 Tab、指标卡一排、分步指示、资产表格)可大胆借;**视觉调性**上我们的定调是上面那套「浅色纸感 + 品牌紫」(见「二、设计风格」),与它的深色多色是两条路线 —— 请按我们的令牌配色,但把它的**布局骨架与密度**借过来;哪一处你认为必须偏离我们的令牌才成立,用一句话单独说明理由。
## 四、要求
这是工具型页面(数据 + 操作,不是营销落地页);把八页的主要形态都做出来;状态(空 / 加载 / 错误 / 禁用)要落地;页面要能在浏览器里真实打开。
请在代码之前先用三句话说明:你把主视觉放在哪、为什么这么排、和你见过的同类产品有什么不同。
```
---
## 二、模型回答原文
### 2.1 开场说明(原文摘录)
> 可以。下面直接贴完整源码,不再生成文件。
>
> XML
(⚠️ 记账:模板要求「先用三句话说明主视觉/为什么/与同类产品不同」,模型给的是**功能清单**、未按三句话答;取回时未追。)
### 2.2 完整 HTML(48800 字符)
```html
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>MCN 短视频整合营销工作台</title>
<style>
:root{
--paper:#faf9f5;
--surface:#fff;
--sub:#f7f6f1;
--ink:#1a1a18;
--muted:#57564f;
--quiet:#8a887f;
--line:#e7e5dc;
--weak:#efeee7;
--purple:#9E4CFF;
--purple-soft:#f3e9ff;
--ok:#3d7a4f;
--bad:#b4453a;
--warn:#8a5a00;
--shadow:
0 1px 2px rgba(26,26,24,.05),
0 12px 30px rgba(26,26,24,.035);
--r-lg:24px;
--r-md:16px;
--r-sm:14px;
}
*{
box-sizing:border-box;
}
html,
body{
margin:0;
background:var(--paper);
color:var(--ink);
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
"PingFang SC",
"Hiragino Sans GB",
"Microsoft YaHei",
Arial,
sans-serif;
font-size:14px;
}
button,
input,
textarea,
select{
font:inherit;
color:inherit;
}
button{
cursor:pointer;
}
button:disabled{
cursor:not-allowed;
opacity:.45;
}
/* =========================
顶部导航
========================= */
.topbar{
position:sticky;
top:0;
z-index:20;
background:rgba(250,249,245,.94);
backdrop-filter:blur(14px);
border-bottom:1px solid var(--line);
}
.nav{
max-width:1440px;
margin:auto;
height:66px;
display:flex;
align-items:center;
gap:18px;
padding:0 28px;
}
.brand{
font-family:
Georgia,
"Songti SC",
"STSong",
serif;
font-size:19px;
white-space:nowrap;
}
.navtabs{
display:flex;
gap:3px;
align-items:center;
flex:1;
}
.navtab{
border:0;
background:transparent;
padding:10px 13px;
border-radius:24px;
color:var(--muted);
font-size:13px;
}
.navtab:hover{
background:var(--sub);
color:var(--ink);
}
.navtab.active{
background:var(--purple-soft);
color:#7130b7;
font-weight:650;
}
.search{
width:225px;
height:38px;
border:1px solid var(--line);
border-radius:22px;
background:#fff;
display:flex;
align-items:center;
padding:0 13px;
gap:8px;
color:var(--quiet);
}
.search input{
border:0;
outline:0;
width:100%;
background:transparent;
font-size:13px;
}
/* =========================
页面基础
========================= */
main{
max-width:1220px;
margin:0 auto;
padding:28px 28px 64px;
}
.pagehead{
display:flex;
justify-content:space-between;
align-items:flex-start;
margin-bottom:20px;
}
.eyebrow{
color:var(--quiet);
font-size:12px;
margin-bottom:6px;
}
h1,
h2,
h3{
margin:0;
font-family:
Georgia,
"Songti SC",
"STSong",
serif;
font-weight:600;
}
h1{
font-size:30px;
letter-spacing:-.4px;
}
h2{
font-size:20px;
}
h3{
font-size:16px;
}
.head-actions{
display:flex;
gap:8px;
}
.btn{
border:1px solid var(--line);
background:#fff;
border-radius:26px;
padding:9px 15px;
font-weight:600;
}
.btn:hover{
background:var(--sub);
}
.btn.primary{
background:var(--purple);
border-color:var(--purple);
color:#fff;
}
.btn.ghost{
background:transparent;
}
.btn.danger{
color:var(--bad);
}
.grid{
display:grid;
gap:16px;
}
.cols2{
grid-template-columns:1.35fr .9fr;
}
.cols3{
grid-template-columns:repeat(3,1fr);
}
.card{
background:var(--surface);
border:1px solid var(--line);
border-radius:var(--r-md);
box-shadow:var(--shadow);
padding:18px;
}
.card.tight{
padding:14px;
}
.section{
margin-top:20px;
}
.section-title{
display:flex;
justify-content:space-between;
align-items:center;
margin-bottom:10px;
}
.section-title .hint{
font-size:12px;
color:var(--quiet);
}
/* =========================
指标卡
========================= */
.metric-row{
display:grid;
grid-template-columns:repeat(4,1fr);
gap:10px;
}
.metric{
padding:15px;
border:1px solid var(--line);
border-radius:16px;
background:#fff;
}
.metric .label{
font-size:12px;
color:var(--muted);
}
.metric .num{
font-size:26px;
font-weight:650;
margin-top:5px;
}
.unit{
font-size:12px;
color:var(--quiet);
font-weight:400;
}
/* =========================
子 Tab
========================= */
.subtabs{
display:flex;
gap:6px;
margin:0 0 16px;
padding:4px;
background:var(--sub);
border:1px solid var(--weak);
border-radius:26px;
width:max-content;
}
.subtab{
border:0;
background:transparent;
border-radius:22px;
padding:8px 13px;
color:var(--muted);
font-size:13px;
}
.subtab.active{
background:#fff;
color:var(--ink);
box-shadow:0 1px 4px rgba(0,0,0,.05);
font-weight:650;
}
/* =========================
表格
========================= */
.table{
width:100%;
border-collapse:collapse;
}
.table th{
text-align:left;
color:var(--quiet);
font-size:12px;
font-weight:500;
padding:9px 8px;
border-bottom:1px solid var(--line);
}
.table td{
padding:11px 8px;
border-bottom:1px solid var(--weak);
vertical-align:middle;
}
.table tr:last-child td{
border-bottom:0;
}
/* =========================
账号
========================= */
.account{
display:flex;
align-items:center;
gap:9px;
}
.avatar{
width:30px;
height:30px;
border-radius:50%;
background:var(--sub);
border:1px solid var(--line);
display:grid;
place-items:center;
font-weight:650;
font-size:12px;
}
/* =========================
标签
========================= */
.tag{
display:inline-flex;
align-items:center;
border:1px solid var(--line);
background:var(--sub);
padding:4px 8px;
border-radius:20px;
font-size:11px;
color:var(--muted);
white-space:nowrap;
}
.tag.ok{
color:var(--ok);
background:#f1f7f2;
border-color:#dceadd;
}
.tag.bad{
color:var(--bad);
background:#fff2f0;
border-color:#f0d8d4;
}
.tag.warn{
color:var(--warn);
background:#fff8e8;
border-color:#efe2c1;
}
.tag.purple{
color:#7130b7;
background:var(--purple-soft);
border-color:#e8d7ff;
}
.kpi{
font-size:18px;
font-weight:650;
}
.muted{
color:var(--muted);
}
.quiet{
color:var(--quiet);
}
.link{
color:#7130b7;
cursor:pointer;
}
.small{
font-size:12px;
}
.mono{
font-family:
ui-monospace,
SFMono-Regular,
Menlo,
monospace;
}
/* =========================
状态
========================= */
.empty{
padding:28px;
text-align:center;
color:var(--quiet);
border:1px dashed var(--line);
border-radius:14px;
background:var(--sub);
}
.loading{
position:relative;
overflow:hidden;
color:transparent;
background:var(--sub);
border-radius:8px;
height:14px;
}
.loading:after{
content:"";
position:absolute;
inset:0;
transform:translateX(-100%);
background:
linear-gradient(
90deg,
transparent,
rgba(255,255,255,.8),
transparent
);
animation:sheen 1.2s infinite;
}
@keyframes sheen{
to{
transform:translateX(100%);
}
}
.alert{
padding:11px 13px;
border:1px solid var(--line);
border-radius:14px;
background:var(--sub);
display:flex;
justify-content:space-between;
gap:10px;
}
.alert.bad{
background:#fff7f5;
border-color:#f0d8d4;
}
.alert.warn{
background:#fffaf0;
border-color:#efe2c1;
}
/* =========================
列表
========================= */
.list{
display:flex;
flex-direction:column;
}
.listrow{
display:flex;
justify-content:space-between;
align-items:center;
padding:12px 0;
border-bottom:1px solid var(--weak);
gap:12px;
}
.listrow:last-child{
border-bottom:0;
}
/* =========================
标签行
========================= */
.chiprow{
display:flex;
gap:7px;
flex-wrap:wrap;
}
/* =========================
引用
========================= */
.quote{
border-left:2px solid var(--line);
padding-left:12px;
color:var(--muted);
line-height:1.6;
}
/* =========================
表单
========================= */
.input,
.textarea,
.select{
width:100%;
border:1px solid var(--line);
border-radius:9px;
background:#fff;
padding:10px 11px;
outline:none;
}
.input:focus,
.textarea:focus{
border-color:var(--purple);
box-shadow:0 0 0 3px var(--purple-soft);
}
.textarea{
min-height:150px;
resize:vertical;
}
.twofields{
display:grid;
grid-template-columns:1fr 1fr;
gap:10px;
}
.formlabel{
font-size:12px;
color:var(--muted);
margin:0 0 5px;
display:block;
}
/* =========================
进度
========================= */
.stepper{
display:flex;
gap:6px;
margin-bottom:16px;
overflow:auto;
}
.step{
flex:1;
min-width:105px;
border:1px solid var(--line);
background:#fff;
border-radius:14px;
padding:10px 11px;
text-align:left;
}
.step.active{
border-color:#d9b9fb;
background:var(--purple-soft);
}
.step.done{
background:var(--sub);
}
.step b{
font-size:12px;
display:block;
}
.step span{
font-size:11px;
color:var(--quiet);
}
/* =========================
创作工作区
========================= */
.workgrid{
display:grid;
grid-template-columns:1.2fr .8fr;
gap:16px;
}
.sticky{
position:sticky;
top:86px;
align-self:start;
}
.version{
border:1px solid var(--line);
border-radius:14px;
padding:13px;
margin-bottom:9px;
}
.version.active{
border-color:#d9b9fb;
background:#fcf9ff;
}
/* =========================
时间线
========================= */
.timeline{
position:relative;
padding-left:22px;
}
.timeline:before{
content:"";
position:absolute;
left:6px;
top:5px;
bottom:5px;
width:1px;
background:var(--line);
}
.event{
position:relative;
padding:0 0 16px;
}
.event:before{
content:"";
position:absolute;
left:-20px;
top:4px;
width:7px;
height:7px;
border-radius:50%;
background:#fff;
border:1px solid #aaa;
}
/* =========================
Toast
========================= */
.toast{
position:fixed;
right:22px;
bottom:22px;
background:var(--ink);
color:#fff;
padding:11px 15px;
border-radius:12px;
display:none;
z-index:99;
}
.toast.show{
display:block;
}
/* =========================
Modal
========================= */
.modal{
position:fixed;
inset:0;
background:rgba(26,26,24,.22);
display:none;
place-items:center;
z-index:80;
padding:20px;
}
.modal.show{
display:grid;
}
.modalbox{
width:min(520px,100%);
background:#fff;
border:1px solid var(--line);
border-radius:20px;
padding:22px;
box-shadow:0 20px 60px rgba(0,0,0,.12);
}
.notice{
font-size:12px;
color:var(--quiet);
line-height:1.6;
}
/* =========================
响应式
========================= */
@media(max-width:1000px){
.nav{
overflow:auto;
}
.navtabs{
flex:none;
}
.search{
display:none;
}
.metric-row{
grid-template-columns:1fr 1fr;
}
.cols2,
.workgrid{
grid-template-columns:1fr;
}
.sticky{
position:static;
}
}
@media(max-width:650px){
main{
padding:20px 14px 50px;
}
.metric-row,
.cols3,
.twofields{
grid-template-columns:1fr;
}
.nav{
padding:0 14px;
}
.brand{
display:none;
}
h1{
font-size:25px;
}
}
</style>
</head>
<body>
<header class="topbar">
<nav class="nav">
<div class="brand">
矩阵工作台
</div>
<div class="navtabs">
<button class="navtab active" data-page="p1">
总览
</button>
<button class="navtab" data-page="p2">
找选题
</button>
<button class="navtab" data-page="p3">
资产库
</button>
<button class="navtab" data-page="p4">
创作
</button>
<button class="navtab" data-page="p5">
发布
</button>
<button class="navtab" data-page="p6">
账号画像
</button>
<button class="navtab" data-page="p7">
复盘
</button>
<button class="navtab" data-page="p8">
记录与对账
</button>
</div>
<label class="search">
⌕
<input
id="globalSearch"
placeholder="全局搜索内容、账号、记录…"
>
</label>
</nav>
</header>
<main id="app"></main>
<div id="toast" class="toast"></div>
<div id="modal" class="modal">
<div class="modalbox" id="modalBox"></div>
</div>
<script>
/* =========================================================
模拟数据
========================================================= */
const accounts = [
{
n:"小周说职场",
a:"小周",
p:"抖音",
status:"待发布",
today:"效率低的 3 个真相",
views:"18.6万",
delta:"+42%",
tone:"实用、直接"
},
{
n:"阿梨生活",
a:"阿梨",
p:"小红书",
status:"待审核",
today:"租房收纳的反常识",
views:"9.8万",
delta:"+18%",
tone:"松弛、细节感"
},
{
n:"老陈商业局",
a:"老陈",
p:"B站",
status:"已发布",
today:"老板最容易忽略的成本",
views:"32.1万",
delta:"+76%",
tone:"理性、案例"
},
{
n:"Mia成长笔记",
a:"M",
p:"抖音",
status:"异常",
today:"停止内耗的一个动作",
views:"4.2万",
delta:"-31%",
tone:"温柔、陪伴"
},
{
n:"阿森探店",
a:"阿森",
p:"小红书",
status:"已发布",
today:"本周 3 家宝藏小店",
views:"12.4万",
delta:"+27%",
tone:"真实、快节奏"
}
];
const ideas = [
[
"为什么越努力越低效?",
"小周说职场",
"8.4×",
"1.7万 → 14.3万",
"已加入选题"
],
[
"租房收纳最容易买错的 5 件东西",
"阿梨生活",
"5.9×",
"8.2万 → 48.3万",
"待判断"
],
[
"小公司真正烧钱的不是工资",
"老陈商业局",
"7.2×",
"2.6万 → 18.7万",
"已拆解"
],
[
"停止内耗后,我反而做成了这件事",
"成长类对标",
"4.1×",
"6.4万 → 26.2万",
"待判断"
]
];
const assets = [
[
"开场白",
"反常识",
"“如果你还在用这个方法,效率只会越来越低。”",
"小周说职场 / 2026-10-06"
],
[
"标题",
"结果导向",
"“月薪 1 万的人,最该戒掉的 3 个习惯”",
"商业类对标 / 2026-10-04"
],
[
"结构",
"清单型",
"问题 → 误区 → 3 个动作 → 结果证明",
"内部拆解 / 2026-10-02"
],
[
"角度",
"身份代入",
"“站在老板视角看,这笔钱其实最贵。”",
"老陈商业局 / 2026-10-01"
],
[
"开场白",
"冲突",
"“我用了 30 天,才发现努力方向一直错了。”",
"成长类对标 / 2026-09-29"
]
];
/* =========================================================
基础组件
========================================================= */
function btn(t, cls="", attr=""){
return `
<button
class="btn ${cls}"
${attr}
>
${t}
</button>
`;
}
function accountCell(a){
return `
<div class="account">
<div class="avatar">
${a.a.slice(0,1)}
</div>
<div>
<b>${a.n}</b>
<div class="quiet small">
${a.p}
</div>
</div>
</div>
`;
}
function pageHead(
kicker,
title,
desc,
actions=""
){
return `
<div class="pagehead">
<div>
<div class="eyebrow">
${kicker}
</div>
<h1>
${title}
</h1>
${
desc
?
`<div
class="muted"
style="margin-top:6px"
>
${desc}
</div>`
:
""
}
</div>
<div class="head-actions">
${actions}
</div>
</div>
`;
}
function section(
title,
body,
extra=""
){
return `
<section class="section">
<div class="section-title">
<h2>
${title}
</h2>
<span class="hint">
${extra}
</span>
</div>
${body}
</section>
`;
}
function metrics(items){
return `
<div class="metric-row">
${
items.map(x => `
<div class="metric">
<div class="label">
${x[0]}
</div>
<div class="num">
${x[1]}
<span class="unit">
${x[2] || ""}
</span>
</div>
</div>
`).join("")
}
</div>
`;
}
/* =========================================================
Toast / Modal
========================================================= */
function showToast(t){
let e = document.getElementById("toast");
e.textContent = t;
e.classList.add("show");
setTimeout(
() => e.classList.remove("show"),
1800
);
}
function modal(
title,
body,
actions
){
document.getElementById("modalBox").innerHTML = `
<h2>
${title}
</h2>
<div style="margin:14px 0">
${body}
</div>
<div
style="
display:flex;
justify-content:flex-end;
gap:8px
"
>
${
actions ||
btn(
"关闭",
"ghost",
"onclick='closeModal()'"
)
}
</div>
`;
document
.getElementById("modal")
.classList
.add("show");
}
function closeModal(){
document
.getElementById("modal")
.classList
.remove("show");
}
/* =========================================================
P1 矩阵总览
========================================================= */
function p1(){
return (
pageHead(
"P1 · 矩阵总览",
"今天先把这 5 件事处理完",
"10–50 个账号的日常操作台,优先显示需要人做决定的事项.",
btn(
"随手记",
"ghost",
"onclick='openNote()'"
)
+
btn(
"新建内容",
"primary",
"onclick=\"go('p4')\""
)
)
+
metrics([
["今日待处理","12","项"],
["今日已发布","7","条"],
["异常值","2","条"],
["本月播放","428.6","万"]
])
+
section(
"今日待处理",
`
<div class="card tight">
<table class="table">
<thead>
<tr>
<th>账号</th>
<th>今天要做</th>
<th>状态</th>
<th>截止</th>
<th></th>
</tr>
</thead>
<tbody>
${
accounts.map(
(a,i) => `
<tr>
<td>
${accountCell(a)}
</td>
<td>
<b>
${a.today}
</b>
<div class="quiet small">
${
i%2
?
"已完成脚本,等审核"
:
"选题已确认 · 正在成稿"
}
</div>
</td>
<td>
<span
class="tag ${
a.status==="异常"
?
"bad"
:
a.status==="已发布"
?
"ok"
:
"purple"
}"
>
${a.status}
</span>
</td>
<td>
${i<2 ? "16:00" : "今天"}
</td>
<td>
${
btn(
"处理",
"ghost",
`onclick="go('${i%2?'p5':'p4'}')"`
)
}
</td>
</tr>
`
).join("")
}
</tbody>
</table>
</div>
`
)
+
section(
"账号矩阵",
`
<div class="card tight">
<table class="table">
<thead>
<tr>
<th>账号</th>
<th>今日内容</th>
<th>表现</th>
<th>近 7 日</th>
<th>负责人</th>
</tr>
</thead>
<tbody>
${
accounts.map(
(a,i) => `
<tr>
<td>
${accountCell(a)}
</td>
<td>
${a.today}
</td>
<td>
<span class="kpi">
${a.views}
</span>
<span
class="${
a.delta.startsWith("-")
?
"tag bad"
:
"tag ok"
}"
>
${a.delta}
</span>
</td>
<td>
<div class="progress">
<i
style="
width:${38+i*11}%
"
></i>
</div>
</td>
<td class="muted">
${
[
"林林",
"小北",
"阿哲",
"林林",
"小北"
][i]
}
</td>
</tr>
`
).join("")
}
</tbody>
</table>
</div>
`
)
+
`
<div class="grid cols2 section">
<div>
${
section(
"异常值提示",
`
<div class="list card">
${
[
"Mia成长笔记:近 3 条完播率连续下降 31%",
"阿梨生活:评论区出现同一问题 17 次",
"老陈商业局:昨日发布后 2 小时互动异常上涨"
].map(
(x,i) => `
<div class="listrow">
<span>
${x}
</span>
<span
class="tag ${
i===0
?
"bad"
:
"warn"
}"
>
${
i===0
?
"需看"
:
"关注"
}
</span>
</div>
`
).join("")
}
</div>
`
)
}
</div>
<div>
${
section(
"本月表现最好的一条",
`
<div class="card">
<div class="quiet small">
老陈商业局 · 10 月 06 日
</div>
<h2 style="margin-top:7px">
“小公司真正烧钱的不是工资”
</h2>
<div
style="margin:12px 0"
class="quote"
>
相对账号平时水平
<b>7.2×</b>
· 32.1 万播放
· 6,482 收藏
</div>
${
btn(
"查看拆解",
"ghost",
"onclick=\"go('p2')\""
)
}
</div>
`
)
}
</div>
</div>
`
);
}
/* =========================================================
P2 选题雷达
========================================================= */
function p2(){
return (
pageHead(
"P2 · 找选题",
"选题雷达",
"把外部信号变成可推进的选题,不只做收藏。",
btn(
"灵感速记",
"ghost",
"onclick='openNote()'"
)
+
btn(
"加入选题",
"primary",
"onclick='showToast(\"已加入选题库\")'"
)
)
+
metrics([
["监控账号","38","个"],
["低粉爆款","24","条"],
["异常值","9","条"],
["近三天更新","117","条"]
])
+
`
<div class="subtabs">
<button class="subtab active">
精选总览
</button>
<button class="subtab">
对标动态
</button>
<button class="subtab">
评论洞察
</button>
</div>
`
+
section(
"对标内容",
`
<div class="card tight">
<table class="table">
<thead>
<tr>
<th>内容</th>
<th>账号</th>
<th>相对平时</th>
<th>数据变化</th>
<th>动作</th>
</tr>
</thead>
<tbody>
${
ideas.map(
x => `
<tr>
<td>
<b>
${x[0]}
</b>
<div class="quiet small">
今日更新 · 口播 / 42s
</div>
</td>
<td>
${x[1]}
</td>
<td>
<span class="tag purple">
${x[2]}
</span>
</td>
<td>
${x[3]}
</td>
<td>
${
btn(
"拆解",
"ghost",
"onclick=\"go('p3')\""
)
}
</td>
</tr>
`
).join("")
}
</tbody>
</table>
</div>
`
)
+
`
<div class="grid cols2 section">
<div>
${
section(
"评论区洞察",
`
<div class="card">
<div class="quote">
“能不能讲讲具体怎么做?”
出现 <b>42</b> 次
</div>
<div
class="quote"
style="margin-top:12px"
>
“我也遇到过,但不知道是不是同一种情况。”
出现 <b>19</b> 次
</div>
<div style="margin-top:14px">
${
btn(
"生成选题方向",
"ghost",
"onclick='showToast(\"已生成 4 个方向\")'"
)
}
</div>
</div>
`
)
}
</div>
<div>
${
section(
"选题库",
`
<div class="card">
<div
class="chiprow"
style="margin-bottom:12px"
>
<span class="tag purple">
待做 18
</span>
<span class="tag">
在写 6
</span>
<span class="tag">
已用 42
</span>
</div>
<div class="list">
${
[
"为什么越努力越低效?",
"老板真正想看的不是日报",
"租房收纳的反常识"
].map(
(x,i) => `
<div class="listrow">
<span>
${x}
</span>
<span class="quiet small">
${
[
"待做",
"在写",
"已用"
][i]
}
</span>
</div>
`
).join("")
}
</div>
</div>
`
)
}
</div>
</div>
`
);
}
/* =========================================================
P3 资产库
========================================================= */
function p3(){
return (
pageHead(
"P3 · 资产库",
"拆解结果,下一次直接拿",
"沉淀可复用的角度、结构、开场白和标题。",
btn(
"引用到创作",
"primary",
"onclick=\"go('p4')\""
)
)
+
`
<div class="subtabs">
<button class="subtab active">
角度
</button>
<button class="subtab">
结构
</button>
<button class="subtab">
开场白
</button>
<button class="subtab">
标题
</button>
</div>
`
+
`
<div class="grid cols2">
<div class="card tight">
<table class="table">
<thead>
<tr>
<th>类型</th>
<th>命名</th>
<th>出处</th>
</tr>
</thead>
<tbody>
${
assets.map(
(x,i) => `
<tr
onclick="assetDetail(${i})"
style="cursor:pointer"
>
<td>
<span class="tag">
${x[0]}
</span>
</td>
<td>
<b>
${x[1]}
</b>
<div class="quiet small">
${x[2]}
</div>
</td>
<td class="quiet small">
${x[3]}
</td>
</tr>
`
).join("")
}
</tbody>
</table>
</div>
<div
class="card"
id="assetDetail"
>
<div class="eyebrow">
单条详情
</div>
<h2>
选择左侧资产
</h2>
<div
class="empty"
style="margin-top:14px"
>
这里显示原文、出处与引用动作。
当前为空。
</div>
</div>
</div>
`
);
}
/* =========================================================
P4 创作台
========================================================= */
function p4(){
return (
pageHead(
"P4 · 创作台",
"小公司真正烧钱的不是工资",
"内容 ID:MCN-1026-031 · 当前账号:老陈商业局",
btn(
"返回选题",
"ghost",
"onclick=\"go('p2')\""
)
+
btn(
"进入发布",
"primary",
"onclick=\"go('p5')\""
)
)
+
`
<div class="stepper">
${
[
"定选题",
"搭结构",
"写文案",
"起标题",
"做封面",
"发布检查",
"完成"
].map(
(x,i) => `
<button
class="step ${
i===2
?
"active"
:
i<2
?
"done"
:
""
}"
onclick="showToast('已切换到:${x}')"
>
<b>
${i+1} · ${x}
</b>
<span>
${
i===2
?
"当前环节"
:
"可回退"
}
</span>
</button>
`
).join("")
}
</div>
`
+
`
<div class="workgrid">
<div>
<div class="card">
<div class="section-title">
<h2>
写文案
</h2>
<span class="tag purple">
编辑中
</span>
</div>
<label class="formlabel">
当前稿件
</label>
<textarea
class="textarea"
id="draft"
>很多人以为小公司最烧钱的是工资。其实真正贵的,是每个人都在做低价值的重复工作。
我把过去 12 个月的成本拆了一遍,最值得先处理的有 3 件事:会议、返工和没有明确负责人的任务。
如果你只能改一个地方,先把“谁负责、什么时候交、什么算完成”写清楚。</textarea>
<div
style="
display:flex;
justify-content:space-between;
align-items:center;
margin-top:10px
"
>
<span class="quiet small">
326 字 · 已自动保存
</span>
${
btn(
"保存版本",
"ghost",
"onclick='showToast(\"版本已保存\")'"
)
}
</div>
</div>
<div class="card section">
<div class="section-title">
<h2>
AI 产出与采纳
</h2>
<span class="quiet small">
不自动覆盖当前稿
</span>
</div>
<div class="version active">
<div
style="
display:flex;
justify-content:space-between
"
>
<b>
版本 A · 结果导向
</b>
<span class="tag ok">
已生成
</span>
</div>
<p class="muted">
把“工资贵”这个认知反转成“返工才贵”,
前 3 秒直接给结论。
</p>
<div class="chiprow">
${
btn(
"采纳",
"ghost",
"onclick='acceptAI()'"
)
}
${
btn(
"驳回",
"ghost",
"onclick='showToast(\"已驳回\")'"
)
}
${
btn(
"改后再用",
"ghost",
"onclick='showToast(\"已复制到编辑区\")'"
)
}
</div>
</div>
<div class="version">
<div
style="
display:flex;
justify-content:space-between
"
>
<b>
版本 B · 失败重试
</b>
<span class="tag bad">
失败
</span>
</div>
<p class="quiet small">
生成超时,原稿不受影响。
</p>
${
btn(
"重试",
"ghost",
"onclick='showToast(\"正在重新生成…\")'"
)
}
</div>
</div>
</div>
<div class="sticky">
<div class="card">
<div class="section-title">
<h2>
资产引用
</h2>
<span class="quiet small">
3 条
</span>
</div>
${
assets.slice(0,3).map(
x => `
<div class="listrow">
<div>
<span class="tag">
${x[0]}
</span>
<b>
${x[1]}
</b>
<div
class="quiet small"
style="margin-top:3px"
>
${x[2]}
</div>
</div>
${
btn(
"引用",
"ghost",
"onclick='showToast(\"已插入资产\")'"
)
}
</div>
`
).join("")
}
</div>
<div class="card section">
<div class="section-title">
<h2>
版本列表
</h2>
<span class="quiet small">
自动保存
</span>
</div>
${
[
"v3 · 16:21 当前",
"v2 · 15:48",
"v1 · 14:06"
].map(
(x,i) => `
<div class="listrow">
<span>
${x}
</span>
<span
class="${
i===0
?
"tag purple"
:
"quiet small"
}"
>
${
i===0
?
"当前"
:
"恢复"
}
</span>
</div>
`
).join("")
}
</div>
</div>
</div>
`
);
}
/* =========================================================
P5 发布中心
========================================================= */
function p5(){
return (
pageHead(
"P5 · 发布中心",
"过闸之后,再由人确认发出",
"同一内容按账号与平台展开版本;硬拦优先解决,提醒允许人工判断。",
btn(
"发布记录",
"ghost",
"onclick=\"go('p8')\""
)
)
+
`
<div class="subtabs">
<button class="subtab active">
目标选择
</button>
<button class="subtab">
版本预览
</button>
<button class="subtab">
发布检查
</button>
<button class="subtab">
确认发布
</button>
</div>
`
+
`
<div class="grid cols2">
<div class="card">
<div class="section-title">
<h2>
目标选择
</h2>
<span class="quiet small">
已选 3 个
</span>
</div>
${
accounts.slice(0,4).map(
(a,i) => `
<label
class="listrow"
style="cursor:pointer"
>
<span
style="
display:flex;
gap:10px;
align-items:center
"
>
<input
type="checkbox"
${i<3 ? "checked" : ""}
>
${accountCell(a)}
</span>
<span class="quiet small">
${a.p}
</span>
</label>
`
).join("")
}
<div style="margin-top:14px">
${
btn(
"批量应用账号画像",
"ghost",
"onclick='showToast(\"已应用账号语气与红线\")'"
)
}
</div>
</div>
<div class="card">
<div class="section-title">
<h2>
各版本预览
</h2>
<span class="quiet small">
点击逐版编辑
</span>
</div>
${
accounts.slice(0,3).map(
(a,i) => `
<div
class="version ${
i===0
?
"active"
:
""
}"
>
<div
style="
display:flex;
justify-content:space-between
"
>
<b>
${a.n} · ${a.p}
</b>
<span
class="tag ${
i===2
?
"bad"
:
"ok"
}"
>
${
i===2
?
"有 1 项硬拦"
:
"通过"
}
</span>
</div>
<div
class="muted small"
style="margin-top:7px"
>
${a.today}
|“很多人以为小公司最烧钱的是工资……”
</div>
${
btn(
"编辑此版本",
"ghost",
"onclick='showToast(\"已进入逐版编辑\")'"
)
}
</div>
`
).join("")
}
</div>
</div>
`
+
section(
"检查结果",
`
<div class="card">
<div class="listrow">
<span>
<b>硬拦</b>
· Mia成长笔记:标题含“最有效”,缺少依据
</span>
<span class="tag bad">
必须处理
</span>
</div>
<div class="listrow">
<span>
<b>提醒</b>
· 阿梨生活:封面文字超过 12 字
</span>
<span class="tag warn">
建议修改
</span>
</div>
<div class="listrow">
<span>
<b>通过</b>
· 小周说职场:账号红线、标题、正文检查完成
</span>
<span class="tag ok">
可发布
</span>
</div>
</div>
`
)
+
section(
"确认发布",
`
<div
class="card"
style="
display:flex;
justify-content:space-between;
align-items:center;
gap:16px
"
>
<div>
<b>
还剩 2 个版本可发布
</b>
<div
class="quiet small"
style="margin-top:4px"
>
发布后将写入发布留痕,并进入复盘队列。
</div>
</div>
${
btn(
"确认发布",
"primary",
"onclick='confirmPublish()'"
)
}
</div>
`
)
);
}
/* =========================================================
P6 账号画像
========================================================= */
function p6(){
return (
pageHead(
"P6 · 账号画像",
"账号画像与长期记忆",
"每个账号一份可持续维护的工作上下文;记忆只追加,不覆盖历史。",
btn(
"新增记忆",
"primary",
"onclick='addMemory()'"
)
)
+
`
<div class="grid cols2">
<div class="card tight">
<div class="section-title">
<h2>
账号列表
</h2>
<span class="quiet small">
${accounts.length} / 38
</span>
</div>
${
accounts.map(
(a,i) => `
<div
class="listrow"
onclick="profile(${i})"
style="cursor:pointer"
>
${accountCell(a)}
<span
class="tag ${
i===0
?
"purple"
:
""
}"
>
${
i===0
?
"当前"
:
"查看"
}
</span>
</div>
`
).join("")
}
</div>
<div class="card">
<div class="eyebrow">
当前账号
</div>
<h2>
小周说职场
</h2>
<div
class="chiprow"
style="margin:10px 0 16px"
>
<span class="tag">
抖音
</span>
<span class="tag">
职场效率
</span>
<span class="tag ok">
活跃
</span>
</div>
<div class="grid cols2">
${
[
["定位","给普通职场人可执行的方法"],
["风格","直接、少铺垫、结论先行"],
["受众","22–35 岁职场人"],
["平台","抖音为主,小红书同步"],
["偏好与红线","偏好具体案例;不夸大承诺"],
["长期记忆","用户更信真实复盘,不信空泛鸡汤"]
].map(
x => `
<div>
<div class="quiet small">
${x[0]}
</div>
<div style="margin-top:4px">
${x[1]}
</div>
</div>
`
).join("")
}
</div>
<div class="section-title section">
<h2>
记忆条目
</h2>
<span class="quiet small">
只追加
</span>
</div>
<div class="list">
${
[
"2026-10-07:封面尽量少于 10 字",
"2026-10-03:案例优先于抽象观点",
"2026-09-28:标题避免“你一定要”"
].map(
x => `
<div class="listrow">
<span>
${x}
</span>
<span class="quiet small">
已生效
</span>
</div>
`
).join("")
}
</div>
<div class="section-title section">
<h2>
关联内容
</h2>
<span class="link">
查看全部
</span>
</div>
<div class="chiprow">
${
[
"小公司真正烧钱的不是工资",
"为什么越努力越低效?",
"会议为什么越开越多"
].map(
x => `
<span class="tag">
${x}
</span>
`
).join("")
}
</div>
</div>
</div>
`
);
}
/* =========================================================
P7 复盘台
========================================================= */
function p7(){
return (
pageHead(
"P7 · 复盘台",
"把表现读回来,写成下一次经验",
"复盘不是打分,而是把一次发布变成账号长期可用的判断。",
btn(
"历史复盘",
"ghost",
"onclick='showToast(\"历史复盘已展开\")'"
)
)
+
`
<div class="grid cols2">
<div class="card">
<div class="section-title">
<h2>
待复盘项
</h2>
<span class="tag purple">
3 条
</span>
</div>
${
[
"小公司真正烧钱的不是工资",
"租房收纳的反常识",
"停止内耗后,我反而做成了这件事"
].map(
(x,i) => `
<div class="listrow">
<div>
<b>
${x}
</b>
<div class="quiet small">
${
[
"老陈商业局 · 发布后 48h",
"阿梨生活 · 发布后 36h",
"Mia成长笔记 · 发布后 24h"
][i]
}
</div>
</div>
<button
class="btn ghost"
onclick="showToast('已选择该条复盘')"
>
复盘
</button>
</div>
`
).join("")
}
</div>
<div class="card">
<div class="eyebrow">
当前复盘
</div>
<h2>
小公司真正烧钱的不是工资
</h2>
${
metrics([
["播放","32.1","万"],
["完播","48.6","%"],
["收藏","6,482","次"],
["关注转化","2.8","%"]
])
}
<div class="section-title section">
<h2>
归因结论
</h2>
<span class="tag purple">
AI 初稿 · 可编辑
</span>
</div>
<textarea
class="textarea"
style="min-height:125px"
>结果反转式开场明显提升前 3 秒留存;“工资不是最大成本”的冲突点与账号商业定位一致。评论区大量出现“返工、会议、负责人不清晰”,说明下一条可继续深挖具体管理动作。</textarea>
<div style="margin-top:10px">
${
btn(
"确认结论",
"primary",
"onclick='showToast(\"复盘已确认\")'"
)
}
${
btn(
"改判",
"ghost",
"onclick='showToast(\"已标记为人工改判\")'"
)
}
</div>
<div class="section-title section">
<h2>
回写目标提示
</h2>
<span class="quiet small">
确认后写入账号画像
</span>
</div>
<div class="alert">
<span>
“保留结果反转开场;优先使用真实成本案例。”
</span>
${
btn(
"写回画像",
"ghost",
"onclick='showToast(\"已写回目标提示\")'"
)
}
</div>
</div>
</div>
`
);
}
/* =========================================================
P8 记录与对账
========================================================= */
function p8(){
return (
pageHead(
"P8 · 记录与对账",
"发布留痕与经营对账",
"从一条已发布内容反查版本、账号、时间、商单与收入。",
btn(
"导出当前筛选",
"ghost",
"onclick='showToast(\"导出任务已创建\")'"
)
)
+
`
<div class="subtabs">
<button class="subtab active">
发布记录
</button>
<button class="subtab">
单条溯源
</button>
<button class="subtab">
对账核对
</button>
<button class="subtab">
商单与收支
</button>
</div>
`
+
section(
"发布记录",
`
<div class="card tight">
<table class="table">
<thead>
<tr>
<th>时间</th>
<th>账号</th>
<th>内容</th>
<th>平台</th>
<th>结果</th>
<th>操作</th>
</tr>
</thead>
<tbody>
${
[
"10-08 15:42",
"10-08 14:18",
"10-07 19:06",
"10-07 17:32",
"10-06 20:11"
].map(
(t,i) => `
<tr>
<td class="mono small">
${t}
</td>
<td>
${accounts[i].n}
</td>
<td>
${accounts[i].today}
</td>
<td>
${accounts[i].p}
</td>
<td>
<span class="tag ok">
已发布
</span>
</td>
<td>
${
btn(
"溯源",
"ghost",
"onclick='trace()'"
)
}
</td>
</tr>
`
).join("")
}
</tbody>
</table>
</div>
`
)
+
`
<div class="grid cols2 section">
<div>
${
section(
"对账核对区",
`
<div class="card">
<div class="listrow">
<span>
平台回款待核
</span>
<b>
¥ 18,600
</b>
</div>
<div class="listrow">
<span>
商单应收
</span>
<b>
¥ 42,000
</b>
</div>
<div class="listrow">
<span>
已核对
</span>
<span class="tag ok">
27 / 31
</span>
</div>
<div style="margin-top:14px">
${
btn(
"开始核对",
"primary",
"onclick='showToast(\"已进入逐笔核对\")'"
)
}
</div>
</div>
`
)
}
</div>
<div>
${
section(
"商单与收支",
`
<div class="card">
<div class="listrow">
<span>
10 月品牌合作 · A 品牌
</span>
<b>
¥ 30,000
</b>
</div>
<div class="listrow">
<span>
内容制作成本
</span>
<span>
− ¥ 8,420
</span>
</div>
<div class="listrow">
<span>
平台服务费
</span>
<span>
− ¥ 2,160
</span>
</div>
<div class="listrow">
<b>
预计净收入
</b>
<b>
¥ 19,420
</b>
</div>
</div>
`
)
}
</div>
</div>
`
);
}
/* =========================================================
页面路由
========================================================= */
function render(page="p1"){
const map = {
p1,
p2,
p3,
p4,
p5,
p6,
p7,
p8
};
document.getElementById("app").innerHTML =
map[page]();
document
.querySelectorAll(".navtab")
.forEach(
x =>
x.classList.toggle(
"active",
x.dataset.page === page
)
);
window.scrollTo({
top:0,
behavior:"smooth"
});
}
function go(p){
render(p);
}
/* =========================================================
导航
========================================================= */
document
.querySelectorAll(".navtab")
.forEach(
b =>
b.onclick = () =>
go(b.dataset.page)
);
/* =========================================================
P3 资产详情
========================================================= */
function assetDetail(i){
let x = assets[i];
document.getElementById(
"assetDetail"
).innerHTML = `
<div class="eyebrow">
${x[0]} · ${x[1]}
</div>
<h2>
${x[2]}
</h2>
<div class="section">
<div class="quiet small">
出处
</div>
<div style="margin-top:4px">
${x[3]}
</div>
</div>
<div class="section">
<div class="quiet small">
原文
</div>
<div
class="quote"
style="margin-top:6px"
>
“如果你还在用这个方法,效率只会越来越低。
真正应该先改的是工作顺序,而不是加班时间。”
</div>
</div>
<div style="margin-top:16px">
${
btn(
"引用到创作",
"primary",
"onclick=\"go('p4')\""
)
}
${
btn(
"复制原文",
"ghost",
"onclick='showToast(\"已复制\")'"
)
}
</div>
`;
}
/* =========================================================
灵感速记
========================================================= */
function openNote(){
modal(
"灵感速记",
`
<textarea
class="textarea"
placeholder="记下一个刚看到的观点、评论或一句开场白…"
></textarea>
`,
btn(
"保存速记",
"primary",
"onclick=\"closeModal();showToast('已保存到灵感速记')\""
)
+
btn(
"取消",
"ghost",
"onclick='closeModal()'"
)
);
}
/* =========================================================
发布二次确认
========================================================= */
function confirmPublish(){
modal(
"二次确认发布",
`
<div class="alert warn">
你即将发布
<b>2</b>
个账号版本。
发布后会产生平台留痕,并进入复盘队列。
</div>
<p class="notice">
请确认:
版本已由人工检查;
硬拦项已处理;
账号画像与红线已应用。
</p>
`,
btn(
"确认并发布",
"primary",
"onclick=\"closeModal();showToast('已提交发布,等待平台结果')\""
)
+
btn(
"返回检查",
"ghost",
"onclick='closeModal()'"
)
);
}
/* =========================================================
AI 采纳
========================================================= */
function acceptAI(){
document.getElementById(
"draft"
).value =
`很多人以为小公司最烧钱的是工资。其实真正贵的,是每个人都在做低价值的重复工作。
我把过去 12 个月的成本拆了一遍,最值得先处理的有 3 件事:会议、返工和没有明确负责人的任务。
如果你只能改一个地方,先把“谁负责、什么时候交、什么算完成”写清楚。`;
showToast(
"AI 版本已采纳到当前稿"
);
}
/* =========================================================
新增账号记忆
========================================================= */
function addMemory(){
modal(
"新增记忆",
`
<label class="formlabel">
记忆内容
</label>
<textarea
class="textarea"
placeholder="例如:用户更偏好真实案例,不接受空泛鸡汤。"
></textarea>
<div
class="notice"
style="margin-top:8px"
>
新增后只追加,不覆盖历史记忆。
</div>
`,
btn(
"追加记忆",
"primary",
"onclick=\"closeModal();showToast('记忆已追加')\""
)
+
btn(
"取消",
"ghost",
"onclick='closeModal()'"
)
);
}
/* =========================================================
账号切换
========================================================= */
function profile(i){
showToast(
"已切换到 " +
accounts[i].n
);
}
/* =========================================================
单条溯源
========================================================= */
function trace(){
modal(
"单条溯源",
`
<div class="timeline">
<div class="event">
<b>
15:42 发布
</b>
<div class="quiet small">
老陈商业局 · B站
</div>
</div>
<div class="event">
<b>
15:31 人工确认
</b>
<div class="quiet small">
检查通过,2 个提醒已忽略
</div>
</div>
<div class="event">
<b>
14:58 v3 保存
</b>
<div class="quiet small">
采纳 AI 版本 A 后人工修改
</div>
</div>
<div class="event">
<b>
10:12 选题进入创作
</b>
<div class="quiet small">
来源:对标低粉爆款 7.2×
</div>
</div>
</div>
`,
btn(
"关闭",
"ghost",
"onclick='closeModal()'"
)
);
}
/* =========================================================
全局搜索
========================================================= */
document
.getElementById("globalSearch")
.addEventListener(
"keydown",
e => {
if(e.key === "Enter"){
let q =
e.target.value.trim();
if(q){
showToast(
"已检索:" + q
);
}else{
showToast(
"请输入搜索词"
);
}
}
}
);
/* =========================================================
Modal 点击遮罩关闭
========================================================= */
document
.getElementById("modal")
.addEventListener(
"click",
e => {
if(
e.target.id === "modal"
){
closeModal();
}
}
);
/* =========================================================
默认首页
========================================================= */
render();
</script>
</body>
</html>
```
---
## 三、对照表(参考版做法 → 我方处置)
| # | 参考版的做法 | 我方处置 | 理由 | 若采纳,落在哪 |
|---|---|---|---|---|
| 1 | 顶部横向一级导航(替代左侧栏),扁平八项 | **改判(第三轮):结构采纳、载体不采纳** | 2026-10-08 用户两条口径把它拆开了:①「左侧功能导航 只有大板块的导航 只有一层」+ 随后的截图(这张顶部导航条的八个短名)⇒ **「扁平八项、一项一页」这层结构已采纳**;②「左侧导航参考 tiaoyue 的导航」⇒ **载体仍是左侧栏**,而且照 tiaoyue 的 `app-sidebar` 做成 64px 图标栏(不是它这种顶部横条)。八项就是:总览 / 找选题 / 资产库 / 创作 / 发布 / 账号画像 / 复盘 / 记录与对账 —— 名字与参考版一一对应 | 外壳左侧栏;`DESIGN.md` §1① ⑤「导航层级」「侧栏形态」 |
| 2 | 居中宽内容区 + 顶栏常驻全局搜索 | **改判(第四轮):居中宽内容区保留,顶栏常驻搜索撤掉** | 上一轮判「采纳」,理由是②段 P1 要求「全局检索一次点击内可达」。本轮查清:②段 P1 的第 5 板块原文是「**全局检索与随手记入口**」——那是 **P1 的页内板块**,⛔ 不是全局外壳件;②段只在 §286 把**随手记**定为「全局可达」,没给全局检索同样的待遇。⇒ 检索留在 P1 页内,顶栏那颗删掉(详 `3d-审查报告.md` §十 第 5 条) | P1 页内;`DESIGN.md` §2.4 `G-10` |
| 3 | 首屏超大主张式标题(「今天先把这 5 件事处理完」) | **不采纳** | 基础层 `oil-ui-pro` 把「工具页顶部放超大标题/口号」列为模型默认;工具型页一进来就该是可读工作面 | —(保留现有页标题行) |
| 4 | 指标卡一排 4 张(今日待处理 / 已发布 / 异常值 / 本月播放) | **采纳(第三轮扩到八页)** | 与我方 P1 统计条同形;⛔ 不采用它的「每卡一色」(基础层要求同层同级卡保持同一重量)。**落位按参考版**:指标条紧跟页标题、中间不夹卡片行。第三轮用户口径「每个板块的首页 样式参考 MCN工作台首页」⇒ 把它**扩到八页**:每页页头之下先统计条、再功能入口卡 | 八页 `.home-stats`;`DESIGN.md` §2.5「页面统计条」 |
| 5 | 账号矩阵改用表格(账号 / 今日内容 / 表现 / 近 7 日 / 负责人) | **已采纳(2026-10-08 第三轮改判)** | ②段 §二 原文写明「⛔ 本块不写怎么呈现(矩阵、列表、卡片都是形态,归③段判)」⇒ 形态不必回②段。上一轮判「暂不采纳」的理由是**密度**:照搬后首行顶 724px ⇒ 一屏 2 行(契约 ≥6)。本轮用户口径「gpt 给的布局是看不到 还是学不会」⇒ **真照搬了**,并同时把行高从 67px 压到 **31px**(每格一个短值 + 22px 的 `.btn-micro` + 内衬 `4/8`)⇒ **首行顶 708px、一屏 6 行,达标**。⇒ 旧结论「满宽顺排与密度不可兼得」**作废**,正确表述是「可以兼得,但行高必须压到 31px 上下」 | P1 + P2/P3/P5/P6/P7/P8 的主列表;`DESIGN.md` §2.5「满宽表格」、§五 第 7 条 |
| 6 | 指标涨跌用**绿色**表示上升 | **不采纳** | 中文语境是「涨红跌绿」,内容数据的正增长同样该用红 —— 参考版按欧美惯例上了绿 | 所有带涨跌的组件 |
| 7 | 状态一律用 pill 徽章(待发布 / 待审核 / 已发布 / 异常) | **采纳** | 与我方 tag 同形,且是「用状态词、不用单侧色条」,符合基础层 | 已有 |
| 8 | 每行行尾一个「处理」行级动作 | **采纳** | 与②段「今日待处理」的行级动作一致 | 已有 |
| 9 | **每页都有一处左右两栏**(`.grid.cols2`,宽比 1.35fr : .9fr) | **采纳(照抄)** | 用户 2026-10-08 口径「哪里左右布局的功能照着抄」。左放上下文/列表、右放产出/动作/详情,主数据块仍满宽;DOM 里的板块先后照旧 ⇒ 不与②段骨架冲突 | 全部八页;`DESIGN.md` §2.3「两栏分栏(.grid-main-side)」 |
| 10 | 导航项用**两三个字的短名**(总览 / 找选题 / 资产库 / 创作 / 发布 / 账号画像 / 复盘 / 记录与对账) | **采纳,但落法与参考版不同** | 用户 2026-10-08 口径「看看 gpt 的板块 或功能命名,再看看你的」⇒ 名字**逐字照抄**(八项与②段八页一一对应,页头与面包屑仍写②段全名)。**落法不同**:参考版是把名字常驻在顶部横条上;我方侧栏照 tiaoyue 做成 64px 图标栏,名字改由**悬停/聚焦时向右浮出的提示**给出(`≤640` 的窄屏例外:转成带名字的横滚标签条,名字常驻) | 八项名字全部;`DESIGN.md` §1① ⑤、§2.5「侧栏导航项」「导航提示」 |
> 口径说明:处置一律对照 `DESIGN.md`、②段与**基础层** `oil-ui-pro`;参考版只是参照物,不是命令。