diff --git a/docs/Dialog.md b/.recycle/2026-01-21/docs/Dialog.md
similarity index 100%
rename from docs/Dialog.md
rename to .recycle/2026-01-21/docs/Dialog.md
diff --git a/docs/OptBtnGroups.md b/.recycle/2026-01-21/docs/OptBtnGroups.md
similarity index 100%
rename from docs/OptBtnGroups.md
rename to .recycle/2026-01-21/docs/OptBtnGroups.md
diff --git a/docs/Toolbar.md b/.recycle/2026-01-21/docs/Toolbar.md
similarity index 100%
rename from docs/Toolbar.md
rename to .recycle/2026-01-21/docs/Toolbar.md
diff --git a/demo/DEPLOY.md b/demo/部署指南.md
similarity index 100%
rename from demo/DEPLOY.md
rename to demo/部署指南.md
diff --git a/docs/AI代码规范模板.md b/docs/AI代码规范模板.md
new file mode 100644
index 0000000..8039c44
--- /dev/null
+++ b/docs/AI代码规范模板.md
@@ -0,0 +1,2024 @@
+# AI 代码规范模板
+
+> 本文档是通用的 AI 协作与代码规范模板,适用于 TypeScript、Java、React、Vue 等技术栈。
+> 使用时请根据项目实际情况进行调整。
+
+---
+
+## 📋 目录
+
+### 第一部分:通用规范
+- [1. AI 协作基本原则](#1-ai-协作基本原则)
+- [2. 通用编码规范](#2-通用编码规范)
+- [3. 文件与文档管理](#3-文件与文档管理)
+
+### 第二部分:语言特定规范
+- [4. TypeScript 规范](#4-typescript-规范)
+- [5. Java 规范](#5-java-规范)
+
+### 第三部分:框架特定规范
+- [6. React 规范](#6-react-规范)
+- [7. Vue 规范](#7-vue-规范)
+
+### 第四部分:工程化规范
+- [8. Git 提交规范](#8-git-提交规范)
+- [9. API 设计规范](#9-api-设计规范)
+- [10. 测试规范](#10-测试规范)
+
+### 附录
+- [附录 A:代码审查清单](#附录-a代码审查清单)
+- [附录 B:常见任务快速参考](#附录-b常见任务快速参考)
+- [附录 C:模板使用说明](#附录-c模板使用说明)
+
+---
+
+# 第一部分:通用规范
+
+## 1. AI 协作基本原则
+
+### 1.1 语言要求(强制)
+
+#### 输出语言
+- **所有输出必须使用中文**,包括:
+ - 代码注释(**强制:所有代码注释必须使用中文,解释清晰详细**)
+ - 文档说明
+ - 与用户交流
+ - 错误信息和日志输出
+
+#### 思考语言
+- **思考过程也必须使用中文**:
+ - 分析问题时用中文思考
+ - 解释代码逻辑时用中文
+ - 讨论设计方案时用中文
+
+#### 代码中的字符串
+- 根据业务需求决定(支持国际化的项目使用翻译键)
+- 注释和文档必须使用中文
+
+### 1.2 思考与沟通方式
+
+#### 思考过程要求
+- 分析问题时,用中文描述问题、分析思路、得出结论
+- 解释代码时,用中文说明逻辑、设计意图、实现方式
+- 讨论方案时,用中文描述优缺点、选择理由
+
+#### 工作流程
+1. **理解需求**:用中文理解用户需求,明确任务目标
+2. **分析问题**:用中文分析问题,梳理相关代码和架构
+3. **设计方案**:用中文设计解决方案,考虑边界情况
+4. **实现代码**:编写代码,添加中文注释
+5. **测试验证**:用中文描述测试结果和发现的问题
+6. **更新文档**:用中文更新相关文档
+
+### 1.3 问答与开发流程
+
+#### 用户询问"如何实现"时的处理流程
+
+**当用户询问如何实现某个功能时,必须遵循以下流程:**
+
+1. **分析需求**:用中文理解用户需求,明确要实现的功能
+
+2. **制定详细开发计划**:必须包含以下内容:
+ - **需要修改的文件列表**
+ - **需要新增的文件列表**
+ - **需要删除的文件列表**
+ - **每个文件的作用说明**
+ - **对整体结构的影响**
+
+3. **展示开发计划**:以清晰的格式展示给用户
+
+4. **等待用户确认**:**在用户明确同意之前,绝对不能修改任何代码**
+
+5. **用户同意后执行**:只有在用户明确表示同意后,才能开始修改代码
+
+#### 开发计划格式模板
+
+```markdown
+## 开发计划
+
+### 需要修改的文件
+1. `src/xxx/xxx.ts`
+ - 修改:添加新的 `xxxMethod()` 方法
+ - 作用:提供某某功能
+
+### 需要新增的文件
+1. `src/xxx/index.ts`
+ - 作用:实现某某功能
+ - 内容:包含 XxxClass 类
+
+### 需要删除的文件
+1. `src/old/xxx.ts`
+ - 原因:已被新组件替代
+ - **处理方式**:移动到 `.recycle/YYYY-MM-DD/` 文件夹
+
+### 对整体结构的影响
+- **架构影响**:说明对现有架构的影响
+- **功能影响**:说明对现有功能的影响
+- **文档更新**:需要更新哪些文档
+- **风险点**:可能的风险和注意事项
+
+请确认是否按照此计划进行开发?
+```
+
+#### 用户直接要求修改时的处理
+
+**当用户直接要求修改代码时**(如"帮我修改XXX"、"实现XXX功能"),可以:
+- 直接执行代码修改
+- 但仍需遵循其他规范
+- 删除文件时仍需移动到回收文件夹
+
+---
+
+## 2. 通用编码规范
+
+### 2.1 代码可读性
+
+#### 基本原则
+- **优先保证代码可读性**,有时可以不使用高级函数,使用低级函数
+- **必须添加详细的中文注释**,解释代码逻辑和设计意图
+- 函数、类、接口必须有文档注释(使用中文)
+- 复杂逻辑必须添加行内注释说明
+
+#### 代码组织
+- 单个文件不宜超过 **500 行**
+- 单个函数不宜超过 **50 行**
+- 单行代码不宜超过 **120 字符**
+- 嵌套层级不宜超过 **4 层**
+
+### 2.2 命名规范
+
+#### 通用命名规则
+
+| 类型 | 命名方式 | 示例 |
+|-----|---------|------|
+| 类名 | 大驼峰 (PascalCase) | `UserManager`, `OrderService` |
+| 接口名 | 大驼峰,可选 `I` 前缀 | `IUserService`, `UserRepository` |
+| 类型/枚举 | 大驼峰 | `UserStatus`, `OrderType` |
+| 函数/方法 | 小驼峰 (camelCase) | `getUserInfo`, `handleSubmit` |
+| 变量 | 小驼峰 | `userName`, `isActive`, `itemCount` |
+| 常量 | 全大写下划线 | `MAX_COUNT`, `API_BASE_URL` |
+| 私有属性 | 下划线前缀或 `#` | `_cache`, `#privateField` |
+| 文件名 | 小写短横线或小写 | `user-manager.ts`, `index.ts` |
+| CSS 类名 | 小写短横线 (kebab-case) | `user-card`, `btn-primary` |
+
+#### 命名语义化
+
+```typescript
+// ✅ 好的命名 - 语义清晰
+const userList: User[] = [];
+const isLoading: boolean = false;
+const maxRetryCount: number = 3;
+function calculateTotalPrice(items: Item[]): number { }
+function validateUserInput(input: string): boolean { }
+
+// ❌ 不好的命名 - 语义不清
+const list: any[] = [];
+const flag: boolean = false;
+const num: number = 3;
+function calc(arr: any[]): number { }
+function check(str: string): boolean { }
+```
+
+#### 布尔值命名
+- 使用 `is`、`has`、`can`、`should`、`will` 等前缀
+- 例如:`isActive`、`hasPermission`、`canEdit`、`shouldUpdate`
+
+#### 函数命名
+- 动词开头,表明行为
+- 查询:`get`、`find`、`query`、`fetch`、`load`
+- 创建:`create`、`add`、`insert`、`save`
+- 更新:`update`、`modify`、`set`、`change`
+- 删除:`delete`、`remove`、`clear`、`reset`
+- 判断:`is`、`has`、`can`、`should`、`validate`、`check`
+- 转换:`to`、`convert`、`parse`、`format`
+- 事件:`handle`、`on`、`trigger`、`emit`
+
+### 2.3 注释规范
+
+#### 文档注释(JSDoc / JavaDoc)
+
+**TypeScript / JavaScript:**
+```typescript
+/**
+ * 计算订单总价
+ *
+ * @description 根据商品列表计算总价,包含折扣计算
+ * @param items - 商品列表
+ * @param discount - 折扣比例(0-1),默认为 1(无折扣)
+ * @returns 计算后的总价
+ * @throws {Error} 当商品列表为空时抛出错误
+ * @example
+ * const total = calculateTotal(items, 0.8); // 8折
+ */
+function calculateTotal(items: CartItem[], discount: number = 1): number {
+ if (items.length === 0) {
+ throw new Error('商品列表不能为空');
+ }
+ // 计算原价总和
+ const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
+ // 应用折扣
+ return subtotal * discount;
+}
+```
+
+**Java:**
+```java
+/**
+ * 计算订单总价
+ *
+ *
根据商品列表计算总价,包含折扣计算
+ *
+ * @param items 商品列表
+ * @param discount 折扣比例(0-1),默认为 1(无折扣)
+ * @return 计算后的总价
+ * @throws IllegalArgumentException 当商品列表为空时抛出
+ * @since 1.0.0
+ * @author AI Assistant
+ */
+public BigDecimal calculateTotal(List items, BigDecimal discount) {
+ // 实现逻辑
+}
+```
+
+#### 行内注释
+```typescript
+// 单行注释:解释接下来一行或几行代码的作用
+
+/*
+ * 多行注释:
+ * 用于解释复杂的逻辑块
+ * 或临时禁用代码
+ */
+
+// TODO: 待完成的功能
+// FIXME: 需要修复的问题
+// HACK: 临时解决方案,需要优化
+// NOTE: 重要说明
+// DEPRECATED: 已废弃,请使用新方法
+```
+
+#### 注释原则
+- **解释为什么,而不是是什么**:代码本身说明做什么,注释说明为什么
+- **保持注释与代码同步**:代码修改后必须更新注释
+- **不要注释显而易见的代码**:避免无意义的注释
+- **复杂业务逻辑必须注释**:特别是涉及特定业务规则的代码
+
+### 2.4 错误处理
+
+#### 基本原则
+- 所有异步操作必须有错误处理
+- 错误信息必须清晰、有意义,使用中文
+- 区分可恢复错误和不可恢复错误
+- 不要吞掉异常(空 catch 块)
+
+#### TypeScript 错误处理
+```typescript
+// ✅ 正确的错误处理
+async function fetchUserData(userId: string): Promise {
+ try {
+ const response = await fetch(`/api/users/${userId}`);
+
+ if (!response.ok) {
+ // 根据状态码抛出具体错误
+ if (response.status === 404) {
+ throw new Error(`用户不存在:${userId}`);
+ }
+ throw new Error(`请求失败:${response.status}`);
+ }
+
+ return await response.json();
+ } catch (error) {
+ // 记录错误日志
+ console.error('获取用户数据失败:', error);
+ // 重新抛出或返回默认值
+ throw error;
+ }
+}
+
+// ❌ 错误的错误处理
+async function badFetch(userId: string) {
+ try {
+ const res = await fetch(`/api/users/${userId}`);
+ return await res.json();
+ } catch (e) {
+ // 空 catch 块,吞掉了错误
+ }
+}
+```
+
+#### Java 错误处理
+```java
+// ✅ 正确的错误处理
+public User getUserById(Long id) {
+ try {
+ return userRepository.findById(id)
+ .orElseThrow(() -> new BusinessException("用户不存在:" + id));
+ } catch (DataAccessException e) {
+ log.error("查询用户失败,ID:{}", id, e);
+ throw new ServiceException("数据库查询异常", e);
+ }
+}
+
+// 自定义业务异常
+public class BusinessException extends RuntimeException {
+ private final String code;
+
+ public BusinessException(String message) {
+ super(message);
+ this.code = "BUSINESS_ERROR";
+ }
+
+ public BusinessException(String code, String message) {
+ super(message);
+ this.code = code;
+ }
+}
+```
+
+### 2.5 日志规范
+
+#### 日志级别
+| 级别 | 使用场景 |
+|-----|---------|
+| `ERROR` | 错误,影响功能正常运行 |
+| `WARN` | 警告,潜在问题但不影响运行 |
+| `INFO` | 重要业务信息,如用户操作、接口调用 |
+| `DEBUG` | 调试信息,开发环境使用 |
+| `TRACE` | 详细追踪信息,极少使用 |
+
+#### 日志内容要求
+```typescript
+// ✅ 好的日志
+logger.info(`用户登录成功,用户ID:${userId},IP:${clientIp}`);
+logger.error(`订单创建失败,订单号:${orderId},原因:${error.message}`, error);
+logger.warn(`库存不足,商品ID:${productId},当前库存:${stock},请求数量:${quantity}`);
+
+// ❌ 不好的日志
+logger.info('success'); // 信息不完整
+logger.error(error); // 缺少上下文
+console.log('here'); // 调试代码未清理
+```
+
+#### 日志原则
+- 包含足够的上下文信息(ID、参数等)
+- 敏感信息脱敏(密码、手机号等)
+- 生产环境不使用 `console.log`
+- 异常日志要包含堆栈信息
+
+### 2.6 安全规范
+
+#### 输入验证
+```typescript
+// ✅ 验证所有外部输入
+function processUserInput(input: unknown): string {
+ // 类型检查
+ if (typeof input !== 'string') {
+ throw new Error('输入必须是字符串');
+ }
+ // 长度检查
+ if (input.length > 1000) {
+ throw new Error('输入长度超出限制');
+ }
+ // 内容清理
+ return sanitize(input);
+}
+```
+
+#### XSS 防护
+```typescript
+// ❌ 危险:直接插入 HTML
+element.innerHTML = userInput;
+
+// ✅ 安全:使用 textContent 或转义
+element.textContent = userInput;
+// 或
+element.innerHTML = escapeHtml(userInput);
+```
+
+#### 敏感数据处理
+```typescript
+// ❌ 不要在日志中输出敏感信息
+console.log(`用户密码:${password}`);
+
+// ✅ 脱敏处理
+console.log(`手机号:${phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')}`);
+```
+
+---
+
+## 3. 文件与文档管理
+
+### 3.1 文件删除规范(强制)
+
+**严禁直接删除文件,必须遵循以下流程:**
+
+#### 步骤 1:创建回收文件夹
+在项目根目录创建 `.recycle/` 文件夹(如果不存在)
+
+#### 步骤 2:按日期组织
+- 在 `.recycle/` 下按日期创建子文件夹
+- 格式:`YYYY-MM-DD`(如 `2024-01-15`)
+- 同一天删除的文件存放在同一个日期文件夹中
+
+#### 步骤 3:移动文件而非删除
+
+```bash
+# ❌ 错误方式
+rm src/old-file.ts
+
+# ✅ 正确方式
+DATE=$(date +%Y-%m-%d)
+mkdir -p .recycle/$DATE/src
+mv src/old-file.ts .recycle/$DATE/src/old-file.ts
+```
+
+#### 步骤 4:保持目录结构
+在日期文件夹中保持原文件的目录结构
+
+例如:`src/components/old.ts` → `.recycle/2024-01-15/src/components/old.ts`
+
+#### 回收文件夹结构示例
+```
+.recycle/
+├── 2024-01-15/
+│ ├── README.md # 可选:记录删除原因
+│ └── src/
+│ └── components/
+│ └── old-component.ts
+└── 2024-02-20/
+ └── src/
+ └── services/
+ └── old-service.ts
+```
+
+### 3.2 文档更新规则
+
+#### 必须更新的情况
+
+| 操作 | 需要更新的文档 |
+|-----|--------------|
+| 新增文件 | 在相关文档中添加文件描述 |
+| 删除文件 | 从文档中移除对应条目 |
+| 修改文件功能 | 更新对应文件的描述 |
+| 新增组件/模块 | 添加说明,创建详细文档 |
+| 修改 API | 同步更新 API 文档 |
+| 修改架构 | 更新架构设计部分 |
+| 修改配置 | 更新配置说明 |
+
+#### 更新方式
+1. 修改代码后,**立即**更新相关文档
+2. 确保文档与代码保持一致
+3. 如果发现文档过时,优先更新文档
+
+---
+
+# 第二部分:语言特定规范
+
+## 4. TypeScript 规范
+
+### 4.1 类型定义规范
+
+#### 优先使用 interface 定义对象类型
+```typescript
+// ✅ 推荐:使用 interface
+interface UserInfo {
+ id: string;
+ name: string;
+ email: string;
+ age?: number; // 可选属性
+ readonly createdAt: Date; // 只读属性
+}
+
+// 接口继承
+interface AdminUser extends UserInfo {
+ role: 'admin';
+ permissions: string[];
+}
+```
+
+#### 使用 type 定义联合类型、交叉类型
+```typescript
+// 联合类型
+type Status = 'pending' | 'processing' | 'completed' | 'failed';
+type ID = string | number;
+
+// 交叉类型
+type UserWithMeta = UserInfo & {
+ metadata: Record;
+};
+
+// 工具类型
+type PartialUser = Partial;
+type RequiredUser = Required;
+type ReadonlyUser = Readonly;
+type UserKeys = keyof UserInfo;
+```
+
+### 4.2 避免 any,使用正确的类型
+
+```typescript
+// ❌ 避免使用 any
+function processData(data: any): any {
+ return data.value;
+}
+
+// ✅ 使用 unknown + 类型守卫
+function processData(data: unknown): string {
+ if (typeof data === 'object' && data !== null && 'value' in data) {
+ return String((data as { value: unknown }).value);
+ }
+ throw new Error('无效的数据格式');
+}
+
+// ✅ 使用泛型
+function processData(data: T): string {
+ return data.value;
+}
+```
+
+### 4.3 泛型使用
+
+```typescript
+// 基础泛型
+function identity(value: T): T {
+ return value;
+}
+
+// 泛型约束
+function getProperty(obj: T, key: K): T[K] {
+ return obj[key];
+}
+
+// 泛型接口
+interface Repository {
+ findById(id: string): Promise;
+ findAll(): Promise;
+ save(entity: T): Promise;
+ delete(id: string): Promise;
+}
+
+// 泛型类
+class BaseService {
+ constructor(private repository: Repository) {}
+
+ async getById(id: string): Promise {
+ return this.repository.findById(id);
+ }
+}
+```
+
+### 4.4 模块导入导出
+
+```typescript
+// ✅ 导入顺序(按此顺序组织)
+// 1. Node.js 内置模块
+import path from 'path';
+import fs from 'fs';
+
+// 2. 第三方库
+import React from 'react';
+import axios from 'axios';
+
+// 3. 项目内部模块 - 绝对路径
+import { UserService } from '@/services/user';
+import { formatDate } from '@/utils/date';
+
+// 4. 项目内部模块 - 相对路径
+import { Button } from '../components/Button';
+import { useAuth } from './hooks/useAuth';
+
+// 5. 类型导入
+import type { User, UserRole } from '@/types';
+
+// 6. 样式文件
+import './styles.css';
+```
+
+```typescript
+// ✅ 导出方式
+// 命名导出 - 推荐用于工具函数、类型等
+export function formatDate(date: Date): string { }
+export interface UserInfo { }
+export const MAX_COUNT = 100;
+
+// 默认导出 - 推荐用于组件、类
+export default class UserService { }
+export default function UserCard() { }
+
+// 重新导出
+export { UserService } from './user-service';
+export * from './types';
+export { default as Button } from './Button';
+```
+
+### 4.5 异步编程
+
+```typescript
+// ✅ 使用 async/await
+async function fetchUserData(userId: string): Promise {
+ try {
+ const response = await fetch(`/api/users/${userId}`);
+ if (!response.ok) {
+ throw new Error(`HTTP error: ${response.status}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error('获取用户数据失败:', error);
+ throw error;
+ }
+}
+
+// ✅ 并行请求
+async function fetchMultipleUsers(ids: string[]): Promise {
+ const promises = ids.map(id => fetchUserData(id));
+ return Promise.all(promises);
+}
+
+// ✅ 带超时的请求
+async function fetchWithTimeout(
+ promise: Promise,
+ timeoutMs: number
+): Promise {
+ const timeout = new Promise((_, reject) => {
+ setTimeout(() => reject(new Error('请求超时')), timeoutMs);
+ });
+ return Promise.race([promise, timeout]);
+}
+```
+
+### 4.6 枚举与常量
+
+```typescript
+// ✅ 字符串枚举 - 推荐
+enum OrderStatus {
+ Pending = 'PENDING',
+ Processing = 'PROCESSING',
+ Completed = 'COMPLETED',
+ Cancelled = 'CANCELLED'
+}
+
+// ✅ const 枚举 - 编译时内联
+const enum Direction {
+ Up = 'UP',
+ Down = 'DOWN',
+ Left = 'LEFT',
+ Right = 'RIGHT'
+}
+
+// ✅ 常量对象 + as const - 更灵活
+const HTTP_STATUS = {
+ OK: 200,
+ CREATED: 201,
+ BAD_REQUEST: 400,
+ UNAUTHORIZED: 401,
+ NOT_FOUND: 404,
+ INTERNAL_ERROR: 500
+} as const;
+
+type HttpStatusCode = typeof HTTP_STATUS[keyof typeof HTTP_STATUS];
+```
+
+---
+
+## 5. Java 规范
+
+### 5.1 包结构与命名
+
+#### 标准包结构
+```
+com.company.project
+├── controller/ # 控制器层
+│ └── UserController.java
+├── service/ # 服务层
+│ ├── UserService.java # 接口
+│ └── impl/
+│ └── UserServiceImpl.java # 实现
+├── repository/ # 数据访问层
+│ └── UserRepository.java
+├── model/ # 数据模型
+│ ├── entity/ # 数据库实体
+│ │ └── User.java
+│ ├── dto/ # 数据传输对象
+│ │ ├── UserDTO.java
+│ │ └── UserCreateRequest.java
+│ └── vo/ # 视图对象
+│ └── UserVO.java
+├── config/ # 配置类
+│ └── WebConfig.java
+├── common/ # 公共模块
+│ ├── exception/ # 异常类
+│ ├── util/ # 工具类
+│ └── constant/ # 常量类
+└── Application.java # 启动类
+```
+
+#### 类命名规范
+
+| 类型 | 命名规则 | 示例 |
+|-----|---------|------|
+| 控制器 | `Xxx Controller` | `UserController` |
+| 服务接口 | `XxxService` | `UserService` |
+| 服务实现 | `XxxServiceImpl` | `UserServiceImpl` |
+| 数据访问 | `XxxRepository` / `XxxMapper` | `UserRepository` |
+| 实体类 | `Xxx` | `User`, `Order` |
+| DTO | `XxxDTO` / `XxxRequest` / `XxxResponse` | `UserDTO` |
+| VO | `XxxVO` | `UserVO` |
+| 工具类 | `XxxUtil` / `XxxUtils` / `XxxHelper` | `DateUtils` |
+| 常量类 | `XxxConstants` | `ApiConstants` |
+| 枚举 | `XxxEnum` / `XxxType` / `XxxStatus` | `OrderStatus` |
+| 异常 | `XxxException` | `BusinessException` |
+
+### 5.2 类设计原则
+
+#### 实体类
+```java
+/**
+ * 用户实体
+ *
+ * @author AI Assistant
+ * @since 1.0.0
+ */
+@Data
+@Entity
+@Table(name = "t_user")
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID
+ */
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ /**
+ * 用户名
+ */
+ @Column(nullable = false, length = 50)
+ private String username;
+
+ /**
+ * 邮箱
+ */
+ @Column(nullable = false, unique = true)
+ private String email;
+
+ /**
+ * 状态:0-禁用,1-启用
+ */
+ private Integer status;
+
+ /**
+ * 创建时间
+ */
+ @CreatedDate
+ private LocalDateTime createdAt;
+
+ /**
+ * 更新时间
+ */
+ @LastModifiedDate
+ private LocalDateTime updatedAt;
+}
+```
+
+#### 服务类
+```java
+/**
+ * 用户服务实现
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class UserServiceImpl implements UserService {
+
+ private final UserRepository userRepository;
+ private final PasswordEncoder passwordEncoder;
+
+ /**
+ * 根据ID获取用户
+ *
+ * @param id 用户ID
+ * @return 用户信息
+ * @throws BusinessException 用户不存在时抛出
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public UserVO getUserById(Long id) {
+ log.info("查询用户信息,ID:{}", id);
+
+ User user = userRepository.findById(id)
+ .orElseThrow(() -> new BusinessException("用户不存在:" + id));
+
+ return convertToVO(user);
+ }
+
+ /**
+ * 创建用户
+ *
+ * @param request 创建请求
+ * @return 用户ID
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createUser(UserCreateRequest request) {
+ log.info("创建用户,用户名:{}", request.getUsername());
+
+ // 检查用户名是否存在
+ if (userRepository.existsByUsername(request.getUsername())) {
+ throw new BusinessException("用户名已存在");
+ }
+
+ // 创建用户实体
+ User user = new User();
+ user.setUsername(request.getUsername());
+ user.setEmail(request.getEmail());
+ user.setPassword(passwordEncoder.encode(request.getPassword()));
+ user.setStatus(1);
+
+ // 保存并返回ID
+ User saved = userRepository.save(user);
+ log.info("用户创建成功,ID:{}", saved.getId());
+
+ return saved.getId();
+ }
+}
+```
+
+### 5.3 异常处理
+
+#### 自定义异常体系
+```java
+/**
+ * 基础业务异常
+ */
+@Getter
+public class BusinessException extends RuntimeException {
+
+ private final String code;
+ private final String message;
+
+ public BusinessException(String message) {
+ super(message);
+ this.code = "BUSINESS_ERROR";
+ this.message = message;
+ }
+
+ public BusinessException(String code, String message) {
+ super(message);
+ this.code = code;
+ this.message = message;
+ }
+}
+
+/**
+ * 全局异常处理器
+ */
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ /**
+ * 处理业务异常
+ */
+ @ExceptionHandler(BusinessException.class)
+ public Result handleBusinessException(BusinessException e) {
+ log.warn("业务异常:{}", e.getMessage());
+ return Result.fail(e.getCode(), e.getMessage());
+ }
+
+ /**
+ * 处理参数校验异常
+ */
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public Result handleValidationException(MethodArgumentNotValidException e) {
+ String message = e.getBindingResult().getFieldErrors().stream()
+ .map(error -> error.getField() + ": " + error.getDefaultMessage())
+ .collect(Collectors.joining(", "));
+ log.warn("参数校验失败:{}", message);
+ return Result.fail("VALIDATION_ERROR", message);
+ }
+
+ /**
+ * 处理未知异常
+ */
+ @ExceptionHandler(Exception.class)
+ public Result handleException(Exception e) {
+ log.error("系统异常:", e);
+ return Result.fail("SYSTEM_ERROR", "系统繁忙,请稍后重试");
+ }
+}
+```
+
+### 5.4 Controller 规范
+
+```java
+/**
+ * 用户管理接口
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/v1/users")
+@RequiredArgsConstructor
+@Tag(name = "用户管理", description = "用户相关接口")
+public class UserController {
+
+ private final UserService userService;
+
+ /**
+ * 获取用户详情
+ *
+ * @param id 用户ID
+ * @return 用户信息
+ */
+ @GetMapping("/{id}")
+ @Operation(summary = "获取用户详情")
+ public Result getUser(@PathVariable Long id) {
+ return Result.success(userService.getUserById(id));
+ }
+
+ /**
+ * 获取用户列表
+ *
+ * @param query 查询条件
+ * @return 用户列表
+ */
+ @GetMapping
+ @Operation(summary = "获取用户列表")
+ public Result> listUsers(@Valid UserQuery query) {
+ return Result.success(userService.listUsers(query));
+ }
+
+ /**
+ * 创建用户
+ *
+ * @param request 创建请求
+ * @return 用户ID
+ */
+ @PostMapping
+ @Operation(summary = "创建用户")
+ public Result createUser(@Valid @RequestBody UserCreateRequest request) {
+ return Result.success(userService.createUser(request));
+ }
+
+ /**
+ * 更新用户
+ *
+ * @param id 用户ID
+ * @param request 更新请求
+ * @return 操作结果
+ */
+ @PutMapping("/{id}")
+ @Operation(summary = "更新用户")
+ public Result updateUser(
+ @PathVariable Long id,
+ @Valid @RequestBody UserUpdateRequest request) {
+ userService.updateUser(id, request);
+ return Result.success();
+ }
+
+ /**
+ * 删除用户
+ *
+ * @param id 用户ID
+ * @return 操作结果
+ */
+ @DeleteMapping("/{id}")
+ @Operation(summary = "删除用户")
+ public Result deleteUser(@PathVariable Long id) {
+ userService.deleteUser(id);
+ return Result.success();
+ }
+}
+```
+
+### 5.5 统一响应格式
+
+```java
+/**
+ * 统一响应结果
+ *
+ * @param 数据类型
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 状态码
+ */
+ private String code;
+
+ /**
+ * 消息
+ */
+ private String message;
+
+ /**
+ * 数据
+ */
+ private T data;
+
+ /**
+ * 时间戳
+ */
+ private long timestamp = System.currentTimeMillis();
+
+ /**
+ * 成功响应
+ */
+ public static Result success(T data) {
+ Result result = new Result<>();
+ result.setCode("SUCCESS");
+ result.setMessage("操作成功");
+ result.setData(data);
+ return result;
+ }
+
+ /**
+ * 成功响应(无数据)
+ */
+ public static Result success() {
+ return success(null);
+ }
+
+ /**
+ * 失败响应
+ */
+ public static Result fail(String code, String message) {
+ Result result = new Result<>();
+ result.setCode(code);
+ result.setMessage(message);
+ return result;
+ }
+}
+```
+
+---
+
+# 第三部分:框架特定规范
+
+## 6. React 规范
+
+### 6.1 组件设计原则
+
+#### 函数组件 + TypeScript
+```tsx
+/**
+ * 用户卡片组件
+ *
+ * @description 展示用户基本信息的卡片组件
+ */
+interface UserCardProps {
+ /** 用户信息 */
+ user: User;
+ /** 是否显示详情 */
+ showDetails?: boolean;
+ /** 编辑回调 */
+ onEdit?: (user: User) => void;
+ /** 删除回调 */
+ onDelete?: (userId: string) => void;
+ /** 子元素 */
+ children?: React.ReactNode;
+}
+
+const UserCard: React.FC = ({
+ user,
+ showDetails = false,
+ onEdit,
+ onDelete,
+ children
+}) => {
+ // 组件逻辑
+ return (
+
+ {/* 组件内容 */}
+
+ );
+};
+
+export default UserCard;
+```
+
+#### 组件文件结构
+```
+components/
+└── UserCard/
+ ├── index.tsx # 组件主文件
+ ├── UserCard.tsx # 组件实现(可选,复杂组件时分离)
+ ├── UserCard.module.css # 样式文件(CSS Modules)
+ ├── UserCard.test.tsx # 测试文件
+ ├── types.ts # 类型定义(复杂时分离)
+ └── hooks.ts # 组件专用 Hooks(可选)
+```
+
+### 6.2 Hooks 使用规范
+
+#### Hooks 使用顺序
+```tsx
+function UserProfile({ userId }: { userId: string }) {
+ // 1. useState - 状态定义
+ const [user, setUser] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ // 2. useRef - 引用
+ const containerRef = useRef(null);
+
+ // 3. useContext - 上下文
+ const { theme } = useContext(ThemeContext);
+
+ // 4. 自定义 Hooks
+ const { data, isLoading } = useQuery(['user', userId], fetchUser);
+
+ // 5. useCallback - 缓存回调
+ const handleEdit = useCallback(() => {
+ // 处理编辑
+ }, [userId]);
+
+ // 6. useMemo - 缓存计算结果
+ const displayName = useMemo(() => {
+ return user ? `${user.firstName} ${user.lastName}` : '';
+ }, [user]);
+
+ // 7. useEffect - 副作用
+ useEffect(() => {
+ // 副作用逻辑
+ return () => {
+ // 清理函数
+ };
+ }, [userId]);
+
+ // 8. 条件渲染和返回
+ if (loading) return ;
+ if (error) return ;
+
+ return {/* 内容 */}
;
+}
+```
+
+#### 自定义 Hook 规范
+```tsx
+/**
+ * 用户数据获取 Hook
+ *
+ * @param userId 用户ID
+ * @returns 用户数据、加载状态、错误信息
+ */
+function useUser(userId: string) {
+ const [user, setUser] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ let cancelled = false;
+
+ async function fetchUser() {
+ try {
+ setLoading(true);
+ setError(null);
+ const data = await userApi.getUser(userId);
+ if (!cancelled) {
+ setUser(data);
+ }
+ } catch (err) {
+ if (!cancelled) {
+ setError(err instanceof Error ? err : new Error('未知错误'));
+ }
+ } finally {
+ if (!cancelled) {
+ setLoading(false);
+ }
+ }
+ }
+
+ fetchUser();
+
+ // 清理函数:防止组件卸载后设置状态
+ return () => {
+ cancelled = true;
+ };
+ }, [userId]);
+
+ return { user, loading, error };
+}
+```
+
+### 6.3 状态管理
+
+#### 本地状态 vs 全局状态
+```tsx
+// ✅ 本地状态:组件内部使用,不需要共享
+const [isOpen, setIsOpen] = useState(false);
+const [inputValue, setInputValue] = useState('');
+
+// ✅ 全局状态:多个组件共享,使用状态管理库
+// 例如:用户信息、主题设置、购物车等
+```
+
+#### 使用 Zustand(推荐)
+```tsx
+import { create } from 'zustand';
+
+/**
+ * 用户状态 Store
+ */
+interface UserStore {
+ user: User | null;
+ isAuthenticated: boolean;
+ login: (user: User) => void;
+ logout: () => void;
+ updateUser: (updates: Partial) => void;
+}
+
+const useUserStore = create((set) => ({
+ user: null,
+ isAuthenticated: false,
+
+ login: (user) => set({ user, isAuthenticated: true }),
+
+ logout: () => set({ user: null, isAuthenticated: false }),
+
+ updateUser: (updates) => set((state) => ({
+ user: state.user ? { ...state.user, ...updates } : null
+ }))
+}));
+
+// 使用
+function UserProfile() {
+ const { user, logout } = useUserStore();
+ // ...
+}
+```
+
+### 6.4 性能优化
+
+```tsx
+// ✅ 使用 React.memo 避免不必要的重渲染
+const UserCard = React.memo(function UserCard({ user }: UserCardProps) {
+ return {user.name}
;
+});
+
+// ✅ 使用 useCallback 缓存回调函数
+const handleClick = useCallback((id: string) => {
+ // 处理点击
+}, [/* 依赖项 */]);
+
+// ✅ 使用 useMemo 缓存计算结果
+const sortedItems = useMemo(() => {
+ return [...items].sort((a, b) => a.name.localeCompare(b.name));
+}, [items]);
+
+// ✅ 列表渲染使用稳定的 key
+{items.map((item) => (
+ // ✅ 使用唯一 ID
+ // // ❌ 避免使用索引
+))}
+
+// ✅ 懒加载组件
+const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
+
+function App() {
+ return (
+ }>
+
+
+ );
+}
+```
+
+---
+
+## 7. Vue 规范
+
+### 7.1 组件设计(Vue 3 Composition API)
+
+#### 单文件组件结构
+```vue
+
+
+
+
+
+
+
+
邮箱:{{ user.email }}
+
电话:{{ user.phone }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 7.2 组合式函数(Composables)
+
+```typescript
+// composables/useUser.ts
+import { ref, computed, watch } from 'vue';
+import type { Ref } from 'vue';
+import type { User } from '@/types';
+import { userApi } from '@/api';
+
+/**
+ * 用户数据组合式函数
+ *
+ * @param userId 用户ID(响应式引用)
+ * @returns 用户数据、加载状态、错误信息、刷新方法
+ */
+export function useUser(userId: Ref | string) {
+ const user = ref(null);
+ const loading = ref(false);
+ const error = ref(null);
+
+ // 获取用户数据
+ async function fetchUser(id: string) {
+ loading.value = true;
+ error.value = null;
+
+ try {
+ user.value = await userApi.getUser(id);
+ } catch (err) {
+ error.value = err instanceof Error ? err : new Error('获取用户失败');
+ user.value = null;
+ } finally {
+ loading.value = false;
+ }
+ }
+
+ // 刷新数据
+ function refresh() {
+ const id = typeof userId === 'string' ? userId : userId.value;
+ return fetchUser(id);
+ }
+
+ // 计算属性
+ const displayName = computed(() => {
+ if (!user.value) return '';
+ return `${user.value.firstName} ${user.value.lastName}`;
+ });
+
+ // 侦听 userId 变化
+ if (typeof userId !== 'string') {
+ watch(userId, (newId) => {
+ if (newId) {
+ fetchUser(newId);
+ }
+ }, { immediate: true });
+ } else {
+ // 立即获取数据
+ fetchUser(userId);
+ }
+
+ return {
+ user,
+ loading,
+ error,
+ displayName,
+ refresh
+ };
+}
+```
+
+### 7.3 Pinia 状态管理
+
+```typescript
+// stores/user.ts
+import { defineStore } from 'pinia';
+import type { User } from '@/types';
+import { userApi } from '@/api';
+
+/**
+ * 用户状态 Store
+ */
+export const useUserStore = defineStore('user', {
+ // 状态
+ state: () => ({
+ currentUser: null as User | null,
+ isAuthenticated: false,
+ loading: false
+ }),
+
+ // 计算属性
+ getters: {
+ /** 用户显示名称 */
+ displayName(): string {
+ if (!this.currentUser) return '游客';
+ return `${this.currentUser.firstName} ${this.currentUser.lastName}`;
+ },
+
+ /** 是否是管理员 */
+ isAdmin(): boolean {
+ return this.currentUser?.role === 'admin';
+ }
+ },
+
+ // 方法
+ actions: {
+ /**
+ * 用户登录
+ */
+ async login(credentials: { username: string; password: string }) {
+ this.loading = true;
+ try {
+ const user = await userApi.login(credentials);
+ this.currentUser = user;
+ this.isAuthenticated = true;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ /**
+ * 用户登出
+ */
+ logout() {
+ this.currentUser = null;
+ this.isAuthenticated = false;
+ },
+
+ /**
+ * 更新用户信息
+ */
+ updateUser(updates: Partial) {
+ if (this.currentUser) {
+ this.currentUser = { ...this.currentUser, ...updates };
+ }
+ }
+ }
+});
+
+// 使用 Setup Store 语法(更灵活)
+export const useUserStore2 = defineStore('user', () => {
+ // 状态
+ const currentUser = ref(null);
+ const isAuthenticated = ref(false);
+
+ // 计算属性
+ const displayName = computed(() => {
+ return currentUser.value?.name ?? '游客';
+ });
+
+ // 方法
+ async function login(credentials: LoginCredentials) {
+ const user = await userApi.login(credentials);
+ currentUser.value = user;
+ isAuthenticated.value = true;
+ }
+
+ function logout() {
+ currentUser.value = null;
+ isAuthenticated.value = false;
+ }
+
+ return {
+ currentUser,
+ isAuthenticated,
+ displayName,
+ login,
+ logout
+ };
+});
+```
+
+---
+
+# 第四部分:工程化规范
+
+## 8. Git 提交规范
+
+### 8.1 提交信息格式
+
+```
+():
+
+
+
+