feat(server): MinIO/S3 对象存储兼容(F21)

- 新增 storage 抽象:local 与 s3: 前缀兼容(不改 schema)
- invoice-pool 上传/预览/ocr 读取适配 S3/MinIO
- trialrun compose 增加 minio profile + env 示例与 runbook 指引
- 更新 README 与 v3 CSV 状态推进
这个提交包含在:
2026-02-09 20:42:53 +08:00
父节点 6ecebf8ad6
当前提交 c791e67b20
共修改 12 个文件,包含 2558 行新增和 28 行删除
+13
查看文件
@@ -21,6 +21,19 @@ DATABASE_URL="postgresql://hyboa_user:hyboa_password@db:5432/hyb_oa?schema=publi
# ===== 存储(票据上传目录)=====
# 在 deploy/trialrun/docker-compose.yml 中映射到宿主机 deploy/trialrun/data/storage
STORAGE_DIR="/data/storage"
# 可选:对象存储(MinIO/S3 兼容,F21)
# - 默认 local:文件写到 STORAGE_DIR
# - 启用 MinIO:STORAGE_DRIVER="s3" 并启用 compose profile:--profile minio
STORAGE_DRIVER="local" # local|s3
S3_ENDPOINT="http://minio:9000"
S3_REGION="us-east-1"
S3_BUCKET="hyb-oa"
S3_ACCESS_KEY_ID="minioadmin"
S3_SECRET_ACCESS_KEY="minioadmin"
S3_FORCE_PATH_STYLE="true"
MINIO_ROOT_USER="minioadmin"
MINIO_ROOT_PASSWORD="minioadmin"
# ===== 单域托管 client/dist =====
SERVE_CLIENT_DIST="true"
+51
查看文件
@@ -19,6 +19,36 @@ services:
timeout: 5s
retries: 10
minio:
image: minio/minio:RELEASE.2025-01-20T14-49-07Z
container_name: hyb-oa-trialrun-minio
restart: unless-stopped
profiles: ["minio"]
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
command: ["server", "/data", "--console-address", ":9001"]
ports:
- "9000:9000"
- "9001:9001"
volumes:
- ./data/minio:/data
minio_init:
image: minio/mc:RELEASE.2025-08-13T08-35-41Z
container_name: hyb-oa-trialrun-minio-init
profiles: ["minio"]
depends_on:
- minio
entrypoint: ["sh", "-c"]
command: |
set -e
for i in $(seq 1 60); do
mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" && break || true
sleep 1
done
mc mb --ignore-existing "local/$S3_BUCKET"
server:
build:
context: ../..
@@ -35,6 +65,13 @@ services:
JWT_SECRET: ${JWT_SECRET}
DATABASE_URL: ${DATABASE_URL}
STORAGE_DIR: ${STORAGE_DIR}
STORAGE_DRIVER: ${STORAGE_DRIVER}
S3_ENDPOINT: ${S3_ENDPOINT}
S3_REGION: ${S3_REGION}
S3_BUCKET: ${S3_BUCKET}
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID}
S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY}
S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE}
HOST: ${HOST}
PORT: ${PORT}
COOKIE_SECURE: ${COOKIE_SECURE}
@@ -83,6 +120,13 @@ services:
JWT_SECRET: ${JWT_SECRET}
DATABASE_URL: ${DATABASE_URL}
STORAGE_DIR: ${STORAGE_DIR}
STORAGE_DRIVER: ${STORAGE_DRIVER}
S3_ENDPOINT: ${S3_ENDPOINT}
S3_REGION: ${S3_REGION}
S3_BUCKET: ${S3_BUCKET}
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID}
S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY}
S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE}
SERVE_CLIENT_DIST: "false"
CLIENT_DIST_DIR: ${CLIENT_DIST_DIR}
@@ -119,6 +163,13 @@ services:
JWT_SECRET: ${JWT_SECRET}
DATABASE_URL: ${DATABASE_URL}
STORAGE_DIR: ${STORAGE_DIR}
STORAGE_DRIVER: ${STORAGE_DRIVER}
S3_ENDPOINT: ${S3_ENDPOINT}
S3_REGION: ${S3_REGION}
S3_BUCKET: ${S3_BUCKET}
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID}
S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY}
S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE}
SERVE_CLIENT_DIST: ${SERVE_CLIENT_DIST}
CLIENT_DIST_DIR: ${CLIENT_DIST_DIR}
OCR_PROVIDER: ${OCR_PROVIDER}
+10
查看文件
@@ -23,6 +23,10 @@ cp deploy/trialrun/.env.example deploy/trialrun/.env
- 如需快速回滚作业调度:将 `JOB_DRIVER` 改回 `cron`
- 可选 Worker 拆分(F20):将 `JOBS_ENABLED=false` 并启用 `--profile worker`(worker 进程会强制跑作业)
存储建议:
- 默认 `STORAGE_DRIVER=local`(票据文件落到 `deploy/trialrun/data/storage`)
- 可选启用 MinIO(F21):`STORAGE_DRIVER=s3` 并启用 `--profile minio`
### 1.2 启动数据库与服务
```bash
cd /path/to/hyb-oa
@@ -30,6 +34,12 @@ docker compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/
docker compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env up -d --build server
```
可选:启用 MinIO(对象存储,F21):
```bash
cd /path/to/hyb-oa
docker compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env --profile minio up -d minio minio_init
```
可选:启用 Worker 进程(推荐在试运行/多进程模式使用):
```bash
cd /path/to/hyb-oa