docs(项目文档): 添加项目指南和开发文档

- 添加 AGENTS.md 项目结构和开发指南
- 添加 CLAUDE.md AI辅助开发配置文档
- 更新 .gitignore 忽略 docs 和 .serena 目录
This commit is contained in:
gaoziman 2025-11-18 21:20:10 +08:00
parent 660ab2eb9c
commit 4a6a0c2209
3 changed files with 561 additions and 1 deletions

4
.gitignore vendored
View File

@ -49,3 +49,7 @@ yarn-error.log*
# build output
/dist
/docs/
# IDE and tool configs
.serena/

39
AGENTS.md Normal file
View File

@ -0,0 +1,39 @@
# Repository Guidelines
## 项目结构与模块组织
- `src/` 存放核心前端代码:`pages/` 管理业务页面(登录、用户管理、个人信息),`components/` 复用组件,`api/` 与后端交互封装,`store/` 保存全局设置与标签页状态,`utils/` 管理工具函数,`mock/` 仅在本地调试启用。
- `docs/` 收录 API 对接与集成报告,提交前务必同步更新。
- `dist/``pnpm run build` 产物,禁止手动修改;`.env.*` 提供环境变量,请按需复制调整。
## 构建与开发命令
| 命令 | 说明 |
| ---------------------------------------- | --------------------------------------------------------- |
| `pnpm install` | 安装依赖,项目首选 pnpm若使用 npm需同步更新锁文件。 |
| `pnpm run dev` | 启动 Vite 开发服务器,默认走 `/api` 代理到本地 8080。 |
| `pnpm run build` | 生成产物到 `dist/`,用于联调或上线前校验。 |
| `pnpm run preview` | 以本地静态服务验证构建结果。 |
| `pnpm run eslint` / `pnpm run stylelint` | 校验并自动修复 TS/TSX 与 Less。 |
| `pnpm run pre-commit` | 执行 pretty-quick、ESLint、StylelintPR 前必跑。 |
## 编码风格与命名
- 语法统一使用 TypeScript + React 17 Hooks目录与文件采用小写连字符示例`user-management`)。
- ESLint 继承 `plugin:@typescript-eslint/recommended``plugin:react-hooks/recommended`Prettier 约定 2 空格缩进、单引号、强制分号。
- 样式使用 Less + CSS Modules遵循 `.module.less` 命名Stylelint 规则在 `.stylelintrc` 中定义。
## 测试指引
- 当前仓库尚未集成自动化测试;提交复杂功能时,需给出手工测试步骤,并优先在 `src/__tests__`(或相应页面目录)补充 `*.spec.tsx`
- 覆盖重点:核心表单(登录、用户管理)与 API 适配层,可借助 Jest + @testing-library/react命名遵循 `模块名.行为.spec.tsx`
## 提交与 PR 规范
- Commit 信息遵循 `type(scope): 描述`,与现有记录(如 `feat(布局): ...`、`style(导航栏): ...`)保持一致,描述使用简体中文。
- Pull Request 需包含:变更摘要、关联 Issue/需求编号、截图或命令输出、测试与 lint 结果;若改动 API 或配置,同步更新 `docs/``.env.*` 示例。
## 安全与配置提示
- `.env.development` 默认将 `VITE_API_BASE_URL` 指向 `/api`,生产环境务必更新为真实网关地址,避免调试代理泄漏。
- Mock 入口在 `src/main.tsx` 引入,如需生产构建剔除,可通过环境变量包装 `import './mock'`,防止将虚拟数据发布到线上。

517
CLAUDE.md Normal file
View File

