codernew-api-frontend/CLAUDE.md
gaoziman 4a6a0c2209 docs(项目文档): 添加项目指南和开发文档
- 添加 AGENTS.md 项目结构和开发指南
- 添加 CLAUDE.md AI辅助开发配置文档
- 更新 .gitignore 忽略 docs 和 .serena 目录
2025-11-18 21:20:10 +08:00

518 lines
13 KiB
Markdown
Raw Permalink 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.

# 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/)