# 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对应
运行中
```
### 引用规则
```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
// 表头
操作 | // 200px
操作 | // 120px
// 单元格
|
```
**禁止内联样式定义操作列**
---
## 组件规范
### 新增组件流程
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 (
);
}
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
} />
} />
} />
} />
```
### 子页面路由
每个主页面内部管理子页面:
```jsx
// ConsolePage.jsx示例
const [currentPage, setCurrentPage] = useState('chat');
const renderPage = () => {
switch (currentPage) {
case 'chat': return ;
case 'skills': return ;
// ...
}
};
```
### 页面配置
```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 {user.name}
;
}
```
### 页面状态持久化
| 模块 | 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*