同步 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 条上限。
7.1 KiB
构建与部署
本章介绍「汇账」的构建方式、分发形态与生产部署流程。
前置条件
- JDK 21(Temurin 21 LTS,含
jpackage) - Node.js(构建前端时需要)
- 依赖仓库:本地 Nexus(Maven)与 verdaccio(npm);构建时经
-I nexus-init.gradle注入 Maven 私服地址
开发模式
前后端分离,便于调试:
# 后端(默认 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/,单文件同时提供页面与接口。
# 普通 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,可另指定端口):
java -jar build/libs/ledgerly-0.1-jdk21.jar --server.port=18081
构建任务链(build.gradle):npmInstall → frontendLint → frontendBuild → bootJar;check 任务另挂 Spotless、Checkstyle、SpotBugs。代码检查不通过会中断构建与打包,详见开发环境与规范。
::: 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 产物)。
./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;最新下载地址见使用文档的下载与安装(该页链接指向已上传的发布产物)。
上传方式:
- 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 容器负责续期:
安全配置
- JWT 签名密钥:默认使用内置密钥签发 Token(有效期 24 小时);生产环境可通过环境变量
JWT_SECRET覆盖,未配置时回退内置默认值,避免个人自托管场景重启后登录态失效。 - CORS 放行来源:仅放行本机与局域网来源——
localhost、127.0.0.1、[::1]、192.168.*、10.*、172.*(任意端口),并允许携带凭证;生产环境前后端同源,无需额外的跨域配置。
发布流程
服务(构建 → 复制 → 重启):
# 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,目录挂载即时生效):
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导入。