修正了部署脚本
parent
60b4c1f3a6
commit
9079d82729
32
.env.example
32
.env.example
|
|
@ -1,15 +1,28 @@
|
||||||
|
# ==================== 部署模式说明 ====================
|
||||||
|
# 1. 默认 Docker 一体化部署(./start.sh / docker-compose.yml):
|
||||||
|
# 使用下方 MYSQL_* / REDIS_* 初始化内置 MySQL、Redis。
|
||||||
|
# 2. 直接运行后端或外接中间件部署:
|
||||||
|
# 后端现在也兼容读取当前文件中的 MYSQL_HOST / REDIS_HOST,
|
||||||
|
# 也可以使用 backend/.env 中的 DB_* / REDIS_* 配置。
|
||||||
|
|
||||||
# ==================== 数据库配置 ====================
|
# ==================== 数据库配置 ====================
|
||||||
# MySQL数据库配置
|
# MySQL 初始化参数(Docker 内置 MySQL)。
|
||||||
MYSQL_ROOT_PASSWORD=Unis@123
|
# 当后端也运行在 Docker 中时,数据库主机应为服务名 `mysql`。
|
||||||
|
# 只有在宿主机直接运行后端时,才需要改成 127.0.0.1 或实际地址。
|
||||||
|
MYSQL_HOST=mysql
|
||||||
|
MYSQL_ROOT_PASSWORD=change_this_password
|
||||||
MYSQL_DATABASE=imeeting
|
MYSQL_DATABASE=imeeting
|
||||||
MYSQL_USER=imeeting
|
MYSQL_USER=imeeting
|
||||||
MYSQL_PASSWORD=Unis@123
|
MYSQL_PASSWORD=change_this_password
|
||||||
MYSQL_PORT=3306
|
MYSQL_PORT=3306
|
||||||
|
|
||||||
# ==================== 缓存配置 ====================
|
# ==================== 缓存配置 ====================
|
||||||
# Redis配置
|
# Redis 初始化参数(Docker 内置 Redis)。
|
||||||
|
# 当后端也运行在 Docker 中时,Redis 主机应为服务名 `redis`。
|
||||||
|
# 只有在宿主机直接运行后端时,才需要改成 127.0.0.1 或实际地址。
|
||||||
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_PASSWORD=Unis@123
|
REDIS_PASSWORD=change_this_password
|
||||||
REDIS_DB=0
|
REDIS_DB=0
|
||||||
|
|
||||||
# ==================== 应用端口配置 ====================
|
# ==================== 应用端口配置 ====================
|
||||||
|
|
@ -17,10 +30,11 @@ REDIS_DB=0
|
||||||
HTTP_PORT=80
|
HTTP_PORT=80
|
||||||
|
|
||||||
# ==================== 应用配置 ====================
|
# ==================== 应用配置 ====================
|
||||||
# 应用访问地址(用于生成外部链接、二维码等)
|
# 应用访问地址(用于生成外部链接、客户端下载链接,以及音频转录时提供给云端拉取音频文件的公网 URL)
|
||||||
# - 直接访问: http://服务器IP
|
# - 本地联调可先填写: http://localhost
|
||||||
# - 域名访问: https://your-domain.com (需配置接入服务器Nginx)
|
# - 使用云端音频转录时,必须改成外部可访问的域名或公网地址,不能填写容器名、127.0.0.1 或内网地址
|
||||||
BASE_URL=https://imeeting.unisspace.com
|
# - 不要以 / 结尾,例如: https://your-domain.com
|
||||||
|
BASE_URL=https://your-domain.com
|
||||||
|
|
||||||
# 前端API地址(通过Nginx代理访问后端)
|
# 前端API地址(通过Nginx代理访问后端)
|
||||||
VITE_API_BASE_URL=/api
|
VITE_API_BASE_URL=/api
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
```bash
|
```bash
|
||||||
# 1. 复制并配置环境变量
|
# 1. 复制并配置环境变量
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
vim .env # 配置七牛云、LLM密钥等
|
vim .env # 配置 BASE_URL、密码等
|
||||||
|
|
||||||
# 2. 一键启动
|
# 2. 一键启动
|
||||||
./start.sh
|
./start.sh
|
||||||
|
|
@ -60,9 +60,7 @@ vim .env # 配置七牛云、LLM密钥等
|
||||||
```bash
|
```bash
|
||||||
# 1. 配置环境变量
|
# 1. 配置环境变量
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
cp backend/.env.example backend/.env
|
|
||||||
vim .env # 配置主环境变量
|
vim .env # 配置主环境变量
|
||||||
vim backend/.env # 配置后端环境变量
|
|
||||||
|
|
||||||
# 2. 启动所有服务
|
# 2. 启动所有服务
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
@ -89,17 +87,12 @@ docker-compose ps
|
||||||
|
|
||||||
### 必须配置项
|
### 必须配置项
|
||||||
|
|
||||||
编辑 `.env` 文件,修改以下配置:
|
编辑根目录 `.env` 文件,修改以下配置:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 七牛云存储(必填,否则无法上传文件)
|
# Docker 一体化部署下,后端容器访问内置 MySQL/Redis 使用服务名
|
||||||
QINIU_ACCESS_KEY=your_actual_access_key
|
MYSQL_HOST=mysql
|
||||||
QINIU_SECRET_KEY=your_actual_secret_key
|
REDIS_HOST=redis
|
||||||
QINIU_BUCKET=your_bucket_name
|
|
||||||
QINIU_DOMAIN=your_domain.clouddn.com
|
|
||||||
|
|
||||||
# LLM API(必填,否则无法使用AI功能)
|
|
||||||
QWEN_API_KEY=your_actual_qwen_api_key
|
|
||||||
|
|
||||||
# 生产环境必改密码
|
# 生产环境必改密码
|
||||||
MYSQL_ROOT_PASSWORD=change_this_password
|
MYSQL_ROOT_PASSWORD=change_this_password
|
||||||
|
|
@ -110,7 +103,8 @@ REDIS_PASSWORD=change_this_password
|
||||||
### 可选配置项
|
### 可选配置项
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 应用访问地址(用于生成二维码等)
|
# 应用访问地址(用于生成外链,以及音频转录时给云端拉取音频文件)
|
||||||
|
# 如果使用云端音频转录,必须改成外部可访问的域名或公网地址,不能填写 localhost / 127.0.0.1 / 容器名
|
||||||
BASE_URL=http://localhost # 生产环境改为: https://your-domain.com
|
BASE_URL=http://localhost # 生产环境改为: https://your-domain.com
|
||||||
|
|
||||||
# Nginx端口(默认80/443)
|
# Nginx端口(默认80/443)
|
||||||
|
|
@ -122,6 +116,21 @@ HTTPS_PORT=443
|
||||||
# HTTP_PORT=80
|
# HTTP_PORT=80
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 外接 MySQL / Redis 部署
|
||||||
|
|
||||||
|
如果使用 `./start-external.sh`,还需要额外配置 `backend/.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp backend/.env.example backend/.env
|
||||||
|
vim backend/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
`backend/.env` 主要负责:
|
||||||
|
|
||||||
|
- `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_NAME`
|
||||||
|
- `REDIS_HOST` / `REDIS_PORT` / `REDIS_DB` / `REDIS_PASSWORD`
|
||||||
|
- 可选的 `BASE_URL`(如显式设置,会覆盖根目录 `.env` 中传给后端容器的值)
|
||||||
|
|
||||||
### 音频预处理依赖
|
### 音频预处理依赖
|
||||||
|
|
||||||
- Docker 部署:后端容器内已安装 `ffmpeg`
|
- Docker 部署:后端容器内已安装 `ffmpeg`
|
||||||
|
|
@ -260,8 +269,9 @@ curl http://localhost/docs
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| 端口被占用 | 修改.env中的HTTP_PORT |
|
| 端口被占用 | 修改.env中的HTTP_PORT |
|
||||||
| 502错误 | 检查backend和frontend是否健康 |
|
| 502错误 | 检查backend和frontend是否健康 |
|
||||||
| 数据库连接失败 | 检查backend/.env配置 |
|
| 数据库连接失败 | 一体化部署检查 `docker-compose.yml` 和根目录 `.env`,外接中间件模式检查 `backend/.env` |
|
||||||
| 前端无法访问API | 检查VITE_API_BASE_URL配置 |
|
| 前端无法访问API | 检查VITE_API_BASE_URL配置 |
|
||||||
|
| 音频转录拉不到音频文件 | 检查 `BASE_URL` 是否为云端可访问的完整地址 |
|
||||||
| 如何配置HTTPS | 参考本文档中的反向代理章节 |
|
| 如何配置HTTPS | 参考本文档中的反向代理章节 |
|
||||||
|
|
||||||
详见:`DOCKER_README.md` 故障排查章节
|
详见:`DOCKER_README.md` 故障排查章节
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,30 @@
|
||||||
# ==================== 数据库配置 ====================
|
# ==================== 数据库配置 ====================
|
||||||
# Docker环境使用容器名称
|
# 供“直接运行 backend”或“./start-external.sh 外接 MySQL/Redis”使用
|
||||||
DB_HOST=10.100.51.51
|
# 如果 backend 运行在 Docker 中,且数据库也在同一 Docker 网络,主机名应填服务名(如 mysql)
|
||||||
DB_USER=root
|
# 如果是宿主机直接运行 backend,再填写 127.0.0.1 或实际地址
|
||||||
DB_PASSWORD=Unis@123
|
DB_HOST=127.0.0.1
|
||||||
DB_NAME=imeeting_dev
|
DB_USER=imeeting
|
||||||
|
DB_PASSWORD=change_this_password
|
||||||
|
DB_NAME=imeeting
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
|
|
||||||
# ==================== Redis配置 ====================
|
# ==================== Redis配置 ====================
|
||||||
# Docker环境使用容器名称
|
# 如果 backend 运行在 Docker 中,且 Redis 也在同一 Docker 网络,主机名应填服务名(如 redis)
|
||||||
REDIS_HOST=10.100.51.51
|
# 如果是宿主机直接运行 backend,再填写 127.0.0.1 或实际地址
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_DB=0
|
REDIS_DB=0
|
||||||
REDIS_PASSWORD=Unis@123
|
REDIS_PASSWORD=change_this_password
|
||||||
|
|
||||||
# ==================== API配置 ====================
|
# ==================== API配置 ====================
|
||||||
API_HOST=0.0.0.0
|
API_HOST=0.0.0.0
|
||||||
API_PORT=8000
|
API_PORT=8000
|
||||||
|
|
||||||
# ==================== 应用配置 ====================
|
# ==================== 应用配置 ====================
|
||||||
# 应用访问地址(用于生成外部链接、二维码等)
|
# 直接运行 backend 时可在这里配置 BASE_URL;
|
||||||
# 开发环境: http://localhost
|
# Docker 容器部署时,优先使用仓库根目录 .env 中的 BASE_URL。
|
||||||
# 生产环境: https://your-domain.com
|
# 使用云端音频转录时,必须填写云端可以访问到的公网地址,且不要以 / 结尾。
|
||||||
BASE_URL=http://imeeting.unisspace.com
|
# BASE_URL=https://your-domain.com
|
||||||
|
|
||||||
|
|
||||||
# ==================== 转录轮询配置 ====================
|
# ==================== 转录轮询配置 ====================
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ from fastapi import APIRouter, Depends, HTTPException
|
||||||
from app.core.database import get_db_connection
|
from app.core.database import get_db_connection
|
||||||
from app.core.auth import get_current_admin_user
|
from app.core.auth import get_current_admin_user
|
||||||
from app.core.response import create_api_response
|
from app.core.response import create_api_response
|
||||||
from app.core.config import QWEN_API_KEY
|
|
||||||
from app.services.system_config_service import SystemConfigService
|
from app.services.system_config_service import SystemConfigService
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
@ -14,6 +13,14 @@ from http import HTTPStatus
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_dashscope_api_key() -> str:
|
||||||
|
audio_config = SystemConfigService.get_active_audio_model_config("asr") or {}
|
||||||
|
api_key = str(audio_config.get("api_key") or "").strip()
|
||||||
|
if not api_key:
|
||||||
|
raise HTTPException(status_code=500, detail="未配置 DashScope API Key")
|
||||||
|
return api_key
|
||||||
|
|
||||||
|
|
||||||
# ── Request Models ──────────────────────────────────────────
|
# ── Request Models ──────────────────────────────────────────
|
||||||
|
|
||||||
class CreateGroupRequest(BaseModel):
|
class CreateGroupRequest(BaseModel):
|
||||||
|
|
@ -135,7 +142,7 @@ async def delete_group(id: int, current_user: dict = Depends(get_current_admin_u
|
||||||
async def sync_group(id: int, current_user: dict = Depends(get_current_admin_user)):
|
async def sync_group(id: int, current_user: dict = Depends(get_current_admin_user)):
|
||||||
"""同步指定组到阿里云 DashScope"""
|
"""同步指定组到阿里云 DashScope"""
|
||||||
try:
|
try:
|
||||||
dashscope.api_key = QWEN_API_KEY
|
dashscope.api_key = _resolve_dashscope_api_key()
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
with get_db_connection() as conn:
|
||||||
cursor = conn.cursor(dictionary=True)
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,9 @@ import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
# 加载 .env 文件
|
|
||||||
env_path = Path(__file__).parent.parent.parent / ".env"
|
|
||||||
load_dotenv(dotenv_path=env_path)
|
|
||||||
|
|
||||||
# 基础路径配置
|
# 基础路径配置
|
||||||
BASE_DIR = Path(__file__).parent.parent.parent
|
BASE_DIR = Path(__file__).parent.parent.parent
|
||||||
|
REPO_DIR = BASE_DIR.parent
|
||||||
UPLOAD_DIR = BASE_DIR / "uploads"
|
UPLOAD_DIR = BASE_DIR / "uploads"
|
||||||
AUDIO_DIR = UPLOAD_DIR / "audio"
|
AUDIO_DIR = UPLOAD_DIR / "audio"
|
||||||
TEMP_UPLOAD_DIR = UPLOAD_DIR / "temp_audio"
|
TEMP_UPLOAD_DIR = UPLOAD_DIR / "temp_audio"
|
||||||
|
|
@ -22,6 +19,42 @@ VOICEPRINT_DIR = USER_DIR
|
||||||
AVATAR_DIR = USER_DIR
|
AVATAR_DIR = USER_DIR
|
||||||
|
|
||||||
|
|
||||||
|
def _load_env_file(dotenv_path: Path) -> None:
|
||||||
|
if dotenv_path.exists():
|
||||||
|
load_dotenv(dotenv_path=dotenv_path, override=False)
|
||||||
|
|
||||||
|
|
||||||
|
# 优先读取仓库根目录 .env,再读取 backend/.env;
|
||||||
|
# 已存在的环境变量(例如 Docker Compose 注入)保持最高优先级。
|
||||||
|
_load_env_file(REPO_DIR / ".env")
|
||||||
|
_load_env_file(BASE_DIR / ".env")
|
||||||
|
|
||||||
|
|
||||||
|
def _get_env(*names: str, default: str | None = None, allow_blank: bool = True) -> str | None:
|
||||||
|
for name in names:
|
||||||
|
value = os.getenv(name)
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
value = value.strip() if isinstance(value, str) else value
|
||||||
|
if value == "" and not allow_blank:
|
||||||
|
continue
|
||||||
|
return value
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def _get_int_env(*names: str, default: int) -> int:
|
||||||
|
raw_value = _get_env(*names, default=str(default), allow_blank=False)
|
||||||
|
try:
|
||||||
|
return int(raw_value) if raw_value is not None else default
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_base_url(value: str | None) -> str:
|
||||||
|
normalized = str(value or "").strip().rstrip("/")
|
||||||
|
return normalized or "http://localhost"
|
||||||
|
|
||||||
|
|
||||||
def get_user_data_dir(user_id: int | str) -> Path:
|
def get_user_data_dir(user_id: int | str) -> Path:
|
||||||
return USER_DIR / str(user_id)
|
return USER_DIR / str(user_id)
|
||||||
|
|
||||||
|
|
@ -55,18 +88,18 @@ LEGACY_AVATAR_DIR.mkdir(exist_ok=True)
|
||||||
|
|
||||||
# 数据库配置
|
# 数据库配置
|
||||||
DATABASE_CONFIG = {
|
DATABASE_CONFIG = {
|
||||||
'host': os.getenv('DB_HOST', '127.0.0.1'),
|
'host': _get_env('DB_HOST', 'MYSQL_HOST', default='127.0.0.1', allow_blank=False),
|
||||||
'user': os.getenv('DB_USER', 'root'),
|
'user': _get_env('DB_USER', 'MYSQL_USER', default='root', allow_blank=False),
|
||||||
'password': os.getenv('DB_PASSWORD', ''),
|
'password': _get_env('DB_PASSWORD', 'MYSQL_PASSWORD', default=''),
|
||||||
'database': os.getenv('DB_NAME', 'imeeting'),
|
'database': _get_env('DB_NAME', 'MYSQL_DATABASE', default='imeeting', allow_blank=False),
|
||||||
'port': int(os.getenv('DB_PORT', '3306')),
|
'port': _get_int_env('DB_PORT', 'MYSQL_PORT', default=3306),
|
||||||
'charset': 'utf8mb4'
|
'charset': 'utf8mb4'
|
||||||
}
|
}
|
||||||
|
|
||||||
# API配置
|
# API配置
|
||||||
API_CONFIG = {
|
API_CONFIG = {
|
||||||
'host': os.getenv('API_HOST', '0.0.0.0'),
|
'host': _get_env('API_HOST', default='0.0.0.0', allow_blank=False),
|
||||||
'port': int(os.getenv('API_PORT', '8000'))
|
'port': _get_int_env('API_PORT', default=8000)
|
||||||
}
|
}
|
||||||
|
|
||||||
# 七牛云配置
|
# 七牛云配置
|
||||||
|
|
@ -77,31 +110,27 @@ API_CONFIG = {
|
||||||
|
|
||||||
# 应用配置
|
# 应用配置
|
||||||
APP_CONFIG = {
|
APP_CONFIG = {
|
||||||
'base_url': os.getenv('BASE_URL', 'http://imeeting.unisspace.com')
|
'base_url': _normalize_base_url(_get_env('BASE_URL', default='http://localhost', allow_blank=False))
|
||||||
}
|
}
|
||||||
|
|
||||||
# Redis配置
|
# Redis配置
|
||||||
REDIS_CONFIG = {
|
REDIS_CONFIG = {
|
||||||
'host': os.getenv('REDIS_HOST', '127.0.0.1'),
|
'host': _get_env('REDIS_HOST', default='127.0.0.1', allow_blank=False),
|
||||||
'port': int(os.getenv('REDIS_PORT', '6379')),
|
'port': _get_int_env('REDIS_PORT', default=6379),
|
||||||
'db': int(os.getenv('REDIS_DB', '0')),
|
'db': _get_int_env('REDIS_DB', default=0),
|
||||||
'password': os.getenv('REDIS_PASSWORD', ''),
|
'password': _get_env('REDIS_PASSWORD', default=''),
|
||||||
'decode_responses': True
|
'decode_responses': True
|
||||||
}
|
}
|
||||||
|
|
||||||
# Dashscope (Tongyi Qwen) API Key
|
|
||||||
QWEN_API_KEY = os.getenv('QWEN_API_KEY', 'sk-c2bf06ea56b4491ea3d1e37fdb472b8f')
|
|
||||||
|
|
||||||
# 转录轮询配置 - 用于 upload-audio-complete 接口
|
# 转录轮询配置 - 用于 upload-audio-complete 接口
|
||||||
TRANSCRIPTION_POLL_CONFIG = {
|
TRANSCRIPTION_POLL_CONFIG = {
|
||||||
'poll_interval': int(os.getenv('TRANSCRIPTION_POLL_INTERVAL', '10')), # 轮询间隔:10秒
|
'poll_interval': _get_int_env('TRANSCRIPTION_POLL_INTERVAL', default=10), # 轮询间隔:10秒
|
||||||
'max_wait_time': int(os.getenv('TRANSCRIPTION_MAX_WAIT_TIME', '1800')), # 最大等待:30分钟
|
'max_wait_time': _get_int_env('TRANSCRIPTION_MAX_WAIT_TIME', default=1800), # 最大等待:30分钟
|
||||||
}
|
}
|
||||||
|
|
||||||
# 后台任务配置
|
# 后台任务配置
|
||||||
BACKGROUND_TASK_CONFIG = {
|
BACKGROUND_TASK_CONFIG = {
|
||||||
'summary_workers': int(os.getenv('SUMMARY_TASK_MAX_WORKERS', '2')),
|
'summary_workers': _get_int_env('SUMMARY_TASK_MAX_WORKERS', default=2),
|
||||||
'monitor_workers': int(os.getenv('MONITOR_TASK_MAX_WORKERS', '8')),
|
'monitor_workers': _get_int_env('MONITOR_TASK_MAX_WORKERS', default=8),
|
||||||
'transcription_status_cache_ttl': int(os.getenv('TRANSCRIPTION_STATUS_CACHE_TTL', '3')),
|
'transcription_status_cache_ttl': _get_int_env('TRANSCRIPTION_STATUS_CACHE_TTL', default=3),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from http import HTTPStatus
|
||||||
import dashscope
|
import dashscope
|
||||||
from dashscope.audio.asr import Transcription
|
from dashscope.audio.asr import Transcription
|
||||||
|
|
||||||
from app.core.config import QWEN_API_KEY, REDIS_CONFIG, APP_CONFIG, BACKGROUND_TASK_CONFIG
|
from app.core.config import REDIS_CONFIG, APP_CONFIG, BACKGROUND_TASK_CONFIG
|
||||||
from app.core.database import get_db_connection
|
from app.core.database import get_db_connection
|
||||||
from app.services.system_config_service import SystemConfigService
|
from app.services.system_config_service import SystemConfigService
|
||||||
|
|
||||||
|
|
@ -31,9 +31,8 @@ class AsyncTranscriptionService:
|
||||||
"""异步转录服务类"""
|
"""异步转录服务类"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
dashscope.api_key = QWEN_API_KEY
|
|
||||||
self.redis_client = redis.Redis(**REDIS_CONFIG)
|
self.redis_client = redis.Redis(**REDIS_CONFIG)
|
||||||
self.base_url = APP_CONFIG['base_url']
|
self.base_url = APP_CONFIG['base_url'].rstrip('/')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_requests_session(default_timeout: Optional[int] = None) -> requests.Session:
|
def _create_requests_session(default_timeout: Optional[int] = None) -> requests.Session:
|
||||||
|
|
@ -53,7 +52,7 @@ class AsyncTranscriptionService:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _resolve_dashscope_api_key(audio_config: Optional[Dict[str, Any]] = None) -> str:
|
def _resolve_dashscope_api_key(audio_config: Optional[Dict[str, Any]] = None) -> str:
|
||||||
api_key = (audio_config or {}).get("api_key") or QWEN_API_KEY
|
api_key = (audio_config or {}).get("api_key")
|
||||||
if isinstance(api_key, str):
|
if isinstance(api_key, str):
|
||||||
api_key = api_key.strip()
|
api_key = api_key.strip()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
|
|
@ -194,7 +193,7 @@ class AsyncTranscriptionService:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
# 2. 构造完整的文件URL
|
# 2. 构造完整的文件URL
|
||||||
file_url = f"{self.base_url}{audio_file_path}"
|
file_url = f"{self.base_url}/{audio_file_path.lstrip('/')}"
|
||||||
|
|
||||||
# 获取音频模型配置
|
# 获取音频模型配置
|
||||||
audio_config = SystemConfigService.get_active_audio_model_config("asr")
|
audio_config = SystemConfigService.get_active_audio_model_config("asr")
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from typing import Optional, Dict, Generator, Any, List
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
import app.core.config as config_module
|
|
||||||
from app.core.database import get_db_connection
|
from app.core.database import get_db_connection
|
||||||
from app.services.system_config_service import SystemConfigService
|
from app.services.system_config_service import SystemConfigService
|
||||||
|
|
||||||
|
|
@ -79,7 +78,7 @@ class LLMService:
|
||||||
endpoint_url = str(config.get("endpoint_url") or SystemConfigService.get_llm_endpoint_url() or "").strip()
|
endpoint_url = str(config.get("endpoint_url") or SystemConfigService.get_llm_endpoint_url() or "").strip()
|
||||||
api_key = cls._normalize_api_key(config.get("api_key"))
|
api_key = cls._normalize_api_key(config.get("api_key"))
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
api_key = cls._normalize_api_key(SystemConfigService.get_llm_api_key(config_module.QWEN_API_KEY))
|
api_key = cls._normalize_api_key(SystemConfigService.get_llm_api_key())
|
||||||
|
|
||||||
default_model = SystemConfigService.get_llm_model_name()
|
default_model = SystemConfigService.get_llm_model_name()
|
||||||
default_timeout = SystemConfigService.get_llm_timeout()
|
default_timeout = SystemConfigService.get_llm_timeout()
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,6 @@ services:
|
||||||
API_HOST: 0.0.0.0
|
API_HOST: 0.0.0.0
|
||||||
API_PORT: 8000
|
API_PORT: 8000
|
||||||
BASE_URL: ${BASE_URL:-http://localhost}
|
BASE_URL: ${BASE_URL:-http://localhost}
|
||||||
|
|
||||||
# LLM配置
|
|
||||||
QWEN_API_KEY: ${QWEN_API_KEY}
|
|
||||||
# 后端不直接暴露端口,通过nginx代理访问
|
# 后端不直接暴露端口,通过nginx代理访问
|
||||||
ports:
|
ports:
|
||||||
- "${BACKEND_PORT:-8000}:8000"
|
- "${BACKEND_PORT:-8000}:8000"
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ check_env_files() {
|
||||||
if [ ! -f .env ]; then
|
if [ ! -f .env ]; then
|
||||||
print_warning ".env 文件不存在,从模板创建..."
|
print_warning ".env 文件不存在,从模板创建..."
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
print_warning "请编辑 .env 文件,配置访问端口、BASE_URL、QWEN_API_KEY 等参数"
|
print_warning "请编辑 .env 文件,配置访问端口、BASE_URL 等参数"
|
||||||
print_warning "按任意键继续,或 Ctrl+C 退出..."
|
print_warning "按任意键继续,或 Ctrl+C 退出..."
|
||||||
read -n 1 -s
|
read -n 1 -s
|
||||||
fi
|
fi
|
||||||
|
|
@ -139,6 +139,12 @@ services:
|
||||||
REDIS_DB: "${REDIS_DB}"
|
REDIS_DB: "${REDIS_DB}"
|
||||||
REDIS_PASSWORD: "${REDIS_PASSWORD}"
|
REDIS_PASSWORD: "${REDIS_PASSWORD}"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
if [ -n "${BASE_URL:-}" ]; then
|
||||||
|
cat >> "$OVERRIDE_FILE" <<EOF
|
||||||
|
BASE_URL: "${BASE_URL}"
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
start_services() {
|
start_services() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue