MediaBrandHub状态规范
界面质量/空 · 加载 · 出错
总览 9 个角色 运营后台

01 · 起点这些屏平时看不到,但上线第一天就在

之前 61 个页面里只有 1 处空态,就是这个项目最大的质量缺口。 不是忘了做,是先做有数据的样子更容易 —— 数据一多,截图就好看,评审就容易过。 但真上线第一天,运营面对的全是空的:新客户没项目、新账号没库存、筛一圈没结果。

这一页做的事只有一件:把「空白」拆开。因为四种空白长得一模一样,用户下一步动作却完全不同。 把「加载失败」画成「暂无数据」,是这个系统里最贵的一种界面错误 —— 运营以为客户没下单,其实接口 500 了,等到周五复盘才发现。

一句话判据:看完这个空,用户知道「我该做什么」吗?知道 = 空态;不知道 = 一块遮羞布。

02 · 核心同一条数据,四种处境

下面四块说的是同一个对象:媒体库里的「位」。库里真实有 1,284 个位。 四块都指向它,四种账号打开,看到四种空白 —— 每一块都是对的, 但每一块让用户做的事完全不同。这就是为什么不能只做一个空态。

四种空的关键差别在「是谁的问题」: 真空是业务还没开始(他的问题,他能解决);筛空是条件的问题(他的问题,改条件就行); 挡空是权限的问题(别人的问题,他只能去找人);错空是系统的问题(跟谁都没关系,只能等或重试)。 分不清这四者,界面就只能说「暂无数据」,然后所有人都去问客服。

03 · 空态 A真空:确实还没有,而且这是正常的

真空是唯一一种不需要道歉的空。新客户第一天上来看见「还没有项目」是正常的, 这时候加一个「出错了」的红框反而吓人。它只要一件事:把第一步说清楚。 所以真空的按钮不是「刷新」,是「新建 / 去接 / 去配」。

三个真实位置

真空最容易犯的错,是「给了一个不解决问题的按钮」。 比如「还没有工单」下面挂一个「刷新」—— 刷新一百次也还是零。 正确做法是往上游走一步:没有工单是因为没有项目,那就把「新建项目」放这儿, 或者至少给一条 → 先去客户与项目 的跳转。

补一种:不是所有空都需要按钮

这一节是做到工单台才发现的,是在代码里撞出来的,不是想出来的。 原本 empty() 强制要求「必须有下一步动作」, 结果给「审核队列清零」和「看板某一列没积压」套上去时,语义直接反了 —— 那是好事,硬塞一个按钮(哪怕叫「刷新」)等于在暗示「出问题了」。

所以单独开一个出口 allClear(),必填的不是动作,而是一句确认: 说清「这是正常的」或者「什么时候会自动有」。绿色是刻意的 —— 让运营一眼知道这块不用管,省下的注意力放到真正红着的地方。

这条值得单独记:规范一旦做成代码,会在第 6 个页面撞出第 1 个页面没想到的情况。 这是好事 —— 说明它真的在被使用。文档不会给你这种反馈,它只会一直显示「已完成」。

04 · 空态 B筛空:数据有,被条件筛掉了

筛空是后台最常出现的空 —— 运营一天筛几十次,总会筛到零。 它和真空的区别只有一句话:「没有数据」和「没有符合条件的数据」是两件事。 说错了,用户会去建一条重复的数据,因为他以为库里没有。

必须回显条件

筛空的标题里不能只说「没有结果」,要把生效的几个条件摆出来, 让人一眼看出哪个条件把结果卡死了。多数时候用户看到条件就自己想起来了: 「哦,我还勾着『已逾期』」。

反例:「暂无数据」+ 一个「新建」按钮。用户以为库里没有,又建了一条, 建完发现重复 —— 而且新建的那条不满足当前筛选条件,新建完还是空的。 这是最典型的「空态把人带沟里」。

05 · 空态 C挡空:有数据,但这个账号看不到

挡空是权限造成的空,在伙伴后台(渠道 / 服务商)和 OEM 租户后台最常见。 它最容易被误做成「没数据」—— 渠道商看到「还没有客户」, 以为客户没进来,其实是客户进来了但没报备给他。

挡空有两条硬规矩:① 必须承认「有,只是你看不到」;② 必须说清「找谁能开」。 只写「无权限」等于把人扔在原地。denied() 缺 who 会直接报规范缺项。

为什么挡空要给「找谁」而不是「申请」: 多数内部系统没有自助审批流,点了「申请」就是发一封没人看的邮件。 直接给一个真人(角色 + 姓名 + 一句话怎么说),比一个假的申请按钮有用。 真有审批流的时候,再换成按钮。

06 · 空态 D错空:没拿到数据,不是没有数据

错空是四种里唯一必须当场说清、不许含糊的。因为它会直接导致错误决策: 媒体接口挂了,库存显示为空 → 交付以为没位可投 → 跟客户说做不了 → 客户流失。 真实情况只是接口超时 6 秒。

