> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# 开发与架构

> 适用版本 1.0.0 ｜ 面向二次开发与源码阅读

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

## 环境

| 工具      | 版本                          |
| ------- | --------------------------- |
| Halo    | ≥ 2.27.0                    |
| JDK     | 21                          |
| Node.js | 22+                         |
| pnpm    | 9                           |
| Docker  | 仅 `./gradlew haloServer` 需要 |

## 构建

```bash
# 安装控制台前端依赖（可选，Gradle 会自动执行 pnpm install）
pnpm --dir ui install

# 启动开发环境（需要 Docker）
./gradlew haloServer

# 构建插件
./gradlew build
```

产物位于 `build/libs/plugin-reward-<version>.jar`。

> 控制台前端由 Gradle 的 `ui` 子模块调用 `pnpm build`，产物经 `Sync` 同步到 `build/resources/main/ui`（Halo 2.11 起优先读取 `resources/ui`）。单独改前端后跑一次 `./gradlew build` 即可，不需要手工拷贝文件。

## 目录结构

```
reward-halo-plugin/
├── src/main/java/cn/nanzhiy/reward/
│   ├── RewardPlugin.java            插件入口，注册模型与索引
│   ├── afdian/                      爱发电客户端与服务
│   │   ├── AfdianClient.java          非阻塞请求、签名、双域名回退
│   │   ├── AfdianService.java         订单入库、反查校验、手动同步
│   │   └── AfdianSettings.java        爱发电配置模型
│   ├── config/                      插件设置的数据模型
│   ├── endpoint/                    接口层
│   │   ├── RewardPublicEndpoint.java    公开接口 + 验证码
│   │   ├── RewardConsoleEndpoint.java   后台记录管理
│   │   ├── AfdianWebhookEndpoint.java   爱发电回调
│   │   └── AfdianConsoleEndpoint.java   连通性检测与同步
│   ├── extension/                   RewardRecord 自定义模型
│   ├── finders/                     主题侧 Finder
│   ├── router/                      /reward 页面路由
│   ├── service/                     记录、配置、通知服务
│   ├── support/                     验证码、限流器、字段清洗
│   └── vo/                          对外视图对象
├── src/main/resources/
│   ├── plugin.yaml                  插件清单
│   ├── extensions/                  设置表单、权限、通知、静态代理
│   ├── templates/                   前台模板与模态框片段
│   └── static/dist/                 前台 CSS 与 JS
├── ui/                              后台界面（Vue 3 + Vite）
│   └── src/
│       ├── views/RewardView.vue     打赏记录页
│       └── components/              编辑弹窗
└── dev/                             开发者文档
```

## 技术架构

| 层      | 实现                                                             |
| ------ | -------------------------------------------------------------- |
| 插件框架   | Halo Plugin Framework（Spring Boot），插件清单 `plugin.yaml`          |
| 页面路由   | `RouterFunction` 注册 `/reward`，模板 `reward.html`，自动套用主题 `layout` |
| 数据存储   | 自定义模型 `RewardRecord`（group `reward.nanzhiy.cn`），Halo 扩展存储      |
| 接口     | 公开 REST、管理 REST、标准 CRUD 三组端点                                   |
| 主题集成   | `rewardFinder` 与模板片段 `reward-modal`                            |
| 爱发电    | 非阻塞客户端 + 回调反查，`afdian.com` / `ifdian.net` 双域名回退                |
| 控制台 UI | Vue 3 + Vite，通过 `@halo-dev/ui-plugin-bundler-kit` 构建           |

## 数据模型

`RewardRecord` 的字段与公开范围：

| 字段              | 说明                              | 前台展示    |
| --------------- | ------------------------------- | ------- |
| `nickname`      | 展示昵称                            | 是       |
| `amount`        | 金额                              | 可配置     |
| `message`       | 留言                              | 是       |
| `contact`       | 联系方式                            | 否，仅后台   |
| `transactionNo` | 交易单号                            | 否，仅后台   |
| `avatar`        | 头像地址                            | 是（赞助者墙） |
| `rewardTime`    | 打赏时间；未填时按入库时间展示与排序              | 是（日期）   |
| `externalId`    | 外部渠道单号（爱发电订单号）                  | 否       |
| `source`        | 来源：`page` / `manual` / `afdian` | 否       |
| `method`        | 支付方式                            | 否       |
| `status`        | 待确认 / 已确认 / 已拒绝                 | 否       |

## 扩展点

| 扩展点    | 位置                               | 用途                                          |
| ------ | -------------------------------- | ------------------------------------------- |
| 页面路由   | `router/`                        | 渲染 `/reward`，支持主题覆盖 `templates/reward.html` |
| Finder | `finders/`                       | 主题侧读取配置、赞助者墙与统计（`rewardFinder`）             |
| 前台片段   | `templates/reward-modal.html`    | 一行引用提交模态框                                   |
| 权限角色   | `extensions/role-templates.yaml` | `打赏记录查看` / `打赏记录管理`                         |
| 通知     | `extensions/notification.yaml`   | 新记录与新订单的通知模板                                |

接口细节见 [主题 API](/reward/theme-api.md) 与 [REST API](/reward/rest-api.md)。

## 二次开发提示

- 前台资源放在 `src/main/resources/static/dist/`，修改后需要重新构建；控制台前端不要手工拷贝，交给 Gradle 同步
- 新增公开接口时同步检查限流与字段脱敏，联系方式、交易单号不能出现在匿名响应里
- 爱发电回调没有签名，任何新增的入库路径都必须先走 `query-order` 反查
- 改权限规则时注意：Halo 会把「有名称段的 POST」降级为非资源请求，相关接口用 PUT
- 修改设置项后，`extensions/settings.yaml`、`config/` 模型与前台读取处要一起改

## 上游脚手架

项目基于 Halo 官方插件脚手架 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 创建。该模板后续由 [create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 取代；本项目沿用生成后的工程结构，不依赖模板仓库的后续更新。
