# 编码规范

**状态**：已确定  
**最后更新**：2026-01-28

---

## 一、通用规范

### 1.1 开发优先原则（最高优先级）

#### 1.1.1 主动性确定性编程

**原则**：主动控制执行时机和状态，确保在确定的状态下执行操作，而非通过防御性检查和重试来弥补时机问题。

**具体要求**：

1. **使用 Vue 响应式系统确保状态一致性**
   - 优先使用 `ref`、`reactive`、`computed` 管理状态
   - 通过 `watch` 和 `nextTick` 确保在正确时机执行
   - 避免手动同步状态，依赖 Vue 的响应式机制

2. **使用模板引用（Template Refs）直接获取 DOM**
   - 优先使用 `:ref` 绑定获取 DOM 元素
   - 避免通过 `querySelector` 等 DOM 查询方式
   - 通过 ref Map 管理多个元素引用

3. **确保执行时机正确**
   - 使用 `nextTick` 等待 DOM 更新完成
   - 使用 `requestAnimationFrame` 等待渲染完成
   - 在正确的生命周期钩子中执行操作

4. **减少防御性编程**
   - 移除不必要的重试循环
   - 移除过多的条件检查和兜底逻辑
   - 确保数据在操作前已准备好，而非通过检查来避免错误

5. **代码简洁直接**
   - 直接表达意图，避免过度抽象
   - 减少中间变量和临时状态
   - 使用明确的函数名和变量名

**示例对比**：

```typescript
// ❌ 防御性编程（不推荐）
const findContainer = async (tabKey, retryCount = 8) => {
  for (let i = 0; i < retryCount; i++) {
    await new Promise(resolve => setTimeout(resolve, 250))
    const container = document.querySelector(`.code-editor[data-tab-key="${tabKey}"]`)
    if (container) {
      const rect = container.getBoundingClientRect()
      if (rect.width > 0 && rect.height > 0) {
        return container
      }
    }
  }
  return null
}

// ✅ 主动性确定性编程（推荐）
const editorContainers = ref(new Map())

// 在模板中直接绑定
<div :ref="el => setEditorContainerRef(el, tab.key)"></div>

const findContainer = async (tabKey) => {
  await nextTick()
  await new Promise(resolve => requestAnimationFrame(resolve))
  const containerInfo = editorContainers.value.get(tabKey)
  return containerInfo?.container || null
}
```

#### 1.1.2 其他优先原则

- **简洁优先**：代码要简洁，避免过度设计；优先使用简单方案，避免不必要的高级特性
- **易于维护**：代码结构清晰，便于维护；减少中间层和抽象，直接表达意图
- **减少AI味**：避免明显的AI生成代码特征；避免过度注释和文档
- **降低幻觉**：避免不必要的高级特性；优先使用简单、直接的方案

### 1.2 注释规范
- **必要注释**：只保留必要的注释，便于维护
- **中文注释**：使用中文编写注释
- **避免冗余**：不写显而易见的注释

---

## 二、Go后端规范

### 2.1 方法参数（设计美学约束）
- **参数限制**：方法参数不得超过3个（硬性约束，不可违反）
- **超过限制**：必须使用结构体/对象封装参数
- **设计美学**：参数过多严重影响代码可读性和维护性，完全不可接受
- **示例**：
  ```go
  // ❌ 9个参数，完全不可接受
  func SaveDbConnection(id uint, name, dbType, host string, port int, username, password, database, options string) error
  
  // ✅ 使用结构体封装
  type SaveConnectionRequest struct {
      ID uint
      Name string
      Type string
      Host string
      Port int
      Username string
      Password string
      Database string
      Options string
  }
  func SaveDbConnection(req SaveConnectionRequest) error
  ```

### 2.2 返回值
- **禁止类型**：不返回 `RetResult<Void>` 类型
- **错误处理**：统一使用 error 返回错误

### 2.3 代码签名
- **作者标识**：新增文件使用 `JueChen` 作为代码签名

### 2.4 架构约束
- **分层架构**：API → Service → Repository → Infrastructure
- **职责分离**：每层只负责自己的职责
- **依赖方向**：只能依赖下层，不能依赖上层

---

## 三、前端规范

### 3.1 样式规范
- **Arco基础样式**：优先使用 Arco Design 提供的基样式
- **避免自定义**：避免过度自定义样式和硬编码样式
- **主题兼容**：确保切换主题时样式正常

### 3.2 组件规范
- **不包含title**：`<a-card>` 元素不包含 title 属性
- **简洁设计**：组件设计要简洁，避免过度复杂

### 3.3 事件规范
- **统一格式**：事件参数使用对象格式
- **类型定义**：所有事件都有 TypeScript 类型定义
- **命名规范**：事件名称使用 kebab-case

---

## 四、文档规范

### 4.1 文档编写
- **精简准确**：文档内容要精简、准确、无幻觉
- **直接回复**：优先直接回复，不创建过多报告文件
- **必要文档**：只创建必要性和长久性文档

### 4.2 代码签名
- **文档签名**：文档使用 `JueChen` 作为签名（本地新增文件）

---

## 五、工具使用

### 5.1 命令行优先
- **文件操作**：文件更名、复制等优先使用命令行
- **Git Bash**：执行类似命令时使用 Git Bash

---

## 六、检查清单

### 开发优先原则检查
- [ ] 是否使用了 Vue 的响应式系统管理状态？
- [ ] 是否使用了模板引用而非 DOM 查询？
- [ ] 是否在正确的时机执行操作（通过 `nextTick`、`requestAnimationFrame` 等）？
- [ ] 是否移除了不必要的重试循环？
- [ ] 是否移除了过多的条件检查和兜底逻辑？
- [ ] 代码是否简洁直接，易于理解？
- [ ] 是否避免了防御性编程模式？

### 代码检查
- [ ] 方法参数不超过3个
- [ ] 不返回 `RetResult<Void>` 类型
- [ ] 代码风格简洁，易于维护
- [ ] 必要注释已添加

### 前端检查
- [ ] 使用 Arco 基础样式
- [ ] 避免过度自定义样式
- [ ] 事件参数使用对象格式
- [ ] 所有事件有类型定义

### 文档检查
- [ ] 文档内容精简准确
- [ ] 不创建过多报告文件
- [ ] 必要文档已创建

