Files
AquaControlAI/开发文档/code-standards.md
T
2026-07-11 13:15:28 +08:00

698 lines
24 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.
# 污水厂智能控制系统 — 代码规范
> 本文档适用于本平台所有模块(数据管理、历史数据、实时监控、智能控制、系统配置等)的代码开发工作。
> 作为代码审查的依据标准,所有合入主分支的代码必须通过本规范的检查。
---
## 目录
- [1. 通用原则](#1-通用原则)
- [2. 项目结构与工程规范](#2-项目结构与工程规范)
- [3. Go 后端规范](#3-go-后端规范)
- [4. 前端规范](#4-前端规范)
- [5. RESTful API 规范](#5-restful-api-规范)
- [6. 数据库规范](#6-数据库规范)
- [7. 日志与错误处理规范](#7-日志与错误处理规范)
- [8. 安全规范](#8-安全规范)
- [9. 代码审核清单](#9-代码审核清单)
- [附录 A:命名约定](#附录-a命名约定)
---
## 1. 通用原则
### 1.1 核心原则
| 原则 | 说明 |
|------|------|
| **可读性优先** | 代码是写给人类看的,其次才是给机器执行。优先清晰直白,避免晦涩技巧 |
| **一致性** | 同一概念在代码、数据库、API、前端中保持命名一致(如 `device_id` 在所有层统一) |
| **最小惊讶** | 函数的名称和签名应让调用者无需查看实现就能大致猜到行为 |
| **防御式编程** | 不信任外部输入,对所有外部输入做校验,但内部调用尽量减少冗余校验 |
| **模块自治** | 每个模块有清晰的边界,模块间通过 API 通信,不直接访问其他模块的内部数据 |
### 1.2 命名风格对照表
| 上下文 | 风格 | 示例 |
|--------|------|------|
| Go 源码 | `camelCase` / `CamelCase` | `deviceService`, `CreateDevice()` |
| 数据库(PG/TDengine | `snake_case` | `device_id`, `protocol_type` |
| RESTful APIURL | `kebab-case` | `/api/v1/collection-points` |
| RESTful APIJSON Body | `snake_case` | `"device_id": "uuid"` |
| 前端 JS/TS 源码 | `camelCase` | `fetchDeviceList()` |
| 前端 CSS 类名 | `kebab-case` | `.device-table-container` |
| 前端组件/目录名 | `kebab-case` | `collection-points/` |
| 环境变量 | `UPPER_SNAKE_CASE` | `DB_CONNECTION_STRING` |
| Git 分支名 | `kebab-case` | `feat/aeration-model` |
### 1.3 注释规范
- **Go 注释**:遵循 `// PackageName` 包注释和 `// FunctionName 功能描述` 的 Go 标准注释风格
- **不要注释显而易见的事**`// 递增 i` 是废话注释
- **TODO 注释**:必须附带责任人,如 `// TODO(张三): 后续需要处理断线重连的边界情况`
- **FIXME 注释**:必须附带 issue 编号,如 `// FIXME(#123): 此处有并发安全问题`
- **代码删除**:不保留被注释掉的旧代码,直接删除,有需要从 git 历史查找
### 1.4 复用约束
- 新增功能前,必须优先复用 `internal/pkg/``web/src/components/``web/src/utils/` 中的现有实现及已引入的依赖
- 复用优先级:项目既有能力 → 官方 SDK / 框架内置能力 → 维护活跃的开源库 → 自研实现
- **禁止**:自行实现已有成熟方案已覆盖的通用能力,包括但不限于鉴权、参数校验、密码哈希、UUID、数据库迁移、HTTP 客户端重试、日期处理、图表、CSV 编解码和协议编解码
- 封装边界:对第三方库的调用应集中在适配层或公共封装中,业务代码不得散落依赖某个供应商的私有 API
---
## 2. 项目结构与工程规范
### 2.1 整体目录结构
```
water-plant-control/
├── cmd/ # 可执行程序入口
│ ├── server/ # Web 服务端入口
│ │ └── main.go
│ └── collector/ # 采集引擎入口
│ └── main.go
├── internal/ # 私有应用代码(不对外暴露)
│ ├── api/ # HTTP handler 层
│ │ ├── router.go # 路由注册
│ │ ├── middleware/ # 中间件(鉴权、日志、CORS、恢复等)
│ │ ├── device/ # 设备管理 API
│ │ ├── collection/ # 采集点管理 API
│ │ ├── writepoint/ # 写入点管理 API
│ │ ├── history/ # 历史数据 API
│ │ └── system/ # 系统配置 API
│ ├── service/ # 业务逻辑层
│ │ ├── device/
│ │ ├── collection/
│ │ ├── writepoint/
│ │ ├── history/
│ │ └── collector/ # 采集引擎业务逻辑
│ ├── repository/ # 数据访问层
│ │ ├── postgres/ # PostgreSQL 访问
│ │ └── tdengine/ # TDengine 访问
│ ├── model/ # 数据模型定义
│ │ ├── device.go
│ │ ├── collection_point.go
│ │ ├── write_point.go
│ │ └── history.go
│ ├── engine/ # 运行时引擎
│ │ ├── collector/ # 采集引擎
│ │ │ ├── manager.go # 设备连接管理器
│ │ │ ├── scheduler.go # 采集任务调度器
│ │ │ └── runner.go # 采集点执行单元
│ │ └── writer/ # 写入引擎
│ │ └── writer.go
│ ├── protocol/ # 协议插件化
│ │ ├── driver.go # ProtocolDriver 接口定义
│ │ ├── registry.go # 注册表
│ │ ├── s7/ # S7 协议实现
│ │ └── modbus/ # Modbus TCP 协议实现
│ └── pkg/ # 内部共享工具包
│ ├── config/ # 配置管理
│ ├── logger/ # 日志工具
│ ├── response/ # HTTP 响应统一封装
│ ├── validator/ # 自定义校验器
│ └── csvutil/ # CSV 导入导出工具
├── web/ # 前端代码
│ ├── src/
│ │ ├── api/ # API 调用层
│ │ ├── components/ # 公共组件
│ │ ├── views/ # 页面级组件
│ │ │ ├── device/ # 设备管理
│ │ │ ├── collection/ # 数据采集
│ │ │ ├── write-point/ # 数据写入
│ │ │ └── history/ # 历史数据
│ │ ├── router/ # 前端路由
│ │ ├── store/ # 状态管理
│ │ └── utils/ # 工具函数
│ └── ...
├── deploy/ # 部署相关
├── docs/ # 文档
└── Makefile # 构建脚本
```
### 2.2 模块目录与命名约束
新增模块时,后端在 `internal/` 下各层同步添加子包,前端在 `web/src/views/` 下添加页面目录。
| 模块 | 后端 Go package | 前端目录 | API 路径前缀 |
|------|----------------|----------|-------------|
| 数据管理-设备 | `device` | `device/` | `/api/v1/devices` |
| 数据管理-采集点 | `collection` | `collection/` | `/api/v1/collection-points` |
| 数据管理-写入点 | `writepoint` | `write-point/` | `/api/v1/write-points` |
| 历史数据 | `history` | `history/` | `/api/v1/history` |
### 2.3 依赖管理
- **Go**:使用 `go.mod` 管理依赖,定期执行 `go mod tidy`
- **前端**:使用 `package.json` + `pnpm-lock.yaml`(优先 pnpm,其次 npm
- **禁止**:直接拷贝第三方库源码到项目中(除非 fork 修改,且需在 README 中注明)
- **版本锁定**:提交依赖变更时必须同时提交锁文件;禁止使用不受控的浮动版本
- **最小化引入**:不得为单个小功能引入体积过大或功能重叠的依赖
---
## 3. Go 后端规范
### 3.1 代码风格
- 严格遵循 `gofmt` / `goimports` 格式,不允许任何格式化例外
- 使用 `go vet``golangci-lint` 作为 CI 前置检查
- 每行代码不超过 120 字符
### 3.2 分层架构规范
项目采用经典的三层架构(API Handler → Service → Repository),层间调用规则:
```
Handler (参数校验、请求/响应转换)
Service (业务逻辑、事务管理)
Repository (数据访问、ORM 查询)
禁止:
✗ Handler 直接调用 Repository
✗ Service 层处理 HTTP 请求/响应
✗ 循环依赖(A → B → A
```
#### 3.2.1 Handler 层规范
```go
// ✅ 正确:Handler 只做参数校验和响应转换
func (h *DeviceHandler) Create(c *gin.Context) {
var req CreateDeviceRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "无效的请求参数", err.Error())
return
}
device, err := h.svc.Create(c.Request.Context(), &req)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, device)
}
// ✗ 禁止:Handler 中写业务逻辑或直接操作数据库
```
#### 3.2.2 Service 层规范
```go
// ✅ 正确:Service 层专注业务逻辑
func (s *DeviceService) Create(ctx context.Context, req *CreateDeviceRequest) (*Device, error) {
// 复杂校验放 Service 层
if err := s.validate(req); err != nil {
return nil, err
}
// 调用 Repository
if err := s.repo.Create(ctx, device); err != nil {
return nil, fmt.Errorf("创建设备失败: %w", err)
}
return device, nil
}
```
#### 3.2.3 Repository 层规范
- 使用参数化查询,禁止字符串拼接 SQL
- 显式指定查询字段,禁止 `SELECT *`
- 复杂查询使用 QueryBuilder,避免字符串拼接
- 简单 CRUD 操作统一封装 BaseRepo
### 3.3 错误处理
```go
// 使用自定义错误类型,而非 magic string
var (
ErrDeviceNotFound = errors.New("设备不存在")
ErrDeviceNameConflict = errors.New("设备名称已存在")
)
// 错误包装:始终携带上下文
if err != nil {
return nil, fmt.Errorf("创建采集点失败: %w", err)
}
// 禁止:
// ✗ return errors.New("设备不存在") // 没有上下文
// ✗ return nil, fmt.Errorf("err: %v", err) // "err: " 无意义前缀
```
### 3.4 并发安全
- 采集引擎涉及设备连接池、共享内存状态,必须使用 `sync.Mutex``sync.RWMutex` 保护
- 避免裸 `sync.Map`,优先使用 `map + sync.RWMutex`
- 协程启动必须可控:使用 `context.Context` + `sync.WaitGroup` 管理生命周期
- **禁止无限制启动 goroutine**,必须通过缓冲 channel 或协程池限制并发数
### 3.5 单元测试
| 层级 | 测试策略 | 覆盖率目标 |
|------|---------|-----------|
| Service | 使用 mock repository 进行纯逻辑测试 | ≥ 80% |
| Handler | 使用 httptest 进行 API 测试 | ≥ 60% |
| Repository | 使用 testcontainers 或内嵌数据库 | ≥ 50% |
| Engine | 使用 mock protocol driver 测试采集逻辑 | ≥ 70% |
- 测试文件与源码同目录,命名 `*_test.go`
- Mock 统一使用 `github.com/stretchr/testify/mock``go.uber.org/mock`
- 测试数据使用 `t.Helper()` + `t.Cleanup()` 管理
---
## 4. 前端规范
### 4.1 技术栈约定
| 领域 | 选型 |
|------|------|
| UI 框架 | Vue 3 + Composition API |
| 构建工具 | Vite |
| 状态管理 | Pinia |
| 路由 | Vue Router |
| HTTP 请求 | Axios |
| 图表 | ECharts |
| CSS | Tailwind CSS(或 Less/Sass scoped |
| 代码规范 | ESLint + Prettier |
### 4.2 组件设计规范
```vue
<!-- props emit 使用类型定义 -->
<script setup lang="ts">
interface Props {
deviceId: string
loading?: boolean
}
const props = withDefaults(defineProps<Props>(), {
loading: false
})
const emit = defineEmits<{
(e: 'update', id: string): void
(e: 'delete', id: string): void
}>()
// 组合式函数提取可复用逻辑
const { data, fetchData } = useDeviceDetail(props.deviceId)
</script>
<template>
<div class="device-detail">
<!-- 模板保持简洁复杂条件逻辑使用计算属性 -->
</div>
</template>
<style scoped>
/* 使用 scoped style,避免全局污染 */
</style>
```
### 4.3 API 调用层规范
```typescript
// src/api/device.ts
import request from '@/utils/request'
// 每个模块一个 API 文件,所有请求集中在 api/ 目录
export function fetchDeviceList(params: Record<string, unknown>) {
return request.get('/api/v1/devices', { params })
}
// ✗ 禁止:在组件中直接调用 axios
// ✗ 禁止:URL 路径写在组件内部
```
### 4.4 ECharts 使用规范
- 图表组件统一封装在 `src/components/charts/` 目录下
- ECharts 的 option 构造使用纯函数,方便测试
- 图表容器使用 `ResizeObserver` 自动适应窗口变化
### 4.5 状态管理规范
- 跨组件共享状态使用 Pinia store 统一管理
- 每个 Store 文件职责单一,按业务模块拆分
- 禁止在组件中直接修改非本组件的状态
---
## 5. RESTful API 规范
### 5.1 URL 设计
```
格式:/api/v1/{资源名}[/{资源ID}][/{子资源}][/{动作}]
约定:
- 资源名使用 kebab-case 复数形式(devices, collection-points, write-points
- 批量操作使用 POST,非 GET(避免 URL 过长)
- 版本号 v1 写在路径中
```
### 5.2 响应格式
所有 API 响应使用统一格式:
```json
{
"code": 0,
"message": "success",
"data": { ... }
}
```
| 字段 | 必填 | 说明 |
|------|------|------|
| `code` | 是 | 0 表示成功,非 0 表示业务错误码 |
| `message` | 是 | 人类可读的描述信息 |
| `data` | 否 | 响应数据,可为 null |
### 5.3 分页响应格式
```json
{
"code": 0,
"message": "success",
"data": {
"total": 200,
"page": 1,
"page_size": 20,
"items": [ ... ]
}
}
```
### 5.4 错误码规范
| 错误码范围 | 类别 | 说明 |
|-----------|------|------|
| 0 | 成功 | 请求正常处理 |
| 400xx | 参数错误 | 请求参数校验失败 |
| 401xx | 鉴权错误 | 未登录或 token 过期 |
| 403xx | 权限错误 | 无操作权限 |
| 404xx | 未找到 | 请求的资源不存在 |
| 409xx | 冲突 | 唯一性冲突等 |
| 500xx | 服务端错误 | 内部错误 |
各模块错误码分配:
| 模块 | 范围 |
|------|------|
| 设备管理 | 40001~40999 |
| 采集点管理 | 41001~41999 |
| 写入点管理 | 42001~42999 |
| 历史数据 | 43001~43999 |
| 采集引擎 | 50001~50999 |
| 写入引擎 | 51001~51999 |
### 5.5 路径参数命名规范
```
✅ /api/v1/devices/{id} // 路径参数使用 {param} 风格
✅ /api/v1/collection-points/groups // 固定子路径
查询参数命名(与数据库字段一致):
?page=1&page_size=20&keyword=XXX&enabled=true
```
---
## 6. 数据库规范
### 6.1 PostgreSQL 规范
| 规则 | 说明 |
|------|------|
| 表名 | 全部小写 `snake_case`,复数形式:`devices`, `collection_points`, `write_points` |
| 字段名 | 全部小写 `snake_case` |
| 主键 | 统一使用 `UUID` 类型,默认 `gen_random_uuid()` |
| 时间字段 | `created_at`, `updated_at` 使用 `TIMESTAMP WITH TIME ZONE` |
| 逻辑删除 | 统一使用 `deleted BOOLEAN NOT NULL DEFAULT FALSE` |
| 索引命名 | `idx_{表名}_{字段名}`:如 `idx_devices_name` |
| 唯一索引 | 逻辑删除的表使用 `WHERE deleted = FALSE` 的条件唯一索引 |
| 外键 | 显式声明 `REFERENCES`,但不启用级联(业务层处理级联逻辑) |
| 迁移 | 使用 golang-migrate 或类似工具管理,禁止手动修改库结构 |
```sql
-- ✅ 正确示例
CREATE TABLE devices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(128) NOT NULL,
protocol_type VARCHAR(32) NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
deleted BOOLEAN NOT NULL DEFAULT FALSE,
host VARCHAR(256) NOT NULL,
port INTEGER NOT NULL,
connect_timeout INTEGER NOT NULL DEFAULT 5,
reconnect_interval INTEGER NOT NULL DEFAULT 10,
protocol_config JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
created_by VARCHAR(64),
updated_by VARCHAR(64)
);
CREATE UNIQUE INDEX idx_devices_name ON devices(name) WHERE deleted = FALSE;
```
### 6.2 TDengine 规范
| 规则 | 说明 |
|------|------|
| 表名 | 超级表用 `snake_case``collection_data`, `computed_data` |
| 子表名 | 使用采集点 ID 去连字符后的 32 位小写字符串 |
| 时间戳 | 统一使用 `TIMESTAMP`,精度毫秒 |
| 质量戳 | `INT` 类型:`0=good`, `1=bad` |
| 值 | 统一使用 `DOUBLE`BOOL 类型存 0/1 |
| 标签 | 元数据信息存为 TAGS,不做查询条件的有选择缓存 |
### 6.3 SQL 书写规范
```sql
-- ✅ 关键字大写,字段名/表名小写
SELECT id, name, protocol_type
FROM devices
WHERE enabled = TRUE AND deleted = FALSE
ORDER BY name
LIMIT 20 OFFSET 0;
-- ✗ 禁止:SELECT *,必须显式指定字段列表
-- ✅ INSERT 语句:显式指定列名
INSERT INTO devices (name, protocol_type, host, port, protocol_config)
VALUES ($1, $2, $3, $4, $5)
RETURNING id;
```
### 6.4 数据库连接规范
- 数据库连接参数通过环境变量注入,禁止硬编码在代码中
- 连接 DSN 按 `postgres://USER:PASS@HOST:PORT/DB?sslmode=require` 格式组装
- Go 后端使用连接池,并在应用启动时通过带超时的 `PingContext` 校验连接
- 数据库连接配置仅由 `.env.example` 提供占位符模板,`.env` 文件必须加入 `.gitignore`
---
## 7. 日志与错误处理规范
### 7.1 日志级别
| 级别 | 使用场景 |
|------|---------|
| DEBUG | 调试信息,仅开发环境 |
| INFO | 正常运行信息 |
| WARN | 可恢复的异常 |
| ERROR | 需要关注的错误 |
### 7.2 日志格式规范
```go
// ✅ 正确:采用结构化键值对
logger.Info("设备连接成功",
"device_id", device.ID,
"device_name", device.Name,
)
// ✗ 禁止:没有上下文的日志
// ✗ logger.Info("连接成功")
// ✗ logger.Error("报错了: " + err.Error())
// ✗ fmt.Println() 或 fmt.Errorf() 替代日志库
```
### 7.3 关键业务日志埋点
| 操作 | 日志级别 |
|------|---------|
| 设备创建/修改/删除 | INFO |
| 采集点/写入点创建/修改/删除 | INFO |
| 写入操作 | INFO |
| 采集引擎启停 | INFO |
| 设备连接/断开 | WARN |
| 重连失败 | WARN |
| 协议驱动异常 | ERROR |
---
## 8. 安全规范
### 8.1 SQL 注入防护
```go
// ✅ 正确:使用参数化查询,并显式声明返回字段
db.QueryContext(ctx, "SELECT id, name FROM devices WHERE name = $1", name)
// ✗ 禁止:字符串拼接 SQL
```
### 8.2 输入校验
| 场景 | 校验规则 |
|------|---------|
| IP 地址 | 使用 `net.ParseIP()` 或正则校验合法格式 |
| 端口号 | 范围 1~65535 |
| 时间范围 | 结束时间必须晚于开始时间,最大跨度不超过 31 天 |
| 分页 | page >= 1, page_size <= 100 |
| 文件名 | 导出的 CSV 文件名不含用户输入(防止路径穿越) |
### 8.3 写入安全
- **写入开关校验**:在 Service 层校验 `write_enabled=true`
- **写入来源校验**:校验 `write_source` 与请求 `source` 的匹配关系
- **回读验证**:写入后必须执行回读确认
- **写入权限**:人工写入需登录鉴权;程序自动写入需 API Token
### 8.4 配置安全
- 数据库密码、API Key 等敏感信息通过环境变量注入,**禁止硬编码在代码中**
- `.env` 文件加入 `.gitignore`,仅提供 `.env.example` 占位符模板
- `protocol_config` 中不存储凭据类信息
---
## 9. 代码审核清单
### 9.1 提交流程前置检查(开发者在提审前自行检查)
```
□ 代码通过 gofmt / goimports / eslint / prettier 格式化
□ 本地 go vet 和 ESLint 检查通过
□ 单元测试通过,且覆盖率满足要求
□ 无被注释掉的旧代码
□ 无 console.log / fmt.Println 等调试输出
□ 无硬编码的敏感信息(密码、token、key)
□ 新增能力已复用既有实现或成熟依赖
□ 数据库变更已提供迁移文件
□ 所有 TODO/FIXME 已确认或附带了责任人
```
### 9.2 代码审查 Checklist
#### 架构层面
| 检查项 | 说明 |
|--------|------|
| 模块边界是否清晰 | 是否有 Handler 直接调用其他模块的 Repo |
| 分层是否遵守 | Handler → Service → Repository 单向依赖 |
| 是否引入循环依赖 | 包间依赖不能成环 |
| 扩展点是否留好 | 协议驱动是否遵循 ProtocolDriver 接口 |
#### 功能层面
| 检查项 | 说明 |
|--------|------|
| 边界条件是否处理 | 空列表、分页边界、超长输入、逻辑删除记录等 |
| 并发安全 | 共享状态的读写是否有锁保护 |
| 事务管理 | 跨表操作的 Service 方法是否使用了数据库事务 |
#### 性能层面
| 检查项 | 说明 |
|--------|------|
| N+1 查询 | 列表查询时是否 batch 加载关联数据 |
| 索引 | 新增查询条件是否添加了对应的数据库索引 |
| 分页 | 列表接口是否都有分页,且 page_size 有上限约束 |
| 连接池 | 数据库连接是否使用了连接池 |
#### 安全层面
| 检查项 | 说明 |
|--------|------|
| SQL 注入 | 全库搜索字符串拼接的 SQL 语句 |
| 参数校验 | 所有用户输入是否都通过了校验 |
| 敏感信息泄露 | 错误信息是否直接返回给前端 |
| 路径穿越 | 文件操作的路径是否使用用户输入构造 |
#### 前端层面
| 检查项 | 说明 |
|--------|------|
| API 路径 | 路径是否统一在 `src/api/` 中管理 |
| 组件拆分 | 是否合理拆分为可复用组件 |
| 状态管理 | 跨组件共享状态是否使用 Pinia |
| 错误处理 | API 调用是否有统一的错误处理 |
---
## 附录 A:命名约定
### A.1 Go 模型命名与数据库字段映射
| 数据库表(snake_case | Go 结构体(PascalCase | 说明 |
|----------------------|-----------------------|------|
| `devices` | `Device` | 设备 |
| `collection_points` | `CollectionPoint` | 采集点 |
| `write_points` | `WritePoint` | 写入点 |
| `write_logs` | `WriteLog` | 写入日志 |
Go 结构体字段映射规则:
```go
type Device struct {
ID string `json:"id" db:"id"`
Name string `json:"name" db:"name"`
ProtocolType string `json:"protocol_type" db:"protocol_type"`
Enabled bool `json:"enabled" db:"enabled"`
Deleted bool `json:"-" db:"deleted"` // json:"-" 不返回前端
Host string `json:"host" db:"host"`
Port int `json:"port" db:"port"`
ProtocolConfig json.RawMessage `json:"protocol_config" db:"protocol_config"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
CreatedBy *string `json:"created_by,omitempty" db:"created_by"`
UpdatedBy *string `json:"updated_by,omitempty" db:"updated_by"`
}
```
规则:
- `json:"-"` 标记的字段不返回前端(如 `deleted`
- `omitempty` 用于可空字段
- 请求体结构体以 `Request` 结尾(如 `CreateDeviceRequest`
### A.2 前端目录与路由命名
| 页面 | 路由路径 | 目录 |
|------|---------|------|
| 设备管理 | `/data/device` | `views/device/` |
| 数据采集 | `/data/collection` | `views/collection/` |
| 数据写入 | `/data/write-point` | `views/write-point/` |
| 历史数据 | `/history` | `views/history/` |
---
> 本文档版本:v1.1
> 最后更新:2026-07-11
> 适用范围:污水厂智能控制系统全部后端(Go)、前端(Vue 3)代码
>
> **使用说明**
> 1. 开发者开发新功能前阅读本文档,确保代码风格一致
> 2. 提交 MR/PR 前依据 [第 9 章 代码审核清单](#9-代码审核清单) 逐条自查
> 3. Code Review 时以本文档作为审核标准,不符合规范的要求修改后重新提审
> 4. 本文档随项目推进持续更新,新增模块时补充对应章节