Files
ledgerly-docs/dev/build-deploy.md
T
rosercode 5eb1d331f9 docs: 补充接口加解密、代码检查与安全配置等开发文档
同步 ledgerly 近期开发改动(接口请求/响应体加解密、代码检查工具、安全与稳定性修复、AI 提示词模板抽取),补齐对应开发文档并修正过时表述,同时在快速开始补充小屏适配说明。

变更内容:
- dev/api.md:新增「接口数据加密」小节,说明 RSA + AES-GCM 握手流程、信封格式、会话有效期与失效码、豁免范围及编译期开关。
- dev/architecture.md:请求处理流程补入加密会话拦截器与请求/响应体 Advice,关键设计亮点新增接口数据加密一条。
- dev/development.md:新增「代码检查」小节,登记 Spotless / Checkstyle / SpotBugs 与前端 ESLint / Prettier 配置及运行命令。
- dev/build-deploy.md:新增「安全配置」(JWT_SECRET 覆盖、CORS 放行来源),构建任务链补入前端 lint 校验说明。
- dev/ai.md:修正已重命名的提示词模板名,补充「提示词模板」片段机制与图片记账 SSE 超时、心跳说明。
- dev/project-structure.md:补充 config.crypto / util.crypto 包、prompts 资源目录、crypto-keys.json 运行时文件与交易服务拆分说明。
- guide/getting-started.md:新增「小屏与移动端适配」说明。
- guide/transactions.md:导出说明补充单次 10000 条上限。
2026-10-13 21:02:53 +08:00

