原型(执行会话/目标-…-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
69 KiB
69 KiB
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 字符)
<!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;参考版只是参照物,不是命令。