Files
GrandClaw-prototype/README.md
lanyuanxiaoyao 76d613c4fe docs: 重构开发文档 - 强化统一规范约束
- 核心约束前置:项目性质、语言规范、技术约束
- 统一开发规范:样式BEM命名、组件模板、路由模式
- 新增开发清单:新增功能前检查、代码提交前检查
- 精简文档篇幅:1004行 → 428行,聚焦规范驱动
2026-03-26 15:00:32 +08:00

429 lines
10 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.
# GrandClaw 原型项目
企业级AI智能助手平台前端原型展示主要页面布局、交互流程和视觉设计。
---
## ⚠️ 核心约束(必读)
> 以下约束必须严格遵守,不得违反
### 项目性质
- **纯前端展示原型**无后端交互供内部开发人员参考UI界面
- **目标**:展示页面布局、样式和组件能力
- **交互限制**:允许轻量级交互展示(表单验证、弹框),重叠/覆盖类状态(弹框、下拉)允许简单交互切换
### 语言规范
| 场景 | 语言 |
|------|------|
| 交流、文档、注释、提交信息 | **中文** |
| 代码命名(变量、函数、类、文件) | **英文** |
### 技术约束
| 约束项 | 规则 |
|--------|------|
| UI库 | **禁止引入**使用当前SCSS样式方案 |
| TypeScript | **禁止引入**使用JavaScript |
| ESLint | **禁止引入** |
| 包管理器 | **pnpm**不允许npm、yarn |
| 测试 | **不构建**,使用`pnpm build`验证打包即可 |
| 性能优化 | **不做**保持vite-plugin-singlefile单文件打包 |
| 安全防御 | **不做**eval/dangerouslySetInnerHTML按需使用 |
### 复用优先原则
```
新增代码时优先级:
1. 复用已有样式src/styles
2. 复用已有组件src/components
3. 复用已有页面布局模式
4. 最后才创建新代码
```
### Git提交规范
```
格式: 类型: 简短描述
类型可选:
- feat: 新功能
- fix: 修复
- refactor: 重构
- docs: 文档
- style: 格式
- test: 测试
- chore: 构建/工具
多行描述: 空行后加详细说明
示例:
feat: 添加技能详情页面
- 新增技能详情布局
- 集成版本历史展示
```
---
## 快速开始
```bash
pnpm install # 安装依赖
pnpm build # 验证打包不运行pnpm dev会挂起流程
```
---
## 技术栈
| 技术 | 版本 | 用途 |
|------|------|------|
| React | 19.2.4 | UI框架 |
| React Router (HashRouter) | 7.13.1 | 路由管理 |
| Vite | 8.0.1 | 构建工具 |
| react-icons | 5.5.0 | 图标库 |
| Sass | 1.98.0 | 样式预处理 |
| vite-plugin-singlefile | 2.3.2 | 单文件打包 |
---
## 项目结构
```
src/
├── components/ # 组件库
│ ├── common/ # 通用组件 (Modal, Toast, EmptyState等)
│ ├── layout/ # 布局组件 (SidebarBrand, SidebarUser等)
│ ├── Layout.jsx # 主布局组件
│ └── ListSelector.jsx # 列表选择器
├── contexts/ # 全局状态 (UserContext)
├── hooks/ # 自定义Hook (usePageState, useNavigation)
├── constants/ # 常量配置 (pages, storageKeys)
├── services/ # 数据访问层 (api.js)
├── data/ # 模拟数据
├── pages/ # 页面组件
│ ├── console/ # 工作台子页面
│ ├── admin/ # 管理台子页面
│ └── developer/ # 开发台子页面
├── styles/ # 样式系统(五层架构)
│ ├── tokens/ # 设计令牌(颜色、间距等)
│ ├── core/ # 核心样式重置、CSS变量
│ ├── layouts/ # 布局系统
│ ├── components/ # 组件样式
│ ├── pages/ # 页面样式
│ └── global.scss # 主入口
├── App.jsx # 路由配置
└── main.jsx # 应用入口
```
---
## 核心模块
| 模块 | 路由 | 功能 |
|------|------|------|
| 首页 | `/` | 品牌展示、登录入口 |
| 工作台 | `/console` | 聊天、技能市场、定时任务、项目管理 |
| 管理台 | `/admin` | 部门/用户/项目管理、模型配置 |
| 开发台 | `/developer` | 技能开发、版本管理 |
---
## 样式规范
### 五层架构
```
tokens → core → layouts → components → pages
```
| 层级 | 职责 | 规则 |
|------|------|------|
| tokens/ | 设计令牌 | **禁止硬编码**颜色、间距、字号 |
| core/ | 核心样式 | CSS重置、全局变量 |
| layouts/ | 布局系统 | 页面骨架,不含具体组件 |
| components/ | 组件样式 | 可复用,**BEM命名** |
| pages/ | 页面样式 | 页面独有,不放置可复用样式 |
### BEM命名规范
```scss
// 格式: .block__element--modifier
.card { }
.card__header { }
.card__body { }
.btn--primary { }
.tag--running { }
```
```jsx
// JSX对应
<div className="card">
<div className="card__header">标题</div>
</div>
<button className="btn btn--primary">确认</button>
<span className="tag tag--running">运行中</span>
```
### 引用规则
```scss
// tokens层无依赖
@use 'colors' as *;
// 其他层依赖tokens
@use '../tokens' as *; // core、layouts
@use '../../tokens' as *; // components
@use '../tokens' as *; // pages
```
**禁止跨层引用**如components引用pages
### 按钮规范
| 场景 | 类名 |
|------|------|
| 主操作 | `btn btn--primary` |
| 次要操作 | `btn` |
| 表格内编辑 | `text-btn text-btn-primary` |
| 表格内删除 | `text-btn text-btn-danger` |
| 危险确认 | `btn btn--danger` |
| 警告操作 | `btn btn--warning` |
### 表格操作列规范
```jsx
// 表头
<th className="col-actions">操作</th> // 200px
<th className="col-actions--narrow">操作</th> // 120px
// 单元格
<td className="col-actions">
<div className="table-actions">
<button className="text-btn text-btn-primary">编辑</button>
<button className="text-btn text-btn-danger">删除</button>
</div>
</td>
```
**禁止内联样式定义操作列**
---
## 组件规范
### 新增组件流程
1. 创建 `src/components/{category}/ComponentName.jsx`
2. 创建 `src/styles/components/{name}/_index.scss`
3. 使用 `@use '../../tokens' as *;`
4. 遵循BEM命名
5.`components/_index.scss` 添加 `@forward '{name}';`
### 组件模板
```jsx
// components/common/Example.jsx
function Example({ title, children }) {
return (
<div className="example">
<div className="example__header">{title}</div>
<div className="example__body">{children}</div>
</div>
);
}
export default Example;
```
```scss
// styles/components/example/_index.scss
@use '../../tokens' as *;
.example {
padding: $spacing-4;
&__header {
font-weight: $font-weight-semibold;
color: $text-1;
}
&__body {
color: $text-2;
}
}
```
### 可复用组件
| 组件 | 路径 | 用途 |
|------|------|------|
| Layout | `components/Layout.jsx` | 主布局sidebar+header+main |
| Modal | `components/common/Modal.jsx` | 确认弹窗 |
| Toast | `components/common/Toast.jsx` | 消息提示 |
| EmptyState | `components/common/EmptyState.jsx` | 空状态展示 |
| SearchBar | `components/common/SearchBar.jsx` | 搜索框 |
| StatusBadge | `components/common/StatusBadge.jsx` | 状态标签 |
| SidebarBrand | `components/layout/SidebarBrand.jsx` | 侧边栏品牌 |
| SidebarUser | `components/layout/SidebarUser.jsx` | 侧边栏用户信息 |
| SidebarNavItem | `components/layout/SidebarNavItem.jsx` | 侧边栏导航项 |
---
## 路由规范
### 顶层路由
```jsx
// App.jsx
<HashRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/console" element={<ConsolePage />} />
<Route path="/admin" element={<AdminPage />} />
<Route path="/developer" element={<DeveloperPage />} />
</Routes>
</HashRouter>
```
### 子页面路由
每个主页面内部管理子页面:
```jsx
// ConsolePage.jsx示例
const [currentPage, setCurrentPage] = useState('chat');
const renderPage = () => {
switch (currentPage) {
case 'chat': return <ChatPage />;
case 'skills': return <SkillsPage />;
// ...
}
};
```
### 页面配置
```javascript
// constants/pages.js
export const CONSOLE_PAGES = {
chat: { title: '智能助手', icon: 'FiMessageSquare' },
skills: { title: '技能市场', icon: 'FaPuzzlePiece' },
// ...
};
```
### 新增页面流程
1.`constants/pages.js` 添加页面配置
2. 在父页面组件导入新页面
3.`renderPage()` 添加case分支
4. 添加导航项(如需要)
---
## 状态管理
### 全局状态UserContext
```jsx
// 使用
import { useUserContext } from '../contexts/UserContext.jsx';
function Component() {
const { user } = useUserContext();
return <div>{user.name}</div>;
}
```
### 页面状态持久化
| 模块 | localStorage键 | 默认值 |
|------|---------------|--------|
| 工作台 | `console_currentPage` | `'chat'` |
| 管理台 | `admin_currentPage` | `'overview'` |
| 开发台 | `developer_currentPage` | `'overview'` |
### 自定义Hook
```javascript
// usePageState - 页面状态持久化
const { currentPage, setCurrentPage } = usePageState({
storageKey: CONSOLE_KEYS.CURRENT_PAGE,
defaultPage: 'chat',
pageTitles: CONSOLE_PAGES,
});
// useNavigation - 导航逻辑
const { navigateToPage, extraData } = useNavigation(setCurrentPage);
navigateToPage('skillDetail', { skillId: '1' });
```
---
## 数据访问
所有数据通过 `src/services/api.js` 访问:
```javascript
import api from '../services/api.js';
// 用户
api.user.getInfo();
// 技能
api.skills.list();
api.skills.getById(id);
// 开发台
api.developer.getMySkills();
api.developer.getOverview();
// 管理台
api.admin.departments.list();
api.admin.users.list();
api.admin.modelConfigs.create(data);
// 日志筛选
api.logs.filter({ user, type, status });
```
---
## 开发清单
### 新增功能前检查
- [ ] 是否可复用已有样式?
- [ ] 是否可复用已有组件?
- [ ] 是否可复用已有页面布局模式?
### 代码提交前检查
- [ ] 类名是否遵循BEM
- [ ] 颜色/间距是否使用tokens变量
- [ ] 表格操作列是否使用规范类名?
- [ ] `pnpm build` 是否通过?
- [ ] 文档注释是否使用中文?
- [ ] 变量/函数命名是否使用英文?
---
## 已知问题
| 问题 | 说明 | 处理 |
|------|------|------|
| 构建警告 | `inlineDynamicImports is deprecated` | 来自vite-plugin-singlefile可忽略 |
| 浏览器兼容 | 不支持IE | 使用现代浏览器 |
---
*最后更新2026-03-26*