一个基于 Spring Boot + Vue 3 的智能协同云图库系统,支持公共图库、私有空间、团队协作、AI 能力、实时协同编辑与数据分析。
CoGallery 协图云 是一个全栈智能云图库平台,集图片托管、协同编辑、智能分析于一体。系统面向个人用户与团队,提供从图片上传、自动压缩、智能审核到团队空间协作的完整工作流。
在数字化协作日益普及的今天,团队对图片素材的统一管理、高效检索与协同编辑需求日益增长。传统的 FTP 或网盘方案缺乏针对图片场景的深度优化,无法满足自动压缩、智能搜索、按色检索、实时协作等专业需求。CoGallery 协图云 正是为解决这些痛点而生——它将对象存储、AI 智能、实时通信与数据可视化融为一体,为个人和团队提供一个开箱即用的智能图片协作平台。
- 开箱即用:提供完整的用户注册、图片上传、空间管理、数据分析功能链路,无需额外开发即可部署使用
- 弹性扩展:基于 ShardingSphere 动态分表,旗舰团队空间自动独立分表存储,从容应对海量数据
- 安全可控:Sa-Token 双账号体系实现细粒度权限管控,配合图片审核机制保障内容安全
- 极致性能:Caffeine + Redis 双层缓存、Disruptor 无锁队列、WebSocket 长连接,全链路保障低延迟体验
- 智能赋能:集成智谱 GLM 大模型与以图搜图能力,让图片管理更聪明
| 特性 | 说明 |
|---|---|
| 智能图库 | 自动压缩、缩略图生成、主色调提取 |
| 协同编辑 | WebSocket 实时同步 + Disruptor 高性能消息队列 |
| 动态分表 | ShardingSphere 按 spaceId 动态分片,旗舰团队空间独立存储 |
| AI 赋能 | 以图搜图、按颜色搜图、智谱 GLM 智能分析 |
| 精细权限 | Sa-Token 双账号体系 + JSON 驱动的角色权限矩阵 |
| 数据分析 | 6 大维度可视化分析(ECharts + 词云) |
| 多级缓存 | Caffeine 本地缓存 + Redis 分布式缓存,随机过期防雪崩 |
系统采用清晰的三级角色模型,满足不同场景下的权限需求:
graph LR
A[游客] -->|注册/登录| B[普通用户]
B -->|兑换码激活| C[VIP 会员]
B -->|管理员分配| D[管理员]
C --> D
style A fill:#e0e0e0,stroke:#999
style B fill:#42a5f5,stroke:#1976d2,color:#fff
style C fill:#ffb74d,stroke:#f57c00
style D fill:#ef5350,stroke:#c62828,color:#fff
- 注册 / 登录 / 注销,MD5 加盐密码加密
- 三种角色:普通用户、VIP 会员、管理员
- VIP 兑换码机制,支持过期时间管理
图片管理是系统的核心模块,覆盖从上传到检索的完整生命周期:
- 多种上传方式:文件上传 / URL 上传 / 批量抓取(Bing 图源),适配不同业务场景
- 自动处理:上传后自动调用腾讯云数据万象进行图片压缩(转 WebP)、缩略图生成与主色调提取,无需人工干预
- 多维度搜索:支持按名称、分类、标签模糊搜索,按颜色相似度检索,按时间范围过滤,灵活排序组合
- 审核流程:管理员上传自动过审,普通用户上传默认待审,管理员可执行通过 / 拒绝操作
- 批量编辑:支持批量修改分类、标签,以及基于规则模板的批量重命名(支持
{序号}占位符) - 异步清理:删除图片时通过
@Async异步清理 COS 文件,且会检查 URL 引用计数避免误删共享图片
空间是图片的隔离单元,系统通过空间级别与空间类型的组合,灵活适配个人与团队场景:
| 空间级别 | 容量上限 | 数量上限 | 适用场景 |
|---|---|---|---|
| 普通版 | 100 MB | 100 张 | 个人轻量使用 |
| 专业版 | 1 GB | 1,000 张 | 团队日常协作 |
| 旗舰版 | 10 GB | 10,000 张 | 大型团队 / 独立分表 |
| 空间类型 | 说明 |
|---|---|
| 私有空间 | 个人专属,仅所有者可访问 |
| 团队空间 | 多人协作,支持成员管理与角色分配 |
旗舰版团队空间 会自动触发 ShardingSphere 动态建表,该空间的所有图片数据将独立存储在
picture_{spaceId}分表中,实现物理隔离与性能优化。
系统深度融合 AI 能力,提供三种智能化图片检索与分析方式:
flowchart LR
subgraph S1 ["以图搜图"]
A1["上传图片"] --> A2["获取搜索页URL"]
A2 --> A3["解析首个结果"]
A3 --> A4["抓取相似图片列表"]
end
subgraph S2 ["颜色搜索"]
B1["选择目标颜色"] --> B2["计算颜色相似度"]
B2 --> B3["返回最相似Top12"]
end
subgraph S3 ["智谱AI"]
C1["构建提示词"] --> C2["异步创建任务"]
C2 --> C3["轮询任务结果"]
end
- 以图搜图:通过 Jsoup 解析 Bing 图片搜索页面,三步获取相似图片列表,实现"以图找图"
- 按颜色搜索:基于图片主色调,使用颜色空间距离算法计算相似度,返回视觉上最接近的图片
- 智谱 AI 分析:集成智谱 GLM 大模型,采用异步"创建任务 → 轮询结果"模式,支持智能图片分析与内容生成
系统提供 6 大分析维度,支持全平台 / 公共图库 / 指定空间三种数据范围,帮助管理者和团队洞察图片资产分布与使用趋势:
| 维度 | 可视化方式 | 说明 |
|---|---|---|
| 使用状态 | 进度条 / 环形图 | 容量与数量使用比例 |
| 分类分析 | 饼图 | 各分类占比 |
| 标签分析 | 词云图 | 标签使用频率 |
| 大小分析 | 柱状图 | 图片体积分段统计 |
| 用户行为 | 折线图 | 按日/周/月上传趋势 |
| 空间排行 | 排行榜 | 空间使用量 Top N |
权限说明:全平台与公共图库级别的分析仅管理员可访问;指定空间的分析仅空间所有者或空间成员可访问。
graph TB
subgraph FE ["前端 Frontend"]
FE1["Vue 3 + Vite + TypeScript"]
FE1 --> UI["Ant Design Vue"]
FE1 --> ECharts["ECharts 数据可视化"]
FE1 --> WS_Client["WebSocket 协同客户端"]
end
subgraph BE ["后端 Backend"]
API["Spring Boot REST API"]
API --> Auth["Sa-Token 权限认证"]
API --> AOP["AuthCheck AOP 鉴权"]
API --> Upload["图片上传模板"]
Upload --> COS["腾讯云 COS"]
API --> AI["智谱 GLM AI"]
API --> Search["以图搜图 / 颜色搜索"]
end
subgraph MW ["中间件 Middleware"]
Redis[("Redis - 会话 + 缓存")]
MySQL[("MySQL + ShardingSphere")]
Caffeine[("Caffeine 本地缓存")]
end
subgraph CL ["实时协同 Collaboration"]
WSServer["WebSocket Server"]
WSServer --> Disruptor["Disruptor 无锁消息队列"]
end
FE1 -->|"HTTP / WebSocket"| API
FE1 -->|WebSocket| WSServer
API --> Redis
API --> MySQL
API --> Caffeine
API --> COS
API --> AI
前端基于 Vue 3 + TypeScript 构建,使用 Ant Design Vue 作为 UI 组件库,通过 ECharts 实现数据可视化,WebSocket 客户端支持实时协同编辑。后端采用 Spring Boot 框架,通过 Sa-Token 实现双层权限认证,AOP 切面处理管理员鉴权,模板模式统一管理图片上传流程。中间件层由 Redis(分布式会话与缓存)、MySQL(配合 ShardingSphere 分表)、Caffeine(本地缓存)组成。实时协同模块独立运行 WebSocket Server,底层使用 Disruptor 无锁队列实现高性能消息分发。
graph TB
User["用户<br/>普通用户 / VIP / 管理员"]
Admin["管理员<br/>系统管理与分析"]
Sys["CoGallery 协图云<br/>智能协同云图库"]
COS["腾讯云 COS<br/>对象存储 + 数据万象"]
AI["智谱 GLM<br/>AI 智能分析"]
Bing["Bing 图片<br/>批量抓取图源"]
Redis["Redis<br/>分布式缓存 + 会话"]
MySQL["MySQL<br/>数据持久化 + 分表"]
User -->|"上传/浏览/搜索/编辑"| Sys
Admin -->|"审核/管理/分析"| Sys
Sys -->|"存储/压缩/缩略图"| COS
Sys -->|"AI 扩图/分析"| AI
Sys -->|"抓取图片"| Bing
Sys -.->|"缓存/会话"| Redis
Sys -.->|"读写数据"| MySQL
style User fill:#42a5f5,stroke:#1976d2,color:#fff
style Admin fill:#ef5350,stroke:#c62828,color:#fff
style Sys fill:#66bb6a,stroke:#2e7d32,color:#fff
style COS fill:#ffa726,stroke:#ef6c00
style AI fill:#ab47bc,stroke:#6a1b9a,color:#fff
style Bing fill:#26c6da,stroke:#00838f
style Redis fill:#ef5350,stroke:#c62828,color:#fff
style MySQL fill:#ffa726,stroke:#ef6c00
| 技术 | 版本 | 用途 |
|---|---|---|
| Java | 1.8 | 开发语言 |
| Spring Boot | 2.7.6 | 应用框架 |
| MyBatis-Plus | 3.5.9 | ORM 框架 |
| Sa-Token | 1.39.0 | 权限认证 |
| ShardingSphere | 5.2.0 | 动态分库分表 |
| Spring Session + Redis | - | 分布式会话 |
| Caffeine | 2.9.3 | 本地缓存 |
| WebSocket | - | 实时协同编辑 |
| Disruptor | 3.4.2 | 高性能无锁队列 |
| 腾讯云 COS SDK | 5.6.227 | 对象存储 + 图片处理 |
| Knife4j | 4.4.0 | 接口文档 |
| Hutool | 5.8.26 | 工具库 |
| Jsoup | 1.15.3 | HTML 解析 / 爬虫 |
| 技术 | 版本 | 用途 |
|---|---|---|
| Vue | 3.5.13 | 前端框架 |
| Vite | 6.0.1 | 构建工具 |
| TypeScript | 5.6.3 | 类型安全 |
| Ant Design Vue | 4.2.6 | UI 组件库 |
| Pinia | 2.2.6 | 状态管理 |
| Vue Router | 4.4.5 | 路由管理 |
| ECharts | 5.5.1 | 数据可视化 |
| echarts-wordcloud | 2.1.0 | 标签词云 |
| Axios | 1.7.9 | HTTP 请求 |
| vue-cropper | 1.1.4 | 图片裁剪 |
| vue3-colorpicker | 2.3.0 | 颜色选择器 |
前端通过
@umijs/openapi根据后端 Swagger 文档自动生成 API 请求层代码,保持前后端接口同步,减少手动维护成本。
CoGallery/
├── src/main/java/com/chp/cogallery/
│ ├── CoGalleryApplication.java # 启动类
│ ├── annotation/ # @AuthCheck 自定义注解
│ ├── aop/ # AuthInterceptor 鉴权切面
│ ├── api/ # 第三方 API 封装
│ │ ├── imagesearch/ # 以图搜图
│ │ └── zhipuai/ # 智谱 AI
│ ├── common/ # 通用响应封装
│ ├── config/ # 配置类(COS/CORS/MyBatis)
│ ├── constant/ # 常量定义
│ ├── controller/ # REST 控制器(7 个模块)
│ ├── exception/ # 全局异常处理
│ ├── manager/ # 核心管理组件
│ │ ├── auth/ # Sa-Token 权限体系
│ │ ├── sharding/ # 动态分表引擎
│ │ ├── upload/ # 图片上传模板
│ │ ├── websocket/ # 协同编辑 + Disruptor
│ │ ├── CosManager.java # 腾讯云 COS
│ │ └── FileManager.java # 本地文件
│ ├── mapper/ # MyBatis Mapper
│ ├── model/ # 实体 / DTO / VO / 枚举
│ ├── service/ # 业务逻辑层
│ └── utils/ # 工具类(颜色相似度等)
├── src/main/resources/
│ ├── application.yml # 应用配置
│ ├── mapper/ # MyBatis XML
│ └── biz/ # 业务配置(权限/兑换码)
├── sql/
│ └── create_table.sql # 建表脚本
├── CoGallery-frontend/ # Vue 3 前端
│ └── src/
│ ├── pages/ # 页面(含 admin 子目录)
│ ├── components/ # 通用组件
│ ├── api/ # OpenAPI 自动生成
│ ├── stores/ # Pinia 状态管理
│ ├── layouts/ # 全局布局
│ └── router/ # 路由配置
└── pom.xml # Maven 依赖
后端采用经典的分层架构:controller(接口层)→ service(业务层)→ mapper(数据访问层),辅以 manager(管理组件层)封装第三方服务与基础设施交互。model 目录按照 entity(数据库实体)、dto(请求传输对象)、vo(视图对象)、enums(枚举)清晰分类。前端按功能职责划分为 pages(页面)、components(组件)、api(接口请求)、stores(状态管理)、layouts(布局)、router(路由),结构清晰易于维护。
erDiagram
USER ||--o{ PICTURE : "上传"
USER ||--o{ SPACE : "创建"
USER ||--o{ SPACE_USER : "加入"
SPACE ||--o{ PICTURE : "包含"
SPACE ||--o{ SPACE_USER : "拥有成员"
SPACE ||--o{ PICTURE_SHARD : "动态分表"
USER {
bigint id PK
varchar userAccount "登录账号 唯一"
varchar userPassword "加密密码"
varchar userName "昵称"
varchar userAvatar "头像"
varchar userProfile "简介"
varchar userRole "user / vip / admin"
datetime vipExpireTime "VIP过期时间"
int isDelete "逻辑删除"
}
PICTURE {
bigint id PK
varchar url "图片地址"
varchar thumbnailUrl "缩略图地址"
varchar name "名称"
varchar category "分类"
json tags "标签数组"
varchar picColor "主色调"
bigint picSize "体积"
int picWidth "宽度"
int picHeight "高度"
bigint userId "上传者"
bigint spaceId "空间ID"
int reviewStatus "审核状态"
int isDelete "逻辑删除"
}
SPACE {
bigint id PK
varchar spaceName "空间名称"
int spaceLevel "级别 0 / 1 / 2"
int spaceType "类型 0私有 / 1团队"
bigint maxSize "最大容量"
bigint maxCount "最大数量"
bigint totalSize "已用容量"
bigint totalCount "已用数量"
bigint userId "所有者"
}
SPACE_USER {
bigint id PK
bigint spaceId "空间ID"
bigint userId "用户ID"
varchar spaceRole "viewer / editor / admin"
}
| 表名 | 说明 | 关键特性 |
|---|---|---|
user |
用户表 | 逻辑删除、雪花算法主键、VIP 字段 |
picture |
图片表 | 逻辑删除、JSON 标签、审核状态、空间归属 |
picture_{spaceId} |
图片分表 | 旗舰团队空间动态创建,按 spaceId 分片 |
space |
空间表 | 容量配额、使用量统计 |
space_user |
空间成员表 | 唯一索引(spaceId, userId)、角色分配 |
所有业务表均使用
@TableLogic逻辑删除(isDelete字段,0 为正常,1 为已删除),主键采用雪花算法(IdType.ASSIGN_ID)保证分布式唯一。数据库字符集统一为utf8mb4_unicode_ci,完整支持 Emoji 与多语言字符。
| 环境 | 版本要求 |
|---|---|
| JDK | 1.8+ |
| Node.js | 18+ |
| MySQL | 8.0+ |
| Redis | 6.0+ |
| Maven | 3.6+ |
git clone <repository-url>
cd CoGallery# 创建数据库
mysql -u root -p -e "CREATE DATABASE cogallery DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# 导入建表脚本
mysql -u root -p cogallery < sql/create_table.sql编辑 src/main/resources/application.yml,填入你的配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/cogallery
username: root
password: <你的数据库密码>
redis:
host: 127.0.0.1
port: 6379
cos:
client:
host: <腾讯云COS地域域名>
secretId: <腾讯云SecretId>
secretKey: <腾讯云SecretKey>
region: <地域如ap-guangzhou>
bucket: <桶名>
url: <桶访问域名>
zhipu:
apiKey: <智谱API Key>
model: glm-5.2
user:
password:
salt: <自定义盐值>
default:
password: <新用户默认密码>mvn spring-boot:run
# 或使用 IDE 运行 CoGalleryApplication.java后端启动后访问接口文档:http://localhost:8123/api/doc.html
cd CoGallery-frontend
npm install
npm run dev前端启动后访问:http://localhost:5173
注册账号后,在数据库中手动将用户角色改为管理员:
UPDATE user SET userRole = 'admin' WHERE userAccount = '你的账号';flowchart TB
subgraph Upload ["上传图片流程"]
A["上传图片到团队空间"] --> B{"spaceId 是否存在?"}
B -->|是| C{"对应分表是否存在?"}
C -->|是| D["ShardingSphere 路由到 picture_spaceId"]
C -->|否| E["CREATE TABLE LIKE"]
E --> F["热更新分片规则"]
F --> D
B -->|否| G["写入公共 picture 表"]
end
- 基于 ShardingSphere
StandardShardingAlgorithm - 以
spaceId为分片键,路由到picture_{spaceId}分表 - 创建旗舰团队空间时自动建表并热更新规则
DynamicShardingManager通过反射操作 ShardingSphereContextManager
传统分表方案需要停机维护,CoGallery 通过运行时动态建表 + 反射热更新规则,实现了分表操作的零停机。
DynamicShardingManager在应用启动时会自动扫描所有已存在的团队空间并注册分片规则,确保历史数据正常路由。
graph TB
subgraph S1 ["双账号体系"]
DEFAULT["StpKit.DEFAULT(用户登录态)"]
SPACE["StpKit.SPACE(空间权限)"]
end
subgraph S2 ["角色权限矩阵"]
VIEWER["Viewer - picture:view"]
EDITOR["Editor - view / upload / edit / delete"]
ADMIN["Admin - 全部权限 + spaceUser:manage"]
end
DEFAULT --> SPACE
SPACE --> VIEWER
SPACE --> EDITOR
SPACE --> ADMIN
| 权限码 | Viewer | Editor | Admin |
|---|---|---|---|
picture:view |
✅ | ✅ | ✅ |
picture:upload |
- | ✅ | ✅ |
picture:edit |
- | ✅ | ✅ |
picture:delete |
- | ✅ | ✅ |
spaceUser:manage |
- | - | ✅ |
权限规则由 biz/spaceUserAuthConfig.json 配置驱动,支持递进式鉴权:公共图库 → 私有空间 → 团队空间。
鉴权流程采用递进式判断:首先检查是否为公共图库(本人上传或管理员即可操作),其次检查是否为私有空间(空间所有者或管理员),最后才查询
space_user表获取团队空间内的成员角色。这种分层设计避免了不必要的数据库查询,提升了鉴权效率。
sequenceDiagram
participant UserA as 用户 A
participant UserB as 用户 B
participant WS as WebSocket Server
participant D as Disruptor 队列
UserA->>WS: 连接 /ws/picture/edit
WS->>WS: 校验登录 + 权限
UserB->>WS: 连接 /ws/picture/edit
WS->>WS: 校验登录 + 权限
UserA->>WS: 进入编辑(锁定)
WS-->>UserB: 广播:A 正在编辑
UserA->>WS: 执行缩放操作
WS->>D: 生产消息(无锁入队)
D->>WS: 消费分发
WS-->>UserB: 广播编辑动作(排除 A)
UserA->>WS: 退出编辑(释放锁)
WS-->>UserB: 广播:A 已退出
UserB->>WS: 进入编辑
- 连接路径:
/ws/picture/edit - 握手拦截器校验:登录状态、图片存在性、团队空间、编辑权限
- Disruptor 环形缓冲区(256K),实现高性能无锁消息处理
- 同一图片同时仅允许一人编辑,支持 4 种编辑动作广播
选择 Disruptor 而非传统阻塞队列的原因:Disruptor 基于环形缓冲区(RingBuffer)和 CAS 无锁机制,在高并发场景下吞吐量远超
ArrayBlockingQueue。系统通过PictureEditEventProducer生产消息、PictureEditEventWorkHandler消费分发,将 WebSocket 消息处理的序列化与网络 IO 解耦。此外,广播时将 Long 类型 ID 序列化为 String,避免 JavaScript 精度丢失问题。
flowchart LR
A["查询请求"] --> B["Caffeine 本地缓存"]
B -->|命中| R["返回结果"]
B -->|未命中| C["Redis 分布式缓存"]
C -->|命中| R
C -->|未命中| D["数据库查询"]
D --> E["写入 Caffeine"]
D --> F["写入 Redis 随机过期300-600s"]
E --> R
F --> R
style B fill:#a5d6a7,stroke:#388e3c
style C fill:#ef9a9a,stroke:#c62828
style D fill:#ce93d8,stroke:#6a1b9a
缓存设计要点:
- Caffeine 本地缓存设置最大 10000 条、5 分钟过期,命中时直接返回,零网络开销
- Redis 分布式缓存采用 300~600 秒随机过期时间,有效防止缓存雪崩
- 查询链路严格遵循"本地 → 分布式 → 数据库"的顺序,回写时同时更新两级缓存
- 此缓存策略已在
listPictureVOByPageWithCache方法中实现(标注@Deprecated,建议参考其设计思路)
系统采用 RESTful 风格设计接口,所有接口统一返回 BaseResponse 包装结构,包含 code(状态码)、data(数据体)、message(提示信息)三个字段,便于前端统一处理。服务端口为 8123,上下文路径为 /api。
| 模块 | 前缀 | 主要功能 |
|---|---|---|
| 用户管理 | /user |
注册、登录、查询、VIP 兑换 |
| 图片管理 | /picture |
上传、搜索、审核、批量编辑、AI 扩图 |
| 空间管理 | /space |
创建、编辑、查询、级别列表 |
| 空间成员 | /spaceUser |
添加、移除、角色编辑 |
| 空间分析 | /space/analyze |
6 大维度数据分析 |
| 文件管理 | /file |
上传下载测试(管理员) |
| 系统 | / |
健康检查 |
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| POST | /user/register |
用户注册 | 公开 |
| POST | /user/login |
用户登录 | 公开 |
| POST | /picture/upload |
上传图片 | 登录 |
| POST | /picture/upload/url |
URL 上传 | 登录 |
| POST | /picture/search/picture |
以图搜图 | 登录 |
| POST | /picture/search/color |
按颜色搜索 | 登录 |
| POST | /picture/out_painting/create_task |
创建 AI 任务 | 登录 |
| POST | /picture/review |
图片审核 | 管理员 |
| POST | /picture/upload/batch |
批量抓取 | 管理员 |
| POST | /space/add |
创建空间 | 登录 |
| POST | /space/analyze/usage |
使用分析 | 空间成员 |
| POST | /space/analyze/rank |
空间排行 | 管理员 |
完整接口文档:启动后端后访问 http://localhost:8123/api/doc.html(Knife4j)
本项目(CoGallery 协图云)由 chp 独立设计并开发,相关知识产权归作者所有。
- 本项目仅用于 学术交流 目的,不得用于任何商业用途。
- 未经作者书面许可,禁止将本项目代码、设计文档、论文内容等用于商业出版、售卖或二次分发。
- 引用本项目代码或设计思想时,请注明出处并保留原作者信息。
- 作者保留对本项目的最终解释权。