diff --git a/.gitignore b/.gitignore index 5d20302..6ecf05a 100755 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,77 @@ -# Python-generated files -__pycache__/ -*.py[oc] -build/ -dist/ -wheels/ -*.egg-info +# ============================================================================= +# Operation Room Monitor — root .gitignore +# ============================================================================= -# Virtual environments -.venv +# --- OS --- +.DS_Store +.AppleDouble +.LSOverride +Thumbs.db +ehthumbs.db +Desktop.ini +# --- IDE / editors --- +.idea/ +.vscode/ +*.swp +*.swo +*~ +.project +.classpath +.settings/ -# Runtime consumption TSV (开发联调) -logs/ - -# Environment +# --- Environment & secrets (all layers) --- .env .env.* !.env.example +!**/.env.example +backend/.env +backend/.env.* +!backend/.env.example -# Demo 一键联调写入的 RTSP 映射(可被覆盖) +# --- Python caches (never commit) --- +.mypy_cache/ +**/.mypy_cache/ +**/__pycache__/ +**/*.py[cod] +**/*$py.class +**/.pytest_cache/ +**/.mypy_cache/ +**/.ruff_cache/ +**/.pycache-verify/ +**/build/ +**/wheels/ +**/*.egg-info/ +**/.coverage +**/htmlcov/ +**/.tox/ +**/.nox/ +**/dist/ +!clients/voice-confirmation/scripts/ + +# Backend runtime & caches +backend/logs/ +backend/Ultralytics/ + +# Large model weights (deploy via mount or offline delivery) +backend/app/resources/actionformer_epoch_045.pth.tar + +# --- Clients --- clients/demo-client/.runtime/ clients/demo-client/labels.json clients/voice-confirmation/dist/ -# IDE / OS -.idea/ -.vscode/ -.DS_Store +# --- Docker --- +**/.docker/ -# Ultralytics / YOLO: local cache and user settings (keep on machine only) +# --- Logs & temp --- +*.log +*.tmp +*.temp +.cache/ + +# --- Legacy / local-only at repo root (pre-restructure) --- +.venv/ +logs/ Ultralytics/ - -# - -# 5-6 ActionFormer checkpoint:>100MB,部署时挂载或离线下发,不入库 -app/resources/actionformer_epoch_045.pth.tar \ No newline at end of file +scripts/ diff --git a/README.md b/README.md index e69de29..8bd6055 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,41 @@ +# Operation Room Monitor + +手术室耗材监控:后端 API(GPU 推理)+ 独立浏览器客户端。 + +## 目录结构 + +``` +. +├── backend/ # FastAPI + PostgreSQL + MinIO +│ ├── app/ # 业务与算法 +│ ├── docker-compose.yml +│ ├── Dockerfile +│ ├── .env.example +│ └── ... +├── clients/ # 独立前端(手动部署) +│ ├── demo-client/ # 联调 Demo 页 (:38081) +│ └── voice-confirmation/ # 语音确认页 (:8080) +└── docs/ # 部署与接口文档 +``` + +## 快速开始 + +```bash +# 1. 配置并启动后端(在 backend/ 目录) +cp backend/.env.example backend/.env # 编辑配置 +cd backend && docker compose up -d --build + +# 2. 启动客户端(各开终端) +cd clients/demo-client && ./start.sh +cd clients/voice-confirmation && ./start.sh +``` + +- API:`http://<服务器IP>:38080` +- Demo:`http://<服务器IP>:38081` +- 语音确认:`http://<服务器IP>:8080` + +## 文档 + +- [Docker 部署](docs/Docker部署.md) +- [客户端接口说明](docs/客户端手术通信接口说明.md) +- [语音确认页使用指南](docs/部署版使用指南.md) diff --git a/.dockerignore b/backend/.dockerignore similarity index 100% rename from .dockerignore rename to backend/.dockerignore diff --git a/.env.example b/backend/.env.example similarity index 97% rename from .env.example rename to backend/.env.example index 3c3575a..98be648 100755 --- a/.env.example +++ b/backend/.env.example @@ -1,4 +1,4 @@ -# 复制为 `.env` 并按环境填写。后端通过 Docker Compose 部署:`docker compose up -d --build` +# 复制为 `backend/.env` 并按环境填写。在 `backend/` 目录执行:`docker compose up -d --build` # 详细说明见 docs/Docker部署.md 与 docs/video-backends.md。 # 算法、管线、归档路径、视觉/语音日志等非部署项见 `app/baked/algorithm.py` 与 `app/baked/pipeline.py`。 # diff --git a/Dockerfile b/backend/Dockerfile similarity index 100% rename from Dockerfile rename to backend/Dockerfile diff --git a/alembic.ini b/backend/alembic.ini similarity index 100% rename from alembic.ini rename to backend/alembic.ini diff --git a/alembic/env.py b/backend/alembic/env.py similarity index 100% rename from alembic/env.py rename to backend/alembic/env.py diff --git a/alembic/script.py.mako b/backend/alembic/script.py.mako similarity index 100% rename from alembic/script.py.mako rename to backend/alembic/script.py.mako diff --git a/alembic/versions/0001_initial.py b/backend/alembic/versions/0001_initial.py similarity index 100% rename from alembic/versions/0001_initial.py rename to backend/alembic/versions/0001_initial.py diff --git a/app/__init__.py b/backend/app/__init__.py similarity index 100% rename from app/__init__.py rename to backend/app/__init__.py diff --git a/app/algorithm_ipc/__init__.py b/backend/app/algorithm_ipc/__init__.py similarity index 100% rename from app/algorithm_ipc/__init__.py rename to backend/app/algorithm_ipc/__init__.py diff --git a/app/algorithm_ipc/schema.py b/backend/app/algorithm_ipc/schema.py similarity index 100% rename from app/algorithm_ipc/schema.py rename to backend/app/algorithm_ipc/schema.py diff --git a/app/algorithm_runner/__init__.py b/backend/app/algorithm_runner/__init__.py similarity index 100% rename from app/algorithm_runner/__init__.py rename to backend/app/algorithm_runner/__init__.py diff --git a/app/algorithm_runner/__main__.py b/backend/app/algorithm_runner/__main__.py similarity index 100% rename from app/algorithm_runner/__main__.py rename to backend/app/algorithm_runner/__main__.py diff --git a/app/algorithm_runner/actionformer_gated/__init__.py b/backend/app/algorithm_runner/actionformer_gated/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/__init__.py rename to backend/app/algorithm_runner/actionformer_gated/__init__.py diff --git a/app/algorithm_runner/actionformer_gated/inference.py b/backend/app/algorithm_runner/actionformer_gated/inference.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/inference.py rename to backend/app/algorithm_runner/actionformer_gated/inference.py diff --git a/app/algorithm_runner/actionformer_gated/runner.py b/backend/app/algorithm_runner/actionformer_gated/runner.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/runner.py rename to backend/app/algorithm_runner/actionformer_gated/runner.py diff --git a/app/algorithm_runner/actionformer_gated/segment_helpers.py b/backend/app/algorithm_runner/actionformer_gated/segment_helpers.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/segment_helpers.py rename to backend/app/algorithm_runner/actionformer_gated/segment_helpers.py diff --git a/app/algorithm_runner/actionformer_gated/videoswin.py b/backend/app/algorithm_runner/actionformer_gated/videoswin.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/videoswin.py rename to backend/app/algorithm_runner/actionformer_gated/videoswin.py diff --git a/app/algorithm_runner/actionformer_gated/whitelist_indices.py b/backend/app/algorithm_runner/actionformer_gated/whitelist_indices.py similarity index 100% rename from app/algorithm_runner/actionformer_gated/whitelist_indices.py rename to backend/app/algorithm_runner/actionformer_gated/whitelist_indices.py diff --git a/app/algorithm_runner/actionformer_release/__init__.py b/backend/app/algorithm_runner/actionformer_release/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_release/__init__.py rename to backend/app/algorithm_runner/actionformer_release/__init__.py diff --git a/app/algorithm_runner/actionformer_release/libs/__init__.py b/backend/app/algorithm_runner/actionformer_release/libs/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/__init__.py rename to backend/app/algorithm_runner/actionformer_release/libs/__init__.py diff --git a/app/algorithm_runner/actionformer_release/libs/core/__init__.py b/backend/app/algorithm_runner/actionformer_release/libs/core/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/core/__init__.py rename to backend/app/algorithm_runner/actionformer_release/libs/core/__init__.py diff --git a/app/algorithm_runner/actionformer_release/libs/core/config.py b/backend/app/algorithm_runner/actionformer_release/libs/core/config.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/core/config.py rename to backend/app/algorithm_runner/actionformer_release/libs/core/config.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/__init__.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/__init__.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/__init__.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/backbones.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/backbones.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/backbones.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/backbones.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/blocks.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/blocks.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/blocks.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/blocks.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/loc_generators.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/loc_generators.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/loc_generators.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/loc_generators.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/losses.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/losses.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/losses.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/losses.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/meta_archs.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/meta_archs.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/meta_archs.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/meta_archs.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/models.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/models.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/models.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/models.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/necks.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/necks.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/necks.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/necks.py diff --git a/app/algorithm_runner/actionformer_release/libs/modeling/weight_init.py b/backend/app/algorithm_runner/actionformer_release/libs/modeling/weight_init.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/modeling/weight_init.py rename to backend/app/algorithm_runner/actionformer_release/libs/modeling/weight_init.py diff --git a/app/algorithm_runner/actionformer_release/libs/utils/__init__.py b/backend/app/algorithm_runner/actionformer_release/libs/utils/__init__.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/utils/__init__.py rename to backend/app/algorithm_runner/actionformer_release/libs/utils/__init__.py diff --git a/app/algorithm_runner/actionformer_release/libs/utils/nms.py b/backend/app/algorithm_runner/actionformer_release/libs/utils/nms.py similarity index 100% rename from app/algorithm_runner/actionformer_release/libs/utils/nms.py rename to backend/app/algorithm_runner/actionformer_release/libs/utils/nms.py diff --git a/app/algorithm_runner/cli.py b/backend/app/algorithm_runner/cli.py similarity index 100% rename from app/algorithm_runner/cli.py rename to backend/app/algorithm_runner/cli.py diff --git a/app/algorithm_runner/infer_util.py b/backend/app/algorithm_runner/infer_util.py similarity index 100% rename from app/algorithm_runner/infer_util.py rename to backend/app/algorithm_runner/infer_util.py diff --git a/app/algorithm_runner/reference_bundle_runtime.py b/backend/app/algorithm_runner/reference_bundle_runtime.py similarity index 100% rename from app/algorithm_runner/reference_bundle_runtime.py rename to backend/app/algorithm_runner/reference_bundle_runtime.py diff --git a/app/algorithm_runner/segment_policy.py b/backend/app/algorithm_runner/segment_policy.py similarity index 100% rename from app/algorithm_runner/segment_policy.py rename to backend/app/algorithm_runner/segment_policy.py diff --git a/app/api.py b/backend/app/api.py similarity index 100% rename from app/api.py rename to backend/app/api.py diff --git a/app/baked/__init__.py b/backend/app/baked/__init__.py similarity index 100% rename from app/baked/__init__.py rename to backend/app/baked/__init__.py diff --git a/app/baked/algorithm.py b/backend/app/baked/algorithm.py similarity index 100% rename from app/baked/algorithm.py rename to backend/app/baked/algorithm.py diff --git a/app/baked/pipeline.py b/backend/app/baked/pipeline.py similarity index 100% rename from app/baked/pipeline.py rename to backend/app/baked/pipeline.py diff --git a/app/config.py b/backend/app/config.py similarity index 98% rename from app/config.py rename to backend/app/config.py index 3fe304f..725fab6 100755 --- a/app/config.py +++ b/backend/app/config.py @@ -193,7 +193,7 @@ class Settings(BaseSettings): default="vision", validation_alias=AliasChoices("VIDEO_RESULT_DOCTOR_ID", "video_result_doctor_id"), ) - #: 算法引用包目录(相对仓库根,如 ``refs/5.15``);可用环境变量 ``REFERENCE_BUNDLE_RELATIVE`` 覆盖。 + #: 算法引用包目录(相对 backend 根目录,如 ``refs/5.15``);可用环境变量 ``REFERENCE_BUNDLE_RELATIVE`` 覆盖。 reference_bundle_relative: str = Field( default="refs/5.15", validation_alias=AliasChoices("REFERENCE_BUNDLE_RELATIVE", "reference_bundle_relative"), diff --git a/app/consumable_catalog.py b/backend/app/consumable_catalog.py similarity index 100% rename from app/consumable_catalog.py rename to backend/app/consumable_catalog.py diff --git a/app/database.py b/backend/app/database.py similarity index 100% rename from app/database.py rename to backend/app/database.py diff --git a/app/db/__init__.py b/backend/app/db/__init__.py similarity index 100% rename from app/db/__init__.py rename to backend/app/db/__init__.py diff --git a/app/db/base.py b/backend/app/db/base.py similarity index 100% rename from app/db/base.py rename to backend/app/db/base.py diff --git a/app/db/models.py b/backend/app/db/models.py similarity index 100% rename from app/db/models.py rename to backend/app/db/models.py diff --git a/app/dependencies.py b/backend/app/dependencies.py similarity index 100% rename from app/dependencies.py rename to backend/app/dependencies.py diff --git a/app/domain/__init__.py b/backend/app/domain/__init__.py similarity index 100% rename from app/domain/__init__.py rename to backend/app/domain/__init__.py diff --git a/app/domain/consumption.py b/backend/app/domain/consumption.py similarity index 100% rename from app/domain/consumption.py rename to backend/app/domain/consumption.py diff --git a/app/domain/vision_prediction.py b/backend/app/domain/vision_prediction.py similarity index 100% rename from app/domain/vision_prediction.py rename to backend/app/domain/vision_prediction.py diff --git a/app/or_site_config.py b/backend/app/or_site_config.py similarity index 100% rename from app/or_site_config.py rename to backend/app/or_site_config.py diff --git a/app/repositories/__init__.py b/backend/app/repositories/__init__.py similarity index 100% rename from app/repositories/__init__.py rename to backend/app/repositories/__init__.py diff --git a/app/repositories/surgery_results.py b/backend/app/repositories/surgery_results.py similarity index 100% rename from app/repositories/surgery_results.py rename to backend/app/repositories/surgery_results.py diff --git a/app/repositories/voice_audits.py b/backend/app/repositories/voice_audits.py similarity index 100% rename from app/repositories/voice_audits.py rename to backend/app/repositories/voice_audits.py diff --git a/app/resources/consumable_classifier.pt b/backend/app/resources/consumable_classifier.pt similarity index 100% rename from app/resources/consumable_classifier.pt rename to backend/app/resources/consumable_classifier.pt diff --git a/app/resources/consumable_classifier_labels.yaml b/backend/app/resources/consumable_classifier_labels.yaml similarity index 100% rename from app/resources/consumable_classifier_labels.yaml rename to backend/app/resources/consumable_classifier_labels.yaml diff --git a/app/resources/goodbad_frame_best.pt b/backend/app/resources/goodbad_frame_best.pt similarity index 100% rename from app/resources/goodbad_frame_best.pt rename to backend/app/resources/goodbad_frame_best.pt diff --git a/app/resources/hand_detect_best.pt b/backend/app/resources/hand_detect_best.pt similarity index 100% rename from app/resources/hand_detect_best.pt rename to backend/app/resources/hand_detect_best.pt diff --git a/app/resources/haocai_41cls_best.pt b/backend/app/resources/haocai_41cls_best.pt similarity index 100% rename from app/resources/haocai_41cls_best.pt rename to backend/app/resources/haocai_41cls_best.pt diff --git a/app/resources/or_site_config.sample.json b/backend/app/resources/or_site_config.sample.json similarity index 100% rename from app/resources/or_site_config.sample.json rename to backend/app/resources/or_site_config.sample.json diff --git a/app/routers/__init__.py b/backend/app/routers/__init__.py similarity index 100% rename from app/routers/__init__.py rename to backend/app/routers/__init__.py diff --git a/app/routers/demo_orch.py b/backend/app/routers/demo_orch.py similarity index 100% rename from app/routers/demo_orch.py rename to backend/app/routers/demo_orch.py diff --git a/app/schemas.py b/backend/app/schemas.py similarity index 100% rename from app/schemas.py rename to backend/app/schemas.py diff --git a/app/services/__init__.py b/backend/app/services/__init__.py similarity index 100% rename from app/services/__init__.py rename to backend/app/services/__init__.py diff --git a/app/services/audio_wav.py b/backend/app/services/audio_wav.py similarity index 100% rename from app/services/audio_wav.py rename to backend/app/services/audio_wav.py diff --git a/app/services/baidu_speech.py b/backend/app/services/baidu_speech.py similarity index 100% rename from app/services/baidu_speech.py rename to backend/app/services/baidu_speech.py diff --git a/app/services/consumption_tsv_log.py b/backend/app/services/consumption_tsv_log.py similarity index 100% rename from app/services/consumption_tsv_log.py rename to backend/app/services/consumption_tsv_log.py diff --git a/app/services/minio_audio_storage.py b/backend/app/services/minio_audio_storage.py similarity index 100% rename from app/services/minio_audio_storage.py rename to backend/app/services/minio_audio_storage.py diff --git a/app/services/pending_confirmation_port.py b/backend/app/services/pending_confirmation_port.py similarity index 100% rename from app/services/pending_confirmation_port.py rename to backend/app/services/pending_confirmation_port.py diff --git a/app/services/surgery_pipeline.py b/backend/app/services/surgery_pipeline.py similarity index 100% rename from app/services/surgery_pipeline.py rename to backend/app/services/surgery_pipeline.py diff --git a/app/services/synthetic_rtsp.py b/backend/app/services/synthetic_rtsp.py similarity index 100% rename from app/services/synthetic_rtsp.py rename to backend/app/services/synthetic_rtsp.py diff --git a/app/services/video/__init__.py b/backend/app/services/video/__init__.py similarity index 100% rename from app/services/video/__init__.py rename to backend/app/services/video/__init__.py diff --git a/app/services/video/archive_persister.py b/backend/app/services/video/archive_persister.py similarity index 100% rename from app/services/video/archive_persister.py rename to backend/app/services/video/archive_persister.py diff --git a/app/services/video/backend_resolver.py b/backend/app/services/video/backend_resolver.py similarity index 100% rename from app/services/video/backend_resolver.py rename to backend/app/services/video/backend_resolver.py diff --git a/app/services/video/frame_encode.py b/backend/app/services/video/frame_encode.py similarity index 100% rename from app/services/video/frame_encode.py rename to backend/app/services/video/frame_encode.py diff --git a/app/services/video/hikvision_runtime.py b/backend/app/services/video/hikvision_runtime.py similarity index 100% rename from app/services/video/hikvision_runtime.py rename to backend/app/services/video/hikvision_runtime.py diff --git a/app/services/video/rtsp_redact.py b/backend/app/services/video/rtsp_redact.py similarity index 100% rename from app/services/video/rtsp_redact.py rename to backend/app/services/video/rtsp_redact.py diff --git a/app/services/video/session_manager.py b/backend/app/services/video/session_manager.py similarity index 100% rename from app/services/video/session_manager.py rename to backend/app/services/video/session_manager.py diff --git a/app/services/video/session_registry.py b/backend/app/services/video/session_registry.py similarity index 100% rename from app/services/video/session_registry.py rename to backend/app/services/video/session_registry.py diff --git a/app/services/video/types.py b/backend/app/services/video/types.py similarity index 100% rename from app/services/video/types.py rename to backend/app/services/video/types.py diff --git a/app/services/video_batch_runner.py b/backend/app/services/video_batch_runner.py similarity index 100% rename from app/services/video_batch_runner.py rename to backend/app/services/video_batch_runner.py diff --git a/app/services/voice_audit_emitter.py b/backend/app/services/voice_audit_emitter.py similarity index 100% rename from app/services/voice_audit_emitter.py rename to backend/app/services/voice_audit_emitter.py diff --git a/app/services/voice_confirm.py b/backend/app/services/voice_confirm.py similarity index 100% rename from app/services/voice_confirm.py rename to backend/app/services/voice_confirm.py diff --git a/app/services/voice_file_log.py b/backend/app/services/voice_file_log.py similarity index 100% rename from app/services/voice_file_log.py rename to backend/app/services/voice_file_log.py diff --git a/app/services/voice_resolution.py b/backend/app/services/voice_resolution.py similarity index 100% rename from app/services/voice_resolution.py rename to backend/app/services/voice_resolution.py diff --git a/app/services/voice_terminal_binding.py b/backend/app/services/voice_terminal_binding.py similarity index 100% rename from app/services/voice_terminal_binding.py rename to backend/app/services/voice_terminal_binding.py diff --git a/app/services/voice_terminal_hub.py b/backend/app/services/voice_terminal_hub.py similarity index 100% rename from app/services/voice_terminal_hub.py rename to backend/app/services/voice_terminal_hub.py diff --git a/app/surgery_errors.py b/backend/app/surgery_errors.py similarity index 100% rename from app/surgery_errors.py rename to backend/app/surgery_errors.py diff --git a/app/terminal_markdown.py b/backend/app/terminal_markdown.py similarity index 100% rename from app/terminal_markdown.py rename to backend/app/terminal_markdown.py diff --git a/docker-compose.yml b/backend/docker-compose.yml similarity index 96% rename from docker-compose.yml rename to backend/docker-compose.yml index 845bfc2..b1a4a80 100644 --- a/docker-compose.yml +++ b/backend/docker-compose.yml @@ -1,6 +1,6 @@ # Unified backend stack: FastAPI + PostgreSQL + MinIO (GPU via NVIDIA Container Toolkit). -# Deploy: docker compose up -d --build -# Client pages: clients/demo-client/start.sh, clients/voice-confirmation/start.sh +# Deploy from this directory: docker compose up -d --build +# Client pages (repo root): ../clients/demo-client/start.sh, ../clients/voice-confirmation/start.sh services: db: image: m.daocloud.io/docker.io/library/postgres:16-alpine diff --git a/main.py b/backend/main.py similarity index 100% rename from main.py rename to backend/main.py diff --git a/pyproject.toml b/backend/pyproject.toml similarity index 100% rename from pyproject.toml rename to backend/pyproject.toml diff --git a/tests/__init__.py b/backend/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to backend/tests/__init__.py diff --git a/tests/conftest.py b/backend/tests/conftest.py similarity index 100% rename from tests/conftest.py rename to backend/tests/conftest.py diff --git a/tests/faces/图片_20260423151100_350_42.png b/backend/tests/faces/图片_20260423151100_350_42.png similarity index 100% rename from tests/faces/图片_20260423151100_350_42.png rename to backend/tests/faces/图片_20260423151100_350_42.png diff --git a/tests/faces/图片_20260423162025_32_52.png b/backend/tests/faces/图片_20260423162025_32_52.png similarity index 100% rename from tests/faces/图片_20260423162025_32_52.png rename to backend/tests/faces/图片_20260423162025_32_52.png diff --git a/tests/faces/图片_20260423162213_11_62.png b/backend/tests/faces/图片_20260423162213_11_62.png similarity index 100% rename from tests/faces/图片_20260423162213_11_62.png rename to backend/tests/faces/图片_20260423162213_11_62.png diff --git a/tests/faces/图片_20260423172228_12_62.png b/backend/tests/faces/图片_20260423172228_12_62.png similarity index 100% rename from tests/faces/图片_20260423172228_12_62.png rename to backend/tests/faces/图片_20260423172228_12_62.png diff --git a/tests/faces/图片_20260423184622_13_62.png b/backend/tests/faces/图片_20260423184622_13_62.png similarity index 100% rename from tests/faces/图片_20260423184622_13_62.png rename to backend/tests/faces/图片_20260423184622_13_62.png diff --git a/tests/faces/图片_20260424165952_58_52.png b/backend/tests/faces/图片_20260424165952_58_52.png similarity index 100% rename from tests/faces/图片_20260424165952_58_52.png rename to backend/tests/faces/图片_20260424165952_58_52.png diff --git a/tests/faces/图片_20260424170014_59_52.png b/backend/tests/faces/图片_20260424170014_59_52.png similarity index 100% rename from tests/faces/图片_20260424170014_59_52.png rename to backend/tests/faces/图片_20260424170014_59_52.png diff --git a/tests/faces/图片_20260424170052_60_52.png b/backend/tests/faces/图片_20260424170052_60_52.png similarity index 100% rename from tests/faces/图片_20260424170052_60_52.png rename to backend/tests/faces/图片_20260424170052_60_52.png diff --git a/tests/faces/图片_20260424170106_61_52.png b/backend/tests/faces/图片_20260424170106_61_52.png similarity index 100% rename from tests/faces/图片_20260424170106_61_52.png rename to backend/tests/faces/图片_20260424170106_61_52.png diff --git a/tests/faces/图片_20260424170114_62_52.png b/backend/tests/faces/图片_20260424170114_62_52.png similarity index 100% rename from tests/faces/图片_20260424170114_62_52.png rename to backend/tests/faces/图片_20260424170114_62_52.png diff --git a/tests/test_actionformer_gated_runner.py b/backend/tests/test_actionformer_gated_runner.py similarity index 100% rename from tests/test_actionformer_gated_runner.py rename to backend/tests/test_actionformer_gated_runner.py diff --git a/tests/test_actionformer_segment_consumption.py b/backend/tests/test_actionformer_segment_consumption.py similarity index 100% rename from tests/test_actionformer_segment_consumption.py rename to backend/tests/test_actionformer_segment_consumption.py diff --git a/tests/test_algorithm_cli_modes.py b/backend/tests/test_algorithm_cli_modes.py similarity index 100% rename from tests/test_algorithm_cli_modes.py rename to backend/tests/test_algorithm_cli_modes.py diff --git a/tests/test_api_contract.py b/backend/tests/test_api_contract.py similarity index 100% rename from tests/test_api_contract.py rename to backend/tests/test_api_contract.py diff --git a/tests/test_app_integration.py b/backend/tests/test_app_integration.py similarity index 100% rename from tests/test_app_integration.py rename to backend/tests/test_app_integration.py diff --git a/tests/test_archive_persister.py b/backend/tests/test_archive_persister.py similarity index 100% rename from tests/test_archive_persister.py rename to backend/tests/test_archive_persister.py diff --git a/tests/test_archive_restart_recovery.py b/backend/tests/test_archive_restart_recovery.py similarity index 100% rename from tests/test_archive_restart_recovery.py rename to backend/tests/test_archive_restart_recovery.py diff --git a/tests/test_audio_wav_normalize.py b/backend/tests/test_audio_wav_normalize.py similarity index 100% rename from tests/test_audio_wav_normalize.py rename to backend/tests/test_audio_wav_normalize.py diff --git a/tests/test_baidu_asr_fallback.py b/backend/tests/test_baidu_asr_fallback.py similarity index 100% rename from tests/test_baidu_asr_fallback.py rename to backend/tests/test_baidu_asr_fallback.py diff --git a/tests/test_baidu_unified_env.py b/backend/tests/test_baidu_unified_env.py similarity index 100% rename from tests/test_baidu_unified_env.py rename to backend/tests/test_baidu_unified_env.py diff --git a/tests/test_consumption_tsv_log.py b/backend/tests/test_consumption_tsv_log.py similarity index 100% rename from tests/test_consumption_tsv_log.py rename to backend/tests/test_consumption_tsv_log.py diff --git a/tests/test_effective_candidate_consumables.py b/backend/tests/test_effective_candidate_consumables.py similarity index 100% rename from tests/test_effective_candidate_consumables.py rename to backend/tests/test_effective_candidate_consumables.py diff --git a/tests/test_pending_resolve_url_encoding.py b/backend/tests/test_pending_resolve_url_encoding.py similarity index 100% rename from tests/test_pending_resolve_url_encoding.py rename to backend/tests/test_pending_resolve_url_encoding.py diff --git a/tests/test_session_manager_unit.py b/backend/tests/test_session_manager_unit.py similarity index 100% rename from tests/test_session_manager_unit.py rename to backend/tests/test_session_manager_unit.py diff --git a/tests/test_session_rank.py b/backend/tests/test_session_rank.py similarity index 100% rename from tests/test_session_rank.py rename to backend/tests/test_session_rank.py diff --git a/tests/test_stream_worker_redaction.py b/backend/tests/test_stream_worker_redaction.py similarity index 100% rename from tests/test_stream_worker_redaction.py rename to backend/tests/test_stream_worker_redaction.py diff --git a/tests/test_surgery_pipeline_persistence.py b/backend/tests/test_surgery_pipeline_persistence.py similarity index 100% rename from tests/test_surgery_pipeline_persistence.py rename to backend/tests/test_surgery_pipeline_persistence.py diff --git a/tests/test_surgery_repository.py b/backend/tests/test_surgery_repository.py similarity index 100% rename from tests/test_surgery_repository.py rename to backend/tests/test_surgery_repository.py diff --git a/tests/test_video_batch_runner.py b/backend/tests/test_video_batch_runner.py similarity index 100% rename from tests/test_video_batch_runner.py rename to backend/tests/test_video_batch_runner.py diff --git a/tests/test_voice_audit_repository.py b/backend/tests/test_voice_audit_repository.py similarity index 100% rename from tests/test_voice_audit_repository.py rename to backend/tests/test_voice_audit_repository.py diff --git a/tests/test_voice_confirm.py b/backend/tests/test_voice_confirm.py similarity index 100% rename from tests/test_voice_confirm.py rename to backend/tests/test_voice_confirm.py diff --git a/tests/test_voice_file_log.py b/backend/tests/test_voice_file_log.py similarity index 100% rename from tests/test_voice_file_log.py rename to backend/tests/test_voice_file_log.py diff --git a/tests/test_voice_pending_store_protocol.py b/backend/tests/test_voice_pending_store_protocol.py similarity index 100% rename from tests/test_voice_pending_store_protocol.py rename to backend/tests/test_voice_pending_store_protocol.py diff --git a/tests/test_voice_resolution_service.py b/backend/tests/test_voice_resolution_service.py similarity index 100% rename from tests/test_voice_resolution_service.py rename to backend/tests/test_voice_resolution_service.py diff --git a/tests/test_voice_terminal_binding.py b/backend/tests/test_voice_terminal_binding.py similarity index 100% rename from tests/test_voice_terminal_binding.py rename to backend/tests/test_voice_terminal_binding.py diff --git a/uv.lock b/backend/uv.lock similarity index 100% rename from uv.lock rename to backend/uv.lock diff --git a/clients/README.md b/clients/README.md new file mode 100644 index 0000000..e9a4bb9 --- /dev/null +++ b/clients/README.md @@ -0,0 +1,10 @@ +# Clients + +独立浏览器前端,与 `backend/` 分宿部署。 + +| 目录 | 用途 | 默认端口 | +|------|------|----------| +| [demo-client/](demo-client/) | 手术流程联调 Demo | 38081 | +| [voice-confirmation/](voice-confirmation/) | 语音确认终端页 | 8080 | + +启动前请先在 `backend/` 执行 `docker compose up -d --build`。 diff --git a/clients/demo-client/README.md b/clients/demo-client/README.md index 659d9eb..1633c11 100755 --- a/clients/demo-client/README.md +++ b/clients/demo-client/README.md @@ -6,11 +6,11 @@ ``` clients/demo-client/ - start.sh # 启动入口(默认 0.0.0.0:38081) - server.py # stdlib 静态服务器;额外暴露 /labels.json - index.html # 单文件页面(原生 JS,零构建依赖) - labels.yaml # 耗材类名快照(与后端 app/resources/consumable_classifier_labels.yaml 同步) - fake_rtsp_from_file.py # 无真摄像头时:本地视频推 RTSP(ffmpeg + Docker MediaMTX) + start.sh + server.py + index.html + labels.yaml # 耗材类名快照(与 backend/app/resources/consumable_classifier_labels.yaml 同步) + fake_rtsp_from_file.py ``` **`labels.yaml`**:本目录自带副本,与后端解耦。后端类名变更时,请同步更新此文件。 @@ -18,12 +18,11 @@ clients/demo-client/ ## 运行 ```bash -# 1) 在仓库根目录启动 Docker 后端 -docker compose up -d --build +# 1) 启动 Docker 后端 +cd backend && docker compose up -d --build # 2) 在本目录启动 Demo 页 -./start.sh -# 或:python server.py -p 38081 --host 0.0.0.0 +cd ../clients/demo-client && ./start.sh # 3) 浏览器访问 open http://127.0.0.1:38081/ @@ -33,40 +32,12 @@ open http://127.0.0.1:38081/ ## 调试:无真实摄像头,用录好的视频模拟 RTSP -监控服务**只从 RTSP URL 拉流**,没有视频上传 HTTP 接口。推荐在宿主机用 **ffmpeg + MediaMTX** 推假流: - -**单路**: - ```bash python3 fake_rtsp_from_file.py /path/to/recording.mp4 --port 18554 --path demo ``` -**两路**: - -```bash -python3 fake_rtsp_from_file.py --port 18554 \ - --stream 'or-cam-01|./a.mp4|demo1' \ - --stream 'or-cam-02|./b.mp4|demo2' -``` - -`--stream` 格式:`CAMERA_ID|文件路径|RTSP_PATH`。脚本会在 stderr 打印站点 JSON 片段,可合并进后端的 `OR_SITE_CONFIG_JSON_FILE`。 - -### API 在 Docker、假 RTSP 在宿主机 - -容器内访问宿主机 RTSP 应使用 `rtsp://host.docker.internal:<端口>/<路径>`(compose 已配置 `extra_hosts`)。详见 [`../../docs/video-backends.md`](../../docs/video-backends.md)。 - -## 一键开录 - -Demo 页勾选「一键联调」后上传视频,调用 `POST /internal/demo/orchestrate-and-start`。需后端 `.env` 中 `DEMO_ORCHESTRATOR_ENABLED=true`,且 API 容器能执行 `docker`/`ffmpeg`(通常需挂载 docker.sock)。 - -## 页面功能 - -- `GET /health` 连通性检查 -- `POST /client/surgeries/start|end`、`GET /client/surgeries/{id}/result` -- 调试区:多路视频、假 RTSP、`camera_id` 同步 - -不含语音确认 UI(见 [`../voice-confirmation/`](../voice-confirmation/))。 +容器内 API 访问宿主机 RTSP 应使用 `host.docker.internal`。详见 [`../../docs/video-backends.md`](../../docs/video-backends.md)。 ## CORS -跨域访问 API 时,后端需 `DEMO_CORS_ENABLED=true`;生产环境收窄 `DEMO_CORS_ORIGINS`。 +跨域访问 API 时,后端 `backend/.env` 需 `DEMO_CORS_ENABLED=true`;生产环境收窄 `DEMO_CORS_ORIGINS`。 diff --git a/clients/demo-client/start.sh b/clients/demo-client/start.sh index ed7a9c0..b96c129 100755 --- a/clients/demo-client/start.sh +++ b/clients/demo-client/start.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Start the standalone demo client page for LAN access. -# Backend must be running first: docker compose up -d --build (in repo root) +# Backend must be running first: cd backend && docker compose up -d --build # Usage: ./start.sh [port] set -euo pipefail diff --git a/clients/voice-confirmation/README.md b/clients/voice-confirmation/README.md index b0a9a96..014e366 100755 --- a/clients/voice-confirmation/README.md +++ b/clients/voice-confirmation/README.md @@ -3,41 +3,35 @@ **与监控 API 分宿**的浏览器静态页(`index.html` + `voice_app.js`,Tailwind 使用 CDN)。复制本目录或 `dist/` 即可独立分发。 - 功能:播放 TTS、并行录音、`POST .../resolve` 上传 WAV;WebSocket 收 `voice_assignment` / `voice_pending` 等。协议见 [`../../docs/客户端手术通信接口说明.md`](../../docs/客户端手术通信接口说明.md)。 -- 界面:默认 **术间模式**;接口地址与调试信息在 **「高级设置」** 内。 - **禁止使用 `file://` 打开**;须通过 HTTP(S) 访问。 ## 启动 -仅需 **Python 3**: - ```bash ./start.sh # 默认 0.0.0.0:8080 -./start.sh 9000 # 指定端口 +./start.sh 9000 ./start.sh --single # 打包单 HTML 后启动 dist/ ``` Windows:`start.bat`(用法同上)。 -也可直接使用本目录内的 `start_http.sh` / `start_http.bat`。 +浏览器将 **Base URL** 指向监控 API(例如 `http://192.168.1.100:38080`)。后端启动: -环境变量 **`VOCH_HTTP_BIND`**:默认 `0.0.0.0`(局域网终端访问);仅本机调试可设 `127.0.0.1`。 +```bash +cd backend && docker compose up -d --build +``` -浏览器将 **Base URL** 指向监控 API,例如 `http://192.168.1.100:38080`(后端由仓库根目录 `docker compose up -d --build` 启动,详见 [`../../docs/Docker部署.md`](../../docs/Docker部署.md))。 +详见 [`../../docs/Docker部署.md`](../../docs/Docker部署.md)。 -## 单 HTML 分发(`dist/`) +## 单 HTML 分发 ```bash python3 scripts/bundle_single_html.py # 或:./start.sh --single ``` -生成 `dist/index.html`(内联脚本)及 `dist/start_http.*`。对外只发包 **`dist/`** 即可;该目录被 `.gitignore` 忽略。 - -## 生产部署 - -- 本目录整体或 **`dist/`** 可交给 Nginx / Caddy / CDN;非 localhost 通常需 **HTTPS** 才能稳定使用麦克风。 -- **CORS**:后端需 `DEMO_CORS_ENABLED=true`;生产建议收窄 `DEMO_CORS_ORIGINS`。 +生成 `dist/index.html`;该目录被 `.gitignore` 忽略。 ## 与 Demo 客户端的关系 -流程联调见 [`../demo-client/`](../demo-client/)(默认 `:38081`)。语音闭环仅在本目录或 `dist/` 完成。 +流程联调见 [`../demo-client/`](../demo-client/)(默认 `:38081`)。 diff --git a/docs/Docker部署.md b/docs/Docker部署.md index 9ad5e27..ba0e867 100644 --- a/docs/Docker部署.md +++ b/docs/Docker部署.md @@ -2,169 +2,76 @@ 本文说明在 **NVIDIA GPU 服务器**上通过 Docker Compose 部署全套后端(FastAPI + PostgreSQL + MinIO),以及 Demo 客户端、语音确认页的**手动**启动方式。 +## 仓库结构 + +``` +operation-room-monitor/ + backend/ # API + DB + MinIO(docker compose) + clients/ # 独立前端(手动启动) + docs/ # 文档 +``` + ## 架构 | 组件 | 部署方式 | 默认端口 | |------|----------|----------| -| API + PostgreSQL + MinIO | `docker compose up -d --build` | 38080 / 35432 / 9000 | -| Demo 客户端 | `clients/demo-client/start.sh`(宿主机 Python) | 38081 | -| 语音确认页 | `clients/voice-confirmation/start.sh`(宿主机 Python) | 8080 | - -Demo 页与语音页通过 HTTP/WebSocket 访问 API;浏览器 Base URL 填 `http://:38080`。 +| API + PostgreSQL + MinIO | `cd backend && docker compose up -d --build` | 38080 / 35432 / 9000 | +| Demo 客户端 | `clients/demo-client/start.sh` | 38081 | +| 语音确认页 | `clients/voice-confirmation/start.sh` | 8080 | --- ## 一、前置条件 -### 宿主机 - -- **Docker** 与 **Docker Compose V2**(`docker compose`) -- **NVIDIA 驱动**,`nvidia-smi` 正常 -- **[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)**,且 `docker run --rm --gpus all nvidia/cuda:12.0.0-base-ubuntu22.04 nvidia-smi` 可用 -- 磁盘:PostgreSQL / MinIO 使用命名卷,建议预留数十 GB - -### 仓库与配置 - -1. 复制环境变量模板: - -```bash -cp .env.example .env -``` - -2. 编辑 `.env`:至少修改 `POSTGRES_PASSWORD`;配置 `BAIDU_*`(语音)、`OR_SITE_CONFIG_JSON_FILE`(站点 JSON)等。 - -3. 确保 ActionFormer 权重存在:`app/resources/actionformer_epoch_045.pth.tar`(~110MB,离线下发,未入 git)。 - -4. VideoSwin 预训练权重首次运行可能需联网下载;容器内默认缓存目录 `TORCH_HOME=/root/.cache/torch`。 +- Docker Compose V2、NVIDIA 驱动、NVIDIA Container Toolkit +- 复制 `backend/.env.example` 为 `backend/.env` 并填写 +- ActionFormer 权重:`backend/app/resources/actionformer_epoch_045.pth.tar` --- ## 二、启动后端 ```bash +cd backend docker compose up -d --build ``` -首次构建或代码变更后加 `--build`;日常重启可用 `docker compose up -d`。 - 健康检查: ```bash curl -sf http://127.0.0.1:38080/health ``` -GPU 验证(可选): +GPU 验证: ```bash docker compose exec api python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))" ``` -常用环境变量(写在 `.env` 中): - -| 变量 | 说明 | -|------|------| -| `API_PORT` | API 宿主机映射端口,默认 38080 | -| `DOCKER_POSTGRES_PUBLISH_PORT` | PostgreSQL 宿主机映射端口,默认 35432(仅调试) | - -查看日志: - -```bash -docker compose logs -f api -``` - -停止服务: +停止 / 重置: ```bash docker compose down -``` - -**重置所有数据**(PostgreSQL + MinIO 卷会被删除): - -```bash -docker compose down -v +docker compose down -v # 删除 PostgreSQL / MinIO 卷 ``` --- -## 三、手动启动客户端页面 - -后端 `docker compose up -d` 成功后,在**同一台或局域网内其他机器**上: +## 三、手动启动客户端 ```bash -# Demo 联调页(默认 0.0.0.0:38081) cd clients/demo-client && ./start.sh - -# 语音确认页(默认 0.0.0.0:8080) cd clients/voice-confirmation && ./start.sh ``` -浏览器访问: - -- Demo:`http://<主机IP>:38081/` -- 语音确认:`http://<主机IP>:8080/` - -两页内的 **服务端 Base URL** 均指向监控 API:`http://:38080`。 - -### CORS - -独立部署的前端跨域访问 API 时,`.env` 中需 `DEMO_CORS_ENABLED=true`。生产环境建议将 `DEMO_CORS_ORIGINS` 收窄为具体来源,例如: - -```bash -DEMO_CORS_ORIGINS=http://192.168.1.100:8080,http://192.168.1.100:38081 -``` - -### 语音确认单 HTML 分发 - -```bash -cd clients/voice-confirmation && ./start.sh --single 8080 -``` - -会生成 `clients/voice-confirmation/dist/index.html` 并启动静态服务,便于离线拷贝。 +浏览器 Base URL 填 `http://:38080`。 --- -## 四、RTSP 与站点配置 +## 四、相关文档 -- 站点 JSON(`OR_SITE_CONFIG_JSON_FILE`)维护术间、摄像头 RTSP、语音终端绑定;样例见 `app/resources/or_site_config.sample.json`。 -- API 在 Docker 内访问**宿主机**上的 RTSP 假流时,URL 应使用 `host.docker.internal`(compose 已为 `api` 配置 `extra_hosts`)。 -- 详见 [video-backends.md](video-backends.md)。 - -无真摄像头联调时,可在宿主机运行 `clients/demo-client/fake_rtsp_from_file.py`,详见 [clients/demo-client/README.md](../clients/demo-client/README.md)。 - ---- - -## 五、常见问题 - -**Q:容器内 GPU 不可用?** - -确认宿主机已安装 NVIDIA Container Toolkit,且 `docker-compose.yml` 中 `api` 服务含 `gpus: all`。验证: - -```bash -docker compose exec api python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))" -``` - -**Q:语音页麦克风不可用?** - -勿用 `file://` 打开;须通过 HTTP(S) 访问。非 localhost 场景通常需要 HTTPS。 - -**Q:如何升级 API?** - -```bash -docker compose build api -docker compose up -d api -``` - -容器启动时会执行 `alembic upgrade head`。 - -**Q:离线 tarball 交付?** - -见 [离线镜像tarball部署.md](离线镜像tarball部署.md)。 - ---- - -## 六、相关文档 - -- [部署版使用指南.md](部署版使用指南.md) — 语音确认页填写说明(面向现场人员) -- [客户端手术通信接口说明.md](客户端手术通信接口说明.md) — API 协议 -- [clients/voice-confirmation/README.md](../clients/voice-confirmation/README.md) — 语音页独立分发 -- [clients/demo-client/README.md](../clients/demo-client/README.md) — Demo 页与假 RTSP +- [部署版使用指南.md](部署版使用指南.md) +- [客户端手术通信接口说明.md](客户端手术通信接口说明.md) +- [clients/demo-client/README.md](../clients/demo-client/README.md) +- [clients/voice-confirmation/README.md](../clients/voice-confirmation/README.md) +- [离线镜像tarball部署.md](离线镜像tarball部署.md) diff --git a/docs/video-backends.md b/docs/video-backends.md index 2cc5e67..40fded8 100755 --- a/docs/video-backends.md +++ b/docs/video-backends.md @@ -17,7 +17,7 @@ ## Docker 与 RTSP 地址 - **站点 JSON 中的局域网 IP**(如 `[or_site_config.sample.json](../app/resources/or_site_config.sample.json)` 的 `192.168.3.x`):API 在默认 **bridge** 网络下出站流量经 **宿主机** 转发,只要**宿主机**能访问该网段,容器内一般可直接使用相同 URL,无需改成 `172.x` 等。 -- **`127.0.0.1` / `localhost`**:在容器内指向**容器自身**。若 RTSP 服务跑在宿主机(含 `fake_rtsp_from_file.py`、本机 MediaMTX),URL 应使用 **`rtsp://host.docker.internal:<端口>/<路径>`**。[`docker-compose.yml`](../docker-compose.yml) 已为 `api` 服务配置 `extra_hosts: host.docker.internal:host-gateway`(Linux 兼容;macOS/Windows Desktop 通常已内置该主机名)。 +- **`127.0.0.1` / `localhost`**:在容器内指向**容器自身**。若 RTSP 服务跑在宿主机(含 `fake_rtsp_from_file.py`、本机 MediaMTX),URL 应使用 **`rtsp://host.docker.internal:<端口>/<路径>`**。[`backend/docker-compose.yml`](../backend/docker-compose.yml) 已为 `api` 服务配置 `extra_hosts: host.docker.internal:host-gateway`(Linux 兼容;macOS/Windows Desktop 通常已内置该主机名)。 - **传输协议**:compose 默认设置环境变量 **`OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp`**,使 OpenCV 经 FFmpeg 以 **TCP** 拉 RTSP,降低容器/NAT 下 UDP 丢包导致的首帧超时;可通过环境变量覆盖。 ## 海康官方 SDK 模式(可选) @@ -47,4 +47,4 @@ SDK **不作为构建期依赖**:将厂商提供的 Linux x86_64 动态库挂 ## 相关环境变量 -详见仓库根目录 `.env.example` 中「视频:RTSP + 可选海康 HCNetSDK」一节。 \ No newline at end of file +详见 `backend/.env.example` 中「视频:RTSP + 可选海康 HCNetSDK」一节。 \ No newline at end of file diff --git a/docs/客户端手术通信接口说明.md b/docs/客户端手术通信接口说明.md index 52b9c82..098c085 100755 --- a/docs/客户端手术通信接口说明.md +++ b/docs/客户端手术通信接口说明.md @@ -36,7 +36,7 @@ RTSP 地址、账号、口令等由客户端对接工程师提供给服务端运 | `or-cam-03` | `rtsp://admin:Aa183137@192.168.3.4:554/Streaming/Channels/101` | 同上 | | `or-cam-04` | `rtsp://admin:Aa183137@192.168.3.5:554/Streaming/Channels/101` | 同上 | -**Docker 部署**:API 在容器内拉流时,上表这类**术间摄像头局域网 IP**通常可继续使用(出站经宿主机路由,须宿主机已能访问该网段)。若 RTSP 实际跑在**宿主机本机**(假流等),URL 中的主机应使用 `host.docker.internal`,勿写 `127.0.0.1`;详见 `docs/video-backends.md` 与 `docker-compose.yml`。 +**Docker 部署**:API 在容器内拉流时,上表这类**术间摄像头局域网 IP**通常可继续使用(出站经宿主机路由,须宿主机已能访问该网段)。若 RTSP 实际跑在**宿主机本机**(假流等),URL 中的主机应使用 `host.docker.internal`,勿写 `127.0.0.1`;详见 `docs/video-backends.md` 与 `backend/docker-compose.yml`。 ## 3. HTTP 路由一览 diff --git a/docs/离线镜像tarball部署.md b/docs/离线镜像tarball部署.md index 00d31fc..afe2eac 100755 --- a/docs/离线镜像tarball部署.md +++ b/docs/离线镜像tarball部署.md @@ -2,7 +2,7 @@ 本文说明 **方式 B**:厂商在可联网环境构建并导出 API 镜像为 `tar`/`tar.gz`,客户在目标服务器 **不拉取 API 镜像构建上下文** 的情况下,通过 `docker load` 加载后启动完整后端(PostgreSQL + MinIO + API)。 -> 说明:仓库默认的 `docker-compose.yml` 中 `api` 使用 `build:`。客户侧使用 tarball 时,必须使用下方 **「仅使用已加载镜像」** 的 Compose 片段(将 `build` 换成 `image`),否则仍会尝试本地构建。 +> 说明:仓库默认的 `backend/docker-compose.yml` 中 `api` 使用 `build:`。客户侧使用 tarball 时,必须使用下方 **「仅使用已加载镜像」** 的 Compose 片段(将 `build` 换成 `image`),否则仍会尝试本地构建。 --- @@ -13,7 +13,7 @@ ### 1. 构建并打标签 ```bash -cd /path/to/operation-room-monitor-server +cd /path/to/operation-room-monitor/backend docker compose build api docker tag operation-room-monitor-server-api:latest <交付镜像名>:<版本号> # 示例:docker tag operation-room-monitor-server-api:latest acme/or-monitor-api:1.0.0 @@ -51,8 +51,8 @@ docker save \ |------|------| | `or-monitor-api_*.tar.gz`(或全栈 `*_offline.tar.gz`) | 镜像包 | | 本文档 | 客户部署步骤 | -| `docker-compose.yml` **或** 下文「离线 Compose」全文 | `api` 使用 `image:` 而非 `build:` | -| `.env.example`(按项目实际改名) | 环境变量模板,勿包含真实密钥 plaintext 于公共渠道 | +| `docker-compose.yml` **或** 下文「离线 Compose」全文 | `api` 使用 `image:` 而非 `build:`(位于 `backend/`) | +| `backend/.env.example`(按项目实际改名) | 环境变量模板,勿包含真实密钥 plaintext 于公共渠道 | |(可选)语音确认前端静态包、`OR_SITE_CONFIG` 样例 | 按需 | --- @@ -212,7 +212,7 @@ volumes: ## 五、环境变量与密钥 -在同一目录放置 `.env`(可参考仓库内 `.env.example`)。至少建议关注: +在同一目录(`backend/`)放置 `.env`(可参考 `backend/.env.example`)。至少建议关注: - `POSTGRES_PASSWORD`:生产请务必改为强密码。 - `API_PORT`:宿主机监听端口。 diff --git a/docs/部署版使用指南.md b/docs/部署版使用指南.md index 48b154d..5f2efe3 100755 --- a/docs/部署版使用指南.md +++ b/docs/部署版使用指南.md @@ -52,4 +52,4 @@ --- -以上内容对应仓库里的语音确认页面(`clients/voice-confirmation`)。手术室主程序、摄像头等由别家软件或信息科配置,不在此页填写。 \ No newline at end of file +以上内容对应 `clients/voice-confirmation/` 语音确认页面。手术室主程序、摄像头等由别家软件或信息科配置,不在此页填写。 \ No newline at end of file