Deploy huijutec package and stabilize AI model
This commit is contained in:
182
README.md
182
README.md
@@ -1,5 +1,62 @@
|
||||
# 手术图文病历报告系统
|
||||
|
||||
## huijutec.cn / QNAP QTS 直接部署说明
|
||||
|
||||
本部署包已按 `https://sstwbg.huijutec.cn/` 和 QNAP 路径 `/share/Container/tuwen_system_v2` 预置,无需再手动修改 `docker-compose-Nas.yaml` 或 `frpc/frpc.nas.toml`。NAS 版 frpc 配置已直接内置在 `docker-compose-Nas.yaml` 的 `tuwen_frpc` 启动命令中,避免 QTS/Container Station 把配置文件挂载路径改到应用临时目录。
|
||||
|
||||
部署时请把本压缩包内容完整解压/复制到 NAS 的共享目录:
|
||||
|
||||
```text
|
||||
/share/Container/tuwen_system_v2
|
||||
```
|
||||
|
||||
对应 Windows 访问路径通常是:
|
||||
|
||||
```text
|
||||
\\192.168.31.5\Container\tuwen_system_v2
|
||||
```
|
||||
|
||||
目录根部必须能看到这些文件:
|
||||
|
||||
```text
|
||||
Dockerfile
|
||||
Dockerfile.server
|
||||
docker-compose-Nas.yaml
|
||||
package.json
|
||||
package-lock.json
|
||||
nginx.conf
|
||||
index.html
|
||||
```
|
||||
|
||||
在 QTS Container Station 中新建应用时,直接粘贴/选择 `docker-compose-Nas.yaml` 即可。该文件已经写死:
|
||||
|
||||
- 构建目录:`/share/Container/tuwen_system_v2`
|
||||
- 数据目录:`/share/Container/tuwen_system_v2/data`
|
||||
- 公网入口:`https://sstwbg.huijutec.cn`
|
||||
- Web 端口:`4002:80`
|
||||
- API 诊断端口:`4102:3100`
|
||||
- frpc:默认启动 `tuwen_frpc`,映射 `TuWen_System_V2 -> tuwen_web:80 -> remotePort 4002`
|
||||
- 构建/运行代理:`http://192.168.31.7:7893`
|
||||
- 容器命名:不再写死 `container_name`,由 QTS/Compose 按应用名自动生成,减少旧容器名残留冲突。
|
||||
- 镜像命名:`tuwen_api`、`tuwen_web` 使用 huijutec 专用镜像 tag,减少旧 web/api 镜像被复用导致 `nginx.conf` 更新不生效的概率。
|
||||
|
||||
正常启动后应出现 4 个容器:
|
||||
|
||||
```text
|
||||
tuwen_system_v2-tuwen_db-1
|
||||
tuwen_system_v2-tuwen_api-1
|
||||
tuwen_system_v2-tuwen_web-1
|
||||
tuwen_system_v2-tuwen_frpc-1
|
||||
```
|
||||
|
||||
不同 QTS/Compose 版本可能使用下划线或短横线生成容器名,这是正常的;只要服务名能对应上 `tuwen_db`、`tuwen_api`、`tuwen_web`、`tuwen_frpc` 即可。
|
||||
|
||||
FRP 面板中 `TuWen_System_V2` 应显示 `Online`,随后访问:
|
||||
|
||||
```text
|
||||
https://sstwbg.huijutec.cn/
|
||||
```
|
||||
|
||||
手术图文病历报告系统是一个面向医院/科室场景的前端应用,用于撰写手术图文报告、管理报告模板、维护用户权限、从手术视频抽取关键帧,并通过 AI 辅助生成或改写报告内容。
|
||||
|
||||
当前系统已开始后端化:登录认证已接入 NestJS Session API 和数据库 Session Store,工作台统计、报告、报告媒体、模板、字段库、模板图片资源、视频/关键帧文件、用户、部门权限、系统设置、签名文件、AI 对话和讯飞语音听写已优先接入后端 API/代理。开发模式仍保留 `localStorage` 兼容回退,生产构建默认关闭本地回退。
|
||||
@@ -245,163 +302,110 @@ docker-compose down
|
||||
- Docker 前端同时暴露 `http://localhost:4002` 和自签名证书的 `https://localhost:4443`;麦克风听写建议使用 HTTPS 演示入口。
|
||||
- `api` 服务运行 NestJS 后端,启动时默认执行 `prisma migrate deploy` 和 `prisma db seed`,并把上传文件目录挂载到 `uploads_data` volume。
|
||||
- `db` 服务运行 PostgreSQL 16。
|
||||
- `frpc` 服务是可选公网隧道客户端。`# XXX` 默认 Docker Compose 通过 profile 关闭,配置文件在 `frpc/frpc.toml`;NAS 版为了适配 Container Station 图形界面会默认创建 `tuwen_frpc`,读取 `frpc/frpc.nas.toml`。
|
||||
- `frpc` 服务是可选公网隧道客户端。`# XXX` 默认 Docker Compose 通过 profile 关闭,配置文件在 `frpc/frpc.toml`;NAS 版为了适配 Container Station 图形界面会默认创建 `tuwen_frpc`,并在容器启动时自动写入 frpc 配置,不依赖宿主机文件挂载。
|
||||
- `nginx.conf` 已配置 SPA 路由回退、`/api` 反向代理和 `100m` 请求体上限。
|
||||
- `nginx.conf` 已支持 `/api/speech/iat` WebSocket upgrade。
|
||||
完整 Docker 说明见 [docs/docker.md](./docs/docker.md)。
|
||||
|
||||
## 威联通 NAS 部署
|
||||
|
||||
<!-- # XXX NAS 部署新增:适用于 QNAP/威联通 Container Station 或 NAS 终端 docker compose 部署。 -->
|
||||
本 huijutec.cn 适配包提供 [docker-compose-Nas.yaml](./docker-compose-Nas.yaml),用于在威联通 QTS Container Station 中直接部署完整图文报告系统。该文件已经写入你的当前部署参数:
|
||||
|
||||
仓库提供 [docker-compose-Nas.yaml](./docker-compose-Nas.yaml),用于在威联通 NAS 上直接部署完整图文报告系统。它与默认 Compose 的主要区别:
|
||||
|
||||
- 使用 `/share/Container/tuwen_system_v2/data` 作为默认持久化目录。`# XXX` 如 NAS 共享目录不同,修改 `NAS_DATA_ROOT` 或 compose 文件中的路径。
|
||||
- 项目源码目录固定为 `/share/Container/tuwen_system_v2`,避免 QTS 在临时目录执行 Compose 时找不到 `Dockerfile.server`。
|
||||
- 使用 `/share/Container/tuwen_system_v2/data` 作为默认持久化目录。
|
||||
- API 默认映射到 NAS 宿主机 `4102`,前端仍映射到 `4002`。
|
||||
- 保留 `api` 网络别名,确保容器内 Nginx 可以继续把 `/api` 代理到后端。
|
||||
- 使用 `127.0.0.1` 做 API 健康检查,规避部分 NAS 固件上的 IPv6 localhost 解析问题。
|
||||
- 默认创建 `tuwen_frpc` 容器,读取 [frpc/frpc.nas.toml](./frpc/frpc.nas.toml),把容器内 `tuwen_web:80` 映射到公网服务器;如果不需要公网映射,可删除或注释 `tuwen_frpc` 服务。
|
||||
- 默认创建 `tuwen_frpc` 容器,在容器内自动写入 frpc 配置,把容器内 `tuwen_web:80` 映射到公网服务器 `82.157.255.195:4002`。
|
||||
- 默认公网入口为 `https://sstwbg.huijutec.cn`。
|
||||
- 默认构建和运行代理为 `http://192.168.31.7:7893`。
|
||||
- 容器 Nginx 已对 `/api` 强制传递 `X-Forwarded-Proto: https`,确保后端能正常写入 `Secure` 登录 Cookie。
|
||||
|
||||
NAS 终端部署:
|
||||
QTS Container Station 部署时,直接选择或粘贴 [docker-compose-Nas.yaml](./docker-compose-Nas.yaml) 内容即可。
|
||||
|
||||
NAS 终端部署也可以直接执行:
|
||||
|
||||
```bash
|
||||
# XXX 进入 NAS 上的项目目录后执行。
|
||||
cd /share/Container/tuwen_system_v2
|
||||
docker compose -f docker-compose-Nas.yaml up -d --build
|
||||
|
||||
curl http://127.0.0.1:4002/api/health
|
||||
docker compose -f docker-compose-Nas.yaml ps
|
||||
```
|
||||
|
||||
公网部署时建议先准备 NAS `.env` 或 Container Station 环境变量:
|
||||
|
||||
```bash
|
||||
# XXX 必改:生产环境不要继续使用默认 Session 密钥。
|
||||
SESSION_SECRET=替换为足够长的随机字符串
|
||||
|
||||
# XXX 如果公网入口是 https://your-domain.example,建议开启这两项。
|
||||
SESSION_COOKIE_SECURE=true
|
||||
TRUST_PROXY=true
|
||||
CORS_ORIGIN=http://NAS_IP:4002,https://your-domain.example
|
||||
|
||||
# XXX 如需代理构建或让后端访问外网,可按 NAS 网络环境配置。
|
||||
HTTP_PROXY=http://PROXY_IP:PROXY_PORT
|
||||
HTTPS_PROXY=http://PROXY_IP:PROXY_PORT
|
||||
NO_PROXY=localhost,127.0.0.1,LAN_CIDR,tuwen_db,tuwen_api,tuwen_web,api,db,web
|
||||
```
|
||||
|
||||
NAS 上的 frpc 隧道:
|
||||
|
||||
```bash
|
||||
# XXX 先编辑 frpc/frpc.nas.toml,替换 serverAddr 和 auth.token。
|
||||
docker compose -f docker-compose-Nas.yaml up -d --build
|
||||
docker compose -f docker-compose-Nas.yaml logs -f tuwen_frpc
|
||||
```
|
||||
|
||||
`# XXX` NAS 公网访问仍然只需要把 `4002` 通过 frpc 映射到公网服务器,再由 Nginx Proxy Manager 给 `your-domain.example` 提供 HTTPS。`4443` 仍只是本机自签名 HTTPS 演示入口,不建议映射到公网域名。
|
||||
`tuwen_frpc` 启动后,FRP 面板中 `TuWen_System_V2` 应显示 `Online`。公网访问地址为:
|
||||
|
||||
```text
|
||||
https://sstwbg.huijutec.cn/
|
||||
```
|
||||
|
||||
## 公网反向代理部署
|
||||
|
||||
<!-- # XXX 公网部署新增:适用于本机 Docker 4002 端口通过 frpc 映射到公网服务器,再由 Nginx Proxy Manager 绑定 your-domain.example 的部署链路。 -->
|
||||
|
||||
推荐公网链路:
|
||||
本 huijutec.cn 适配包已按下面链路预置:
|
||||
|
||||
```text
|
||||
浏览器 https://your-domain.example
|
||||
浏览器 https://sstwbg.huijutec.cn
|
||||
-> 公网服务器 Nginx Proxy Manager
|
||||
-> frps/frpc 映射端口
|
||||
-> 本机 Docker web:4002
|
||||
-> frps/frpc remotePort 4002
|
||||
-> NAS Docker tuwen_web:80
|
||||
-> 容器 Nginx /api 代理
|
||||
-> api:3100
|
||||
-> tuwen_api:3100
|
||||
```
|
||||
|
||||
本机部署并确认 Docker 服务正常:
|
||||
|
||||
```bash
|
||||
# XXX 在部署机器上使用当前最新版分支。
|
||||
git fetch origin
|
||||
git checkout surclaw-system-backendized-20260502
|
||||
git pull --ff-only origin surclaw-system-backendized-20260502
|
||||
|
||||
# XXX 公网 HTTPS 部署建议替换 Session 密钥,并信任外层反向代理。
|
||||
export SESSION_SECRET="替换为足够长的随机字符串"
|
||||
export SESSION_COOKIE_SECURE="true"
|
||||
export TRUST_PROXY="true"
|
||||
|
||||
docker-compose up -d --build
|
||||
curl http://127.0.0.1:4002/api/health
|
||||
```
|
||||
|
||||
如果使用 frpc 把本机 `4002` 映射到公网服务器,先编辑仓库内置配置:
|
||||
NAS 版 frpc 配置已经写入 [docker-compose-Nas.yaml](./docker-compose-Nas.yaml) 的 `tuwen_frpc` 服务启动命令:
|
||||
|
||||
```toml
|
||||
# frpc/frpc.toml
|
||||
# XXX 替换公网 frps 地址和 token;不要把正式 token 提交到仓库。
|
||||
serverAddr = "XX.XX.XX.XX"
|
||||
serverAddr = "82.157.255.195"
|
||||
serverPort = 7000
|
||||
|
||||
auth.method = "token"
|
||||
auth.token = "XXX"
|
||||
auth.token = "en.xjtu.edu.cn"
|
||||
|
||||
[[proxies]]
|
||||
name = "TuWen_System_V2"
|
||||
type = "tcp"
|
||||
localIP = "127.0.0.1"
|
||||
localPort = 4002
|
||||
localIP = "tuwen_web"
|
||||
localPort = 80
|
||||
remotePort = 4002
|
||||
```
|
||||
|
||||
`# XXX` 当前 `docker-compose.yaml` 已内置可选 `frpc` 服务,并使用 `network_mode: host` 让 frpc 容器可以访问本机 `127.0.0.1:4002`。启动完整系统和 frpc:
|
||||
公网服务器 Nginx Proxy Manager 中对应 Proxy Host 应保持:
|
||||
|
||||
```bash
|
||||
docker-compose --profile frpc up -d --build
|
||||
docker-compose logs -f frpc
|
||||
```
|
||||
|
||||
如果只想先启动系统、不启用公网隧道,继续使用:
|
||||
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
`# XXX` 公网正式访问只需要映射 `4002` 到公网服务器,再由公网 Nginx Proxy Manager 提供 `https://your-domain.example`。不建议把 `4443` 映射到公网域名;`4443` 是本机自签名 HTTPS 演示入口,主要用于 `https://localhost:4443` 测试麦克风。
|
||||
|
||||
Nginx Proxy Manager 中为 `your-domain.example` 新建 Proxy Host:
|
||||
|
||||
- `Domain Names`:`your-domain.example`
|
||||
- `Domain Names`:`sstwbg.huijutec.cn`
|
||||
- `Scheme`:`http`
|
||||
- `Forward Hostname / IP`:frps 可访问到的映射地址,通常是 `127.0.0.1`、公网服务器内网 IP 或 frps 指定监听地址。
|
||||
- `Forward Port`:frpc 暴露出来的 `remotePort`,例如 `4002`。
|
||||
- `Websockets Support`:开启。`# XXX` 语音识别使用 `/api/speech/iat` WebSocket,必须透传 Upgrade。
|
||||
- `Forward Hostname / IP`:frps 暴露 `remotePort` 的地址。
|
||||
- `Forward Port`:`4002`
|
||||
- `Websockets Support`:开启。语音识别使用 `/api/speech/iat` WebSocket,必须透传 Upgrade。
|
||||
- `Block Common Exploits`:开启。
|
||||
- `SSL`:申请或绑定 `your-domain.example` 证书,开启 `Force SSL`。`# XXX` 浏览器麦克风权限要求 HTTPS,普通公网 HTTP 下语音识别不可用。
|
||||
- `SSL`:绑定 `sstwbg.huijutec.cn` 证书,开启 `Force SSL`。浏览器麦克风权限要求 HTTPS。
|
||||
|
||||
Nginx Proxy Manager 的 `Advanced` 可加入:
|
||||
|
||||
```nginx
|
||||
# XXX 图文报告、关键帧和模板图片可能较大,公网代理请求体上限需与容器 Nginx/API 保持一致。
|
||||
client_max_body_size 100m;
|
||||
|
||||
# XXX WebSocket 语音听写需要较长连接时间。
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
|
||||
# XXX SESSION_COOKIE_SECURE=true 时,后端必须能看到原始公网协议是 HTTPS。
|
||||
# XXX 如果登录接口 200 但没有 Set-Cookie,或 /api/auth/me 返回 401 未登录,补充这两行。
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Ssl on;
|
||||
```
|
||||
|
||||
公网验收顺序:
|
||||
|
||||
```text
|
||||
1. 打开 https://your-domain.example/api/health,确认 API 健康检查可访问。
|
||||
2. 打开 https://your-domain.example 登录 admin / 123456。
|
||||
1. 打开 https://sstwbg.huijutec.cn/api/health,确认 API 健康检查可访问。
|
||||
2. 打开 https://sstwbg.huijutec.cn 登录 admin / 123456。
|
||||
3. 进入系统设置,确认 AI Provider 和讯飞语音配置有效。
|
||||
4. 进入报告编辑页,测试上传视频、自动抽帧、报告保存、AI 对话和语音听写。
|
||||
5. 浏览器控制台执行 window.isSecureContext,应返回 true;否则语音麦克风权限不会开放。
|
||||
```
|
||||
|
||||
如果登录失败或刷新后掉登录,优先检查 `SESSION_SECRET` 是否稳定、`SESSION_COOKIE_SECURE=true` 时是否同时设置了 `TRUST_PROXY=true`,以及外层 NPM 是否把 `X-Forwarded-Proto: https` 传给后端链路。若 `POST /api/auth/login` 返回 200 但响应头没有 `Set-Cookie`,随后 `GET /api/auth/me` 返回 `401 未登录`,基本就是 HTTPS 协议头没有传到后端;按上面的 NPM Advanced 配置补充 `proxy_set_header X-Forwarded-Proto https;` 后重建/重启 Web/API。
|
||||
如果登录失败或刷新后掉登录,优先检查 `SESSION_SECRET` 是否稳定、`SESSION_COOKIE_SECURE=true` 时是否同时设置了 `TRUST_PROXY=true`,以及外层 NPM 是否把 `X-Forwarded-Proto: https` 传给后端链路。
|
||||
如果只有语音识别失败,优先检查 NPM 的 `Websockets Support`、HTTPS 证书、浏览器麦克风权限、系统设置中的讯飞 APPID/APIKey/APISecret,以及后端容器是否能访问讯飞 `wss://iat-api.xfyun.cn/v2/iat`。
|
||||
|
||||
## 当前限制
|
||||
|
||||
Reference in New Issue
Block a user