# ERP 系统 DESIGN.md

> 基于 Google Stitch DESIGN.md 格式 | 适用平台：Web 管理后台 + Telegram Bot
> 版本：v1.0 | 日期：2026-05-25

---

## 1. Visual Theme & Atmosphere

**整体氛围**
专业、干净、高效。面向新西兰/澳大利亚 IT 小型企业的 ERP 系统，强调实用性和可读性，避免过度装饰。

**设计哲学**
- 信息密度适中：后台管理需要承载较多数据，但不能拥挤
- 操作导向：常用操作（新建、筛选、发送）要显眼且容易触达
- 状态清晰：发票状态、订阅状态通过颜色即时区分，不需要 hover 猜测
- AI 融合：AI 功能（对话式开票）作为一级入口，不是藏在设置里的附属功能

**视觉基调**
- 侧边栏：深沉（品牌色区隔），内容区：浅亮（阅读舒适）
- 暗侧边 + 亮主区 = 标准 SaaS 管理后台范式
- 卡片式布局：每个功能模块是独立卡片，视觉清晰

**Telegram Bot 风格**
- 文字为主，简洁消息格式
- 使用 Emoji 作为视觉锚点（📊🧾📧⏰🤖）
- 消息长度控制，避免长篇纯文字

---

## 2. Color Palette & Roles

```css
:root {
  /* 主品牌色 */
  --primary:        #4f46e5;   /* Indigo 600：主要按钮、激活态 */
  --primary-light:  #6366f1;   /* Indigo 500：hover */
  --primary-dark:   #3730a3;   /* Indigo 900：按下态 */

  /* 侧边栏（深色区域）*/
  --sidebar-bg:     #1e1b4b;   /* Indigo 950：侧边栏背景 */
  --sidebar-hover:  #312e81;   /* Indigo 900：菜单 hover */
  --sidebar-active: rgba(99,102,241,0.15); /* 激活项背景 */

  /* 功能色 */
  --accent:         #06b6d4;   /* Cyan 500：辅助高亮 */
  --success:        #10b981;   /* Emerald 500：已付款/活跃 */
  --warning:        #f59e0b;   /* Amber 500：草稿/即将到期 */
  --danger:         #ef4444;   /* Red 500：删除/逾期 */
  --info:           #3b82f6;   /* Blue 500：信息提示 */

  /* 背景与表面 */
  --bg:             #f1f5f9;   /* Slate 100：页面背景 */
  --card:           #ffffff;   /* 卡片/模态框背景 */
  --card-hover:     #fafbff;   /* 表格行 hover */

  /* 文字 */
  --text:           #1e293b;   /* Slate 800：主文字 */
  --text-muted:     #64748b;   /* Slate 500：辅助文字 */
  --text-inverse:   #ffffff;   /* 侧边栏/深色背景上的文字 */

  /* 边框与分割 */
  --border:         #e2e8f0;   /* Slate 200：分割线、输入框边框 */
  --border-focus:   #4f46e5;   /* 聚焦边框 */

  /* 发票状态颜色 */
  --status-draft:   #94a3b8;   /* Slate 400 */
  --status-issued:  #3b82f6;   /* Blue 500 */
  --status-sent:    #8b5cf6;   /* Violet 500 */
  --status-paid:    #10b981;   /* Emerald 500 */
  --status-overdue:  #ef4444;   /* Red 500 */

  /* 订阅状态颜色 */
  --sub-active:     #10b981;   /* Emerald 500 */
  --sub-cancelled:  #94a3b8;   /* Slate 400 */
  --sub-expired:    #ef4444;   /* Red 500 */

  /* 圆角与阴影 */
  --radius-sm:      6px;
  --radius:         12px;
  --radius-lg:      16px;
  --radius-full:    9999px;

  --shadow-sm:      0 1px 2px rgba(0,0,0,0.05);
  --shadow:         0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06);
  --shadow-lg:      0 10px 30px rgba(0,0,0,0.12);
  --shadow-card:    0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06);
}
```

**颜色语义角色**

| 角色 | 颜色 | 用途 |
|------|------|------|
| Primary | `#4f46e5` | 主要按钮、激活菜单项、链接 |
| Sidebar BG | `#1e1b4b` | 侧边栏背景 |
| Success | `#10b981` | 已付款发票、活跃订阅 |
| Warning | `#f59e0b` | 草稿状态、即将到期提醒 |
| Danger | `#ef4444` | 逾期发票、删除按钮 |
| Accent | `#06b6d4` | AI 功能、特殊高亮 |

---

## 3. Typography Rules

**字体**
- 主字体：系统默认无衬线字体栈（最兼容、最快）
  ```css
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  ```
- 等宽字体（发票号、金额、代码）：`'SF Mono', 'Fira Code', 'Consolas', monospace`
- 中文字体：系统自动回退到 PingFang SC / Microsoft YaHei / Noto Sans CJK

**字体层级**

