logo
0
0
WeChat Login

SMH-UI — 腾讯云智能媒体托管Demo

基于腾讯云 SMH(智能媒体托管)服务构建的全栈管理系统,包含三个子项目:

子项目类型说明
serverDemo后端服务示例,演示如何签发 Token、管理空间和配额,接入方需参考此示例实现自己的后端
clientDemo管理后台示例,演示如何集成 uikit UI Kit,接入方可参考此示例了解接入方式
uikitUIKit(核心产物)云盘文件管理组件库,可通过 npm install 直接安装到你的项目中使用

serverclient接入参考 Demo,不是最终产物;uikit可独立发布和安装的 UIKit,是本仓库的核心输出。

完整启动步骤

# 如果没有安装三个项目的依赖 则需要先安装依赖 cd uikit && npm install && cd .. cd demo/server && npm install && cd ../.. cd demo/client && npm install && cd ../.. # 1. 启动后端服务 cd demo/server && npm run dev # 2. 打包 uikit cd uikit && npm run build:lib # 3. 启动 用户管理二合一端 cd demo/client && npm run dev

项目架构

SMH-UI/ ├── demo/ │ ├── client/ # 管理后台 Demo(React + TDesign) │ └── server/ # 后端服务 Demo(Express + smh-node-sdk) └── uikit/ # 云盘 UIKit(React 组件库)
┌─────────────────────────────────────────────────────┐ │ client (5174) │ │ 管理后台 · React + TDesign │ │ │ │ ┌─────────────┐ ┌──────────────────────────────┐ │ │ │ 租户管理 │ │ uikit (UIKit) │ │ │ │ 配额管理 │ │ 云盘文件浏览/上传/下载 │ │ │ │ 踢下线/恢复 │ │ 以 Drawer 形式嵌入 │ │ │ └──────┬──────┘ └──────────┬───────────────────┘ │ │ │ │ │ └─────────┼────────────────────┼───────────────────────┘ │ /api/* │ SMH API (直连) ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ server (3001) │ │ 腾讯云 SMH 服务 │ │ Express 后端 │──▶│ 文件存储 API │ │ smh-node-sdk │ └──────────────────┘ └──────────────────┘

三个项目的功能分工

📦 server — 后端服务

职责说明
管理员认证JWT 登录/登出,Cookie 会话管理
租户管理创建/删除空间、查询租户列表
配额管理查询/修改空间存储配额
Token 签发为前端生成 SMH accessToken(library_secret 仅后端持有)
踢下线/恢复吊销/恢复指定空间的访问权限
用户绑定管理 spaceId 与 userId 的绑定关系

技术栈:Express + cookie-parser + jsonwebtoken + smh-node-sdk

核心文件

  • src/app.js — 服务入口
  • src/routes/admin.js — 管理端 API 路由
  • src/routes/space.js — Token 吊销存储 & spaceId-userId 绑定
  • src/services/smh/ — SMH SDK 封装层
  • src/config/index.js — 环境变量配置

🖥️ client — 管理后台

职责说明
登录页管理员账号密码登录(默认 admin/admin)
仪表盘租户列表、统计概览、搜索过滤
租户操作创建租户、删除租户、绑定/解绑用户
配额管理查看/修改每个租户的存储配额
云盘预览以抽屉方式打开任意租户的云盘,浏览/管理文件
踢下线/恢复禁用/恢复租户的访问权限

技术栈:React 18 + React Router + TDesign + Tailwind CSS + Vite

核心文件

  • src/pages/Login.jsx — 登录页
  • src/pages/Dashboard.jsx — 主仪表盘(租户管理 + 云盘入口)
  • src/styles/globals.css — 全局样式

💾 uikit — 云盘 UIKit

职责说明
文件浏览目录树导航、列表/网格视图
文件操作上传、下载、删除、重命名、移动、复制
Token 管理自动续期、过期检测、并发保护
可嵌入组件作为 npm 包被 client 或其他项目引用

技术栈:React 18 + TDesign + Tailwind CSS + smh-js-sdk

核心文件

  • src/index.js — 库入口,导出 SpaceDrive 组件和工具函数
  • src/pages/SpaceDrive.jsx — 顶层云盘组件
  • src/components/cloudFile/file.jsx — 文件管理核心组件
  • src/services/request.js — Token 管理与自动续期
  • src/services/smh.js — SMH API 调用封装

两种运行模式

  • 独立开发模式npm run dev,端口 5177,可独立调试
  • 库构建模式npm run build:lib,打包为 ES Module,供 client 项目引用

快速启动

1. 环境要求

  • Node.js >= 18
  • npm >= 9
  • 腾讯云 SMH 服务已开通,拥有 LIBRARY_IDLIBRARY_SECRET

2. 核心 SDK 依赖

本项目依赖腾讯云 SMH 官方提供的两个 SDK,分别用于服务端和客户端:

smh-node-sdk(服务端)

项目说明
使用方server
版本要求^1.0.0
用途服务端调用 SMH API,管理令牌、空间、配额、使用量等
安装npm install smh-node-sdk

核心能力:

  • Token 管理smh.token.createToken():签发 admin / space_admin 级别的 accessToken
  • 空间管理smh.space.listSpace() / createSpace() / deleteSpace():租户空间的增删查
  • 配额管理smh.quota.getQuota() / createQuota() / updateQuota():存储配额的查询与设置
  • 使用量统计smh.usage.getUsage():获取空间容量使用情况

使用示例:

const { SMHClient } = require('smh-node-sdk') const smh = new SMHClient({ basePath: 'https://smhxxx.api.tencentsmh.cn' }) smh.setDefaultLibraryId('smhxxx-xxxxx') // 签发 admin token const tokenData = await smh.token.createToken({ libraryId: 'smhxxx-xxxxx', librarySecret: 'your_secret', grant: 'admin', period: 3000, })

smh-js-sdk(客户端)

项目说明
使用方uikit
版本要求^1.0.5
用途前端直连 SMH API,完成文件浏览、上传、下载、删除等操作
安装npm install smh-js-sdk

核心能力:

  • 目录操作client.directory.listDirectoryByPage() / createDirectory() / deleteDirectory():文件列表、创建/删除目录
  • 文件操作client.file.deleteFile() / infoFile():文件删除、获取文件信息
  • 文件上传client.createUploadTask():支持分片上传、断点续传、秒传检测,提供进度回调
  • 使用量统计client.usage.getUsage():获取当前空间的配额和使用量

使用示例:

import { SMHClient, TaskStatus } from 'smh-js-sdk' const client = new SMHClient({ basePath: 'https://smhxxx.api.tencentsmh.cn', libraryId: 'smhxxx-xxxxx', spaceId: 'spaceyyy', accessToken: 'your_access_token', }) // 获取文件列表 const res = await client.directory.listDirectoryByPage({ filePath: '', byPage: 1, page: 1, pageSize: 100, }) // 上传文件(支持分片、断点续传) const uploader = client.createUploadTask({ filePath: 'docs/hello.txt', file: fileObject, conflictResolutionStrategy: 'overwrite', onStateChange: (checkpoint, state, error) => { if (state === TaskStatus.SUCCESS) console.log('上传成功') }, onProgress: (info) => console.log(`进度: ${Math.floor(info.progress * 100)}%`), }) uploader.start()

两个 SDK 的分工关系

┌──────────────────────────────────────────────────────────┐ │ 浏览器 (前端) │ │ │ │ uikit 使用 smh-js-sdk 直连 SMH API │ │ ├── 文件浏览、上传、下载、删除、重命名、移动 │ │ └── 前端持有 accessToken(由后端签发,不含 secret) │ │ │ └──────────────────────────┬───────────────────────────────┘ │ 获取 accessToken ▼ ┌──────────────────────────────────────────────────────────┐ │ Node.js 服务端 (后端) │ │ │ │ server 使用 smh-node-sdk 调用 SMH 管理 API │ │ ├── 签发 accessToken(需要 library_secret,仅后端持有) │ │ ├── 空间管理(创建/删除租户) │ │ ├── 配额管理(查询/修改存储上限) │ │ └── 使用量统计 │ │ │ └──────────────────────────────────────────────────────────┘

⚠️ 安全原则library_secret 仅存在于服务端,前端通过后端签发的 accessToken 访问 SMH API,永远不会接触到密钥。

3. 配置环境变量

cd demo/server cp .env.example .env

编辑 demo/server/.env,填入实际的 SMH 配置:

# SMH 智能媒体托管 LIBRARY_ID=smhxxx-xxxxx # 媒体库 ID LIBRARY_SECRET=your_secret # 媒体库密钥(重要,不要泄露) SMH_HOST=https://smhxxx-xxxxx.api.tencentsmh.cn # SMH API 地址 # JWT JWT_SECRET=your_jwt_secret # JWT 签名密钥,生产环境请使用强随机字符串 # 服务端口 PORT=3001 # 前端地址(用于 CORS) CLIENT_ORIGIN=http://localhost:5173 ADMIN_ORIGIN=http://localhost:5174

4. 安装依赖

# 安装三个项目的依赖 cd demo/server && npm install && cd ../.. cd uikit && npm install && cd .. cd demo/client && npm install && cd ../..

5. 构建 uikit

admin 引用的是 uikit 的打包产物,首次使用或 uikit 源码变更后,需要先构建:

cd uikit npm run build:lib cd ..

⚠️ 每次修改 uikit 源码后,都需要重新执行 npm run build:lib,admin 才能获取到最新的组件。

6. 启动服务

需要同时启动 serverclient 两个服务(uikit 作为 npm 包被 client 引用其打包产物,无需单独启动):

# 终端 1:启动后端服务(端口 3001) cd demo/server npm run dev # 终端 2:启动管理后台(端口 5174) cd demo/client npm run dev

启动后访问 http://localhost:5174 即可进入管理后台。

💡 client 的 Vite 开发服务器已配置代理,所有 /api/* 请求会自动转发到 http://localhost:3001

7. 如果需要单独调试 uikit

# 终端 3:启动云盘 UIKit 独立开发模式(端口 5177) cd uikit npm run dev

使用流程

管理员操作流程

1. 访问 http://localhost:5174 2. 使用 admin/admin 登录 3. 在仪表盘中管理租户: ├── 创建租户 → 输入 userId,系统自动创建 SMH 空间 ├── 配额管理 → 点击配额区域,设置存储上限(GB) ├── 绑定用户 → 为租户绑定业务系统的 userId ├── 进入云盘 → 点击「云盘」按钮,以抽屉方式浏览/管理文件 ├── 踢下线 → 禁止租户获取新的访问令牌 ├── 恢复 → 恢复被踢下线的租户的访问权限 └── 删除租户 → 永久删除租户及其所有数据

将 uikit 集成到其他项目

uikit 可以作为独立的 UIKit 被任何 React 项目引用:

# 1. 构建 UIKit cd uikit npm run build:lib # 2. 在目标项目中引用(本地路径或发布到 npm) npm install ../uikit # 本地引用
import { SpaceDrive } from 'smh-web-uikit' import 'smh-web-uikit/dist/style.css' <SpaceDrive basePath="https://smhxxx.api.tencentsmh.cn" libraryId="smhxxx-xxxxx" spaceId="spaceyyy" getAccessToken={async () => { // 调用你的后端获取 SMH accessToken const res = await fetch('/api/your-backend/get-token') const data = await res.json() return { accessToken: data.accessToken, expiresAt: data.expiresAt } }} />

详细接入文档见 uikit/接入文档.md


☁️ OpenClaw Skill — 对话式云上传

本项目附带一个 OpenClaw Skill(cloud-upload-backup),让你在 AI 对话中直接说一句话就能把文件上传到 SMH 云存储并拿到下载链接,无需手动调用 API。

功能

  • 上传本地文件到 SMH 云空间,返回带签名的直链(有效期 2 小时)
  • 查询已上传文件的信息与下载链接
  • 批量上传,逐条输出进度与链接
  • 支持秒传检测(相同文件秒级完成)

快速配置

第一步:安装 SDK

npm install -g smh-node-sdk

第二步:写入凭证

~/.openclaw/openclaw.jsonenv 字段中填入你的 SMH 空间信息:

{ "env": { "smh-basePath": "https://<your-library-id>.api.tencentsmh.cn", "smh-libraryId": "<your-library-id>", "smh-spaceId": "<your-space-id>", "smh-accessToken": "<space_admin 权限的 accessToken>" } }

也可以在当前工作目录的 .env 文件中配置:

smh-basePath=https://<your-library-id>.api.tencentsmh.cn smh-libraryId=<your-library-id> smh-spaceId=<your-space-id> smh-accessToken=<space_admin 权限的 accessToken>

accessToken 可通过本项目的 server 后端接口 POST /api/admin/generate-space-token 获取,也可直接用 smh-node-sdksmh.token.createToken() 手动签发。

第三步:加载 Skill

cloud-upload-backup/SKILL.md 添加到你的 OpenClaw 配置中,重启后即可使用。

使用示例

配置完成后,直接在对话中说:

"把 /tmp/report.pdf 上传到云,给我下载链接" "备份一下桌面上的 photo.jpg" "把这个文件发给我"

AI 会自动调用脚本完成上传,并回复类似:

链接已生成,有效期 2 小时,可直接在浏览器或手机中打开。

📎 report.pdf (2.3 MB) — https://cos.ap-guangzhou.myqcloud.com/report.pdf?sign=xxx

凭证模式说明

模式配置方式适用场景
直接凭证(推荐)openclaw.json env 字段或 .env 文件中填 smh-accessToken长期使用,配置一次即可
自动换取 Tokenopenclaw.json env 字段或 .env 文件中填 smh-librarySecret需要自动刷新 Token 的场景
命令行传参每次命令中直接传入参数临时覆盖配置文件

详细说明见 cloud-upload-backup/SKILL.md


API 接口一览

方法路径说明
POST/api/admin/login管理员登录
POST/api/admin/logout管理员登出
POST/api/admin/getUserInfo获取当前登录信息
GET/api/admin/tenants获取租户列表
POST/api/admin/tenants/refresh刷新租户列表
POST/api/admin/tenants/create创建租户
DELETE/api/admin/tenants/:spaceId删除租户
GET/api/admin/tenants/:spaceId/quota查询配额
PUT/api/admin/tenants/:spaceId/quota修改配额
POST/api/admin/generate-space-token生成空间访问令牌
POST/api/admin/revoke-space踢下线(吊销令牌)
POST/api/admin/unrevoke-space恢复访问权限
GET/api/admin/space-status/:spaceId查询吊销状态
POST/api/admin/bind-user绑定 spaceId-userId
POST/api/admin/unbind-user解绑 spaceId-userId
GET/api/health健康检查

端口说明

服务端口说明
server3001后端 API 服务
admin5174管理后台前端
uikit5177云盘 UIKit 独立开发模式(可选)