Files
OneOS1.2/rules/global-design-spec.md

453 lines
17 KiB
Markdown
Raw 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.
# ONE-OS 全局设计规范(开发版)
> **对外分享请使用**[`src/resources/design-system/`](../src/resources/design-system/README.md)(含 `DESIGN.md`、`tokens.json`、AI 提示模板)。本文件为项目内 Agent 规则副本。
| 项 | 说明 |
|---|---|
| 文档版本 | v1.0 |
| 适用范围 | Axhub Make 客户端内所有中后台列表页、台账页、运营配置页 |
| 视觉基底 | Linear 主题 **浅色 inverse** 模式 + ONE-OS 品牌绿主色 |
| 事实源 CSS | `src/prototypes/vehicle-management/style.css` |
| 列表页强制规范 | `src/prototypes/vm-shared/DESIGN.md` |
| 台账扩展规范 | `src/prototypes/ledger-shared/DESIGN.md` |
---
## 1. 设计原则
1. **一致性**:新建页面优先复用 `vm-*` 类名与公共组件,不另起一套视觉语言。
2. **信息密度适中**:列表首屏给筛选 + KPI + 表格,不在正文重复侧栏已有的大标题。
3. **可扫描**:表头弱对比、正文强对比;金额/数量用等宽数字 `tabular-nums`
4. **可访问**:可见 focus 态、按钮/卡片可键盘操作;尊重 `prefers-reduced-motion`
5. **左对齐数字**:金额、数量列与文本列统一左对齐,禁止右对齐金额列。
---
## 2. Design Tokens
定义于 `vehicle-management/style.css``:root`Ant Design 页面通过 `ConfigProvider` 同步主色。
### 2.1 色彩
| Token | 值 | 用途 |
|---|---|---|
| `--ln-primary` | `#32a06e` | 主色:主按钮、选中 KPI、链接、当前页码 |
| `--ln-primary-hover` | `#3fb87c` | 主色悬停 |
| `--ln-primary-focus` | `#2b9260` | 主色按下 / 选中文字 |
| `--ln-primary-soft` | `rgba(50,160,110,0.1)` | 浅色选中底、选项高亮 |
| `--ln-ink` | `#18181b` | 标题、强调正文 |
| `--ln-body` | `#52525b` | 正文 |
| `--ln-muted` | `#71717a` | 次要文字、表头 |
| `--ln-muted-soft` | `#a1a1aa` | 占位符、弱图标 |
| `--ln-canvas-parchment` | `#f5f6f6` | 页面背景 |
| `--ln-surface-card` | `#ffffff` | 卡片、输入框、表格容器 |
| `--ln-canvas-soft` | `#f6f7f7` | 表头底、行 hover、次级表面 |
| `--ln-hairline` | `#e5e7eb` | 卡片边框、分割线 |
| `--ln-hairline-strong` | `#d4d4d8` | 输入框边框、分页按钮边框 |
| `--ln-success` | `#27a644` | 成功态 |
| `--ln-warning` | `#d97706` | 警告态 |
| `--ln-error` | `#e5484d` | 错误、删除、欠费强调 |
| `--ln-on-primary` | `#ffffff` | 主色按钮文字 |
### 2.2 字体
| 角色 | 值 |
|---|---|
| 正文字体 `--vm-font` | Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "PingFang SC", "Microsoft YaHei", sans-serif |
| 等宽 `--vm-font-mono` | ui-monospace, JetBrains Mono, SFMono-Regular, Menlo, Consolas, monospace |
| 数字/金额 | 使用 `--vm-font-mono` + `tabular-nums`(全局见 `src/common/ln-numeric.css`,对齐 `.vm-expire-date` |
| 金额格式 | `src/common/format-number.js`(千分位 + 2 位小数Legacy 页可用 `window.__oneosFormatMoney` |
| 页面基础字号 | `0.875rem`14px |
| 筛选标签 | `0.75rem` / 500 |
| 表头 | `0.75rem` / 500 |
| 表格单元格 | `0.8125rem`13px |
| 筛选卡片标题 | `1.125rem` / 600 |
### 2.3 圆角
| Token | 值 | 用途 |
|---|---|---|
| `--ln-radius-xs` | 4px | 小提示、图标按钮 |
| `--ln-radius-sm` | 6px | 多选框 |
| `--ln-radius-control` | 8px | 按钮、输入框、分页 |
| `--ln-radius-card` | 12px | 筛选卡、表格卡、KPI 卡 |
| `--ln-radius-xl` | 16px | 大面板 |
| `--ln-radius-pill` | 9999px | 徽章、胶囊 |
### 2.4 间距与尺寸
| Token | 值 | 用途 |
|---|---|---|
| 页面内边距 | `24px 32px 32px`≤640px 为 16px |
| 筛选卡片内边距 | `24px`(紧凑模式 1620px |
| 筛选栅格间距 | `16px 20px` |
| 区块垂直节奏 | 筛选 / KPI / 工具栏 / 表格之间约 **1620px** |
| `--vm-control-height` | `32px` | 筛选输入、分页控件 |
| `--vm-btn-height` | `36px` | 按钮最小高度 |
### 2.5 阴影
| Token | 用途 |
|---|---|
| `--ln-shadow-soft` | 卡片默认 |
| `--ln-shadow-hover` | 下拉、Tooltip |
| `--ln-shadow-float` | 浮层 |
| `--ln-shadow-modal` | 弹窗 |
### 2.6 Focus 规则
- 使用 **边框变色**`border-color: var(--vm-focus-border-color)`),不用外扩 outline 环(按钮、输入框统一)。
- 类名辅助:`.vm-focus-border:focus-visible`
---
## 3. 页面壳层
### 3.1 标准列表页结构
```text
.vm-page # 页面根(必选)
├── .vm-filter-card # 筛选区
├── .vm-kpi-row # KPI可选
└── .vm-table-section
├── .vm-table-toolbar # 工具栏(右对齐操作)
└── .vm-table-card
├── .vm-table-wrap # 表格滚动区
└── .vm-table-footer # 底部分页
└── <TablePagination />
```
### 3.2 页面类名扩展
| 类名 | 场景 |
|---|---|
| `vm-page` | 所有列表页基类 |
| `vm-page ldb-page` | 台账列表(租赁/维修等) |
| `vm-page lc-page` | 租赁合同 Ant Design 列表 |
### 3.3 必须引入的样式
```typescript
import '../vehicle-management/style.css';
// 台账页另加模块 styles合同页另加 lease-contract.css
```
### 3.4 禁止
- 标准列表页在正文再放与侧栏重复的 `h1` 大标题 + 长说明段落。
- 工具栏在已有 KPI + 底部分页时重复写「共 N 条」。
- 列表主表格用「加载更多」代替分页(除非 PRD 明确排除分页)。
---
## 4. 组件规范
### 4.1 筛选区 `.vm-filter-card`
| 元素 | 类名 | 规格 |
|---|---|---|
| 容器 | `vm-filter-card`(兼容 `lc-filter-card` | 白底、12px 圆角、1px 边框、轻阴影 |
| 标题 | `vm-filter-title` | 「筛选条件」1.125rem / 600 |
| 栅格 | `vm-filter-grid` | 默认 4 列1280px 以下 2 列640px 以下 1 列 |
| 字段 | `vm-filter-field` | 标签在上、控件在下;标签 12px / muted |
| 操作区 | `vm-filter-actions` | 顶部分割线;左侧「更多筛选/收起」,右侧「重置」「查询」 |
**参考实现(强制对齐)**[`lease-business-detail/components/FilterPanel.tsx`](../src/prototypes/lease-business-detail/components/FilterPanel.tsx)
#### 4.1.1 筛选提示文本placeholder— 强制统一
筛选卡内所有空态提示输入框、FilterPicker、日期区间、Ant Select必须一致
| 属性 | Token / 值 |
|---|---|
| 字体 | `var(--vm-font)` |
| 字号 | `0.875rem`14px |
| 字重 | `400` |
| 颜色 | `var(--ln-muted-soft)``#a1a1aa` |
| 透明度 | `opacity: 1`(覆盖 Ant Select 默认半透明) |
样式落点:`vehicle-management/style.css``.vm-filter-card` / `.lc-filter-card` 下的 `::placeholder``.ant-select-selection-placeholder`
**禁止**各页单独改占位色、字号或字重。
#### 4.1.2 日期区间(强制)
- 使用 `DateRangeFilterField``vehicle-management/components/DateRangeFilterField`)。
- 展示分隔符为中文「**至**」。
- 类名:`vm-date-range-field``vm-filter-picker-control`
- 弹层必须 portal + `fixed`(避免滚动容器错位)。
- **禁止**筛选区用 Ant `RangePicker`、双 `<input type="date">` 等替代方案。
#### 4.1.3 更多筛选 / 收起(强制)
超过 4 项时必须折叠;实现与物流业务明细相同:
| 项 | 规则 |
|---|---|
| 拆分 | `splitFilterFields()` / `shouldShowFilterExpand()`[`src/common/vm-filter-panel.ts`](../src/common/vm-filter-panel.ts) |
| 首行 | 最多 4 项;**禁止**首行 5 项导致第二行仅 1 项 |
| 展开区 | `vm-filter-expand` + `is-expanded`;内层 `vm-filter-expand-inner` + 独立 `vm-filter-grid` |
| 文案 | 仅「更多筛选」/「收起」(禁用「展开」) |
| 按钮 | `vm-btn vm-btn-link vm-filter-toggle``data-vm-icon``filter` / `chevron-up` |
| 角标 | 收起且扩展项有值时显示 `vm-filter-toggle-badge`(主色底、白字) |
| 操作区布局 | 切换在左(`margin-right: auto`),重置/查询在右 |
| 别名 | `ldb-filter-expand` / `ldb-filter-toggle` 等同 `vm-filter-*`**新代码优先 `vm-filter-*`** |
新建或改动列表页必须遵循;旧页触及时迁移。
### 4.2 输入框 `.vm-input`
| 场景 | 高度 | 字号 |
|---|---|---|
| 筛选区内 | 32px | 0.875rem |
| 表单页 | min 44px | 1rem移动端友好 |
- 边框:`--ln-hairline-strong`focus 时主题色边框。
- 占位符:见 §4.1.1`--ln-muted-soft`0.875rem / 400
### 4.3 下拉选择 `.vm-filter-picker-*`
| 元素 | 说明 |
|---|---|
| `vm-filter-picker-control` | 触发器与输入框同高32px |
| `vm-filter-picker-popover` | 下拉面板,卡片圆角 + hover 阴影 |
| `vm-filter-picker-option.checked` | 主色浅底 + 深绿字 |
| 占位符 | 见 §4.1.1与日期区间、Ant Select 同色同字号 |
### 4.4 按钮 `.vm-btn`
| 变体 | 类名 | 用途 |
|---|---|---|
| 主按钮 | `vm-btn vm-btn-primary` | 查询、保存、提交 |
| 次要 | `vm-btn vm-btn-secondary` | 带边框白底 |
| 幽灵 | `vm-btn vm-btn-ghost` | 取消、重置、工具栏次要操作 |
| 文字链 | `vm-btn vm-btn-link` | 表格内操作、行内链接 |
| 返回 | `vm-btn vm-btn-back` | 表单/详情/编辑顶栏左上角Chevron 图标 + 白底描边hover 主色字/边框 + 浅绿底 |
**规格**:高度 36px圆角 8px字号 0.875rem / 500禁用 opacity 0.5。
**弹窗底部**:次要操作用 `vm-btn-ghost`,主操作用 `vm-btn-primary`(或 Ant `Button type="primary"` 且主题色对齐)。
### 4.5 KPI 卡片 `.vm-kpi-row` / `.vm-kpi-card`
| 元素 | 说明 |
|---|---|
| 布局 | 默认 8 列网格1600px→4 列960px→2 列640px→1 列 |
| 卡片 | 最小高度 88px左图标 + 标题 + 数值 |
| 标题 | `vm-kpi-eyebrow` |
| 数值 | `vm-kpi-val`,等宽数字 |
| 说明 | 右上角 `vm-kpi-tip` + `vm-kpi-tooltip` |
| 选中 | `.active`:绿色描边 + 轻阴影;数值变 `--ln-primary-focus` |
台账扩展:`ldb-kpi-row` / `ldb-kpi-val--profit` / `ldb-kpi-val--loss`
### 4.6 工具栏 `.vm-table-toolbar`
- 右对齐:`.vm-table-actions { margin-left: auto }`
- 仅放:筛选开关、批量操作、新建、导入导出等。
- 不放:与分页重复的条数文案。
### 4.7 表格
#### 原生表格 `.vm-table`
| 项 | 规则 |
|---|---|
| 容器 | `vm-table-card` > `vm-table-wrap` > `vm-table` |
| 表头 | 粘性顶;背景 `--ln-canvas-soft`;文字 muted |
| 行 hover | 浅灰底;冻结列同步变色 |
| 冻结列 | `sticky-col` / `sticky-right`;台账用 `sticky-col-left` / `sticky-col-right` |
| 金额列 | `ldb-col-money``ln-modal-detail-table__money` + `tabular-nums`**左对齐** |
| 空值 | 显示「—」或留白,不显示 undefined |
#### Ant Design Table
- 列表页类名:`vm-list-table`(随模块)。
- 弹窗内明细:`ln-modal-detail-table` + `tableLayout="fixed"` + 每列显式 `width`
- 样式源:`src/common/modal-detail-table.css`
- 通过全局规则覆盖 `cell-align-right` 为左对齐。
### 4.8 分页 `TablePagination`
**组件**`src/common/TablePagination.tsx`(强制,禁止手写分页 DOM
**布局顺序**(从左到右):
```text
共 {total} 条 → 上一页 / 页码 / 下一页 → 每页 N 条
```
| 项 | 值 |
|---|---|
| 默认每页 | `DEFAULT_PAGE_SIZE` = 20 |
| 标准选项 | 10 / 20 / 50 / 100 |
| 紧凑选项 | 5 / 10 / 20 / 50`COMPACT_PAGE_SIZE_OPTIONS` |
| 样式类 | `vm-pagination*``src/common/vm-pagination.css` |
| 当前页 | `vm-pagination-page active` 主色填充 |
| 无数据 | 仍显示「共 0 条」,隐藏页码控件 |
**交互**:筛选/重置/KPI 切换/改每页条数时 `page` 重置为 1。
**紧凑 footer**:追加 `vm-table-footer--compact`(详情 Tab 内嵌表)。
### 4.9 多选框 `.vm-checkbox`
样式源:`src/common/vm-checkbox.css`
| 场景 | 用法 |
|---|---|
| 工具栏/表单 | `input.vm-checkbox` |
| 表格勾选列 | `vm-col-check` / `ldb-col-check`;列宽 48px 居中 |
| 下拉多选面板内 | `vm-ops-picker-option` 内用原生紧凑样式(例外) |
| 状态 | 表现 |
|---|---|
| 默认 | 18×18白底细边框 |
| 选中 | 主色底 + 白色对勾 |
| 半选 | 主色底 + 白色横线(表头全选) |
| 禁用 | opacity 45% |
### 4.10 链接与标签
| 元素 | 类名 / 说明 |
|---|---|
| 文本链接 | `vm-link`;颜色 `--ln-link` |
| VIN/编码 | `vm-vin` + mono 字体 |
| 状态标签 | Ant `Tag`;签约等用模块类如 `lc-station-signed-tag` |
| 操作列 | 文字按钮组,左对齐;删除前 `Modal.confirm` |
### 4.11 弹窗 / 抽屉
| 项 | 规则 |
|---|---|
| Ant Modal | `centered: true`;圆角 812pxbody `maxHeight: 78vh` + 滚动 |
| 次要按钮 | `vm-btn-ghost` 或 Ant 默认 + 模块封装 `renderH2GhostButton` 等 |
| 主按钮 | 主题绿 `#32a06e` |
| 表单 | `layout="vertical"`;标签 13px / 600模块内表单 |
| 明细表 | `ln-modal-detail-table`;见 4.7 |
### 4.12 统计卡(下钻/对账等)
模块内常用模式(非全局类名,保持视觉一致即可):
- 白底 + 1px 边框 + 12px 圆角。
- 标签 1213px muted数值 加粗 + `tabular-nums`
- 三列横排统计卡间距 1216px。
---
## 5. Ant Design 接入
使用 Ant Design 的页面(如加氢站、租赁合同)须通过 `ConfigProvider` 对齐 token
```typescript
const vmTheme = {
token: {
colorPrimary: '#32a06e',
colorLink: '#32a06e',
colorLinkHover: '#3fb87c',
borderRadius: 8,
fontFamily: 'Inter, -apple-system, ...',
fontSize: 14,
colorText: '#18181b',
colorTextSecondary: '#52525b',
colorBorder: '#e5e7eb',
colorBgContainer: '#ffffff',
},
components: {
Table: {
headerBg: '#f6f7f7',
headerColor: '#71717a',
rowHoverBg: '#f6f7f7',
borderColor: '#e5e7eb',
cellPaddingBlock: 8,
cellPaddingInline: 12,
},
Card: { borderRadiusLG: 12 },
},
};
```
**筛选区 Ant 控件**`lc-page` 示例):`Select` / `DatePicker` 高度与 `vm-input` 对齐32px圆角 8px边框 `--ln-hairline-strong`
---
## 6. 响应式断点
| 断点 | 主要变化 |
|---|---|
| ≤1600px | KPI 4 列 |
| ≤1280px | 筛选 2 列;台账 KPI 6→4 列 |
| ≤960px | KPI 2 列 |
| ≤640px | 页面/筛选 padding 缩小;筛选/KPI 1 列 |
---
## 7. 动效与无障碍
| 项 | 规则 |
|---|---|
| 过渡 | 按钮/卡片 0.2s;筛选展开 0.28s |
| 减少动效 | `@media (prefers-reduced-motion: reduce)` 关闭过渡与分页缩放 |
| 分页 | `role="navigation"``aria-label="表格分页"`、当前页 `aria-current="page"` |
| KPI/表头提示 | 支持 focus 显示 tooltip |
| 触控 | 可点击区域建议 ≥ 44×44px表单页输入 44px 高) |
| 图标 | 使用 Lucide / Heroicons 等 SVG**不用 emoji 作图标** |
| 对比度 | 正文对比度 ≥ 4.5:1 |
---
## 8. 禁止做法(汇总)
- 不自建分页 UI不用 Ant `Pagination` 替代 `TablePagination`
- 不在 `vm-page` 内自定义 checkbox 皮肤。
- 不用 RangePicker 做筛选区日期区间。
- 不对金额列 `align: right`
- 不在列表工具栏重复总条数。
- 不引入与 Linear/vm token 冲突的第三方分页/表格皮肤。
- 弹窗内表格须 `tableLayout="fixed"`,避免列宽错位。
---
## 9. 文件与参考实现索引
| 类型 | 路径 |
|---|---|
| 全局样式入口 | `src/prototypes/vehicle-management/style.css` |
| 分页组件 | `src/common/TablePagination.tsx` |
| 分页样式 | `src/common/vm-pagination.css` |
| 多选框样式 | `src/common/vm-checkbox.css` |
| 弹窗表格样式 | `src/common/modal-detail-table.css` |
| 日期区间组件 | `src/prototypes/vehicle-management/components/DateRangeFilterField` |
| 筛选折叠逻辑 | `src/common/vm-filter-panel.ts` |
| 列表页规范 | `src/prototypes/vm-shared/DESIGN.md` |
| 台账扩展规范 | `src/prototypes/ledger-shared/DESIGN.md` |
| 合同 Ant 对齐 | `src/prototypes/lease-contract-management/styles/lease-contract.css` |
| 参考:车辆管理 | `src/prototypes/vehicle-management/index.tsx` |
| 参考:租赁合同 | `src/prototypes/lease-contract-management/LeaseContractManagement.jsx` |
| 参考:加氢站站点 | `src/prototypes/oneos-web-h2-station-site/pages/03-站点信息.jsx` |
| 主题 token 来源 | `src/themes/linear/DESIGN.md`inverse 浅色用于 vm |
---
## 10. 新页面开发检查清单
- [ ] 根节点使用 `vm-page`(及必要的 `ldb-page` / `lc-page`
- [ ]`import` `vehicle-management/style.css`
- [ ] 筛选区使用 `vm-filter-card` + `vm-filter-grid` + `vm-filter-actions`
- [ ] 日期区间使用 `DateRangeFilterField`
- [ ] 按钮使用 `vm-btn-*` 变体
- [ ] 表格底部分页使用 `TablePagination` + `vm-table-footer`
- [ ] 金额列左对齐 + `tabular-nums`
- [ ] 多选使用 `vm-checkbox` 或勾选列约定
- [ ] Ant 页面已配置 `ConfigProvider` 主题色
- [ ] 无重复页面大标题、无重复总条数文案
- [ ] Focus 态、键盘操作、减少动效已验证
---
## 修订记录
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.0 | 2026-07-09 | 首版:汇总 vm-shared、ledger-shared、vehicle-management token 与组件规范 |