feat: sharelink 资源下载管理插件 v1.1.0

- 下载资源管理与 /download/{slug} 下载链接
- 下载统计(次数/去重人数/明细/CSV 导出)
- 按资源邮箱验证(Halo 通知中心发信,互认评论插件已验证邮箱)
- 本地附件防直链(/upload/** 404)
- 文章引用扫描
- Console 前端:Vue3 + ui-plugin-bundler-kit
This commit is contained in:
shirainbown
2026-08-03 00:25:15 +08:00
commit aa4befa0ff
62 changed files with 7838 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
# sharelink console UI
Halo 2.x 插件「资源下载管理」的 console 后台前端(Vue 3 + rsbuild +
@halo-dev/ui-plugin-bundler-kit)。工程结构照搬
`blog-comment/packages/ui`
## 命令
```bash
pnpm install
pnpm build # 产物输出到 ../src/main/resources/console(打进插件 jar
pnpm dev # watch 模式,输出到 ../build/resources/main/console
pnpm type-check # vue-tsc 类型检查(构建流程不依赖)
```
## 路由与权限
- 路由:`/download-manager`,挂在 `Root` 下,菜单组 `content`priority 52
- 权限 meta`plugin:sharelink:view`(见
`src/main/resources/extensions/role-templates.yaml`
`role-template-sharelink-view`
- 注意:角色的 `ui-permissions` 里还定义了 `plugin:sharelink:manage`,但
console 菜单只挂了 view 权限;前端未对 manage 操作做按钮级权限隐藏,
写操作是否放行完全由后端 RBAC 决定。
## API 契约(后端并行开发中)
Base`/apis/console.api.sharelink.halo.run/v1alpha1`
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/download-resources` | `{ items: [...], total }`(非标准 ListResult |
| POST | `/download-resources` | 创建,**前端只提交 `{ metadata: { name: '' }, spec }`name 由后端生成** |
| GET/PUT/DELETE | `/download-resources/{name}` | 单资源读写删,PUT 提交完整对象 |
| GET | `/download-records?resourceSlug=&page=&size=` | Halo 标准 ListResult |
| DELETE | `/download-records/{name}` | 删除单条记录 |
| GET | `/download-records/-/export?resourceSlug=` | CSV,前端用 `window.open` 直接导航下载 |
| GET | `/references` | `{ slug: [{ postName, title, permalink, editorUrl }] }` |
| POST | `/references/-/refresh` | 强制重扫,返回同上 |
## 前端字段假设(联调时若与后端不一致,以此为准核对)
1. `DownloadResource.spec``slug``displayName``description`
`attachmentName``requireEmailVerify``enabled``status.downloadCount`
`stats.downloaderCount``stats.referenceCount`。其中 `stats` 是 Halo
自定义资源里不常见的顶层字段(与 `status` 平级),若后端改为放进
`status`,需同步修改 `src/types.ts``DownloadManager.vue` 的两处取值。
2. 列表 GET `/download-resources` 返回 `{ items, total }`,不带分页参数,
前端一次性拉全量。
3. `references` 的 key 是 **slug**(不是 metadata.name)。
4. 引用项 `editorUrl` / `permalink` 均为可直接打开的相对或绝对路径,
前端 `target="_blank"` 打开。
5. 下载记录 `spec.downloadedAt` 为 ISO 时间字符串;`spec.email` 可能为空
(匿名下载)。
6. CSV 导出端点接受 session cookie 直接 GET 导航,无需 axios blob 下载。
7. 附件选择:`AttachmentSelectorModal` 是 Halo Console **全局注册**的业务
组件(不从 `@halo-dev/components` 导出),`v-model:visible` 控制显隐,
`@select` 回调附件数组,前端存 `attachment.metadata.name`
`spec.attachmentName`