客服 Agent 前端开发约束
版本:v1.0
适用分支:qyqy_develop(含我方 §T 用户自助段已上推的 9 端点)
权威性:团队强制规范——所有客服 Agent 前端仓库(含本期看板、未来客户工作台、转人工会话、客户画像确认页)必须遵循本文件
关联规范:docs/05-接口文档.md(接口权威)、docs/40-前端验收清单.md(qyqy 验收清单)、docs/客服Agent一期_合规红队与业务评测集_v1.md(合规红线)
一句话:任何"功能正确但违背本约束"的前端 PR 必须在评审阶段退回。 本约束的检查清单见 §10。
目录
- 适用范围与术语
- 技术栈
- 目录结构
- 命名规范
- 组件拆分原则
- 状态管理
- 接口调用规范
- 权限与角色控制
- 错误处理与日志埋点
- 样式与 UI 规范
- 看板模块专属约束
- 与主客服 Agent 页面的交互跳转
- 验收检查清单
1. 适用范围与术语
| 术语 |
含义 |
| 客服 Agent |
系统中的"奶龙"智能客服;服务层为 app/service/agent/implementations/customer_service.py |
| 门户(Portal) |
五端 portal:访客 / 已登录用户 / 交易系统 / 员工专属(风控)/ 员工专属(投顾) |
| 看板(Dashboard) |
本期 §T 段新增的"我的账户"页面,端点 T001 GET /api/v1/users/me/account/dashboard |
| 门户身份(sub) |
JWT 的 sub 字段,访客为纯数字(≤19位),用户为 customer_id(int)字符串 |
| envelope |
所有接口统一响应壳:{data, meta}(见 docs/05-接口文档.md §3.3) |
| trace_id |
每次请求生成的 UUID v4,前后端全链路打通 |
| Wolin OS |
沃林学生系统的前端 v6(13 个页面),与本约束不共享代码——本约束仅适用于客服 Agent 前端 |
不适用于:
- Wolin OS(已独立维护,有自己的风格)
- 内部运营监控台(
docs/30+ 系列描述)
- 投顾/风控工作台(虽共用底座,但前端结构另起)
2. 技术栈
2.1 强制采用(不可替换)
| 层 |
选型 |
版本约束 |
备注 |
| 框架 |
原生 JavaScript(ES2022+) |
无构建依赖 |
与底座 app/static/index.html 现有 Chat 联调页一致,避免引入 Node/Vite/Webpack |
| 样式 |
原生 CSS + CSS 变量 |
无 Tailwind / 无 CSS-in-JS |
看板的卡片/图表使用 CSS Grid + Flexbox |
| 图表 |
ECharts 5.x(按需引入) |
≥5.4 |
仅看板与允许引入,其他页面用纯 CSS 图形 |
| HTTP |
fetch 封装(见 §7.3) |
不引入 axios / ky |
与底座同源,减少 bundle |
| 运行时 |
浏览器 ≥Chrome 110 / Edge 110 / Safari 16 |
不支持 IE |
公司统一桌面环境标准 |
2.2 禁止使用
- ❌ React / Vue / Svelte(团队暂无相关人力储备,与底座解耦成本不划算)
- ❌ TypeScript(首版不强约束;如要引入必须先经客服组评审)
- ❌ 任何 UI 组件库(Element / Ant Design / MUI 等)——会与品牌色系冲突
- ❌ jQuery / Lodash(现代 API 已覆盖)
- ❌ 任何 npm 全量安装——必须按需 <script> 引入
2.3 必须保留的底座兼容
- 与底座同源部署(同一域名),不引入跨域
- 一切静态资源走
/static/portal/<page>/... 路径,不绕开底座
- SSE / WebSocket 由底座托管(
docs/05 §6.4),前端不要自行实现长连接
3. 目录结构
⚠️ 本节目录树已于 2026-09-14 按实际目录更正。原文写的是
guest/chat/、customer/chat/、customer/portfolio/(标"未来")、customer/orders/(标"未来")、
customer/profile/,且只列了四个角色目录。实际差异:
| 原文 |
实际 |
guest/chat/、customer/chat/ |
不存在 chat/ 目录。客服对话以浮窗形式提供(common/customer-service-widget/ 的 widget.js/widget.css),访客首页即 guest/home/ |
customer/portfolio/、customer/orders/ 标为"未来" |
均已落地:orders/、transactions/、holdings/、cash-ledger/、profit-loss/、risk-questionnaire/ |
customer/profile/(画像候选确认) |
实际为 customer/risk-questionnaire/;画像候选确认并入客户门户流程 |
| 只列 4 个角色目录 |
实际 6 个:另有 employee-console/(管理员)、employee-operations/(运营) |
⚠️ employee-advisor/ 与 employee-console/ 是两个不同角色,不是改名关系,不要合并。
⚠️ 访客公开产品页已接真实接口:GET /api/v1/products(P001)与
GET /api/v1/products/{product_code}/nav-history(P002),
数据源是 app/api/controllers/public_platform.py,不再是 common/mock-data.js。
要求令牌但不校验权限码(访客令牌的角色是 visitor、不带任何权限)。
3.1 强制约束
| 项 |
要求 |
| 目录归属 |
客服 Agent 页面只能放在 portal/{guest,customer,employee-*,trading}/ 下;不在 portal 目录的页面不受本规范保护 |
| 命名空间 |
portal/<角色>/<页面>/... 三层目录;<页面> 用 kebab-case(多个词用 -) |
| 入口文件 |
每个页面必须有 index.html 作为静态入口;JS 入口与 CSS 各一 |
| 公共代码 |
跨页面复用代码只能放在 portal/common/;禁止在业务页直接拷贝 |
| 看板模块路径 |
portal/customer/dashboard/,对应 /api/v1/users/me/account/dashboard 端点 |
| README |
portal/README.md 列所有路由与角色映射;改路由必同步更新 README |
3.2 禁止
- ❌ 把页面直接放
app/static/ 根目录(破坏 portal 命名空间)
- ❌ 在业务页里
import 别的业务页(跨业务复用必须抽到 common/)
- ❌ 在 HTML 里
<script src="https://..."> 引入第三方资源——必须下载到本地 static/vendor/
4. 命名规范
4.1 文件命名
| 类型 |
规则 |
示例 |
| HTML 入口 |
<page>/index.html |
dashboard/index.html |
| JS 模块 |
kebab-case |
metric-card.js、holdings-table.js |
| CSS |
kebab-case 或 <page>.css 单文件 |
dashboard.css |
| 资源(图片) |
snake_case + 后缀 |
logo_brandmark.svg、icon_refresh.svg |
4.2 标识符命名
| 类型 |
规则 |
示例 |
| CSS 类 |
BEM(block__element--modifier) |
metric-card__value--negative |
| CSS 变量 |
--<category>-<name> |
--ink、--brand-dark、--space-3 |
| JS 变量 |
camelCase |
currentAccount, holdingsCache |
| JS 类 / 构造器 |
PascalCase |
HoldingsTable, MetricCard |
| JS 私有(前缀约定) |
下划线前缀 |
_renderChart(), _lastRefreshAt |
| DOM data-* 属性 |
kebab-case + 前缀 |
data-permission-code, data-endpoint-id |
| 端点 ID(用于 data-endpoint-id) |
与 docs/05 §19 一致 |
T001、A039、M003 |
4.3 错误码 / 权限码引用
禁止在前端硬编码错误码或权限码字面量。所有错误码与权限码必须从 portal/common/error-codes.js 与 portal/common/permission-codes.js 引用。
理由:避免后端改名后前端静默失败(这就是 §10 验收清单里"硬编码字面量"红线的由来)。
5. 组件拆分原则
5.1 三层结构
| 层 |
命名约定 |
职责 |
不允许 |
| 入口编排 |
dashboard.js / chat.js |
拉数据 → 装配组件 → 渲染到 DOM |
写业务逻辑 |
| 业务模块 |
modules/<业务名>.js(一个卡片一个) |
接收数据 → 渲染自身 → 暴露事件 |
调接口 |
| 通用组件 |
widgets/<组件名>.js(可复用、无业务含义) |
纯展示 / 纯交互 |
知道任何 endpoint |
禁止业务模块与通用组件互相调用——必须经入口编排串接。示例:
5.2 组件拆分粒度
| 信号 |
应该拆 |
| 同一卡片有 ≥3 个独立可配置字段(标题、单位、趋势) |
✅ 抽 |
| 两个页面同时引用同一段 UI |
✅ 抽到 widgets/ |
| 业务规则只在某卡片内使用 |
❌ 留卡片内部 |
| 单元 ≤30 行 |
❌ 不必拆 |
5.3 看板拆分清单
看板按 §T 端点的 4 个一级字段拆模块:
| 字段 |
模块 |
依赖 widget |
account |
account-summary.js |
metric-card |
summary |
portfolio-summary.js |
metric-card, sparkline |
holdings[] |
holdings-table.js |
data-table |
| 通用操作 |
quick-actions.js(按钮:去下单 / 看记录) |
— |
6. 状态管理
6.1 全局状态
- 不引入 Redux / Vuex / MobX / Zustand 等状态库
- 跨页面状态用
localStorage + sessionStorage(按生命周期选择):
localStorage:用户偏好(暗色模式、字号、刷新频率)
sessionStorage:临时数据(表单草稿、未提交订单预览)—— 关闭标签页即清
- 禁止把 JWT / 客户敏感信息写进 localStorage
6.2 页面级状态
| 场景 |
方案 |
| 单次接口响应 |
页面内闭包变量,不导出 |
| 跨多个组件共享 |
入口 JS 维护 plain object + 显式 setter |
| 表单 |
原生 <form> + FormData,提交后清空 |
| 看板定时刷新 |
setInterval 在 pagehide / visibilitychange=hidden 时必须清理(避免后台请求) |
6.3 关键约束
- 不引入响应式框架(Preact / Alpine / lit-html)
- 看板 4 个模块不能互相修改对方的数据——必须通过入口 JS 中转
- 任何定时器(轮询、SSE 心跳)必须用单一
setInterval ID 维护;不嵌套
7. 接口调用规范
7.1 强制使用 portal/common/api-client.js
调用方禁止直接用 fetch();必须走 apiClient 包装。
7.2 API 调用三大规则
- 所有请求必传
trace_id(由 api-client.js 自动生成 UUID v4 并写入 X-Trace-Id header)
- 所有请求必传 JWT(从 cookie
auth_token 读取,自动注入 Authorization: Bearer <token>)
- 响应必走 envelope 解析(见
docs/05 §3.3:成功取 data、错误取 error)
7.3 端点 ID 注册
每个端点必须在 portal/common/api-client.js 中以端点 ID(如 T001)为 key 注册路径与 method:
禁止在前端代码里直接写字面路径。所有路径必须能从 docs/05 §19 查到对应端点 ID。
7.4 请求超时与重试
| 错误码 |
行为 |
5xx(除 501) |
自动重试 1 次,间隔 2s |
503 FUND_QUOTE_UNAVAILABLE 等可重试码 |
重试 + 显示「行情暂时不可用」 |
429 |
退避 5s 重试,最多 2 次(看板对行情类轮询尤其重要) |
4xx |
不重试——直接展示业务错误 |
| 超时(默认 8s) |
单次重试一次,仍超时则提示「网络不稳定」 |
7.5 看板专用:轮询与缓存
- 看板不主动轮询——必须由用户点击刷新按钮触发(避免无意义流量)
- 看板数据缓存策略:短缓存(60s),命中缓存时不发请求
- 持仓与组合的"今日盈亏"字段,只接受接口返回的服务端计算结果——前端禁止自行用
latest_price × quantity 派生
8. 权限与角色控制
8.1 RBAC 前端三大约束
- 权限码引用:所有权限码(如
9060 account:read:self)从 portal/common/permission-codes.js 引用,禁止硬编码
- JWT 解码:进入页面时调
apiClient.get('M001')(用户信息)或解析 cookie 里的 JWT 拿到 roles[] 与 permissions[]
- 可见性控制:UI 元素按权限显示/隐藏——
<button data-permission-code="9060">买入</button>,由前端权限守卫脚本统一处理
8.2 角色与 portal 对应
| 角色 |
可访问 portal |
关键权限码 |
| 访客(无 token) |
portal/guest/ |
仅公开知识(无 RBAC 权限码) |
| 已登录用户 |
portal/customer/ |
9060 account:read:self、9061 trade:order:create、9062 trade:order:read、9063 trade:order:cancel、9064 holding:read:self、9065 trade:txn:read |
| 风控专员 |
portal/employee-risk/ |
qyqy 已建(risk 段) |
| 投顾 |
portal/employee-advisor/ |
qyqy 已建(promotion / investment-goal 段) |
| 平台管理员 |
全部 |
全量 |
8.3 看板可见性规则
| 元素 |
必需权限 |
缺权限表现 |
| 整个看板卡片(账户看板) |
9060 account:read:self |
卡片灰显 + tooltip「请登录后查看」 |
| 「去下单」按钮 |
9061 trade:order:create |
按钮禁用 + tooltip「暂未开通交易权限」 |
| 「撤单」按钮(持仓卡片内) |
9063 trade:order:cancel |
按钮禁用 + tooltip「暂未开通撤单权限」 |
| 「全部成交记录」链接 |
9065 trade:txn:read |
链接隐藏 |
8.4 前端强制不变量
- 不发明新角色:前端只识别后端 JWT 里写明的 roles,禁止前端"假装是某个角色"
- 不绕过 RBAC 守卫:即使通过开发者工具移除
disabled 也要让请求带正确权限码——后端会再次校验
- 权限码变更必须双向同步:
tools/seed_test_rbac.py(后端)+ portal/common/permission-codes.js(前端),且都通过 PR 评审
9. 错误处理与日志埋点
9.1 错误处理三大约束
- 不吞错:所有
try/catch 必须把错误上报到 apiClient.reportError()
- 错误展示分级:
- 业务可恢复(
4xx):inline 提示(toast / 卡片内红条)
- 系统级(
5xx):顶部横幅 + 自动上报
- 网络错误:底部 status bar 提示
- 错误码文案必须来自后端:
docs/05 §3.6 每个错误码都有 code 与默认 message,前端禁止自行捏造文案
9.2 错误码示例(看板相关)
| 端点 |
错误码 |
HTTP |
前端文案建议 |
| T001 / T006 / T007 / T009 |
FUND_QUOTE_UNAVAILABLE |
503 |
「行情暂时不可用,请稍后刷新」 |
| T002 |
INSUFFICIENT_FUNDS |
422 |
「可用余额不足,请减少买入份额」 |
| T002 |
HOLDING_RATIO_EXCEEDED |
422 |
「超过单一投资者持有比例上限」 |
| T002 |
SUITABILITY_MISMATCH |
422 |
「您的风险等级与产品不匹配」 |
| T005 |
ORDER_NOT_CANCELLABLE |
409 |
「该订单无法撤单(首版市价立即成交)」 |
| 所有 |
AGENT_PERMISSION_DENIED |
403 |
「您没有操作权限」 |
| 所有 |
ACCOUNT_NOT_FOUND / ORDER_NOT_FOUND |
404 |
「记录不存在或已删除」 |
9.3 日志埋点(用户行为级)
- 不打印 raw fetch URL:避免泄露 JWT
- 必埋:
- 页面进入:
page_view { page, portal, sub_role }
- 看板刷新:
dashboard_refresh { source: 'manual' | 'auto', duration_ms }
- 下单提交:
order_submit_attempt { product_code, side, quantity }
- 下单结果:
order_submit_result { order_no, status, error_code? }
- 埋点上报走
apiClient.track(eventName, payload),禁用 console.log
9.4 Trace_id 贯穿
- 每次请求的
trace_id 必须写进 DOM:document.documentElement.dataset.traceId = traceId
- 用户报错截图时,截图工具要把 traceId 也截下来(前端做水印)
- 控制台输出禁止显示 traceId 明文——避免终端被复制到聊天时泄露会话关联
10. 样式与 UI 规范
10.1 设计令牌(必须从 portal/common/tokens.css 引用)
10.2 强制约束
| 项 |
要求 |
| 颜色 |
只引用 --ink / --brand 等 token;禁止 #fff 直接写 |
| 字号 |
只引用 --fs-*;禁止 12px、14px 直接写 |
| 间距 |
只引用 --space-*;禁止 8px 直接写 |
| 圆角 |
只引用 --radius-* |
| 阴影 |
卡片阴影统一 --shadow-card: 0 2px 6px rgba(0,0,0,0.04) |
| 字体栈 |
"Microsoft YaHei", "PingFang SC", sans-serif(统一) |
| 字符编码 |
HTML 强制 <meta charset="UTF-8">、<html lang="zh-CN"> |
| 单位 |
长度统一 px 或 %;禁用 rem(与底座渲染管线冲突) |
| 嵌套 |
CSS 嵌套只允许 & > 一层;禁止 3 层以上 |
10.3 移动端适配
- 看板必须响应式:在
--bp-sm (≤620px) 时卡片单列、表格横滑
- 横滑表格必须有「向右滑动提示」首屏渐隐动画(≥600ms,避免被忽略)
- 触屏目标最小 44×44 px(苹果 HIG 标准)
- 长按选中 / 复制 / 粘贴保留默认——禁止
user-select: none
10.4 品牌元素(奶龙)
- 主色
--brand 不可擅自换色——与底座品牌一致
- 头部品牌标识固定为
static/portal/common/layout/brandmark.svg(与底座 app/static/index.html 一致)
- 客服头像默认
奶龙,角色色 --brand;不引入林黛玉 / 张飞 / 唐僧等多角色头像(与 Wolin OS 风格区分)
11. 看板模块专属约束
11.1 模块归属
| 项 |
值 |
| 目录 |
portal/customer/dashboard/(§3.1) |
| HTML 入口 |
portal/customer/dashboard/index.html |
| JS 入口 |
portal/customer/dashboard/dashboard.js |
| CSS |
portal/customer/dashboard/dashboard.css |
| 后端端点 |
T001 GET /api/v1/users/me/account/dashboard |
| 依赖权限 |
9060 account:read:self(顶层);子项 9061-9065 |
| 跨页面跳转源 |
常驻客服浮窗(portal/common/customer-service-widget/widget.js) |
11.2 组件复用规则
11.2.1 通用 widget
看板只能使用 portal/customer/dashboard/widgets/ 下的组件;跨页面复用必须先抽到 portal/common/widgets/,禁止直接拷贝代码到 customer/dashboard/widgets/。
| widget |
复用范围 |
不允许 |
metric-card.js |
看板 + 未来"组合详情"页 |
业务模块直接调用,必须经 dashboard.js 编排 |
sparkline.js |
看板 |
内嵌业务判断 |
data-table.js |
看板 + 未来"成交记录"页 |
自己实现一个排序逻辑 |
11.2.2 业务模块拆 4 块
按 T001 端点的 4 个一级字段拆模块(§5.3 已列)。每个模块:
- 只接收纯数据 + DOM 容器,不调接口
- 暴露
render(container, data) 与 update(container, data) 两个方法
- 不依赖其他模块
- 销毁时清空 DOM 与所有事件监听(避免内存泄漏)
11.3 数据来源与刷新策略
11.3.1 数据来源
| 模块 |
数据字段 |
来源端点 |
备注 |
account-summary |
account.* |
T001 dashboard.account |
含账户号、余额、冻结金额 |
portfolio-summary |
summary.* |
T001 dashboard.summary |
含总资产、当日盈亏 |
holdings-table |
holdings[] |
T001 dashboard.holdings[] |
含每只基金的市值、盈亏 |
quick-actions |
无数据,按权限显示 |
9061/9063/9065 |
见 §8.3 |
禁止看板额外调取:
- ❌ T006
/api/v1/users/me/holdings(T001 已包含 holdings[],多余请求)
- ❌ T009
/api/v1/users/me/cash-ledger(资金账本,需用户主动跳转到独立页)
11.3.2 刷新策略
| 触发 |
行为 |
| 页面加载 |
自动调一次 T001 |
| 手动刷新按钮 |
调 T001;显示 loading;60s 内不重复(防手抖) |
| 路由离开 |
取消 in-flight 请求 |
visibilitychange=visible |
不自动刷新(避免无意义流量) |
online 事件 |
不自动刷新(提示用户「网络已恢复,请点击刷新」) |
| 下单/撤单成功后 |
自动刷新一次 T001(持仓、余额会变) |
理由:过度主动刷新容易产生陈旧数据展示问题(与底座不变量冲突);用户主动刷新是更稳的契约。
11.4 筛选与时间范围控件标准
看板首版不实现筛选与时间范围选择器(数据已按"截至 now"由后端聚合)。未来若加,按以下规则:
| 控件 |
标准 |
| 时间范围 |
只允许下拉枚举(今天 / 近 7 日 / 近 30 日 / 本年 / 全部);禁止让用户输入起止日期(与底座行情快照策略冲突) |
| 产品筛选 |
多选下拉,最多 5 个产品;超过 5 个提示「请缩小范围」 |
| 筛选应用时机 |
"应用"按钮显式触发;不实时筛选(避免每次勾选都发请求) |
| 默认值 |
时间范围=今天、产品=全部持仓 |
| 清空按钮 |
必须有;回到默认值 |
11.5 布局自适应
11.6 权限可见性控制
11.6.1 顶层守卫
11.6.2 元素级守卫
| 元素 |
DOM 属性 |
守卫脚本处理 |
| 整个 dashboard 容器 |
data-permission-required="9060" |
缺权限 → 显示「请登录」 |
| 「去下单」按钮 |
data-permission-required="9061" |
缺权限 → 禁用 + tooltip |
| 「撤单」按钮(每行) |
data-permission-required="9063" |
缺权限 → 禁用 + tooltip |
| 「成交记录」链接 |
data-permission-required="9065" |
缺权限 → 隐藏 |
统一脚本:portal/common/permission-guard.js,在 index.html 的底部 <script> 中初始化。
11.7 数据展示口径
| 字段 |
展示口径 |
严禁 |
cash_balance |
¥ + 千分位 + 两位小数,红色背景 = 负数 |
❌ 自定义格式化、❌ 截断小数 |
available_cash |
同上 |
❌ |
frozen_cash |
灰色 + (已冻结 ¥X) 标注 |
❌ 隐藏冻结金额 |
total_asset |
加粗 + --fs-title |
❌ 用 --fs-display(避免过度强调) |
total_profit_loss |
正数 --success,负数 --negative,零 --muted |
❌ 用 --danger |
today_profit_loss |
仅展示,不计算;后端返回啥就显示啥 |
❌ 自行算 latest × qty - prev × qty |
| 持仓产品名 |
显示中文 product_name;若无则回退 product_code |
❌ 只显示 code |
时间戳 as_of |
卡片右上角小字:截至 2026-09-12 14:00 |
❌ 显示完整 ISO 字符串 |
11.8 加载与错误状态
每张卡片必须实现三种状态:
| 状态 |
表现 |
时机 |
| loading |
卡片骨架屏(CSS 动画 shimmer) |
接口 in-flight |
| empty |
居中占位符「暂无持仓」+ 空状态图 |
后端返回 holdings: [] |
| error |
卡片顶部红条 + 「重试」按钮 |
接口失败 |
禁止整页 spinner(必须分卡片显示)。禁止空状态直接显示「加载失败」(混淆 loading 与 error)。
12. 与常驻客服浮窗的交互跳转
⚠️ 口径修正(2026-09-14):早期设计里客服对话是一个独立页面 portal/customer/chat/,
该目录从未落地。实际实现是挂在 portal/common/customer-service-widget/ 的常驻浮窗
(widget.js + widget.css),随页面加载、无独立路由。因此下面所有 portal/customer/chat/
一律应读作「浮窗」;跨页跳转仍走 window.location.assign(...),但不需要返回 chat 页,
浮窗在各页面自行保留会话上下文(session_id 存 localStorage)。
12.1 三种入口
| 来源 |
入口元素 |
跳转方式 |
| 客服浮窗 |
客服回复中的「您的账户余额 ¥XXXXX」悬浮卡片 |
点击 → window.location.assign('/portal/customer/dashboard/') |
| 客服浮窗 |
用户主动发问「我有多少钱」 |
客服 Agent 主动建议跳转(前端 widget.js 监听 SSE 事件 hint_navigate) |
| 顶部导航栏 |
「我的账户」链接 |
<a href="/portal/customer/dashboard/"> |
12.2 跳转不变量
- 必带 trace_id:跳转链接拼接
?trace_id=<current>,看板进入时验签(防伪跳转)
- 保留 portal 角色上下文:跳转后由
dashboard.js 重新拉用户身份(不依赖 URL 参数信任)
- 深链支持:看板必须支持
?product_code=510300 直跳到对应持仓行(高亮 1.5s 后恢复)
- 返回路径:从看板回到对话不需要跳转——浮窗随页面常驻;若需恢复上一轮会话,
读
localStorage 里的 session_id(不通过 URL 传递)
12.3 反向跳转(看板 → 浮窗)
| 触发 |
行为 |
| 持仓表「分析收益」按钮 |
调浮窗 API window.CustomerServiceWidget.open({ prefill: "分析 510300 的近期表现" }) |
| 「总收益有疑问」按钮(PortfolioSummary) |
调浮窗 API window.CustomerServiceWidget.open({ prefill: "我的总收益是怎么算的" }) |
| 顶部「客服」链接 |
调浮窗 API window.CustomerServiceWidget.open()(不带 prefill) |
理由:让用户在数据视图与对话视图间平滑切换——这是「看板作为对话的延伸」的产品定位(vs 看板替代对话)。
13. 验收检查清单
任何客服 Agent 前端 PR 在合并前必须逐项核对:
13.1 通用项
13.2 看板专属
13.3 工具自动化(自动校验)
在 PR 流程中由脚本自动检查:
python tools/check_authoritative_docs.py → 含 docs/41-客服Agent前端开发约束_v1.md 且编号唯一
- 后续
tools/check_portal_frontend.py(待建)→ 校验 portal/ 目录命名 / 无硬编码颜色 / 引用完整性
- ESLint 自定义规则(待建)→ 拦截
fetch(、硬编码 #xxx 颜色、localStorage.setItem('token' 等
附录 A:与底座契约的对照
| 本约束 |
底座契约来源 |
| §2 技术栈 |
底座无 frontend 框架约束(与底座解耦) |
| §3 目录结构 |
底座 app/static/index.html 现有 Chat 页(沿用风格) |
| §7 接口调用 |
docs/05-接口文档.md §3.3 envelope / §4 JWT / §19 端点编号 |
| §8 权限 |
tools/seed_test_rbac.py 权限码 / docs/05 §4.2 |
| §9 错误处理 |
docs/05-接口文档.md §3.4 错误信封 + §3.6 错误码 |
| §11 看板 |
§T 段 9 端点(已上推 qyqy_develop,含 ebc3fe4) |
| §12 跳转 |
docs/05 §6 Agent 运行接口 + §7 会话接口 |
附录 B:版本与变更记录
| 版本 |
日期 |
变更 |
| v1.0 |
2026-09-12 |
首版:覆盖 §T 段 9 端点 + 看板专属约束;与底座 ebc3fe4 同步 |
附录 C:相关文档索引
docs/05-接口文档.md — 接口权威(envelope / RBAC / 错误码 / §19 端点)
docs/40-前端验收清单.md — qyqy 团队的验收清单(侧重功能合规)
docs/客服Agent一期_合规红队与业务评测集_v1.md — 合规红线(客服特有)
docs/客服Agent一期远程整合测试手册.md — 集成测试门禁
docs/客服Agent二期_客户画像候选流程_v1.md — 画像候选流程
tools/check_authoritative_docs.py — 文档编号唯一性
tools/check_docs_endpoint_ids.py — §19 端点编号唯一性
tools/check_rbac_seed_consistency.py — 权限码一致性