Files
GrandClaw-prototype/README.md
lanyuanxiaoyao e1a65c1e84 refactor: 优化技能编辑器页面布局 - 三段式设计
- 将两行布局改为三段式布局:技能概览卡片、版本历史卡片、管理操作卡片
- 合并技能概览信息,删除独立的详细信息卡片
- 更新状态标签样式,移除图标,纯文字颜色区分
- 优化技能概览卡片结构:图标、名称行、指标行、标签区、描述
- 分类标签使用蓝色背景突出显示
- 操作按钮重新分组:编辑按钮在概览右上角,上传按钮在版本历史标题旁,删除下架在管理卡片
- 添加完整响应式支持
2026-03-21 14:25:28 +08:00

958 lines
37 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 原型项目
## 项目概述
GrandClaw 是一个企业级AI智能助手平台的前端原型项目主要用于展示平台的主要页面布局、交互流程和视觉设计。项目采用现代化的前端技术栈实现了四大核心模块
- **首页**:平台入口,包含登录功能
- **工作台**用户与AI助手交互的主要界面包含聊天、技能市场、日志查询、定时任务等功能
- **管理台**:运营管理界面,包含总览、部门管理、用户管理、项目管理
- **开发台**:技能开发界面,包含我的技能、技能编辑、开发文档等
## 技术栈
### 核心框架
- **React 19.2.4**UI组件库
- **React Router 7.13.1**路由管理使用HashRouter
- **Vite 8.0.1**:构建工具和开发服务器
### UI与样式
- **react-icons 5.5.0**图标库Feather + FontAwesome图标集
- **Sass 1.98.0**CSS预处理器
- **SCSS模块化**:变量、混入、组件、布局、页面分离
### 构建优化
- **vite-plugin-singlefile 2.3.2**单文件打包解决CORS问题
- **相对路径配置**支持直接打开HTML文件运行
- **注意**:构建时会显示弃用警告 `WARN inlineDynamicImports option is deprecated, please use codeSplitting: false instead.`,这是由 `vite-plugin-singlefile` 插件内部使用弃用选项导致的,不影响功能,可以忽略。
### 包管理
- **pnpm**:高效的包管理器
## 项目结构
```
grandclaw-archtype/
├── dist/ # 构建输出目录单个index.html
├── public/ # 静态资源
├── src/ # 源代码
│ ├── App.jsx # 主路由配置
│ ├── main.jsx # 应用入口
│ ├── components/ # 组件
│ │ ├── layout/ # 布局组件SidebarBrand、SidebarUser、SidebarNavItem
│ │ ├── common/ # 通用UI组件EmptyState、StatusBadge、TagInput、SearchBar
│ │ ├── Layout.jsx # 通用布局组件(侧边栏+主内容)
│ │ └── ListSelector.jsx # 列表选择器组件(支持单选/多选)
│ ├── contexts/ # 全局状态管理
│ │ └── UserContext.jsx # 用户信息上下文
│ ├── hooks/ # 自定义Hook
│ │ ├── useLocalStorage.js # localStorage状态管理Hook
│ │ ├── usePageState.js # 页面状态持久化Hook
│ │ └── useNavigation.js # 导航逻辑Hook
│ ├── constants/ # 常量定义
│ │ ├── pages.js # 页面配置(路由、标题、图标)
│ │ └── storageKeys.js # localStorage键名常量
│ ├── services/ # 数据访问层
│ │ └── api.js # 统一数据访问接口
│ ├── data/ # 模拟数据
│ │ ├── conversations.js # 聊天场景数据
│ │ ├── developerData.js # 开发台数据
│ │ ├── logs.js # 日志数据
│ │ ├── members.js # 成员数据
│ │ ├── skills.js # 技能数据
│ │ ├── tasks.js # 定时任务数据
│ │ └── adminData.js # 管理台数据(部门/用户/项目/总览/日志)
│ ├── pages/ # 页面组件
│ │ ├── HomePage.jsx # 首页
│ │ ├── LoginPage.jsx # 登录页面
│ │ ├── ConsolePage.jsx # 工作台主页面
│ │ ├── AdminPage.jsx # 管理台主页面
│ │ ├── DeveloperPage.jsx # 开发台主页面
│ │ ├── console/ # 工作台子页面
│ │ │ ├── ChatPage.jsx # 聊天页面
│ │ │ ├── SkillsPage.jsx # 技能市场
│ │ │ ├── SkillDetailPage.jsx # 技能详情
│ │ │ ├── LogsPage.jsx # 日志查询
│ │ │ ├── TasksPage.jsx # 定时任务
│ │ │ ├── TaskDetailPage.jsx # 任务详情
│ │ │ ├── AccountPage.jsx # 账号管理
│ │ │ ├── ProjectsPage.jsx # 项目管理
│ │ │ ├── MemberConfigPage.jsx # 成员配置
│ │ │ └── AddMemberPage.jsx # 增加成员
│ │ ├── admin/ # 管理台子页面
│ │ │ ├── OverviewPage.jsx # 运营总览
│ │ │ ├── DepartmentsPage.jsx # 部门管理
│ │ │ ├── AddDepartmentPage.jsx # 新增/编辑部门
│ │ │ ├── UsersPage.jsx # 用户管理
│ │ │ ├── AddUserPage.jsx # 新增/编辑用户
│ │ │ ├── AdminProjectsPage.jsx # 项目管理
│ │ │ ├── AddProjectPage.jsx # 新增/编辑项目
│ │ │ └── AdminLogsPage.jsx # 全局日志查询
│ │ ├── console/ # 工作台子页面
│ │ │ ├── ChatPage.jsx # 聊天页面
│ │ │ ├── SkillsPage.jsx # 技能市场
│ │ │ ├── SkillDetailPage.jsx # 技能详情
│ │ │ ├── LogsPage.jsx # 日志查询
│ │ │ ├── TasksPage.jsx # 定时任务
│ │ │ ├── TaskDetailPage.jsx # 任务详情
│ │ │ ├── AccountPage.jsx # 账号管理
│ │ │ ├── ProjectsPage.jsx # 项目管理
│ │ │ ├── MemberConfigPage.jsx # 成员配置
│ │ │ ├── AddMemberPage.jsx # 增加成员
│ │ │ ├── ConsoleReviewListPage.jsx # 审核管理列表NEW
│ │ │ └── ConsoleReviewDetailPage.jsx # 审核详情NEW
│ │ └── developer/ # 开发台子页面
│ │ ├── DevOverviewPage.jsx # 开发者总览
│ │ ├── MySkillsPage.jsx # 我的技能(筛选+分页)
│ │ ├── SkillEditorPage.jsx # 技能详情(只读+操作)
│ │ ├── UploadSkillPage.jsx # 创建技能(基本信息)
│ │ ├── UpdateSkillInfoPage.jsx # 更新基本信息
│ │ ├── UploadVersionPage.jsx # 上传新版本NEW
│ │ ├── DevDocsPage.jsx # 开发文档
│ │ └── DevAccountPage.jsx # 开发者设置
│ └── styles/ # SCSS样式模块
│ ├── _variables.scss # 设计系统变量
│ ├── _mixins.scss # 可复用混入
│ ├── _base.scss # 基础重置和全局样式
│ ├── _components.scss # 通用组件样式
│ ├── _layout.scss # 布局相关样式
│ ├── _pages.scss # 页面特定样式
│ └── global.scss # 主样式文件,导入所有模块
├── index.html # HTML入口文件
├── package.json # 项目配置和依赖
├── vite.config.js # Vite配置
└── pnpm-lock.yaml # 依赖锁定文件
```
## 开发指南
### 环境要求
- Node.js 18+
- pnpm推荐或 npm
### 安装依赖
```bash
pnpm install
```
### 开发模式
```bash
pnpm dev
# 访问 http://localhost:5173
```
### 构建生产版本
```bash
pnpm build
# 生成 dist/index.html单个HTML文件
```
### 预览生产构建
直接双击 `dist/index.html` 文件,或在浏览器中打开。
## 核心功能
### 1. 首页
- 平台品牌展示
- 导航入口(工作台、开发台、管理台)
- 登录入口
### 2. 登录页面
- 用户名/邮箱登录
- 密码输入
- 验证码(防爆破)
- 记住我功能
- 忘记密码链接
### 3. 工作台Console
- **聊天界面**:支持多种聊天场景(欢迎页、普通对话、技能调用、文件上传)
- **技能市场**:浏览、订阅、查看技能详情(仅展示最新版本)
- **日志查询**:支持按用户、类型、状态筛选
- **定时任务**:管理定时任务,支持启用/禁用,查看任务详情
- **项目管理**:成员列表,增加成员
- **账号管理**:个人信息和密码修改
### 4. 管理台Admin
- **运营总览**:平台运营指标卡片(用户总数、部门数量、项目数量、今日调用)、异常/待办事项提醒、最近操作日志
- **审核管理**版本审核列表与详情、下架审核列表与详情NEW
- **部门管理**:部门列表,支持搜索筛选、新增、编辑、启用/禁用、删除确认
- **用户管理**:用户列表,支持搜索筛选(关键词/部门/状态)、新增、编辑、启用/禁用、删除确认,角色区分(管理员/开发者/成员)
- **项目管理**:项目列表,支持搜索筛选、新增、编辑、启用/禁用、删除确认
- **日志查询**:全局系统日志查询,支持多维度筛选(关键词、用户、部门、类型、状态、时间范围)
### 5. 开发台Developer
- **总览**:开发者指标卡片(我的技能总数、已上架、开发中、待审核)、待审核项目列表、最近动态
- **我的技能**:技能列表,支持关键词搜索、分类筛选、状态筛选(开发中/已上架/下架审核中/已下架)、分页,支持下架(需要先撤回审核中的版本)、删除(已上架需要先下架)
- **技能详情**:基本信息只读展示、版本历史管理(根据状态展示操作按钮:审核中-撤回审核+下载、审核通过/拒绝/撤销-仅下载、审核拒绝-显示拒绝理由)、技能操作(上传新版本-有审核中版本时禁用、下架技能、删除技能-已上架时禁用)
- **创建技能**:基本信息表单 + 技能图标选择(移除技能包上传)
- **更新基本信息**:独立页面编辑技能名称/描述/分类/标签/图标,与版本上传分离
- **上传新版本**仅包含版本说明和技能包上传NEW
- **开发文档**:技能开发相关文档
- **开发者设置**:开发者账号信息
## 路由结构
项目使用 **HashRouter**所有路由基于哈希路径支持直接打开HTML文件运行。
### 主要路由
```
/ # 首页
/login # 登录页面
/console # 工作台
/admin # 管理台
/developer # 开发台
```
### 路由配置App.jsx
```jsx
import { HashRouter as Router, Routes, Route } from 'react-router-dom';
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/console" element={<ConsolePage />} />
<Route path="/admin" element={<AdminPage />} />
<Route path="/developer" element={<DeveloperPage />} />
</Routes>
</Router>
```
## 通用组件
### 布局组件
#### SidebarBrand 品牌区域
侧边栏顶部的品牌展示组件。
```jsx
import { SidebarBrand } from '../components/layout/SidebarBrand.jsx';
<SidebarBrand subtitle="企业级AI平台" />
```
#### SidebarUser 用户信息
侧边栏底部的用户信息展示组件,使用全局用户上下文。
```jsx
import { SidebarUser } from '../components/layout/SidebarUser.jsx';
<SidebarUser
onClick={() => navigate('/account')}
wrapperClassName="sidebar-user"
infoClassName="sidebar-user-info"
nameClassName="sidebar-user-name"
roleClassName="sidebar-user-role"
/>
```
#### SidebarNavItem 导航项
侧边栏导航菜单项组件。
```jsx
import { SidebarNavItem } from '../components/layout/SidebarNavItem.jsx';
<SidebarNavItem
icon={<FiMessageSquare />}
label="智能助手"
active={currentPage === 'chat'}
onClick={() => setCurrentPage('chat')}
itemClassName="sidebar-nav-item"
iconClassName="sidebar-nav-icon"
textClassName="sidebar-nav-text"
/>
```
### 通用UI组件
#### EmptyState 空状态
用于展示空列表或无数据状态的组件。
```jsx
import EmptyState from '../components/common/EmptyState.jsx';
<EmptyState
icon={<FiInbox size={48} />}
title="暂无数据"
description="当前没有可显示的内容"
/>
```
#### Modal 弹窗
用于展示确认操作的弹窗组件,支持自定义标题和内容。
```jsx
import Modal from '../components/common/Modal.jsx';
<Modal
visible={showModal}
title="确认删除"
onConfirm={handleConfirm}
onCancel={handleCancel}
confirmText="删除"
>
确定要删除这个任务吗
</Modal>
```
#### Toast 消息提示
用于展示操作结果的消息提示组件,支持成功、错误、警告、信息四种类型。
```jsx
import Toast from '../components/common/Toast.jsx';
<Toast
visible={showToast}
type="success"
message="操作成功"
onClose={() => setShowToast(false)}
/>
```
**支持的类型:**
- `success` - 成功(绿色)
- `error` - 错误(红色)
- `warning` - 警告(黄色)
- `info` - 信息(蓝色)
#### StatusBadge 状态标签
用于显示状态(成功、失败、警告等)的标签组件。
```jsx
import StatusBadge from '../components/common/StatusBadge.jsx';
<StatusBadge status="success" text="运行中" />
<StatusBadge status="error" text="失败" />
<StatusBadge status="warning" text="警告" />
<StatusBadge status="stopped" text="已停止" />
```
#### TagInput 标签输入
支持输入标签的输入框组件。
```jsx
import TagInput from '../components/common/TagInput.jsx';
<TagInput
tags={tags}
onChange={setTags}
placeholder="输入标签后按回车添加"
/>
```
#### SearchBar 搜索框
通用的搜索输入框组件。
```jsx
import SearchBar from '../components/common/SearchBar.jsx';
<SearchBar
value={searchQuery}
onChange={setSearchQuery}
placeholder="搜索..."
/>
```
### 列表组件
#### ListSelector 列表选择器
通用的列表选择器组件,支持单选和多选模式。
```jsx
import ListSelector from '../components/ListSelector.jsx';
<ListSelector
data={dataList} // 数据数组
selectedIds={selectedIds} // 已选项
onChange={handleChange} // 选择变化回调
searchPlaceholder="搜索..." // 搜索框占位符
columns={columns} // 列配置 [{ key, label }]
multiSelect={false} // 是否多选
selectedLabel="已选标签" // 已选标签文字
onClearSelected={() => {}} // 清除已选回调
/>
```
## 状态管理
### 全局状态
#### UserContext 用户信息上下文
全局用户信息状态,通过 `UserProvider` 提供给整个应用。
```jsx
import { UserProvider, useUserContext } from '../contexts/UserContext.jsx';
// 在 App.jsx 中包裹
<UserProvider user={{ name: '张三', avatar: '张', role: 'AI 产品部' }}>
<App />
</UserProvider>
// 在组件中使用
function Component() {
const { user } = useUserContext();
return <div>{user.name}</div>;
}
```
### 自定义 Hooks
#### usePageState 页面状态持久化
处理页面切换状态的 Hook支持 localStorage 持久化和主页跳转重置。
```javascript
import { usePageState } from '../hooks/usePageState.js';
import { CONSOLE_PAGES } from '../constants/pages.js';
import { CONSOLE_KEYS } from '../constants/storageKeys.js';
const { currentPage, setCurrentPage } = usePageState({
storageKey: CONSOLE_KEYS.CURRENT_PAGE,
defaultPage: 'chat',
pageTitles: CONSOLE_PAGES,
});
```
#### useNavigation 导航逻辑
封装页面导航逻辑的 Hook支持携带额外数据。
```javascript
import { useNavigation } from '../hooks/useNavigation.js';
const { navigateToPage, extraData } = useNavigation(setCurrentPage);
// 导航到指定页面
navigateToPage('skills', { skillId: '1' });
// 获取导航传递的数据
const skillId = extraData.skillId;
```
#### useLocalStorage localStorage 状态管理
同步组件状态到 localStorage 的 Hook。
```javascript
import { useLocalStorage } from '../hooks/useLocalStorage.js';
const [value, setValue] = useLocalStorage('myKey', 'defaultValue');
setValue('newValue'); // 自动同步到 localStorage
```
### 导航状态持久化策略
每个主要页面(工作台、管理台、开发台)都有独立的`localStorage`键:
```javascript
// 工作台
localStorage.setItem('console_currentPage', 'chat');
localStorage.setItem('console_currentScene', 'welcome');
// 管理台
localStorage.setItem('admin_currentPage', 'overview');
// 开发台
localStorage.setItem('developer_currentPage', 'overview');
localStorage.setItem('developer_currentSkillId', '1');
```
### 主页跳转 vs 刷新浏览器
通过`location.state.fromHome`区分两种导航来源:
```javascript
// 从主页跳转:显示默认页面
useEffect(() => {
if (location.state?.fromHome) {
setCurrentPage('chat'); // 默认页面
navigate('.', { replace: true, state: {} }); // 清除state
}
}, [location.state]);
// 刷新浏览器从localStorage恢复
const [currentPage, setCurrentPage] = useState(() => {
return localStorage.getItem('console_currentPage') || 'chat';
});
```
## 样式系统
### SCSS模块化结构
```
src/styles/
├── _variables.scss # 设计系统变量(颜色、间距、阴影等)
├── _mixins.scss # 可复用混入(媒体查询、弹性布局等)
├── _base.scss # 基础重置、CSS变量定义、body样式
├── _components.scss # 通用组件(按钮、卡片、表单、状态标签)
├── _layout.scss # 布局相关(侧边栏、主内容区)
├── _pages.scss # 页面特定样式(首页、管理台等)
└── global.scss # 主文件,导入所有模块
```
### 设计系统变量_variables.scss
```scss
// 品牌主色
$primary: #3B82F6;
$primary-light: #EFF6FF;
$primary-dark: #2563EB;
// 功能色
$success: #10B981;
$warning: #F59E0B;
$danger: #EF4444;
// 中性色
$text-1: #1E293B;
$text-2: #475569;
$text-3: #94A3B8;
// 布局尺寸
$sidebar-width: 240px;
$header-height: 60px;
$radius-md: 8px;
```
### 状态标签样式
支持多种状态标签:
- `status-running` - 成功/运行中(绿色)
- `status-stopped` - 停止/禁用(灰色)
- `status-warning` - 警告(黄色)
- `status-error` - 失败/错误(红色)
### 角色标签样式
- `role-admin` - 管理员(蓝色)
- `role-member` - 成员(灰色)
- `role-developer` - 开发者(橙色)
## 数据访问层
项目使用统一的数据访问接口 `src/services/api.js`,所有数据获取都通过 API 层进行,便于未来对接后端服务。
### API 使用示例
```javascript
import { api } from '../services/api.js';
// 获取技能列表
const skills = api.skills.list();
// 获取单个技能详情
const skill = api.skills.getById('1');
// 获取日志列表
const logs = api.logs.list();
// 按条件筛选日志
const filteredLogs = api.logs.filter({ user, type, status });
// 获取开发者技能
const mySkills = api.developer.getMySkills();
// 获取成员列表
const members = api.members.list();
```
### API 模块结构
- `api.user` - 用户信息
- `api.skills` - 技能市场(列表、详情、文件、版本、图标)
- `api.conversations` - 聊天场景和对话历史
- `api.logs` - 操作日志(列表、筛选)
- `api.developer` - 开发台数据(总览、技能、分类、文档)
- `api.members` - 项目成员
- `api.tasks` - 定时任务
- `api.admin` - 管理台(总览、部门、用户、项目、全局日志)
## 数据模拟
所有数据都存储在 `src/data/` 目录下的JavaScript文件中作为静态模拟数据。API 服务层统一从这些文件读取数据。
### 数据文件说明
- `conversations.js`:聊天场景和对话历史
- `skills.js`技能市场数据包含技能详情含状态dev/published/unlisting/unlisted、文件列表、版本历史含状态reviewing/approved/rejected/withdrawn、拒绝理由、审核列表pendingVersionReviews、pendingUnlistReviews
- `developerData.js`开发台数据包含我的技能含图标、版本审核状态、hasPendingReview标识、技能分类、开发者总览、开发文档
- `logs.js`:操作日志数据(成功/失败/警告状态)
- `tasks.js`:定时任务数据(包含任务配置和执行日志)
- `adminData.js`:管理台数据(部门列表、用户列表、项目列表、总览指标、全局日志、可选项数据)
- `members.js`:项目成员数据
## 构建和部署
### 构建配置vite.config.js
```javascript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { viteSingleFile } from 'vite-plugin-singlefile';
export default defineConfig({
base: './', // 相对路径支持直接打开HTML文件
plugins: [
react(),
viteSingleFile() // 单文件打包
],
});
```
### 构建产物
运行 `pnpm build` 后生成:
- `dist/index.html`包含所有JavaScript和CSS的单个HTML文件
- 支持直接双击打开,无需服务器
- 使用HashRouter路由正常工作
### 部署方式
1. **本地运行**:直接双击 `dist/index.html`
2. **静态服务器**:将 `dist/` 目录部署到任何静态文件服务器
3. **CDN部署**上传单个HTML文件到CDN即可
## 已知问题和注意事项
### 1. 聊天场景渲染
- 聊天内容使用 `dangerouslySetInnerHTML` 渲染HTML字符串
- 深度思考区域支持点击展开/折叠
- 聊天输入框仅为展示,无实际功能
### 2. 浏览器兼容性
- 需要现代浏览器Chrome、Firefox、Safari、Edge
- 不支持IE
- file://协议下可能存在某些限制
### 3. 状态持久化
- 使用localStorage存储子页面状态
- 清除浏览器数据会丢失导航状态
- 不同浏览器标签页共享localStorage
### 4. 性能考虑
- 单个HTML文件较大首次加载可能稍慢
- 所有图标已通过react-icons优化按需加载
- SCSS样式已编译为CSS无运行时开销
### 5. 构建警告
- 构建时会显示弃用警告:`WARN inlineDynamicImports option is deprecated, please use codeSplitting: false instead.`
- 这个警告来自 `vite-plugin-singlefile` 插件内部,无法通过配置消除
- 警告不影响功能,可以安全忽略
## 开发建议
### 添加新页面
1.`src/pages/` 目录下创建页面组件
2. 在父页面组件如ConsolePage、AdminPage中添加路由逻辑
3. 如果需要持久化状态添加localStorage逻辑
4.`src/styles/global.scss` 中添加页面特定样式
### 添加新组件
1.`src/components/` 目录下创建组件
2.`src/styles/global.scss` 中添加组件样式
3. 使用设计系统变量保持一致性
### 修改样式
1. 优先修改 `src/styles/_variables.scss` 中的变量
2. 添加新的混入到 `src/styles/_mixins.scss`
3. 组件样式添加到 `_components.scss`
4. 页面特定样式添加到 `global.scss`
---
## 技能开发流程与审核机制
### 流程概述
技能从创建到上架的完整流程包括:技能创建、版本上传、审核管理、上架销售四个主要环节。
### 状态定义
#### 技能状态
技能有四种状态,表示技能在平台上的可见性和可用性:
| 状态 | 英文 | 描述 | 图标样式 |
|------|------|------|---------|
| 开发中 | `dev` | 技能已创建但尚未有审核通过的版本 | status-stopped (灰色) |
| 已上架 | `published` | 技能有审核通过的版本,可在技能市场展示和订阅 | status-running (绿色) |
| 下架审核中 | `unlisting` | 开发者申请下架,等待管理员审核 | status-warning (黄色) |
| 已下架 | `unlisted` | 技能已下架,不在技能市场展示,可删除 | status-stopped (灰色) |
#### 版本状态
版本有四种状态,表示版本在审核流程中的位置:
| 状态 | 英文 | 描述 | 图标样式 |
|------|------|------|---------|
| 审核中 | `reviewing` | 版本已提交,等待管理员审核 | status-warning (黄色) |
| 审核通过 | `approved` | 版本审核通过,自动生效,技能可上架 | status-running (绿色) |
| 审核拒绝 | `rejected` | 版本审核未通过,需修改后重新提交 | status-error (红色) |
| 已撤销 | `withdrawn` | 开发者主动撤回审核,版本废弃 | status-stopped (灰色) |
### 完整流程
```
┌───────────────────────────────────────────────────────────────────┐
│ 技能开发流程 │
└───────────────────────────────────────────────────────────────────┘
开发者操作 管理员操作 技能市场
──────────── ─────────── ─────────
[1. 创建技能] → 技能: 开发中
↓ (创建后可立即上传版本)
[2. 上传新版本] → 版本: 审核中
│ ──────────────────────────▶ [待审核列表]
↓ │
[3. 提交审核] ↓
│ [4. 审核操作]
├───────────────────────────────────────────────┼───────┐
│ │ │
↓ ↓ ↓
[审核通过] [审核通过] [审核拒绝]
│ │
└───────────────────────────────────────────────┘
技能: 已上架
版本: 审核通过(生效)
───────────────────────────────────────────────────────────▶ [可在技能市场展示]
后续操作:
- [5. 上传新版本] → (需先撤回审核中的版本,一次只能有一个审核中)
- [6. 下架技能] → (需先撤回审核中的版本,下架需管理员审核)
- [7. 删除技能] → (已上架的技能必须先下架)
```
### 关键规则
#### 1. 版本上传规则
- **版本号由后端自动生成**:前端上传时无需填写版本号
- **上传即进入审核**:版本上传后状态自动变为"审核中",没有"草稿"状态
- **一次只能有一个审核中的版本**
- 如果存在审核中的版本,"上传新版本"按钮禁用
- 审核通过或撤回后,才能上传新版本
#### 2. 审核中版本操作
- 可执行操作:撤回审核、下载
- 撤回审核后,版本状态变为"已撤销"(终态),无法继续操作
- 如需重新提交,需上传新版本
#### 3. 技能操作规则
| 技能状态 | 可用操作 | 备注 |
|---------|---------|------|
| 开发中 | 更新基本信息、删除技能 | 未上架,可直接删除 |
| 已上架 | 更新基本信息、下架技能 | 删除按钮禁用(需先下架) |
| 已上架+有审核中版本 | 更新基本信息 | 下架按钮禁用、上传按钮禁用 |
| 下架审核中 | 无(等待管理员审核) | 所有操作按钮禁用 |
| 已下架 | 更新基本信息、删除技能 | 可删除 |
#### 4. 下架流程
- **下架需要管理员审核**
1. 开发者点击"下架技能"
2. 技能状态变为"下架审核中"
3. 管理台"审核管理" -> "下架审核"列表中显示
4. 管理员审核通过/拒绝
5. 通过:技能状态变为"已下架",技能市场移除
6. 拒绝:技能状态回到"已上架"
- **下架期间禁止操作**
- 下架审核中的技能,所有操作按钮禁用
- 不能上传新版本
#### 5. 审核拒绝
- 版本审核拒绝后,在版本说明下方显示拒绝理由
- 被拒绝的版本在技能详情页可见,但无法再次提交审核
- 开发者需上传新版本重新提交
### 数据结构
#### 技能数据skills.js / developerData.js
```javascript
{
id: 1,
name: '代码生成助手',
desc: '根据需求自动生成高质量代码',
tags: ['开发', '代码', 'AI'],
status: 'published', // 技能状态: dev | published | unlisting | unlisted
hasPendingReview: false, // 是否有审核中的版本
category: '开发工具',
versions: [...] // 版本列表
}
```
#### 版本数据
```javascript
{
version: 'v1.3.0',
date: '2026-03-12',
desc: '新增 Python 3.11 支持',
status: 'approved', // 版本状态: reviewing | approved | rejected | withdrawn
rejectionReason: '' // 审核拒绝理由仅status为rejected时
}
```
#### 审核列表数据
```javascript
// 版本审核列表
pendingVersionReviews = [{
id: 1,
skillName: '代码生成助手',
version: 'v1.4.0',
date: '2026-03-20',
developer: '张三'
}]
// 下架审核列表
pendingUnlistReviews = [{
id: 1,
skillName: 'CRM 客户查询',
currentVersion: 'v1.5.0',
date: '2026-03-20',
developer: '赵六'
}]
```
### 页面交互细节
#### 技能详情页SkillEditorPage
**优化后的页面结构(三段式布局):**
```
┌─────────────────────────────────────────────────────────┐
│ 技能编辑页面优化 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 技能概览卡片 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ ┌────┐ 技能名称 [状态] [编辑基本信息] │ │
│ │ │图标│ ─────────────────────────────────────────── │ │
│ │ │80px│ 👤 1,234 ⭐ 4.8 📦 v1.2.0 │ │
│ │ │x80 │ [分类] [标签1] [标签2] [标签3] │ │
│ │ └────┘ 技能描述... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 版本历史卡片 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 版本历史 [上传新版本] │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ 版本号 │ 状态 │ 说明 │ 时间 │ 操作 │ │ │
│ │ │ v1.3.0 │ 通过 │ ... │ ... │ [下载] │ │ │
│ │ │ v1.2.0 │ 拒绝 │ ... │ ... │ [下载] │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 管理操作卡片 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 管理 │ │
│ │ [下架技能] [删除技能] │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
**关键改进:**
1. **三段式布局**:头部概览、版本历史、管理操作三个独立卡片
2. **图标简化**:移除渐变背景,直接显示图标或首字母
3. **信息整合**
- 第一行:技能名称、状态标签、编辑按钮
- 第二行:指标行(图标+数值,无文字说明)
- 第三行:标签区(分类标签在前,蓝色背景区分)
- 第四行:技能描述
4. **操作按钮分组**:编辑操作在右上角,危险操作在底部管理区
5. **上传按钮单一入口**:只在版本历史卡片标题旁显示
6. **状态标签纯文字**:移除图标,通过颜色区分状态
**版本历史表格:**
| 版本号 | 版本说明 | 状态 | 更新时间 | 操作 |
|-------|---------|------|---------|------|
| v1.3.0 | 新增功能... | 审核通过 | 2026-03-12 | [下载] |
| v1.2.0 | 优化性能... | 审核拒绝 | 2026-03-08 | [下载] 拒绝理由: 测试用例不完整 |
| v1.1.0 | 新增支持... | 审核中 | 2026-02-20 | [撤回审核] [下载] |
**技能操作规则:**
- 编辑基本信息:始终可用,位置在概览卡片右上角
- 上传新版本:有审核中版本时禁用,位置在版本历史卡片标题旁
- 下架技能:技能状态为已上架且无审核中版本时可用,位置在管理卡片
- 删除技能:技能状态为开发中或已下架时可用,已上架时禁用,位置在管理卡片
#### 我的技能列表页MySkillsPage
**状态列展示:**
- 开发中:显示"开发中"
- 已上架:显示"已上架"
- 已上架+有审核中版本:显示"已上架 · 审核中"
- 下架审核中:显示"下架审核中"
- 已下架:显示"已下架"
**操作列:**
- 编辑:始终可用
- 下架技能:已上架且无审核中版本时可用
- 删除技能:开发中或已下架时可用
#### 管理台审核管理AdminPage - reviewList
**Tab切换**
- 版本审核:显示待审核的版本列表
- 下架审核:显示待审核的下架申请列表
**版本审核列表:**
| 技能名称 | 版本号 | 提交时间 | 开发者 | 操作 |
|---------|-------|---------|--------|------|
| 代码生成助手 | v1.4.0 | 2026-03-20 | 张三 | [审核] |
**审核详情页reviewDetail**
**版本审核详情:**
- 基本信息:技能名称、开发者、分类、标签
- 版本信息:版本号、提交时间、版本说明
- 文件列表:显示技能包包含的文件
- 操作:[拒绝] [通过]
**下架审核详情:**
- 技能信息:技能名称、开发者、当前版本、订阅数、申请时间
- 操作:[拒绝] [通过]
#### 技能市场详情页SkillDetailPage
**版本展示:**
- 只显示最新审核通过版本的信息
- 不展示完整版本历史
- 示例:
```
当前版本: v1.3.0
更新说明: 新增 Python 3.11 支持
更新时间: 2026-03-12
```
### 状态映射关系
```javascript
// 技能状态映射
const skillStatusMap = {
dev: { text: '开发中', className: 'status-stopped' },
published: { text: '已上架', className: 'status-running' },
unlisting: { text: '下架审核中', className: 'status-warning' },
unlisted: { text: '已下架', className: 'status-stopped' }
};
// 版本状态映射
const versionStatusMap = {
reviewing: { text: '审核中', className: 'status-warning' },
approved: { text: '审核通过', className: 'status-running' },
rejected: { text: '审核拒绝', className: 'status-error' },
withdrawn: { text: '已撤销', className: 'status-stopped' }
};
```
### 注意事项
1. **原型说明**:本页面为静态原型,所有交互均为前端模拟,未连接真实后端
2. **状态持久化**:页面刷新后,状态会重置为初始值
3. **按钮禁用**:使用 HTML 原生 `disabled` 属性,配合 `title` 提示显示禁用原因
4. **Modal 确认**:删除和下架操作需要二次确认,使用 Modal 组件展示确认对话框
5. **Toast 提示**:操作完成后显示 Toast 提示,展示操作结果(成功/失败)
*最后更新2026-03-21*