For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /oneimg/development.md.

开发与架构

适用版本 1.0.4 | 面向二次开发与源码阅读

插件由「Java 后端 + Vue 3 控制台扩展」两部分组成,构建产物是一个 Halo 插件 JAR。许可证为 GPL-3.0。

环境

工具版本
JDK21
Gradle8.x
pnpm最近主版本

构建

# 前端(修改过 ui/ 目录时)
cd ui && pnpm install && pnpm build
cp dist/main.js dist/style.css ../src/main/resources/console/

# 后端
./gradlew build

# 产物
build/libs/plugin-oneimg-X.X.X.jar

前端产物需要手动拷贝到 src/main/resources/console/,否则打出来的 JAR 里还是旧的控制台资源。

目录结构

├── ui/                                # Vue 3 前端(同步标签页)
│   ├── src/
│   │   ├── index.ts                   # 插件入口,注册扩展点
│   │   └── SyncView.vue               # 同步 UI 组件
│   └── vite.config.ts                 # IIFE 构建配置
├── src/main/java/io/github/alonenannan/oneimg/
│   ├── OneImgPlugin.java              # 插件生命周期
│   ├── OneImgAttachmentHandler.java   # 上传 / 删除附件
│   ├── OneImgSyncEndpoint.java        # 同步 REST API
│   └── OneImgUtils.java               # 配置校验等工具方法
└── src/main/resources/
    ├── plugin.yaml                    # 插件元数据
    ├── console/                       # 前端构建产物
    └── extensions/
        ├── policy-template.yaml       # 存储策略表单
        └── settings.yaml              # 插件设置

技术架构

层实现
插件框架Halo Plugin Framework,实现 AttachmentHandler 扩展点
上传Spring WebClient 调用初春图床 API,响应式非阻塞
同步java.net.http.HttpClient 异步执行,前端轮询获取实时日志
鉴权同步 API 基于 Spring Security 做登录鉴权
控制台 UIVue 3 + Vite,通过 plugin:self:tabs:create 注册标签页

扩展点与配置

  • 存储策略:extensions/policy-template.yaml 定义策略表单(apiUrl / token / bucketId / tagId),对应 storage.halo.run/v1alpha1 的 PolicyTemplate
  • 插件设置:extensions/settings.yaml(oneimg-sync-v2),当前无表单项,同步入口在自定义标签页
  • 插件元数据:plugin.yaml,要求 Halo ≥ 2.25.0

二次开发提示

  • 修改策略字段时,policy-template.yaml 与后端读取配置的代码要同步改,否则新字段不会生效
  • 同步逻辑涉及「导入 + 反向清理」两步,改动时先确认删除范围,避免误删附件记录
  • 图床 API 变更时需要同时调整上传与同步两处调用
  • 前端产物是 IIFE 构建,拷贝路径写错是最常见的「改了没生效」原因

上游项目

初春图床本体:https://github.com/onexru/oneimg(Go + Vue 3,支持本地 / S3 / WebDAV / FTP 存储,上传自动转 WebP)