错误分三级,按钮跟着分三级

级别什么情况界面怎么给给重试吗
可重试网络断、超时、502/503 说清「没取到,不是没有」,给重试,显示重试次数;超过 3 次改话术 给
不可重试403 无权限、404 已删除、参数错 说清是哪一类,给「返回」或「找谁」,不给重试 绝对不给
部分失败列表 20 条到了 17 条 不占整页:好数据照显,坏的那几条单独标;顶部一条窄提示 按条给
不可重试的却给了重试按钮,比不给更糟。 用户点三次、每次都在原地,从此这个系统里所有「重试」他都不信了 —— 包括那个真能修好的。
部分失败不要做成整页错误。17 条能用、3 条没取到,你给他一个整页红框, 等于把 17 条的可用性也一起丢了。正确做法是列表照显,坏的 3 行单独标「未取到 · 重试」, 顶上一条窄提示说「3 条未加载」。能用的先给用,这是后台的第一原则。

07 · 加载骨架屏不是加载动画,是提前把版式占住

转圈居中看着干净,但它有个致命问题:页面高度从 0 跳到 800。 用户的手指已经在往下按了,按钮跑掉了,他就点错了。 后台一屏几百个可点目标,这个错一天能犯二十次。

骨架的做法是:先按真实结构摆灰条,列宽、行高、间距跟加载完一模一样。 数据到了只是把灰条换成字,位置一个像素都不动。

骨架的灰条宽度要接近真实文字长度,不要全用 100%。 全等长的灰条加载完变成参差不齐的三行,视觉上会「跳」一下 —— 这一下不致命,但会让人觉得这系统不稳。

08 · 局部刷新筛选、翻页、重算,只该影响那一块

整页闪白再画回来,等于每次点筛选都把用户的视线清零一次。 运营筛一个数要连点三四次,一天下来这个「清零」会发生几百次。 正确做法:只让变化的那块变灰,其它原地不动。

为什么用顶部细进度条而不是转圈:转圈转到第 8 秒,用户就开始怀疑卡死了, 然后去点刷新 —— 反而把请求打断了。进度条一直在动,用户就愿意再等两秒。 不确定多久结束的时候,动的东西比准的东西更让人安心。 (这条已写进 prefers-reduced-motion:系统开了减少动态,动画自动关掉。)

09 · 工程规范不写在文档里,写在门里

写一份《空态设计规范》放进 Wiki,第 3 个页面就会开始偷懒,第 8 个页面就开始复制 第 3 个页面的「暂无数据」去糊接口报错。文档没人回看,代码天天被复制。

所以这一轮的规范做成了一道门 —— state.js 里四个出口各带必填项, 缺了不报错、不静默,而是照常渲染 + 挂一条红字。 原型阶段红着,评审时一眼看见;正式实现时这行换成 lint 拦截,页面根本出不来。

出口必填缺了会怎样(代码层面)
empty()title、acts≥1 红字「empty 缺下一步动作」—— 空态不许没有出路
nofilter()title、conds≥1 红字「缺条件回显」—— 不然用户以为没数据
denied()title、who 红字「缺找谁开通」—— 不然用户被扔在原地
broken()title、code 或 rid 红字「缺错误码或请求号」;title 里出现「暂无/没有数据」也报 —— 那说反了

故意缺一个参数,长这样

✕ 反面:少传一个 who(这是代码拦下来的,不是画出来的)
这条红字只在原型和开发环境出现。它存在的意义不是给人看,是让偷懒立刻变得刺眼。

10 · 验收判定表:不靠审美,靠能不能判对错

下面每一条都能被脚本或代码检查,没有一条是「看起来要舒服」。verify.py 里已接其中 14 条。

#判据怎么查状态

11 · 落点接在哪:9 处,全部点得出来

做成一页规范不算完成,接进真实位置才算。下面 9 处都已经接进页面, 每一处都能靠真实操作或顶栏那颗「数据」开关走到 —— 不是摆给人看的样例。 还没接的地方在页脚如实列了,没藏。

端位置用哪种具体情况
还没做的(如实列,不藏):
· 只测桌面 Chromium,未在真机 / Safari / Firefox 上验过状态块的换行与骨架动画
· 「重试超过 3 次改话术」写进了组件参数(tries),但没有真的做退避策略,后端接口还没定
· 部分失败的行级重试只有视觉,没有真实请求重发(原型范围)
· 骨架屏的灰条宽度是手写的,真实实现里应由后端返回的字段长度分布决定 —— 现在没有这个数据
· 客户端只接了对话这一处。报告页「T+7 未到」、媒体匹配筛空这两处还在清单上,没做
· 服务商 / OEM 两个后台还没接。它们的空态判断逻辑和渠道一致(都是挡空 + 真空),但页面上还没落

← 返回总览  ·  运营后台  ·  9 个角色  ·  客户端