@ -0,0 +1,517 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
---
# React Arco Design Pro 项目指南
## 项目概述
这是一个基于 React 17 + Arco Design + TypeScript + Vite 的企业级中后台管理系统模板项目。项目采用前后端分离架构,使用 Redux 进行状态管理,使用 Mock.js 模拟后端数据。
## 常用命令
### 开发与构建
```bash
# 启动开发服务器(推荐)
npm run dev
# 或
npm start
# 生产环境构建
npm run build
# 预览生产构建
npm run preview
```
### 代码质量检查
```bash
# ESLint 检查并自动修复
npm run eslint
# Stylelint 检查并自动修复
npm run stylelint
# Git 提交前检查(自动执行)
npm run pre-commit
```
**注意**: 建议在 `.eslintrc.js` 中配置规则,禁止在响应码判断时使用严格相等:
```javascript
// 可选:配置 ESLint 规则提醒
rules: {
// 其他规则...
// 在代码审查时人工检查响应码判断逻辑
}
```
### 包管理
项目使用 pnpm 作为包管理器,但 npm/yarn 也兼容。建议使用 pnpm 以保持依赖一致性。
## 核心架构设计
### 技术栈核心
- **构建工具**: Vite 2.6.14(快速 HMR基于 ESM
- **UI 框架**: React 17.0.2
- **UI 组件库**: @arco-design/web-react 2.32.2(字节跳动开源)
- **状态管理**: Redux 4.1.2(传统模式,非 Redux Toolkit
- **路由**: React Router 5.2.0
- **HTTP 客户端**: Axios 0.24.0
- **CSS 预处理**: Less 4.1.2
- **类型系统**: TypeScript 4.5.2strict: false
### 架构分层
```
src/
├── pages/ # 页面组件(按功能模块组织,支持懒加载)
├── components/ # 公共组件NavBar, TabBar, Footer 等)
├── layout.tsx # 主布局组件(侧边栏、标签页、内容区)
├── routes.ts # 路由配置 + 权限过滤逻辑
├── store/ # Redux 状态管理settings, userInfo, tabs
├── utils/ # 工具函数(认证、主题、国际化等)
├── mock/ # Mock.js 数据模拟
├── locale/ # 国际化资源文件
└── main.tsx # 应用入口
```
### 关键架构模式
#### 1. 路由懒加载机制
- 使用 `import.meta.glob()` 动态导入页面组件
- 通过 `@loadable/component` 实现代码分割
- 路由配置在 `src/routes.ts`,约定式路由:`./pages/${route.key}/index.tsx`
#### 2. 权限控制系统
- **路由级权限**: `routes.ts` 中的 `useRoute` Hook 根据用户权限过滤路由
- **组件级权限**: 使用 `<PermissionWrapper>` 组件包裹需要权限控制的元素
- **权限验证**: `utils/authentication.ts` 提供权限判断逻辑
- **角色系统**: 简单的 Admin/User 角色,权限存储在 Redux Store
#### 3. 状态管理架构
Redux Store 管理三类全局状态:
```typescript
// src/store/index.ts
GlobalState {
settings: { // 系统设置(主题色、布局配置)
themeColor,
navbar,
menu,
footer
},
userInfo: { // 用户信息
name,
avatar,
permissions // 权限映射表
},
tabs: { // 多标签页状态
activeKey,
tabs[]
}
}
```
**重要**: Redux 使用传统模式(非 Redux Toolkit所有 Action 通过字符串类型派发。
#### 4. 主题系统
- **主题配置**: `src/settings.json` 定义默认主题色
- **主题切换**: `utils/changeTheme.ts` 切换明暗模式
- **色值计算**: `utils/initThemeColor.ts` 根据主题色自动生成 10 个梯度色
- **Vite 集成**: `vite.config.ts` 通过 `@arco-plugins/vite-react` 注入主题变量
#### 5. 多标签页系统
标签页状态由 Redux 管理,支持:
- 添加/关闭标签页(`tabs/addTab`, `tabs/removeTab`
- 切换标签页(`tabs/setActiveTab`
- 右键菜单操作(关闭左侧/右侧/其他)
标签页与路由联动,在 `layout.tsx` 中实现。
### 数据流设计
```
用户交互 → Component
dispatch Redux Action
Reducer 更新 Store
useSelector 订阅变化
Component 重新渲染
```
HTTP 请求流:
```
Component → axios → Mock.js (开发环境) / Backend API (生产环境) → Component State/Redux
```
### 路径别名配置
```typescript
// 在代码中使用 @/ 代替 src/
import utils from '@/utils/xxx';
```
配置位置:
- `tsconfig.json`: `"@/*": ["src/*"]`
- `vite.config.ts`: `alias: [{ find: '@', replacement: '/src' }]`
## API 开发规范
### 响应码处理规范
**【重要】必须使用宽松相等判断响应码,避免类型不一致问题**
#### 问题背景
后端不同接口可能返回不同类型的响应码:
- 部分接口返回字符串 `"0"`
- 部分接口返回数字 `0`
使用严格相等 `===` 判断时会导致类型不匹配,即使业务成功也会被判断为失败。
#### 强制规范
**1. 在所有业务代码中判断响应码时,必须使用宽松相等 `==`**
```typescript
// ✅ 正确:使用宽松相等
if (result.code == SUCCESS_CODE) {
// 处理成功逻辑
}
if (result.code == 0) {
// 处理成功逻辑
}
// ❌ 错误:使用严格相等
if (result.code === SUCCESS_CODE) {
// 可能导致字符串 "0" !== 数字 0
// 处理成功逻辑
}
```
**2. 响应拦截器中必须使用宽松相等**
`src/utils/request.ts` 响应拦截器中:
```typescript
// ✅ 正确
if (data.code == SUCCESS_CODE) {
return response;
}
// ❌ 错误
if (data.code === SUCCESS_CODE) {
return response;
}
```
**3. 类型守卫函数中必须使用宽松相等**
`src/types/api.ts` 中:
```typescript
// ✅ 正确
export function isSuccessResponse<T>(response: R<T>): boolean {
return response.code == 0;
}
// ❌ 错误
export function isSuccessResponse<T>(response: R<T>): boolean {
return response.code === 0;
}
```
#### 适用范围
以下场景必须遵守此规范:
1. **登录处理** (`src/pages/login/form.tsx`)
2. **用户信息页面** (`src/pages/user-info/index.tsx`)
3. **用户管理页面** (`src/pages/user-management/`)
4. **所有调用后端 API 的业务代码**
5. **所有自定义的响应处理工具函数**
#### 常量定义
`src/constants/index.ts` 中:
```typescript
// 响应码定义为数字类型(推荐)
export const SUCCESS_CODE = 0;
export const ERROR_CODE = 1;
```
#### 检查清单
在编写或修改 API 调用代码时,必须检查:
- [ ] 所有 `result.code === xxx` 改为 `result.code == xxx`
- [ ] 所有 `response.code === xxx` 改为 `response.code == xxx`
- [ ] 响应拦截器使用宽松相等判断
- [ ] 工具函数使用宽松相等判断
#### 历史问题记录
**问题日期**: 2025-11-17
**问题描述**: 登录功能失效,用户管理页面空白
**根本原因**:
- 后端登录接口返回 `code: "0"` (字符串)
- 前端使用 `result.code === 0` (严格相等判断数字)
- 导致 `"0" !== 0`,成功响应被判断为失败
**解决方案**:
1. 将所有 `===` 改为 `==` 进行宽松相等判断
2. 修改了以下文件:
- `src/utils/request.ts`
- `src/pages/login/form.tsx`
- `src/pages/user-info/index.tsx`
- `src/pages/user-management/UserFormModal.tsx`
- `src/pages/user-management/index.tsx`
- `src/types/api.ts`
**预防措施**: 制定本规范文档,在代码审查时强制检查
### API 调用最佳实践
```typescript
// 1. 标准 API 调用模式
async function fetchData() {
try {
const result = await apiFunction(params);
// ✅ 使用宽松相等判断
if (result.code == SUCCESS_CODE) {
// 处理成功逻辑
setData(result.data);
}
// 错误消息已在拦截器中显示,无需额外处理
} catch (error) {
console.error('请求失败:', error);
// 异常已在拦截器中提示,此处仅需记录日志
}
}
// 2. 带加载状态的 API 调用
async function handleSubmit() {
try {
setLoading(true);
const result = await apiFunction(params);
if (result.code == SUCCESS_CODE) {
Message.success('操作成功');
onSuccess();
}
} catch (error) {
console.error('操作失败:', error);
} finally {
setLoading(false);
}
}
```
## 关键开发约定
### 页面组件开发
1. **文件位置**: 所有页面放在 `src/pages/{module-name}/index.tsx`
2. **路由注册**: 在 `src/routes.ts``routes` 数组中添加路由配置
3. **权限控制**: 通过 `requiredPermissions``oneOfPerm` 配置权限
4. **国际化**: 页面标题使用 `locale` 多语言 key
示例:
```typescript
// src/routes.ts
{
name: 'menu.moduleName', // 国际化 key
key: 'module-name', // 对应 pages/module-name/index.tsx
requiredPermissions: [ // 可选:需要的权限
{ resource: 'module', actions: ['read'] }
]
}
```
### Redux 状态操作
```typescript
// 获取状态
import { useSelector } from 'react-redux';
const { userInfo, settings } = useSelector((state: GlobalState) => state);
// 更新状态
import { useDispatch } from 'react-redux';
const dispatch = useDispatch();
dispatch({
type: 'update-userInfo',
payload: { userInfo: newUserInfo },
});
```
### 国际化使用
```typescript
// 在组件中使用国际化
import useLocale from '@/utils/useLocale';
import locale from './locale'; // 本地语言文件
function MyComponent() {
const t = useLocale(locale);
return <div>{t['key.name']}</div>;
}
```
### 主题色动态修改
```typescript
// 修改主题色(自动生成 10 个梯度色 CSS 变量)
import initThemeColor from '@/utils/initThemeColor';
initThemeColor('#026166', false); // (颜色值, 是否暗色模式)
```
## Mock 数据开发
- Mock 文件位置: `src/mock/`
- 使用 Mock.js 拦截 axios 请求
- 在 `src/main.tsx` 中导入: `import './mock'`
- 生产环境需移除 mock 导入
## 已知技术债务
1. **TypeScript 严格模式未开启**: `tsconfig.json``strict: false`,建议开启以提升类型安全
2. **依赖版本较旧**:
- React 17建议升级到 18
- axios 0.24.0(存在安全漏洞,建议立即升级)
- React Router 5建议升级到 v6
3. **缺少测试**: 项目无单元测试和集成测试
4. **Redux 传统模式**: 代码冗长,建议迁移到 Redux Toolkit
5. **安全防护不足**:
- localStorage 明文存储敏感信息
- 缺少 CSRF 防护
- 缺少输入验证和清洗
## 常见问题排查
### API 响应成功但业务逻辑未执行
**症状**:
- API 请求返回成功(控制台显示 `code: "0"``code: 0`
- 但成功回调未执行,数据未更新
- 或登录成功但未跳转
**原因**:
使用了严格相等 `===` 判断响应码,导致字符串 `"0"` 和数字 `0` 类型不匹配
**排查步骤**:
1. 打开浏览器开发者工具的 Network 标签页
2. 查看 API 响应中的 `code` 字段类型(字符串还是数字)
3. 检查业务代码中是否使用了 `result.code === xxx`
4. 将所有 `===` 改为 `==`
**解决方案**:
```typescript
// ❌ 错误写法
if (result.code === SUCCESS_CODE) { ... }
if (result.code === 0) { ... }
// ✅ 正确写法
if (result.code == SUCCESS_CODE) { ... }
if (result.code == 0) { ... }
```
**预防措施**:
- 遵守 [API 开发规范](#api-开发规范) 中的响应码处理规范
- 代码审查时检查所有响应码判断逻辑
### 路由懒加载失败
检查页面组件路径是否符合约定:`src/pages/{route.key}/index.tsx`
### 权限控制不生效
1. 检查 Redux Store 中的 `userInfo.permissions` 是否正确
2. 检查路由配置中的 `requiredPermissions` 格式
3. 检查 `utils/authentication.ts` 的权限判断逻辑
### 主题色不生效
1. 检查 `src/settings.json` 中的 `themeColor` 配置
2. 确保在应用启动时调用了 `initThemeColor()`(位于 `src/main.tsx:64-70`
3. 明暗模式切换时需重新调用 `initThemeColor()`
### Vite 构建失败
1. 检查 TypeScript 类型错误(虽然 noEmit: true但仍需类型正确
2. 检查 Less 语法错误
3. 检查路径别名配置是否正确
## 性能优化建议
- 大数据量表格使用虚拟滚动
- 图片较多时使用懒加载
- 搜索、滚动等高频操作添加防抖节流
- 使用 `rollup-plugin-visualizer` 分析打包产物
## 安全注意事项
- 敏感信息Token、用户数据应加密后再存储到 localStorage
- 所有用户输入需进行验证和清洗
- 生产环境强制使用 HTTPS
- 定期运行 `npm audit` 检查依赖漏洞
## 扩展开发指引
### 添加新页面
1. 创建页面组件: `src/pages/new-page/index.tsx`
2. 添加路由配置: `src/routes.ts`
3. 添加国际化: `src/locale/zh-CN.ts``en-US.ts`
4. 如需权限控制,配置 `requiredPermissions`
### 添加新组件
- 业务组件: `src/pages/{module}/components/`
- 公共组件: `src/components/`
- 组件应包含独立的样式文件(`.module.less`
### 添加新的 Redux 状态
`src/store/index.ts` 中:
1. 扩展 `GlobalState` 接口
2. 更新 `initialState`
3. 在 `reducer` 中添加新的 case
## 参考文档
- [Arco Design 官方文档](https://arco.design/)
- [Vite 官方文档](https://vitejs.dev/)
- [React Router v5 文档](https://v5.reactrouter.com/)