前后端分离合同管理系统,适配 Synology NAS:
- 文件存储在共享目录,按部门子目录落盘,复用 NAS 权限管理。
- 登录直接校验 Synology DSM 账号密码,不维护本地用户表。
- 结构化合同数据存储在 SQLite。
- 支持 PDF 预览、AI OCR/解析、远程 FileStation 上传下载。
backend: Flask API + SQLitefrontend: Vue3 + Element Plusdocker-compose.yml: 一键部署
编辑 backend/.env:
SYNOLOGY_BASE_URL: DSM 地址,例如https://192.168.1.10:5001SYNOLOGY_VERIFY_SSL: 内网自签名证书通常设置为falseCONTRACT_STORAGE_MODE:local或remoteCONTRACT_STORAGE_ROOT: 合同根目录,例如/volume1/contractsSYNOLOGY_FILESTATION_ROOT: 群晖 FileStation 中的共享目录路径,例如/contractsSYNOLOGY_UPLOAD_ACCOUNT/SYNOLOGY_UPLOAD_PASSWORD: 远程上传到 NAS 时使用的 DSM 账号MINIMAX_API_KEY: 启用 AI 识别时必填
推荐参考 backend/.env.example 完成配置。
- 在 DSM 中安装
Container Manager。 - 创建共享文件夹用于存放合同文件,例如
contracts或沿海管道/合同管理。 - 在该共享目录下预建部门子目录,例如
法务部、采购部、工程部。 - 为实际使用系统的 DSM 用户分配这些目录的访问权限。
- 准备一个有 FileStation 上传权限的 DSM 账号,用于
SYNOLOGY_UPLOAD_ACCOUNT。 - 确认 DSM 的 HTTPS 地址可以从容器访问,例如
https://NAS_IP:5001。
本项目支持两种 NAS 存储模式:
- 合同文件通过 FileStation API 直接上传到 NAS。
- 适合当前项目默认部署方式。
- 需要配置:
SYNOLOGY_BASE_URLSYNOLOGY_FILESTATION_ROOTSYNOLOGY_UPLOAD_ACCOUNTSYNOLOGY_UPLOAD_PASSWORD
- 后端容器直接写挂载进来的 NAS 目录。
- 需要把共享目录挂载到容器内,并确保容器内路径与
CONTRACT_STORAGE_ROOT一致。
以下步骤适用于 Synology DSM 7.x + Container Manager。
将整个项目目录上传到 NAS,例如:
/volume1/docker/docscool
目录下应至少包含:
docker-compose.ymlbackend/frontend/README.md
编辑 backend/.env,至少确认以下参数:
FLASK_ENV=production
APP_SECRET_KEY=RandomSecret
DATABASE_URL=sqlite:///instance/contracts.db
SYNOLOGY_BASE_URL=https://NAS_URL:5001
SYNOLOGY_VERIFY_SSL=false
CONTRACT_STORAGE_MODE=remote
CONTRACT_STORAGE_ROOT=/volume1/contracts
SYNOLOGY_FILESTATION_ROOT=/contracts
SYNOLOGY_UPLOAD_ACCOUNT=DSM Account
SYNOLOGY_UPLOAD_PASSWORD=DSM Password
SYNOLOGY_UPLOAD_SESSION=FileStation
MINIMAX_API_KEY=KEY_STRING
MINIMAX_API_URL=https://api.minimaxi.com/v1/chat/completions
MINIMAX_MODEL=MiniMax-M2.5
MY_COMP=My_Company_Name说明:
- 如果不用 AI 解析,可先留空
MINIMAX_API_KEY。 SYNOLOGY_FILESTATION_ROOT要写 FileStation 视角下的路径,不是 Linux 挂载路径。- 例如共享目录真实路径是
/volume1/contracts,则 FileStation 路径通常写/contracts。
当前 docker-compose.yml 已支持通过环境变量配置:
DOCSCOOL_STORAGE_HOST_PATH: NAS 主机上的合同目录(例如/volume1/contracts)DOCSCOOL_BACKEND_PORT: 后端映射端口(默认5000)DOCSCOOL_FRONTEND_PORT: 前端映射端口(默认8080)DOCSCOOL_BACKEND_CONTAINER/DOCSCOOL_FRONTEND_CONTAINER: 容器名
可直接复制 .env.compose.example 为根目录 .env 后按需修改:cp .env.compose.example .env
建议在项目根目录(与 docker-compose.yml 同级)创建 .env:
DOCSCOOL_STORAGE_HOST_PATH=/volume1/contracts
DOCSCOOL_BACKEND_PORT=5000
DOCSCOOL_FRONTEND_PORT=8080
DOCSCOOL_BACKEND_CONTAINER=contract-backend
DOCSCOOL_FRONTEND_CONTAINER=contract-frontend说明:
DOCSCOOL_STORAGE_HOST_PATH建议与backend/.env里的CONTRACT_STORAGE_ROOT指向同一目录。remote模式下建议仍保留该挂载用于路径兼容。local模式下该挂载是必需项。
在 DSM 中打开 Container Manager:
- 进入
项目。 - 点击
新增。 - 选择项目目录,例如
/volume1/docker/docscool。 - 选择使用已有的
docker-compose.yml。 - 启动项目。
启动后会创建两个容器:
contract-backendcontract-frontend
- 前端地址:
http://NAS_IP:${DOCSCOOL_FRONTEND_PORT:-8080} - 后端健康检查:
http://NAS_IP:${DOCSCOOL_BACKEND_PORT:-5000}/api/health
如果健康检查返回:
{"status":"ok"}说明后端已正常启动。
如果你希望按 DSM 界面逐步点击部署,可直接参考:
- 使用 DSM 账号登录系统,确认可以成功登录。
- 新建一条合同并上传 PDF,确认上传成功。
- 打开合同编辑框,确认 PDF 可以预览。
- 测试合同下载,确认能从 NAS 正常取回文件。
- 测试 AI 解析,确认接口密钥和超时时间配置正常。
优先检查:
SYNOLOGY_BASE_URL是否可从容器访问- DSM 账号密码是否正确
- DSM 是否开启 5001 HTTPS 访问
- 自签名证书场景下
SYNOLOGY_VERIFY_SSL是否为false
优先检查:
SYNOLOGY_FILESTATION_ROOT是否写对SYNOLOGY_UPLOAD_ACCOUNT是否有共享目录权限- NAS 中目标目录是否真实存在
- 合同文件所在部门目录是否已创建
SQLite 数据库存放在:
backend/instance/contracts.db
如果你重建项目或替换目录,请确保这个目录被保留。
优先检查:
MINIMAX_API_KEY是否有效- NAS 是否能访问外网 AI 接口
- 上传文件是否为可识别的 PDF
cd backend
pip install -r requirements.txt
python run.pycd frontend
npm install
npm run dev访问:http://localhost:5173
docker compose up -d --build访问前端:http://NAS_IP:${DOCSCOOL_FRONTEND_PORT:-8080}
如果是在 NAS Shell 中执行,建议进入项目目录后运行上述命令。
GET /api/health健康检查POST /api/auth/loginDSM 账号登录GET /api/auth/me获取当前登录用户GET /api/contracts查询合同(支持筛选)POST /api/contracts新建合同PUT /api/contracts/<id>更新合同POST /api/contracts/<id>/upload上传合同文件GET /api/contracts/<id>/download下载原文件GET /api/contracts/<id>/preview在线预览 PDFPOST /api/contracts/ai-parseAI 解析 PDFGET /api/settings/departments部门列表POST /api/settings/departments新增部门DELETE /api/settings/departments/<id>删除部门GET /api/settings/projects项目列表POST /api/settings/projects新增项目DELETE /api/settings/projects/<id>删除项目GET /api/options/contract-fields合同字段选项
系统不保存用户密码,不创建本地用户体系;仅在登录时调用 DSM 认证接口校验账号。