| 层级 | 字号 | 字重 | 用途 |
|------|------|------|------|
| H1（页面标题） | 24px | 600 | 页面主标题 |
| H2（卡片标题） | 18px | 600 | 内容区标题 |
| H3（区块标题） | 16px | 600 | 表单区块标题 |
| Body | 14px | 400 | 正文内容 |
| Body Small | 13px | 400 | 表格内容、说明文字 |
| Caption | 12px | 400 | 标签、徽章、时间戳 |
| Stat Value | 26px | 700 | 数据统计卡片数值 |
| Invoice Number | 16px | 600 (mono) | 发票号显示 |

**文字颜色用法**
- 主文字：`--text` (#1e293b)
- 辅助文字：`--text-muted` (#64748b)
- 侧边栏文字：`--text-inverse` (#ffffff)
- 链接文字：`--primary` (#4f46e5)

---

## 4. Component Stylings

### 4.1 按钮（Buttons）

```css
/* 主要按钮 */
.btn-primary {
  background: var(--primary);
  color: white;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  border: none;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
}
.btn-primary:hover { background: var(--primary-dark); }
.btn-primary:active { transform: scale(0.98); }

/* 次要按钮 */
.btn-outline {
  background: white;
  color: var(--primary);
  border: 1px solid var(--primary);
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
.btn-outline:hover { background: #f5f3ff; }

/* 危险按钮 */
.btn-danger {
  background: white;
  color: var(--danger);
  border: 1px solid var(--danger);
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  cursor: pointer;
}
.btn-danger:hover { background: #fef2f2; }

/* 图标按钮 */
.btn-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-icon:hover { background: var(--bg); color: var(--primary); }
```

### 4.2 卡片（Cards）

```css
.card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 20px;
  border: 1px solid var(--border);
}
```

### 4.3 表格（Tables）

```css
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.data-table th {
  text-align: left;
  padding: 12px 16px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.data-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--card-hover); }
```

### 4.4 表单输入（Form Inputs）

```css
.form-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 14px;
  color: var(--text);
  background: white;
  transition: border-color 0.15s;
  outline: none;
}
.form-input:focus {
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px rgba(79,70,229,0.1);
}
.form-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 6px;
}
```

### 4.5 状态徽章（Status Badges）

```css
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: 12px;
  font-weight: 500;
}
.badge-draft    { background: #f1f5f9; color: #64748b; }
.badge-issued   { background: #dbeafe; color: #1d4ed8; }
.badge-sent     { background: #ede9fe; color: #6d28d9; }
.badge-paid     { background: #d1fae5; color: #065f46; }
.badge-overdue  { background: #fee2e2; color: #991b1b; }
.badge-active   { background: #d1fae5; color: #065f46; }
.badge-cancelled { background: #f1f5f9; color: #64748b; }
.badge-expired  { background: #fee2e2; color: #991b1b; }
```

### 4.6 侧边栏菜单项（Sidebar Menu Items）

```css
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  color: rgba(255,255,255,0.7);
  text-decoration: none;
  border-radius: 8px;
  margin: 2px 8px;
  font-size: 14px;
  transition: background 0.15s, color 0.15s;
  cursor: pointer;
  border-left: 3px solid transparent;
}
.sidebar-item:hover {
  background: var(--sidebar-hover);
  color: white;
}
.sidebar-item.active {
  background: var(--sidebar-active);
  color: white;
  border-left-color: var(--primary-light);
  font-weight: 500;
}
```

---

## 5. Layout Principles

### 5.1 整体布局

```
┌──────────────┬──────────────────────────────────────────┐
│              │  顶栏（60px，白色，底部阴影）             │
│  侧边栏       ├──────────────────────────────────────────┤
│  240px       │                                          │
│  深紫色背景   │  内容区域（padding: 24px）                │
│  #1e1b4b    │  #f1f5f9 背景                            │
│              │                                          │
│  Logo       │  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐   │
│  菜单        │  │ Stat │ │ Stat │ │ Stat │ │ Stat │   │
│  ...        │  │ Card │ │ Card │ │ Card │ │ Card │   │
│              │  └──────┘ └──────┘ └──────┘ └──────┘   │
│  ─────────  │                                          │
│  🤖 AI 开票   │  ┌────────────────┐ ┌──────────────┐   │
│  (突出显示)  │  │   柱状图        │ │   饼图       │   │
│              │  │                │ │              │   │
│  ─────────  │  └────────────────┘ └──────────────┘   │
│  用户信息    │                                          │
└──────────────┴──────────────────────────────────────────┘
```

**后台信息架构补充**
- 顶栏只放当前页面标题、全局通知、主要快捷操作，避免和页面内操作重复过多。
- 侧边栏菜单控制在 12 个以内；超过时优先合并到“运营”“系统配置”等分组。
- 发票、客户、商品这类高频列表页以表格为主，不使用大面积营销式卡片布局。
- AI 开票是一级入口，但所有 AI 生成的发票必须落到“草稿/待确认”状态，界面上不能表现成已开票成功。

### 5.2 间距系统

| 名称 | 值 | 用途 |
|------|------|------|
| `--space-1` | 4px | 紧凑间距 |
| `--space-2` | 8px | 元素内间距 |
| `--space-3` | 12px | 小组件间距 |
| `--space-4` | 16px | 标准间距 |
| `--space-5` | 20px | 卡片内间距 |
| `--space-6` | 24px | 页面内间距 |
| `--space-8` | 32px | 区块间距 |
| `--space-10` | 40px | 大区块间距 |

### 5.3 响应式断点

| 断点 | 宽度 | 行为 |
|------|------|------|
| Mobile | < 768px | 侧边栏收起为汉堡菜单 |
| Tablet | 768px - 1024px | 侧边栏缩窄到 64px（图标的） |
| Desktop | > 1024px | 完整侧边栏 240px |

---

## 6. Depth & Elevation

| Level | 用途 | 阴影值 |
|-------|------|--------|
| 0 | Dropdown | `0 0 0 1px rgba(0,0,0,0.05)` |
| 1 | 卡片默认状态 | `0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06)` |
| 2 | 卡片 Hover / Modal | `0 10px 30px rgba(0,0,0,0.12)` |
| 3 | Modal 叠加 | 叠加 `0 0 0 4px rgba(79,70,229,0.2)` |

---

## 7. Do's and Don'ts

### ✅ 这样做

- 用颜色表达状态（绿色=成功，红色=危险，蓝色=信息）
- 发票列表页面：状态徽章放在最后一列，金额在显眼位置
- 操作按钮放在内容区右上角或表格行末
- 使用卡片区分不同功能模块
- AI 开票入口在侧边栏底部，视觉上与其他菜单区分开
- 发票金额始终带币种符号（NZD / AUD / USD）
- 表格支持按状态筛选（Tab 切换：全部/草稿/已开/已付/逾期）

### ❌ 不要这样做

- 不要用纯文字表示发票状态（必须用彩色徽章）
- 不要在侧边栏放超过 12 个菜单项
- 不要让内容区宽度超过 1600px
- 不要在发票列表页展示客户完整地址
- 不要把"删除"按钮设为红色背景
- 不要在表格里用太多颜色

---

## 8. Responsive Behavior

| 断点 | 侧边栏 | 卡片列数 |
|------|--------|---------|
| Mobile <768px | 汉堡菜单 | 1-2 列 |
| Tablet 768-1024px | 64px 窄版 | 2 列 |
| Desktop >1024px | 240px 完整 | 4 列 |

**响应式实现要求**
- `stats-grid` 不能固定 `repeat(4, 1fr)` 到所有屏幕；移动端 1 列，平板 2 列，桌面 4 列。
- 表格外层必须有横向滚动容器，移动端保留关键列：发票号、客户、金额、状态、操作。
- 发票表单在桌面可用两列/多列布局，移动端必须降为单列，明细行允许横向滚动。
- 顶栏按钮在移动端收敛为图标按钮或更多菜单，避免标题和按钮互相挤压。
- 模态框最大宽度不超过视口宽度，移动端使用底部抽屉或全屏表单。
- 所有按钮、徽章、表格单元格文本需要设置 `white-space` / `min-width` / `overflow` 策略，避免中文和金额挤出容器。

**原型验证清单**
- Desktop 1440px：侧边栏完整、四张统计卡一行、发票表格无横向溢出。
- Tablet 768px：侧边栏窄版或可收起、统计卡两列、表单两列以内。
- Mobile 390px：侧边栏抽屉、统计卡单列、发票表格可横向滑动、主要操作可触达。
- 发票金额、币种、状态徽章、长客户名都要用真实长度数据测试。

---

## 9. Agent Prompt Guide

### 颜色 token 速查

```
背景 → var(--bg)
卡片 → var(--card)
侧边栏 → var(--sidebar-bg)
主色 → var(--primary)
文字 → var(--text)
辅助文字 → var(--text-muted)
成功/危险/警告 → var(--success) / var(--danger) / var(--warning)
边框 → var(--border)
```

### 文件命名

```
views/layout/AdminLayout.vue   — 主布局
views/dashboard/Dashboard.vue  — 仪表盘
views/customers/List.vue       — 客户列表
views/customers/Form.vue       — 客户表单
views/products/List.vue        — 商品列表
views/products/Form.vue        — 商品表单
views/invoices/List.vue        — 发票列表
views/invoices/Form.vue        — 发票表单
views/invoices/Detail.vue      — 发票详情
views/subscriptions/List.vue   — 订阅列表
views/email-templates/List.vue — 邮件模板
views/reminders/List.vue       — 提醒规则
views/stats/Stats.vue          — 统计面板
views/config/SmtpConfig.vue    — SMTP 配置
views/ai/Chat.vue              — AI 对话开票
```
