211 lines
9.1 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.

# 代码规范
**分析日期:** 2026-05-07
## 命名规范
**文件命名:**
- 组件文件PascalCase + `.tsx` 扩展名(如 `DashboardShell.tsx``AddOutfitDialog.tsx`
- 工具函数/库文件kebab-case + `.ts` 扩展名(如 `error-handler.ts``client.ts`
- 特殊情况:对话框类组件使用 kebab-case`add-outfit-dialog.tsx``delete-confirmation-dialog.tsx`
**函数命名:**
- 使用 camelCase`handleLogin``fetchOutfits``mapBackendOutfit`
- API 函数:动词 + 名词camelCase`getOutfits``createOutfit``updateOutfit``deleteOutfit`
- 事件处理函数:`handle` + 事件名(如 `handleSubmit``handleChange``handleSendVerificationCode`
- 工具函数:动词 + 目标(如 `formatDate``toDisplayOutfit`
**变量命名:**
- 状态变量camelCase`email``password``isLoading``selectedOutfit`
- 布尔值:`is``has` 前缀(如 `isLoading``isSubmitting``hasPermission`
- 常量UPPER_SNAKE_CASE`TOAST_LIMIT``TOAST_REMOVE_DELAY``API_BASE_URL`
**类型/接口命名:**
- PascalCase`EmailLoginResponse``DashboardShellProps``ApiResponse<T>`
- Props 接口:`组件名Props` 后缀(如 `ButtonProps``DashboardShellProps`
- 联合类型:`RoleName``PermissionModule`
## 代码样式
**格式化:**
- 使用 TypeScript strict 模式(`tsconfig.json``"strict": true`
- 目标ES6`target: "ES6"`
- 模块化解析:`bundler` 模式(用于 Next.js
- 无 ESLint/Prettier 配置文件(`next.config.mjs``eslint.ignoreDuringBuilds: true`
- 代码风格通过 TypeScript 编译器和 Next.js 内置检查
**缩进和空格:**
- 使用 2 空格缩进(根据代码库一致性)
- 函数声明和块语句间使用一致空格
**类型注解:**
- 所有函数参数必须有类型注解
- 所有变量应有类型注解(特别是导出的接口和公共函数返回值)
- 使用 TypeScript 严格模式防止隐式 `any`
## 导入组织
**顺序:**
1. React 和 Next.js 核心库(`import React from "react"``import { useState } from "react"`
2. Next.js 功能(`import { useRouter } from "next/navigation"``import Link from "next/link"`
3. 第三方库(`import axios from "axios"``import Cookies from "js-cookie"`
4. 本项目组件(`import { Button } from "@/components/ui/button"`
5. 本项目库和工具(`import { cn } from "@/lib/utils"`
6. 本项目 hooks`import { useToast } from "@/components/ui/use-toast"`
7. 类型导入(`import type { ApiResponse } from "./client"`
**路径别名:**
- 项目配置 `@/*` 指向项目根目录
- 组件:`@/components/...`
- 库函数:`@/lib/...`
- Hooks`@/hooks/...`
- 类型和接口:通过 `@/lib/api/types` 集中导入
- UI 组件:`@/components/ui/...`
## 错误处理
**模式:**
- 使用 `try-catch` 处理异步操作和 API 调用(见 `auth.ts``outfits.ts`
- 创建自定义错误类 `ApiError` 扩展 `Error`,包含 `status` 属性(见 `error-handler.ts` 第 46-54 行)
- 统一的错误处理函数 `handleApiException()` 将不同类型的错误转换为用户友好的消息(见 `error-handler.ts` 第 79-90 行)
- 错误信息映射表 `errorMessages` 定义特定错误代码(`USER_NOT_FOUND``ROLE_EXISTS` 等)的消息
**API 错误处理:**
- 在 Axios 响应拦截器中处理 401 未授权错误:清除 token 并重定向到登录页面(见 `client.ts` 第 54-61 行)
- 对 API 失败使用 Radix Toast 组件显示错误提示(见 `error-handler.ts` 第 69-76 行、第 93-100 行)
- 统一的 `handleApiRequest()` 包装器函数处理成功/失败情况并自动显示 toast`error-handler.ts` 第 102-144 行)
**日志:**
- 使用 `console.log()``console.warn()``console.error()` 进行调试和错误追踪
- API 请求/响应在拦截器中记录详细日志,包括 token 检查、请求头、响应状态(见 `client.ts` 第 20-66 行)
- 使用 emoji 表情增强日志可读性(`🔍 Token检查``✅ Token已添加``❌ 响应错误`
## 日志记录
**框架:** `console`(浏览器原生)
**使用规范:**
- API 请求/响应日志在 Axios 拦截器中集中管理
- 所有认证流程加日志token 检查、保存、清除)
- 错误信息带上上下文URL、状态码、方法
- 生产环境应考虑减少日志或使用第三方服务(未配置)
## 注释
**何时写注释:**
- JSDoc 风格注释用于公共 API 函数(见 `auth.ts` 第 5-7 行、第 24-30 行)
- 注释解释"为什么"而不是"是什么"
- 复杂业务逻辑或算法需要行内注释
**JSDoc/TSDoc 风格:**
```typescript
/**
* 邮箱登录接口
* @param email 邮箱
* @param password 密码
* @returns 包含token的响应
*/
export const emailLogin = async (email: string, password: string): Promise<EmailLoginResponse> => {
// ...
}
```
**中文注释:** 所有注释使用中文(符合 CLAUDE.md 的语言偏好)
## 函数设计
**大小:**
- 函数长度通常 20-50 行(见 `handleLogin``login/page.tsx` 第 28-63 行)
- 超过 100 行的函数应考虑拆分(如 `AddOutfitDialog` 组件中的多步表单分离为 Tabs
**参数:**
- 单个参数优于多个参数
- 对象参数用于选项(如 `handleApiRequest()` 的 options 对象,第 104-110 行)
- 类型参数用于泛型函数(如 `handleResponse<T>()``ApiResponse<T>`
**返回值:**
- 异步函数返回 `Promise<T>`
- 布尔查询函数返回 `boolean`(如 `hasPermission()``isAuthenticated()`
- 数据获取返回具体类型或 `null`(见 `getOutfit()` 返回 `Promise<Outfit>`
## 模块设计
**导出:**
- 公共 API 函数从 `lib/api/` 模块导出(如 `emailLogin``getOutfits`
- 类型从 `lib/api/types.ts` 集中导出
- Utility 函数从 `lib/utils.ts` 导出(如 `cn()` 用于样式合并)
**Barrel 文件:**
- `lib/api/index.ts` 作为 barrel 文件,导出所有 API 函数以便统一导入
- 组件库采用 Radix UI + shadcn 风格,每个组件文件独立,无 barrel 文件
## React 和组件规范
**状态管理:**
- 使用 React Hooks`useState``useEffect``useCallback`)进行本地状态管理
- 在客户端组件中集中管理表单状态(见 `add-outfit-dialog.tsx` 第 24-36 行)
**组件模式:**
- 所有表单和交互组件用 `"use client"` 指令标记
- Page 组件(`app/*/page.tsx`)使用 `"use client"` 支持交互
- 使用 Radix UI 和 shadcn 风格组件库,组件文件在 `components/ui/`
- Props 接口扩展原生 HTML 属性(如 `ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>`
**样式:**
- 使用 Tailwind CSS 类名
- 使用 `cn()` 工具函数(基于 `clsx` + `tailwind-merge`)合并条件样式(见 `button.tsx` 第 47 行)
- 使用 `class-variance-authority` (CVA) 定义组件变体(见 `button.tsx` 第 7-34 行)
- 颜色、间距、圆角通过 Tailwind 配置变量CSS 变量)定义
## 表单与验证
**表单状态:**
- 使用 `useState` 管理表单字段状态
- 表单提交通过 `handleSubmit()` 函数处理(见 `add-outfit-dialog.tsx` 第 38-56 行)
**验证:**
- 基本的客户端验证(如检查空值:`if (!formData.name || !formData.description)`
- React Hook Form + Zod 在 package.json 中定义但代码中未广泛使用
- 服务器端验证通过 API 响应处理(返回 400/422 等错误状态)
**通知:**
- 成功/错误提示使用 Sonner toast 或 Radix Toast通过 `useToast()` hook
- toast 样式变体:`"default"``"destructive"`(见 `error-handler.ts` 第 71-75 行)
## 权限控制
**权限检查:**
- 运行时权限检查通过 `hasPermission(module)` 函数(见 `permissions.ts` 第 85-87 行)
- 权限矩阵定义在 `PERMISSION_MATRIX` 对象,映射角色到模块列表
- 路由保护:中间件 `middleware.ts` 检查 cookie 中的 token无 token 重定向到登录
- 组件级权限检查:`DashboardShell` 使用 `hasPathPermission()` 处理访问拒绝(见 `dashboard-shell.tsx` 第 23-24 行)
**角色存储:**
- 登录后在 `localStorage` 中存储 `user_role` 字符串(见 `auth.ts` 第 58 行)
- 超级管理员标识存储为 `is_superuser`(见 `auth.ts` 第 53 行)
- token 同时存储在 `localStorage` 和 Cookie 中(见 `auth.ts` 第 49、63 行)
## 异步操作
**模式:**
- 使用 `async/await` 处理异步 API 调用
- 加载状态通过 `isLoading` 布尔值跟踪(见 `login/page.tsx` 第 19、30 行)
- 模拟延迟用于开发和测试(见 `client.ts` `simulateDelay()``mockResponse()` 函数)
## API 集成
**Axios 配置:**
-`lib/api/client.ts` 创建 Axios 实例,基础 URL 来自环境变量 `NEXT_PUBLIC_API_BASE_URL`
- 请求拦截器自动注入 Authorization 头Bearer token
- 响应拦截器处理 401 错误并触发重新登录
- API 端点前缀:`/api/v1/admin/`
**适配器模式:**
- 后端返回数据结构与前端显示结构不同
- 使用 `mapBackendOutfit()` 等适配器函数转换数据(见 `outfits.ts` 第 5-22 行)
- 适配器在 `lib/api/adapters.ts` 中集中管理
---
*规范分析日期2026-05-07*