Files
sharelink/AGENTS.md
T
shirainbown aa4befa0ff feat: sharelink 资源下载管理插件 v1.1.0
- 下载资源管理与 /download/{slug} 下载链接
- 下载统计(次数/去重人数/明细/CSV 导出)
- 按资源邮箱验证(Halo 通知中心发信,互认评论插件已验证邮箱)
- 本地附件防直链(/upload/** 404)
- 文章引用扫描
- Console 前端:Vue3 + ui-plugin-bundler-kit
2026-08-03 00:25:15 +08:00

40 lines
4.0 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.
# AGENTS.md — sharelinkHalo 资源下载管理插件)
## 项目概述
Halo 2.x>=2.22,目标实例 Halo Pro 2.25.4)插件。管理文章中的资源下载链接:按资源的下载统计、邮箱验证、防附件直链、文章引用扫描。邮箱验证体系复制改造自 `~/Documents/Code/Ai/blog-comment`plugin-comment-widget fork 的 emailcode/guard 包)。
## 结构
- `src/main/java/run/halo/sharelink/`
- `model/` 自定义 Extension@GVK group `sharelink.halo.run`):DownloadResourcespec.slug 唯一索引)、DownloadRecordspec.resourceSlug 索引)、VerifiedDownloadername=SHA-256(归一化邮箱)
- `emailcode/` 验证码:Guava 内存缓存、限流、NotificationCenter 发信(REASON_TYPE `sharelink-download-verification`,模板在 `resources/extensions/notification.yaml`
- `verify/` 公开端点 `api.sharelink.halo.run/v1alpha1`email-verify/-/send|/-/check+ VerifiedEmailService(本插件 VerifiedDownloader 评论插件 VerifiedCommenter,后者运行时 Unstructured fetch,缺席自动降级)
- `download/` RouterFunction Bean`GET /download/{slug}`(自包含 HTML 页)、`GET /download/{slug}/file`(一次性 token 核销 → 记录 → 流式下载);FileStreamer 本地附件直接读盘(`halo.work-dir`/attachments + `storage.halo.run/local-relative-path` 注解),外部存储回环 HTTP(带 `X-Sharelink-Internal` 头)
- `protect/UploadProtectFilter` AdditionalWebFilterGET/HEAD `/upload/**` 命中受保护附件 → 404
- `reference/PostReferenceService` 扫描已发布文章 releaseSnapshot 内容匹配 `/download/{slug}`5min 缓存
- `console/ConsoleEndpoint` `console.api.sharelink.halo.run/v1alpha1`:资源 CRUD(body 为扁平 spec)、记录分页/删除/CSV、references 查询/刷新
- `src/main/resources/extensions/` settings.yaml、notification.yaml、role-templates.yaml(匿名放行公开 APIconsole view/manage 角色,`ui-permissions: plugin:sharelink:view/manage`
- `ui/` console 前端:Vue 3 + @halo-dev/ui-shared + ui-plugin-bundler-kitrsbuild),产物输出到 `src/main/resources/console/`(**构建前会覆盖该目录,勿手改**)。API 层 `ui/src/api/index.ts``normalizeResource()` 把后端扁平 ResourceVo 转成 Halo 风格结构
## 构建 / 部署
```bash
pnpm -C ui install && pnpm -C ui build
export JAVA_HOME=~/.gradle/jdks/jdk-21.0.12+8/Contents/Home # 本机无系统 JDK
./gradlew build -x test # build/libs/sharelink-<version>.jar
```
关键经验(踩过的坑):
1. 改代码后发布必须递增 `gradle.properties` 的 version——console 静态资源按 `?version=` 缓存,不递增浏览器会用旧包。
2. Console UI 升级插件会弹「插件已存在,是否升级?」确认框,不点确定不会真正替换 jar。
3. 插件数据存 ExtensionStoreMySQL),卸载/重装插件不丢数据;但 Halo 的插件静态资源目录在重装时才重新解压。
4. 计数在「token 核销 + 附件可流式输出」之后才写入,下载失败不计数;免验证资源按 slug+IP 内存窗口去重。
5. UI 安装有两条路:①「远程下载」需要 Halo 服务器能反向访问本机 jar 服务(本机换网/IP 变化后会失败);②「本地上传」用 webbridge 时 CDP `setFileInputFiles` 被浏览器禁用,可用兜底方案:分块 base64 经 `evaluate` 推到页面 `window.__jarB64` → JS 构造 `File` + `DataTransfer` → 对 `.uppy-Dashboard-inner` 派发合成 `dragenter/dragover/drop` 事件触发 Uppy 上传 → 再点升级确认框「确定」。
6. 下载页自包含 HTML 里若给元素自定义了 `display`(如 flex),必须补 `[hidden] { display: none !important; }`,否则 `hidden` 属性失效导致元素误显示。
## 测试
端到端验证依赖目标实例(http://192.168.3.2:8090)。公开 API 可用 curl 匿名测试:
`POST /apis/api.sharelink.halo.run/v1alpha1/downloads/-/token {"slug":"..."}``GET /download/{slug}/file?token=...`