Archived
接入统一鉴权中心(Keycloak,ADR-012);活动模块 L1/L2 运营态模版(历史活动列表+检索+沙箱);数据域与工作台界面改版;个人中心 /me
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# 项目约定
|
||||
|
||||
本目录存放前端设计相关手册与规范。
|
||||
|
||||
## 强制约定
|
||||
|
||||
凡涉及页面新建或前端修改(任何 HTML/CSS/前端代码产出),必须先读取并严格遵守 `DESIGN-SPEC.md`:
|
||||
|
||||
- 改前按「第 15 节」诊断;
|
||||
- 改中遵守「第二部分 设计规范」的默认值与硬规则;
|
||||
- 改完按「第 17 节」三层 18 条清单验收,并按「第 18 节」输出 token 表。
|
||||
|
||||
规范未提及的部分保持现状,不做顺手优化。
|
||||
|
||||
## 参考手册(规范的依据,需要查原句/术语时阅读)
|
||||
|
||||
- `前端UI描述术语手册.html`:UI 描述词汇库,13 个维度 155 个术语,含可直接复制的提示词;
|
||||
- `PC端产品UI审美心智指导手册.html`:审美六条标准与 PC 端细则,含症状诊断与训练题。
|
||||
|
||||
## 若修改了 DESIGN-SPEC.md
|
||||
|
||||
同步更新 `DESIGN-SPEC.html`(阅读版,单文件 HTML)。
|
||||
@@ -0,0 +1,216 @@
|
||||
# 前端设计规范(PC 端产品)
|
||||
|
||||
> 依据《前端UI描述术语手册》与《PC端产品UI审美心智指导手册》提炼。
|
||||
> 本文件是所有页面新建/修改的执行依据:改前按「设计逻辑」诊断,改中按「设计规范」执行,改完按「评审清单」验收。
|
||||
> 规范中未提及的部分,保持现状不变。
|
||||
|
||||
---
|
||||
|
||||
## 第一部分 设计逻辑(怎么想)
|
||||
|
||||
### 1. 三层金字塔(评审顺序永远自下而上)
|
||||
|
||||
1. **不出错**(底层):对齐、对比度、状态齐全、无装饰噪音;
|
||||
2. **有秩序**(中层):层级清楚、节奏合理、分组明确;
|
||||
3. **有气质**(顶层):字体/配色有个性、有一处记忆点。
|
||||
|
||||
底层没过,不谈顶层。AI 产出的典型问题就是底层一堆错、套着「气质」的外壳。
|
||||
|
||||
### 2. 产品界面 ≠ 海报
|
||||
|
||||
海报追求「三秒抓住你」,产品界面追求「八小时不打扰你」。渐变、光晕、毛玻璃、彩色大图标属于营销页手段,**产品界面里的合理数量是零,最多一处**。
|
||||
|
||||
### 3. 六条可检查标准(每条都能回答「是/否」)
|
||||
|
||||
| 标准 | 一句话 | 检查方法 |
|
||||
|---|---|---|
|
||||
| 对齐 | 专业 vs 业余八成取决于此 | 画一条左线:标题、卡片、表格首列、表单标签是否从同一竖线开始 |
|
||||
| 层级 | 一屏一个主角 | 眯眼:深色块是否只剩 2–3 个重点 |
|
||||
| 克制 | 做减法 | 数:1 个彩色、2 种字体、1 套圆角、2 档阴影、1 个图标库、0 装饰 |
|
||||
| 一致 | 像一个人做的 | 同一组件全站是否只有一种长相;不一样的地方必须有含义 |
|
||||
| 节奏 | 组内紧、组间松 | 量间距:是否三级逐级放大,还是均匀/随意 |
|
||||
| 细节 | 专业感的来源 | 数字对齐、状态齐全、输入框三件套 |
|
||||
|
||||
### 4. 五个第一眼测试(改完页面先过这关,每个 10 秒)
|
||||
|
||||
1. **眯眼测试**:模糊后深色块 ≤3 个,且主角是最该突出的东西;
|
||||
2. **三秒测试**:三秒内能说出「这是什么页」「最重要的操作在哪」;
|
||||
3. **安静测试**:饱和色块/渐变/emoji/感叹号/彩色描边加起来不超过两处;
|
||||
4. **同一人测试**:同类元素(按钮圆角/高度/字号/描边)只有一种处理;
|
||||
5. **空间测试**:宽屏下内容不撑满不飘着——限宽居中或多栏。
|
||||
|
||||
### 5. 工作方式五条(描述与修改的纪律)
|
||||
|
||||
1. **先骨架,后皮肤**:结构 → 布局 → 间距 → 组件 → 字体/色彩/形状 → 状态/动效;
|
||||
2. **用名词加数值,不用形容词**:「大一点」→「按钮高从 32 改 36」;
|
||||
3. **每次只改一个维度**:修改指令 = 改哪里 + 改成什么 + 其余不变;每轮改动 ≤3 处并编号;
|
||||
4. **先列问题再改**:诊断先于动手,说出是哪条标准没过;
|
||||
5. **默认值先声明**:字体、圆角系统、间距系统、强调色、图标库——不声明就会被填进默认值(AI 味)。
|
||||
|
||||
---
|
||||
|
||||
## 第二部分 设计规范(默认值与硬规则)
|
||||
|
||||
> 以下默认值适用于 PC 端后台/工具类产品。营销页/落地页的变体见附录 A。
|
||||
|
||||
### 6. 全局默认值(开工前先声明这五件事)
|
||||
|
||||
- **字体**:系统无衬线栈(中文 PingFang SC / Microsoft YaHei,英文 Inter 或 system-ui);数字用 `tabular-nums`;需要技术感处用等宽;
|
||||
- **圆角系统**:按钮/输入框 6px、卡片 8px、弹窗 12px、标签/头像全圆;嵌套内圆角 = 外圆角 − 内边距;整站不出现 16px 以上;
|
||||
- **间距系统**:只用 8 的倍数(4/8/12/16/24/32/48/64);三级边距 = 页面 24 / 卡片内 16 / 单元格 8–12;
|
||||
- **强调色**:一个(默认蓝,如 #2563EB),只出现在:主操作、链接、状态、图表四处;
|
||||
- **图标库**:一个(默认 Lucide),只选一种风格(默认 Outline 1.5px 描边)。
|
||||
|
||||
### 7. 色彩
|
||||
|
||||
- **三级灰文字**:主文字 #161A22 / 次要 #4A5160 / 辅助 #8B93A3;**禁用比 #8B93A3 更浅的文字色**;
|
||||
- **对比度**:正文 ≥4.5:1,大标题 ≥3:1(WCAG AA);
|
||||
- **底色**:主区背景 #F6F7F9 + 白卡片(1px #DFE3EA 描边);
|
||||
- **语义色**:Success/Warning/Error/Info 各配浅底深字,只用在徽标/提示里;
|
||||
- **图表**:同系列单色;多系列用主色深浅三档 + 一灰;**禁止彩虹色**;
|
||||
- **深色模式**(如需要):不是反色。背景 #0B0D10、卡片 #15181D、弹层 #1E2229(越高层越亮)、描边 rgba(255,255,255,.08)、文字 #E5E7EB / 次要 #8A91A0、去阴影、强调色提亮一档降饱和;
|
||||
- **禁止**:紫蓝渐变按钮、渐变背景、光晕、毛玻璃(营销页除外,见附录 A)。
|
||||
|
||||
### 8. 排版
|
||||
|
||||
- **三档字号 + 两档字重**够用:标题 16px/600、正文 14px/400、元信息 12px 灰;指标卡大数字 28px/600 等宽;
|
||||
- **中文正文**:字号 ≥14px、行高 1.75;标题行高 1.2–1.3;
|
||||
- **层级手段按成本排序**:灰度 < 字重 < 字号 < 颜色——先用便宜的,不用五种字号;
|
||||
- **标题左对齐**,与主按钮同行(标题左上、主按钮右上);居中只给空态和弹窗;
|
||||
- 中英文/数字之间加空格;标点全角;**中文不用斜体**;
|
||||
- 行长 ≤75 字符,超出限宽。
|
||||
|
||||
### 9. 布局与骨架
|
||||
|
||||
- **应用外壳**:顶栏 + 侧栏 + 主内容区,外壳不滚动;
|
||||
- **安全配色组合**:深侧栏 #14171E(当前项 8% 白底)+ 浅主区 #F6F7F9 + 白卡 1px 描边;若浅色侧栏则 #F3F4F7 / 主区纯白 + 1px 分割线;
|
||||
- **限宽**:主内容 1280px、整页上限 1440px;
|
||||
- **宽屏用多栏**:详情页主从 2:1(左主体右辅助)、列表+详情、工具类三面板;
|
||||
- **一条左线**:页面标题、卡片标题、表格第一列、表单标签从同一竖线开始;看文字不看卡片边框;
|
||||
- **节奏**:组内紧(8–16)、组间松(32–48);分组标题离上一组的距离 > 离自己内容的距离;均匀间距是错的;
|
||||
- **密度跟用途走**:扫描型(表格/列表/日志)紧凑 32–36 行高;阅读/填写型舒适 44–48;引导型(空态/向导)宽松。
|
||||
|
||||
### 10. 形状与表面
|
||||
|
||||
- **描边优于阴影**:静态卡片 1px #DFE3EA 描边;阴影只给下拉、弹窗、拖拽中的元素;hover 时描边变深,不浮起;
|
||||
- **一张卡只用一种分层手段**:描边/阴影/底色三选一;
|
||||
- **分割线**:能用间距分组就不用线;要用就内缩对齐文字,不通到边缘。
|
||||
|
||||
### 11. 组件硬规则
|
||||
|
||||
- **按钮**:一屏只有一个实心主按钮;危险操作(删除)永不实心;低频操作收进「⋯」;文案用具体动词(「保存更改」不是「确定」);高度三档 28/36/44;
|
||||
- **表格**:文字左对齐、**数字右对齐 + 等宽 + 小数位统一**、货币单位进表头;行高 36px、单元格左右内边距 12px、字号 13px、表头吸顶;
|
||||
- **输入框三件套**:标签(框上方)、占位符(写示例值)、错误提示(描边变红 + 下方写明原因和改法)——三者职责不可互替;
|
||||
- **图标不是装饰**:只有约定俗成含义(搜索、设置、删除)的才保留;遮住图标无损失就删;**禁止「⚡极速 🔒安全 🚀高效」式三列图标卡**;
|
||||
- **空态** = 一句说明 + 主操作按钮,是引导不是道歉;
|
||||
- **错误文案** = 发生了什么 + 怎么办。
|
||||
|
||||
### 12. 状态(效果图和产品的区别就在「第二种状态」)
|
||||
|
||||
- **控件六态**:Default / Hover(加深 8%)/ Active / Focus / Disabled(45% 透明)/ Loading(转圈 + 禁重复点击);
|
||||
- **Focus 必须可见**:2px 主色外环 + 2px 间隔;禁止因为「不好看」删焦点环;
|
||||
- **每个数据区域四态**:Loading(骨架屏,形状与真实内容一致)/ Empty / Error(原因 + 重试)/ Ideal,再加 Partial;
|
||||
- **悬停是 PC 的层级工具**:行内操作平时隐藏,悬停/键盘聚焦时出现(两个图标 + 「⋯」);
|
||||
- **危险操作**:能撤销(Toast + Undo)就别弹确认;必须确认时,严重后果要求输入名称;
|
||||
- **键盘**:搜索框标 ⌘K、主要操作标快捷键、Tab 顺序与视觉顺序一致。
|
||||
|
||||
### 13. 动效(只说三件事:动多久、怎么加减速、动哪个属性)
|
||||
|
||||
- **时长**:hover/按钮 100–150ms;弹层/展开 200–300ms;页面切换 ≤500ms;
|
||||
- **缓动**:进场 ease-out、退场 ease-in;禁止线性位移;
|
||||
- **进出场有来由**:弹层从触发点展开、抽屉从边缘滑入;退出是进入的反向且更快;
|
||||
- **克制**:一个页面最多一处值得记住的动效;尊重 prefers-reduced-motion。
|
||||
|
||||
### 14. 响应式(PC 为主,但要能缩)
|
||||
|
||||
- 三档:>1024 桌面 / 768–1024 平板 / <768 手机;
|
||||
- 降级路径:卡片 3→2→1 列;侧栏→图标栏→抽屉;顶部导航→汉堡;表格→卡片列表或横滚+首列固定;分栏→上下堆叠;
|
||||
- 触控目标 ≥44px。
|
||||
|
||||
---
|
||||
|
||||
## 第三部分 执行流程(每次改页面都走一遍)
|
||||
|
||||
### 15. 改前:诊断
|
||||
|
||||
1. 过五个第一眼测试,写下「不对劲」的地方;
|
||||
2. 按六条标准逐条归因——说「对齐有问题:卡片标题和表格没对齐到一条左线」,不说「看着乱」;
|
||||
3. 查症状对照(下表)确认处方。
|
||||
|
||||
**症状 → 病因 → 处方**
|
||||
|
||||
| 症状 | 病因 | 处方 |
|
||||
|---|---|---|
|
||||
| 看着廉价 | 效果堆叠、灰字太浅 | 卡片改 1px 描边去阴影;最浅灰提到 #8B93A3 |
|
||||
| 像模板/AI 味 | 居中标题、三列图标卡、紫蓝渐变 | 标题左对齐;删无意义图标;去渐变;圆角收 8 |
|
||||
| 看着乱 | 多条左线、间距随意 | 统一一条左线;间距只取 8 的倍数,组内紧组间松 |
|
||||
| 看着空/飘 | 宽屏拉伸 | 限宽 1280 居中,或改主从两栏 |
|
||||
| 看着挤/累 | 密度不匹配、行高小 | 密度按用途调档;正文行高 1.75 |
|
||||
| 找不到重点 | 多个实心按钮、层级反了 | 只留一个实心按钮;用灰度字重重建层级 |
|
||||
| 太花/太吵 | 彩色超一、彩虹图表、emoji | 彩色收敛到四处;图表单色阶+灰;删 emoji |
|
||||
| 太单调/死板 | 减法做过头 | 加一处对比即可(一个强调色块或一处衬线标题) |
|
||||
| 像网页不像软件 | 无外壳/悬停/快捷键 | 补应用外壳、悬停操作、焦点环、⌘K |
|
||||
| 像效果图不像产品 | 只有默认态 | 补齐 Loading/Empty/Error/Partial |
|
||||
| 不专业/不严谨 | 数字没对齐 | 数字列右对齐、等宽、小数位统一 |
|
||||
| 深色模式难看 | 直接反色 | 按第 7 节深色模式色板重做 |
|
||||
| 说不上来哪里怪 | 1px 级光学对齐 | 放大 200% 检查图标文字中线、按钮文字垂直居中 |
|
||||
|
||||
### 16. 改中:纪律
|
||||
|
||||
- 修改指令 = 改哪里 + 改成什么(数值)+ 其余保持不变;
|
||||
- 每轮 ≤3 处,编号发出;
|
||||
- 结构没确认前不动皮肤——必要时先要黑白线框确认结构;
|
||||
- 新增组件前先查第 6 节默认值和第 11 节组件规则,不重新设计已有组件。
|
||||
|
||||
### 17. 改后:验收清单(三层 18 条,全过才算完)
|
||||
|
||||
**底层 · 不出错(8 条)**
|
||||
- [ ] 同一条左线;同行卡片等高、右缘对齐
|
||||
- [ ] 同屏只有一个实心按钮,危险操作非实心
|
||||
- [ ] 整页一个强调色,状态色只在徽标里
|
||||
- [ ] 按钮/输入框/卡片/图标各只有一种样式
|
||||
- [ ] 最浅灰字 ≥#8B93A3,对比度达标
|
||||
- [ ] 数字列右对齐、等宽、小数位对齐
|
||||
- [ ] 无渐变/光晕/毛玻璃/无意义图标/emoji
|
||||
- [ ] 按钮文字垂直居中、图标与文字中线对齐
|
||||
|
||||
**中层 · 有秩序(6 条)**
|
||||
- [ ] 眯眼深色块 ≤3,视线路径清楚
|
||||
- [ ] 三秒说出页面主题和主操作
|
||||
- [ ] 间距组内紧组间松、三级边距统一
|
||||
- [ ] 密度匹配用途
|
||||
- [ ] 字号 ≤3 档,靠灰度字重分层
|
||||
- [ ] 宽屏限宽或多栏,无拉伸扁条
|
||||
|
||||
**顶层 · 像软件(4 条)**
|
||||
- [ ] 悬停/禁用/加载/空/错误态齐全
|
||||
- [ ] 焦点环可见、有快捷键提示、行内操作悬停出现
|
||||
- [ ] 文案动词前后一致、写具体动作
|
||||
- [ ] 有且仅有一处记忆点
|
||||
|
||||
### 18. 交付要求
|
||||
|
||||
- 改完输出所用 token 表:颜色、字阶、圆角、间距——与第 6–10 节默认值不符处必须说明理由;
|
||||
- 语义化 HTML、键盘可达;icon-only 按钮配 tooltip;
|
||||
- 未提及的部分保持原样,不顺手「优化」。
|
||||
|
||||
---
|
||||
|
||||
## 附录 A 营销页/落地页变体
|
||||
|
||||
场景不同,手段放宽,但纪律不变:
|
||||
|
||||
- **允许**:Hero 大标题(可到 40–56px)居中、一处渐变或氛围动效、Elevated 阴影卡、插画;仍然单强调色、一套圆角(可放宽到 8–16)、一个图标库;
|
||||
- **区块流**:Hero → Logo 墙 → 功能 → 评价 → 定价 → FAQ → CTA → 页脚;
|
||||
- **容器**:1280–1440;密度宽松(区块间距 64–96);
|
||||
- **动效**:scroll reveal 一次性、错落 ≤8 项、氛围动效只在 Hero 一处;
|
||||
- 六条标准照样检查——营销页只是「气质」层权重更高,底层「不出错」不打折。
|
||||
|
||||
## 附录 B 完全不懂数字时的说法(兜底)
|
||||
|
||||
- 指着选:「同内容出三版(紧凑专业/舒适通用/宽松友好),我挑一个」;
|
||||
- 拿实物比:「像微信卡片那么圆」「像 Linear 那种密度」;
|
||||
- 说相对:「圆角收一档」「间距松一档」「灰色深一档」;
|
||||
- 圆角对照:4=专业密集 / 8=网页默认 / 12=微信卡片 / 16=iOS 弹窗;
|
||||
- 字号对照:正文只有 14(后台)和 16(大众)两个选择;
|
||||
- 间距对照:一个字≈16px(同组)、三个字≈48px(小节)、六个字≈96px(大区块)。
|
||||
@@ -0,0 +1,78 @@
|
||||
# 设计中心 · 数据域页面改版记录(2026-08-25)
|
||||
|
||||
> 范围:设计中心 · 数据域首页(`DataHome`)与对象详情子页(`ObjPage`)。
|
||||
> 约束:不改功能、不改接口,只改布局与 UI;全程按 `docs/DESIGN-SPEC.md` 走
|
||||
> (§15 诊断 → 第二部分规范 → §17 验收 → §18 token 表),用户逐轮验收定稿。
|
||||
|
||||
## 涉及文件
|
||||
|
||||
| 文件 | 改动性质 |
|
||||
|---|---|
|
||||
| `apps/web/src/features/gov-data/internal/panel.tsx` | DOM 结构与类名、汇总带、模式转置矩阵、取值呈现(空值/时间格式);无逻辑与取数改动 |
|
||||
| `apps/web/src/app/styles/console.css` | 重写 `.g-actdata*`/`.g-tbl*`,新增 `.g-data` 与 `.g-obj` 作用域;`.g-kpi` 色条改 inset 阴影 |
|
||||
| `apps/web/src/shared/gov/primitives.tsx` | `Kpi` 加可选 `hint` 属性(角标 info 气泡);其余件零改动 |
|
||||
| `apps/web/vite.config.ts` | `/api` 代理默认指向测试服务器 `150.158.83.131:46100`,`API_PROXY_TARGET` 环境变量可覆盖(开发环境配置,非页面) |
|
||||
|
||||
共享组件(`.g-card`/`.g-rows`/`.g-dbtable`/`.g-dh` 等)本体未动,其余治理面板不受影响
|
||||
—— 所有覆盖都在 `.g-data` / `.g-obj` 作用域内。
|
||||
|
||||
## 数据域首页(DataHome)
|
||||
|
||||
1. **隐藏「无人声明」区**(2026-08-24 用户定):壳表数据仍在接口 `unclaimed` 里,
|
||||
只是不渲染;空态判断相应只看有声明表的活动。
|
||||
2. **页顶汇总带**:声明活动 / 声明表 / 正式行 / 在办行四个 KPI,纯前端合计已有数据
|
||||
(不另取数);口径只含活动声明的表,无人声明的壳表不计入。
|
||||
每盒右上角 info 角标,悬停出纯 CSS 气泡(`data-tip` + `::after`)讲口径。
|
||||
3. **表块形态**:灰底格子 → 清单行(一版)→ **白卡片**(用户定稿)—— 1px 描边 `#DFE3EA`、
|
||||
圆角 8;卡内自上而下 = 表名+性质徽(右上 chevron)→ 22px 大数字行数(`tabular-nums`)→
|
||||
mono 地址+主键单行截断(全文在 `title`)。
|
||||
4. **卡片交互**:hover 三层反馈(描边变深 `#C4CCD8` + 洗底 `#F6F7F9` + 行数染主色),
|
||||
active `scale(.99)` 按压感,箭头染色前移 2px;全部 `0.16s ease-out`。
|
||||
5. **节奏**:活动卡组间距合成 32px(组内紧组间松),间距全取 8 的倍数。
|
||||
|
||||
## 对象详情子页(ObjPage)
|
||||
|
||||
1. **上下结构**(用户定稿):记录浏览在上整宽(进来先看行数据),模式在下整宽;
|
||||
主从两栏试过一版,两栏互相挤压,撤了。
|
||||
2. **两个小节同构**:小标题都在盒子外(`Sec` 段标题),下面各一个白底描边圆角盒;
|
||||
「模式」从 `Card` 换成 `Sec`,盒子描边挪给矩阵容器 `.g-sx`。
|
||||
3. **记录浏览表**:套上白卡;斑马纹(偶数行 `#F8FAFC`)+ 行线 `#E2E7EE` +
|
||||
列间发丝竖线 `#EEF1F5`;长 JSON 单元格单行截断(超宽横滚);
|
||||
**数字列按 schema 类型右对齐 + 等宽**;**主键列表头挂蓝色小钥匙图标**;
|
||||
空值(null/undefined)统一显示灰色 `-`。
|
||||
4. **ISO 时间格式化**:取值函数 `cellText` 识别 ISO 8601 时间串,转本地
|
||||
`YYYY-MM-DD HH:MM:SS`(如信号日期 `2026-05-31T16:00:00.000Z` → `2026-06-01 00:00:00`,
|
||||
UTC+8),所有表的日期列同享。
|
||||
5. **行数文案**:接口硬编码 `limit: 50` —— 截断时写「前 50 行 · 共 M 行」,
|
||||
全量在页内写「共 N 行」,不虚报「前」。
|
||||
6. **模式矩阵**:转置(用户定)—— 行 = 参数名/字段/数据类型,列 = 每个字段;
|
||||
最左窄行标签列吸左(横滚不丢);斑马纹与记录表同套;**类型徽分色**
|
||||
(number/integer 蓝、json 紫、text 灰);**悬停整列高亮**(`::after` 纵幕 +
|
||||
`mix-blend-mode: multiply` 护住文字,`pointer-events: none`)。
|
||||
|
||||
## 踩过的坑(留给后来者)
|
||||
|
||||
- **`.g-kpi` 的 `overflow: hidden` 会裁掉内部气泡**(用户报):色条从 `::before` 伪元素
|
||||
改 `inset box-shadow`(自动贴合圆角、无需裁切),撤掉 overflow。
|
||||
注意 `.g-data .g-kpi` 的 `box-shadow` 覆盖必须保留 inset 色条,不能 `none` 一抹了之。
|
||||
- **悬停幕直接画会糊住文字**:`::after` 定位元素绘制序在文字之上,
|
||||
加 `mix-blend-mode: multiply` —— 深字几乎不变色,只染亮底。
|
||||
|
||||
## Token 表(§18)
|
||||
|
||||
| 类别 | 取值 | 说明 |
|
||||
|---|---|---|
|
||||
| 强调色 | `#3370FF`(站点既有飞书蓝) | 未换规范默认 #2563EB —— 整站令牌一致优先 |
|
||||
| 文字灰阶 | `#1F2329` / `#646A73` / `#8F959E` | 同上,沿用站点令牌 |
|
||||
| 卡片 | 白底 + 1px `#DFE3EA` 描边,无阴影 | §10 描边优于阴影 |
|
||||
| 圆角 | 卡 8 / 块与徽 6 / 状态 chip 全圆 / 图标块 10 | §6,整站无 16px 以上 |
|
||||
| 间距 | 8 / 12 / 16 / 32 | §6 全 8 倍数 |
|
||||
| 数字 | `tabular-nums`,数字列右对齐 | §6 / §11 |
|
||||
| 语义色 | 只进徽标(性质徽三色、类型徽蓝/紫、run chips 四色) | §7 |
|
||||
| 动效 | 全部 `0.16s ease-out`,只动 transform/opacity/color | §13 |
|
||||
|
||||
## 验收(§17 三层 18 条)
|
||||
|
||||
底层 8 条、中层 6 条全过;顶层 4 条中「快捷键提示」本页无操作不涉及,其余齐
|
||||
(hover/active/focus 环、空态、title 全文、aria 同源)。
|
||||
每轮改动 `tsc --noEmit -p tsconfig.web.json` + `eslint` 均通过,并在浏览器实测截图验收。
|
||||
@@ -0,0 +1,104 @@
|
||||
# 运营中心 · 活动模块重构 —— 需求记录
|
||||
|
||||
> 记录时间:2026-08-25
|
||||
> 背景:活动模块(原「任务」模块)内容已全部清空(页签、布局、取数均已撤除,区入口与区标题保留),
|
||||
> 本次重构从零定义这个模块「是什么、给谁看、管什么」。
|
||||
> 本文档随用户口述逐条记录,定稿后整理为功能表。
|
||||
|
||||
## 一、原始需求记录
|
||||
|
||||
### 2026-08-25 · 核心概念:活动的定义 与 活动的实例(用户口述)
|
||||
|
||||
一个活动分成两个概念:
|
||||
|
||||
1. **活动的定义**
|
||||
- 来源:把一个业务拆分成多个部分,其中的**一部分内容**成为一个活动;
|
||||
- 活动要做的事:把**输入的数据**经过**一系列的动作**,变成**输出的数据**;
|
||||
- 「数据」的形态不限:可能是一个 JSON 串、一个文件、一个统计结果,也可能是一个字符串;
|
||||
- 一个活动**只会有一个定义**。
|
||||
2. **活动的实例**
|
||||
- 真正输入了一段数据给这个活动,活动经过一系列动作,产生了一个输出的数据;
|
||||
- 一个活动可以有**多个实例**。
|
||||
|
||||
类比(用户原话的类比):好比 Java 中的对象 —— 要使用一个对象,先**声明**这个类、声明里面有几个参数(对应**活动的定义**);要真正用它,就 **new 一个对象并赋值**(对应**活动的实例**)。
|
||||
|
||||
补充确认(2026-08-25 用户定):**活动创建的时候,输入与输出就已经定好了** —— 数据形态虽不限(JSON/文件/统计结果/字符串),但一个具体活动的定义,其输入输出的结构是声明清楚的(像 Java 参数带类型),不是跑到实例时才看。
|
||||
|
||||
### 2026-08-25 · L2 规划确认与补充(用户口述)
|
||||
|
||||
- **实例状态共 5 个**:进行中 / 待执行 / 已完成 / 驳回 / 失败;
|
||||
- **创建实例**:先把入口留出来,功能待做;
|
||||
- **运营概览小统计**:需要;
|
||||
- **验收动作在工作台**,活动模块不管验收 —— L2 只展示状态;
|
||||
- **激活/禁用都需要二次确认**;禁用会访问接口,**有实例时接口会提示无法禁用**(本期只做前端,暂不接接口,前端先把这个规则的样子做出来);
|
||||
- **L2 需要一个沙箱**:用来加载服务器返回的 HTML 页面(活动视图),先做一个版本看效果再改。
|
||||
|
||||
### 2026-08-25 · 版本号与版本迭代入口(用户口述)
|
||||
|
||||
- 活动卡片要展示**版本号**:表示当前已发布的活动属于哪个版本(有版本才显示);
|
||||
- 背景逻辑:因为活动**没有编辑和删除功能**,所以演进只能靠发新版本 —— 子页面(L2)应该有**版本迭代的入口**;
|
||||
- 版本迭代功能怎么设计**回头再讨论**,本期只先把版本号加到卡片里。
|
||||
|
||||
### 2026-08-25 · L1 页面:两个页签(用户口述)
|
||||
|
||||
L1(模块首页 · 活动清单)需要一个**标签页**切换,因为活动分成两类:
|
||||
|
||||
1. **已发布上线**的
|
||||
2. **审核中**的
|
||||
|
||||
### 2026-08-25 · 活动板块的六个功能(用户口述)
|
||||
|
||||
1. **活动的创建**(即创建定义)
|
||||
2. **活动的展示**
|
||||
3. **活动实例的创建**
|
||||
4. **活动实例的展示**
|
||||
5. **活动实例的编辑**
|
||||
6. **活动实例的删除**
|
||||
|
||||
配套的规则(用户定):
|
||||
|
||||
- **活动(定义)只允许创建,不允许编辑、不允许删除**;
|
||||
- **活动创建需要审核,审核通过后才能展示**(进展示列表);
|
||||
- 活动实例**可能也不允许删除** —— 存疑,但先把删除规划出来,后续根据需求再调整。
|
||||
|
||||
### 2026-08-25 · 平台定位纠正(用户口述,推翻我此前的理解)
|
||||
|
||||
- 要做的**不是**只针对一个业务的生产环境系统,而是一个**平台**:以**活动为最小基点**,能串联整个业务的工作流;后续会有**多个类型不同的业务**接入平台。
|
||||
- 目的:**减少人的工作量**,让 AI agent 在整个业务里做执行者。
|
||||
- **每个活动有一个单独的 agent**,负责把这个活动的流程跑通。
|
||||
- 人机分工:
|
||||
- 业务的**规划**部分 → agent 来做;
|
||||
- 规划出来但 **agent 无法完成的执行**部分 → AI 把执行层任务分配给某个人,这个人 = **活动负责人**;
|
||||
- 负责人干两件事:① 做 AI 安排的执行任务;② 对 AI 做的规划任务、统计任务进行**验收**(责任承担 —— AI 不能承担责任,人担)。
|
||||
- 系统架构已经完成;现在对**活动模块**重新规划:活动模块要能**根据业务需求创建各种各样的活动**,做的是「**活动的设计和运营**」。
|
||||
|
||||
## 二、澄清与决策
|
||||
|
||||
- 2026-08-25 · 纠正:产品形态是**可接多类业务的平台**,不是单一业务系统(界面顶栏「单组织 · ≤50 人 · 生产环境」是旧定位的遗留文案,理解时不要被它带偏)。
|
||||
- 2026-08-25 · 活动模块的重新定位:**活动的设计和运营** —— 不再只是「任务的在途监控」(旧版任务模块的心智)。
|
||||
- 2026-08-25 · **双台面合并方向(架构级决策)**:现有「设计中心 / 运营中心」的划分不合理,未来**只保留运营中心,设计是运营的一部分**。本次活动模块重构就按这个思路做 —— 模块内同时包含「设计」与「运营」;活动模块先做样板,**其他模块后续也按这个方式逐一重做**。
|
||||
- 2026-08-25 · **需求工作方式(用户定的规矩)**:不拆讨论稿、不预设结构 —— 旧版活动模块的内容全部抛弃、暂不考虑;由用户口述「活动板块应该是什么样的」,我负责记录、之后再规划。旧内容只在用户明确说「这一步可以参考以前的东西」时才去翻。
|
||||
- 2026-08-25 · **层级划分(用户确认)**:活动模块 = **三级页面**,层级关系即概念关系(定义 → 实例,类 → 对象):
|
||||
- **L1 模块首页 · 活动清单(定义层)**:两个页签 —— **已发布上线 / 审核中**(2026-08-25 用户定);所有活动定义(名称 / 输入输出契约摘要 / 审核状态 / 实例数)→ 落功能 2;功能 1(创建定义)入口在此;
|
||||
- **L2 活动详情 · 一个定义 + 它的实例清单**:定义完整信息(输入/输出结构、动作说明、审核信息)+ 该定义的全部实例(输入摘要 / 状态 / 产出摘要 / 时间)→ 落功能 4(清单);功能 3(实例创建)入口在此(new 实例必须挂在某个定义下);
|
||||
- **L3 实例详情 · 一次运行的完整视图**:完整输入 / 动作过程记录 / 最终输出 / 当前状态 → 落功能 4(详情)、功能 5(编辑)、功能 6(删除),编辑删除收在最深层,不污染清单。
|
||||
- 待定点:审核入口放 L1 还是单列;文件类输入的实例创建入口形态。
|
||||
- 2026-08-25 · **L1 模版已落地(静态占位版)**:页签「已发布 / 审核中」、活动卡片(名称 / 标识·业务 / 状态丸 / 实例·负责人·时间·版本四格底板)、业务色相视觉增强(卡顶色签 / 图标块 / 悬停色影)。数据为静态假数据,接口设计定稿后整体替换。卡片点击(进 L2)未接。
|
||||
- 2026-08-25 · **优先级调整(用户定)**:**先做运营部分,设计功能(创建活动)暂缓** —— L1 的「创建活动」幽灵卡已从页面注释掉(JSX 注释保留在代码里,样式未删,恢复即解开)。
|
||||
- 2026-08-25 · **页签改为运营态(用户定)**:L1 页签「已发布 / 审核中」→「**激活中 / 已禁用**」——每个活动有激活/禁用状态,**在 L2 里修改**;发布与审核属于设计部分的功能,暂缓,等运营功能做好再回头改。禁用卡片走灰底弱化(复用 `.g-fcard.off`)。
|
||||
- 2026-08-25 · **文案口径(用户定)**:创建实例 → **启动活动**;实例清单 → **历史活动**;停止 → **终止活动**。
|
||||
- 2026-08-26 · **L2 历史活动改列表(用户定)**:卡片式清单撤掉,改表格列(实例 / 负责人 / 输入 / 输出 / 启动时间 / 状态 / 操作,操作栏带标题),隔行浅斑马 + 悬停亮行,行内操作(终止活动 / 查看详情)常驻;分页单页 8 条不变。
|
||||
- 2026-08-26 · **L2 历史活动加检索(用户定)**:列表上方检索条 —— 条件下拉四选(实例 / 负责人 / 状态 / 启动时间),控件随条件换:实例=按实例号模糊输入、负责人=人员下拉(候选取自现有实例,接接口后换人员接口)、状态=五态下拉、启动时间=日期段(含两端整日);筛中显示「筛出 X / 共 Y」并可一键清空;分页按筛出的集合走。
|
||||
|
||||
## 三、功能表(整理稿)
|
||||
|
||||
(待需求说完后输出:功能项 / 说明 / 数据来源(接口) / 交互 / 优先级)
|
||||
|
||||
## 四、待确认问题
|
||||
|
||||
- ~~活动模块里的「设计」与设计中心「活动库」是什么关系?~~ **已答(2026-08-25)**:不再有「设计中心 vs 运营中心」的分工 —— 设计并入运营,活动模块自带设计能力;设计中心各区后续按同思路并入运营中心重做。
|
||||
- ~~「设计」在活动模块里做到什么程度?~~ **已答(2026-08-25)**:六功能已界定 —— 活动(定义)的创建与展示 + 实例的创建/展示/编辑/删除;定义只许创建不许编删,创建要过审核。
|
||||
- 活动创建的**审核**:谁来审、在模块内审还是别处、审什么(输入输出契约的合理性?)?(待用户展开)
|
||||
- 实例的**编辑**具体指编辑什么:实例的输入数据?进行中的干预(暂停/叫停)?还是产出修正?(待用户展开)
|
||||
- 实例删除是否真放开 —— 用户已标注存疑,先规划,后续按需求调。(悬着,不阻塞)
|
||||
- 「运营」侧还要不要监控/验收类功能(此前提过负责人验收规划与统计产出)—— 六功能里未直接出现,是否归在「实例的展示/编辑」里,还是另有入口?(待用户展开)
|
||||
@@ -0,0 +1,45 @@
|
||||
# 统一鉴权中心(Keycloak)接入记录 —— 2026-08-26
|
||||
|
||||
依据 `BPOS-MVP/docs/` 三份文档(keycloak-frontend-guide / API文档-鉴权与人员 / 前端对接说明-统一鉴权中心,ADR-012)完成前端侧改造。后端以测试服 `150.158.83.131:46100` 实测:`/api/me` 无头 401「缺少 Bearer token」、`/api/login` 410 退役,Keycloak `corp` realm 在线。
|
||||
|
||||
## 机制
|
||||
|
||||
- 本端 = 用户端 `web-portal`(public client,无 secret,PKCE S256);要求 realm 角色 `user`。
|
||||
- token 只在 keycloak-js 内存里,刷新页面靠 SSO 会话静默恢复;每个请求经 `freshToken()` 挂 `Authorization: Bearer`。
|
||||
- 准入只看 `GET /api/me` 的 `ends`(角色 → 端):入口亮灯、深链保护、个人中心展示都读它;`ends: []` 摆「未授权」页而不是登录页。
|
||||
- 401 先强刷一次 token 重试,仍 401 落登录页;403 不重试(端不够,重登没用)。
|
||||
- SSE 与「下载原件」走 60 秒票据(`GET /api/auth/ticket` → `?ticket=`);SSE 断线后重新取票据重建(浏览器自动重连的旧 URL 必 401)。
|
||||
|
||||
## 改动清单
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `packages/contracts/src/org.ts` | 加 `SURFACES`/`surfaceSchema`/`principalSchema`;`sessionSchema` 标 @deprecated(本仓库 apps/api 仍是旧后端,契约暂留) |
|
||||
| `packages/contracts/src/api/workbench.ts` | 加 `meRoute`(`GET /api/me`)、`authTicketRoute`(`GET /api/auth/ticket`);session/login/logout 三条标 @deprecated |
|
||||
| `apps/web/package.json` | + `keycloak-js@26.2.4` |
|
||||
| `apps/web/.env.development` / `.env.production`(新) | `VITE_KEYCLOAK_URL/REALM/CLIENT_ID=web-portal/VITE_REQUIRED_ROLE=user` |
|
||||
| `apps/web/public/silent-check-sso.html`(新) | 静默 SSO 探测落点页 |
|
||||
| `apps/web/src/shared/auth.ts`(新) | keycloak 实例 + `initAuth/login/logout/freshToken/forceRefreshToken`;未初始化(测试)时 `freshToken` 回 undefined 不带头 |
|
||||
| `apps/web/src/shared/typed-fetch.ts` | 去 cookie,挂 Bearer;401 → `forceRefreshToken` 后重试一次 |
|
||||
| `apps/web/src/app/main.tsx` | 模块加载即 `initAuth()`;Gate 三分支(未登录→登录页 / 角色不够→Denied+登出 / 正常→`/api/me`)+ ends 深链保护(落到能进的第一个端) |
|
||||
| `apps/web/src/features/auth/…/LoginPage.tsx` | 删账号口令表单,改「前往统一登录」跳 Keycloak |
|
||||
| `apps/web/src/shared/gov/surfaces.ts` | `canSeeSurface(me, surface)` = `me.ends.includes(surface)`;删 `SURFACE_FNS` |
|
||||
| `apps/web/src/app/app-shell.tsx` / `gov-shell.tsx` / `desk-me/…/MePage.tsx` | session→me(`queryKeys.me`);登出 = 清缓存 + `keycloak.logout()`;MePage「我的权限」改「我的准入」(角色 + 可进的端,端可直接点过去) |
|
||||
| `apps/web/src/app/subscribe.ts` | SSE 走票据,error 时关旧连接、重取票据、1s 后重建 |
|
||||
| `apps/web/src/features/desk-task/…/FileViewer.tsx` | 「下载原件」点击时现取票据拼 `?ticket=` 再跳转 |
|
||||
| `apps/web/src/shared/query-keys.ts` | `session` → `me` |
|
||||
| `vitest.config.ts` | 补 `@web-shared` / `@features` 别名(与 web 的 vite.config 同口径) |
|
||||
| `apps/web/src/shared/__tests__/typed-fetch.test.ts` | 断言前加 `flushToken()`(fetch 前多了一道取 token 的微任务) |
|
||||
| `apps/web/src/shared/gov/__tests__/surfaces.test.ts` | `canSeeSurface` 改测 ends 口径 |
|
||||
|
||||
## 验证
|
||||
|
||||
- `tsc --noEmit`(web + node)、`eslint` 全部改动文件、`vitest run` 全仓 1691 过。
|
||||
- 浏览器实测:localhost:5173 → 登录页(前往统一登录)→ 跳 `keycloak.akhr-ai.com/realms/corp/...auth?client_id=web-portal&…&code_challenge_method=S256`,登录页正常渲染(无 redirect_uri 报错)。
|
||||
- 真人账号登录 → `/api/me` → 各端落点这后半段需要有权限的账号走一遍(判据见对接说明 §9)。
|
||||
|
||||
## 已知遗留
|
||||
|
||||
- 运营中心「员工」页还在调四条已退役接口(建人/停用/停用前置/岗位授权,410),需按对接说明 §7 换成同步名册 / 指派岗位 / 在途工作 / 角色→端 —— 未做,等指令。
|
||||
- `grantSchema` / `Session` 等旧类型契约里标了 @deprecated,前端已不 import(LoginPage/main/shells/surfaces 全换完),契约物理删除留待后端侧一起收。
|
||||
- Keycloak 侧若要收回 localhost 回调(上线清单 §14),找管理员改 client 配置,前端不用动。
|
||||
Reference in New Issue
Block a user