lanyuanxiaoyao fb9616a10f feat: 实现技能审核全流程 - 新增审核管理模块、技能状态机、版本审核机制
- 新增审核管理页面:版本审核列表、下架审核列表、审核详情页
- 完善技能状态机:开发中/已上架/下架审核中/已下架四种状态
- 实现版本审核机制:审核中/通过/拒绝/撤销四种状态
- 更新 README:详细记录技能开发流程与审核机制
- 优化技能详情页:根据状态展示不同操作按钮
- 完善我的技能列表:状态筛选与操作限制
- 新增上传新版本页面:分离版本上传与基本信息编辑
- 更新 openspec 规范:技能审核流程与状态定义
2026-03-20 17:54:51 +08:00
2026-03-20 09:42:29 +08:00
2026-03-20 09:42:29 +08:00

GrandClaw 原型项目

项目概述

GrandClaw 是一个企业级AI智能助手平台的前端原型项目主要用于展示平台的主要页面布局、交互流程和视觉设计。项目采用现代化的前端技术栈实现了四大核心模块

  • 首页:平台入口,包含登录功能
  • 工作台用户与AI助手交互的主要界面包含聊天、技能市场、日志查询、定时任务等功能
  • 管理台:运营管理界面,包含总览、部门管理、用户管理、项目管理
  • 开发台:技能开发界面,包含我的技能、技能编辑、开发文档等

技术栈

核心框架

  • React 19.2.4UI组件库
  • React Router 7.13.1路由管理使用HashRouter
  • Vite 8.0.1:构建工具和开发服务器

UI与样式

  • react-icons 5.5.0图标库Feather + FontAwesome图标集
  • Sass 1.98.0CSS预处理器
  • 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

安装依赖

pnpm install

开发模式

pnpm dev
# 访问 http://localhost:5173

构建生产版本

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

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 品牌区域

侧边栏顶部的品牌展示组件。

import { SidebarBrand } from '../components/layout/SidebarBrand.jsx';

<SidebarBrand subtitle="企业级AI平台" />

SidebarUser 用户信息

侧边栏底部的用户信息展示组件,使用全局用户上下文。

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 导航项

侧边栏导航菜单项组件。

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 空状态

用于展示空列表或无数据状态的组件。

import EmptyState from '../components/common/EmptyState.jsx';

<EmptyState
  icon={<FiInbox size={48} />}
  title="暂无数据"
  description="当前没有可显示的内容"
/>

Modal 弹窗

用于展示确认操作的弹窗组件,支持自定义标题和内容。

import Modal from '../components/common/Modal.jsx';

<Modal
  visible={showModal}
  title="确认删除"
  onConfirm={handleConfirm}
  onCancel={handleCancel}
  confirmText="删除"
>
  确定要删除这个任务吗
</Modal>

Toast 消息提示

用于展示操作结果的消息提示组件,支持成功、错误、警告、信息四种类型。

import Toast from '../components/common/Toast.jsx';

<Toast
  visible={showToast}
  type="success"
  message="操作成功"
  onClose={() => setShowToast(false)}
/>

支持的类型:

  • success - 成功(绿色)
  • error - 错误(红色)
  • warning - 警告(黄色)
  • info - 信息(蓝色)

StatusBadge 状态标签

用于显示状态(成功、失败、警告等)的标签组件。

import StatusBadge from '../components/common/StatusBadge.jsx';

<StatusBadge status="success" text="运行中" />
<StatusBadge status="error" text="失败" />
<StatusBadge status="warning" text="警告" />
<StatusBadge status="stopped" text="已停止" />

TagInput 标签输入

支持输入标签的输入框组件。

import TagInput from '../components/common/TagInput.jsx';

<TagInput
  tags={tags}
  onChange={setTags}
  placeholder="输入标签后按回车添加"
/>

SearchBar 搜索框

通用的搜索输入框组件。

import SearchBar from '../components/common/SearchBar.jsx';

<SearchBar
  value={searchQuery}
  onChange={setSearchQuery}
  placeholder="搜索..."
/>

列表组件

ListSelector 列表选择器

通用的列表选择器组件,支持单选和多选模式。

import ListSelector from '../components/ListSelector.jsx';

<ListSelector
  data={dataList}              // 数据数组
  selectedIds={selectedIds}     // 已选项
  onChange={handleChange}       // 选择变化回调
  searchPlaceholder="搜索..."   // 搜索框占位符
  columns={columns}             // 列配置 [{ key, label }]
  multiSelect={false}          // 是否多选
  selectedLabel="已选标签"       // 已选标签文字
  onClearSelected={() => {}}   // 清除已选回调
/>

状态管理

全局状态

UserContext 用户信息上下文

全局用户信息状态,通过 UserProvider 提供给整个应用。

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 持久化和主页跳转重置。

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支持携带额外数据。

import { useNavigation } from '../hooks/useNavigation.js';

const { navigateToPage, extraData } = useNavigation(setCurrentPage);

// 导航到指定页面
navigateToPage('skills', { skillId: '1' });

// 获取导航传递的数据
const skillId = extraData.skillId;

useLocalStorage localStorage 状态管理

同步组件状态到 localStorage 的 Hook。

import { useLocalStorage } from '../hooks/useLocalStorage.js';

const [value, setValue] = useLocalStorage('myKey', 'defaultValue');
setValue('newValue'); // 自动同步到 localStorage

导航状态持久化策略

每个主要页面(工作台、管理台、开发台)都有独立的localStorage键:

// 工作台
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区分两种导航来源:

// 从主页跳转:显示默认页面
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

// 品牌主色
$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 使用示例

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

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

{
    id: 1,
    name: '代码生成助手',
    desc: '根据需求自动生成高质量代码',
    tags: ['开发', '代码', 'AI'],
    status: 'published',           // 技能状态: dev | published | unlisting | unlisted
    hasPendingReview: false,       // 是否有审核中的版本
    category: '开发工具',
    versions: [...]               // 版本列表
}

版本数据

{
    version: 'v1.3.0',
    date: '2026-03-12',
    desc: '新增 Python 3.11 支持',
    status: 'approved',           // 版本状态: reviewing | approved | rejected | withdrawn
    rejectionReason: ''           // 审核拒绝理由仅status为rejected时
}

审核列表数据

// 版本审核列表
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

版本历史表格:

版本号 版本说明 状态 更新时间 操作
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
    

状态映射关系

// 技能状态映射
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-20

Description
No description provided
Readme 706 KiB
Languages
JavaScript 79.9%
SCSS 20%