# 硬编码防范规范

> 跨框架通用的硬编码检测与防范标准
> 版本: v1.0.0 | 更新: 2026-03-31

---

## 🎯 核心原则

1. **Token 驱动** — 颜色、字号、圆角、间距必须使用项目定义的 Token / 常量
2. **搜索优先** — 新代码使用样式值前，先 grep 搜索项目是否已有对应常量
3. **零魔法数字** — 出现在布局中的数字必须有语义化名称

---

## 🔴 颜色硬编码防范

### ⚡ Flutter / Dart

```dart
// ❌ 禁止
Container(color: Color(0xFF1C2B45))
Text('Hello', style: TextStyle(color: Colors.grey))
border: Border.all(color: Color(0xFFE5E5E5))

// ✅ 正确 — 使用项目 Token 系统
Container(color: AppColors.primaryDark)       // 语义化颜色
Container(color: $c.primary)                  // Token 快捷方式
Text('Hello', style: TextStyle(color: AppColors.textSecondary))
border: Border.all(color: AppColors.divider)
```

**搜索已有颜色：**
```bash
grep -rn "0xFF1C2B45\|1C2B45" lib/core/themes/
grep -rn "static.*Color" lib/core/themes/app_colors.dart
```

### ⚡ Vue / CSS

```vue
<!-- ❌ 禁止 -->
<div style="color: #1C2B45; background: rgba(0,0,0,0.5)">

<!-- ✅ 正确 -->
<div :style="{ color: 'var(--color-primary-dark)' }">
```

```scss
// ❌ 禁止
.card { background: #ffffff; }

// ✅ 正确
.card { background: var(--bg-elevated); }
```

---

## 🔴 字号硬编码防范

### ⚡ Flutter / Dart

```dart
// ❌ 禁止
Text('Title', style: TextStyle(fontSize: 20))
Text('Body', style: TextStyle(fontSize: 14))

// ✅ 正确
Text('Title', style: TextStyle(fontSize: DesignFontSizes.f20))
Text('Body', style: TextStyle(fontSize: DesignFontSizes.f14))
// 或使用 Token
Text('Title', style: $t.titleLarge)
```

**搜索已有字号常量：**
```bash
grep -rn "static.*double.*f\|fontSize" lib/core/themes/design_constants.dart
```

### ⚡ Vue / CSS

```scss
// ❌ 禁止
.title { font-size: 20px; }

// ✅ 正确
.title { font-size: var(--font-size-xl); }
```

---

## 🔴 圆角硬编码防范

### ⚡ Flutter / Dart

```dart
// ❌ 禁止
BorderRadius.circular(8)
BorderRadius.circular(16)

// ✅ 正确
AppRadius.r8                     // 命名常量
BorderRadius.circular($r.md)     // Token 快捷方式
```

**搜索已有圆角常量：**
```bash
grep -rn "static.*BorderRadius\|static.*r[0-9]" lib/core/themes/app_radius.dart
```

### ⚡ Vue / CSS

```scss
// ❌ 禁止
.card { border-radius: 8px; }

// ✅ 正确
.card { border-radius: var(--radius-md); }
```

---

## 🔴 间距硬编码防范

### ⚡ Flutter / Dart

```dart
// ❌ 禁止
SizedBox(height: 16)
EdgeInsets.all(24)
Padding(padding: EdgeInsets.symmetric(horizontal: 20))

// ✅ 正确
Gap($s.md)                                    // 使用 Gap + Token
EdgeInsets.all($s.lg)
Padding(padding: EdgeInsets.symmetric(horizontal: AppSpacing.pageHorizontal))
```

### ⚡ Vue / CSS

```scss
// ❌ 禁止
.section { margin-bottom: 24px; padding: 16px; }

// ✅ 正确
.section { margin-bottom: var(--spacing-lg); padding: var(--spacing-md); }
```

---

## 🔴 字符串硬编码防范

所有用户可见文本必须走 i18n 系统，详见 `get_standard_by_id({ id: "i18n" })`。

```dart
// ❌
Text('请输入金额')
AppToast.error('网络错误，请重试')

// ✅
Text(S.of(context).enterAmount)
AppToast.error(S.current.networkError)
```

---

## ✅ 通用检查清单

**每次编写新代码前：**

1. **搜索** — `grep` 项目中是否已有该值的常量定义
2. **复用** — 找到则直接使用，避免重复定义
3. **新建** — 找不到则在对应的 Token 文件中新增常量
4. **命名** — 使用语义化名称（`primaryDark` 而非 `color1C2B45`）

**CI 级检查（推荐）：**

```bash
# Flutter: 检测残留的硬编码颜色
grep -rn "Color(0x" lib/ --include="*.dart" | grep -v "themes/" | grep -v ".g.dart"

# Flutter: 检测残留的硬编码字号
grep -rn "fontSize: [0-9]" lib/ --include="*.dart" | grep -v "themes/" | grep -v ".g.dart"

# Flutter: 检测残留的硬编码圆角
grep -rn "BorderRadius.circular([0-9]" lib/ --include="*.dart" | grep -v "themes/" | grep -v ".g.dart"
```

---

## 📊 真实案例

> 来自 my_flutter 项目 P1 优化

| 指标 | 优化前 | 优化后 | 降幅 |
|------|--------|--------|------|
| 硬编码颜色 | 634 处 | 237 处 | -63% |
| 硬编码字号 | 351 处 | 50 处 | -86% |
| 硬编码圆角 | 155 处 | 11 处 | -93% |

**教训**: 项目初期不强制 Token 使用，后期批量修复需要编写脚本处理 56+ 文件。