158 lines
7.1 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.
# 构建与部署
本章介绍「汇账」的构建方式、分发形态与生产部署流程。
## 前置条件
- **JDK 21**(Temurin 21 LTS,含 `jpackage`)
- **Node.js**(构建前端时需要)
- 依赖仓库:本地 Nexus(Maven)与 verdaccio(npm);构建时经 `-I nexus-init.gradle` 注入 Maven 私服地址
## 开发模式
前后端分离,便于调试:
```bash
# 后端(默认 8080)
cd ledgerly
./gradlew bootRun # Windows: gradlew.bat bootRun
# 前端(默认 5173,接口代理到 8080)
cd ledgerly/frontend
npm run dev
```
- 后端地址:`http://localhost:8080`,接口文档 `http://localhost:8080/doc.html`
- 前端地址:`http://localhost:5173`,`/api` 经 Vite 代理到后端 8080
## 构建可执行 jar(前后端一体化)
`bootJar` 会先执行前端 `npm run build`,再把 `frontend/dist` 复制到 jar 内的 `BOOT-INF/classes/static/`,单文件同时提供页面与接口。
```bash
# 普通 jar(无 GUI,不含 JavaFX)
./gradlew -I nexus-init.gradle bootJar
# 带 GUI 启动器的 jar
./gradlew -I nexus-init.gradle bootGuiJar
# 或使用宿主机脚本(一次产出两者)
./package.sh
```
产物文件名携带目标 JDK 版本:
| 任务 | 产物 | 说明 |
|---|---|---|
| `bootJar` | `build/libs/ledgerly-0.1-jdk21.jar` | 普通服务 jar |
| `bootGuiJar` | `build/libs/ledgerly-0.1-jdk21-gui.jar` | 入口为桌面启动器 |
启动(默认 8080,可另指定端口):
```bash
java -jar build/libs/ledgerly-0.1-jdk21.jar --server.port=18081
```
构建任务链(`build.gradle`):`npmInstall` → `frontendLint` → `frontendBuild` → `bootJar`;`check` 任务另挂 Spotless、Checkstyle、SpotBugs。代码检查不通过会中断构建与打包,详见[开发环境与规范](/dev/development)。
::: tip 提示
jar 内置的前端为生产构建,访问时与后端同源,无需额外的反向代理。
:::
为减小可执行 jar 体积,普通 jar 与 GUI jar 均做了裁剪:AI 调用改用 Spring `RestClient` 直连 OpenAI 兼容接口(不再打包 OpenAI Java SDK);接口文档仅保留 `/v3/api-docs`(JSON),Knife4j 的 `doc.html` UI 依赖为 `developmentOnly`,不进生产 jar;普通 jar 通过 `exclude` 排除桌面启动器包,保持无 JavaFX 依赖。
运行时首次配置或切换数据库时,「测试连接」与「保存并应用」会通过 SSE **实时推送执行进度**(连接测试、建表、结构迁移、数据源切换等)。
## 构建免安装应用(jpackage app-image)
`jpackageAppImage` 聚合任务一次生成两个 app-image,自带精简运行时,双击即用;**仅能为当前操作系统生成**(Windows 上生成 Windows 产物,Linux 上生成 Linux 产物)。
```bash
./gradlew -I nexus-init.gradle jpackageAppImage
# 也可单独执行 jpackageServerAppImage / jpackageGuiAppImage
```
| 任务 | 应用名 | 源 jar | 入口 |
|---|---|---|---|
| `jpackageServerAppImage` | `LedgerlyServer` | `bootJar` | `bin/LedgerlyServer`(Windows 为 `LedgerlyServer.exe`,附带控制台) |
| `jpackageGuiAppImage` | `Ledgerly` | `bootGuiJar` | `bin/Ledgerly`(Windows 为 `Ledgerly.exe`) |
产物位于 `build/jpackage/LedgerlyServer/` 与 `build/jpackage/Ledgerly/`。
图标不随源码分发:打包时 `downloadAppIcon` 从 `src/main/resources/launcher/icon.url` 下载源图,再由 `tools/IconGen.java` 生成平台图标(`ico` / `icns` / `png`);可用 `-PsourceIcon=<png>` 指定本地源图。
## 桌面 GUI 启动器
`cn.rosercode.ledgerly.launcher` 提供系统托盘 + 控制窗口的桌面启动器(进程内启停服务、设置端口、打开浏览器、实时查看日志、单实例运行),仅打入带 GUI 的 jar,普通 jar 不含 JavaFX 依赖。
## 分发形态
| 形态 | 构建方式 | 说明 |
|---|---|---|
| 普通 jar | `bootJar` | 需 JDK 21 运行,跨平台 |
| 带 GUI 启动器 jar | `bootGuiJar` | 内含桌面启动器,跨平台(打包含 JavaFX 全平台原生库) |
| Windows 免安装包 | `jpackageAppImage` | 在 Windows 上构建,zip 分发 |
| Linux 免安装包 | `jpackageAppImage` | 在 Linux 上构建,tar.gz 分发 |
## 发布产物与下载地址
发布产物上传至阿里云 OSS(桶 `adccrac`,对象键前缀 `ledgerly/release/<版本>/`),通过 10 年有效的长期签名 URL 对外提供下载;每个文件同时提供 `.sha256` 校验文件与汇总清单 `SHA256SUMS`。
当前工程版本为 `0.1`;最新下载地址见使用文档的[下载与安装](/guide/download)(该页链接指向已上传的发布产物)。
上传方式:
- Linux 产物(jar 与 Linux app-image 包):工作区根 `oss-release-upload.py`,需在带 `oss2` 的虚拟环境执行(如 `20260807_131528/oss-venv`),上传后输出长期签名 URL。
- Windows 产物(Windows app-image 包):在 Windows 主机上用 Node 脚本(`ali-oss` + STS)直接上传,不回传本地。
## 生产部署(云服务器)
服务部署在云服务器 `101.35.20.223` 的 `/opt/ledgerly` 目录,由 Docker Compose 编排:
| 容器 | 镜像 | 端口 | 说明 |
|---|---|---|---|
| `ledgerly` | `eclipse-temurin:21-jre` | `127.0.0.1:15180 → 8080` | 挂载 `app/ledgerly-0.1.jar`、`config/`、`data/`,JVM `-Xmx512m` |
| `ledgerly-docs` | `nginx:1.27` | `127.0.0.1:15181 → 80` | 挂载 `docs-dist/` 与 `docs/nginx.conf` |
云上 `nginx` 容器反代这两个回环端口并终止 HTTPS,证书由 `certbot` 容器负责续期:
- 服务:[https://finance.rosercode.cn](https://finance.rosercode.cn)
- 文档:[https://docs.finance.rosercode.cn](https://docs.finance.rosercode.cn)
### 安全配置
- **JWT 签名密钥**:默认使用内置密钥签发 Token(有效期 24 小时);生产环境可通过环境变量 `JWT_SECRET` 覆盖,未配置时回退内置默认值,避免个人自托管场景重启后登录态失效。
- **CORS 放行来源**:仅放行本机与局域网来源——`localhost`、`127.0.0.1`、`[::1]`、`192.168.*`、`10.*`、`172.*`(任意端口),并允许携带凭证;生产环境前后端同源,无需额外的跨域配置。
### 发布流程
服务(构建 → 复制 → 重启):
```bash
# 1) 本地构建 jar(见上)
# 2) 复制到云端部署目录,目标文件名须与 compose 挂载一致
scp -i ~/.ssh/id_ed25519_www.rosercode.cn \
build/libs/ledgerly-0.1-jdk21.jar \
root@101.35.20.223:/opt/ledgerly/app/ledgerly-0.1.jar
# 3) 重启容器
ssh -i ~/.ssh/id_ed25519_www.rosercode.cn root@101.35.20.223 \
'cd /opt/ledgerly && docker compose restart'
```
文档站(构建 → 覆盖 `docs-dist`,目录挂载即时生效):
```bash
cd doc-site && npm run docs:build
scp -i ~/.ssh/id_ed25519_www.rosercode.cn -r .vitepress/dist/* \
root@101.35.20.223:/opt/ledgerly/docs-dist/
```
> 云服务器不能直连 DockerHub,新镜像需本地 `docker save | gzip` → `scp` → 云端 `docker load` 导入。
## 相关文档
- [项目结构](/dev/project-structure)
- [开发环境与规范](/dev/development)
- [下载与安装(使用文档)](/guide/download)
- [快速开始(使用文档)](/guide/getting-started)