fcfa5af614
- feat(deploy): 前端多阶段构建 (vite build + nginx:alpine),移除 Vite 开发模式 - feat(deploy): OpenResty HTTPS 配置 (SSL + HSTS + 安全头) - fix(ws): WebSocket 路由添加 /api 前缀,修正前后端路径不匹配 - security: SSH AutoAddPolicy → WarningPolicy - security: CORS 来源环境变量化 (CORS_ORIGINS) - security: 限流器使用 X-Forwarded-For 真实客户端 IP - perf(db): 数据库连接池配置 (pool_size=20, max_overflow=40) - refactor: 移除硬编码 URL/IP (NTP、域名、微信代理),改为环境变量 - chore: 更新 .env.example 模板,补充新增配置项 - chore: 清理 .reasonix/、scripts/、guide.md 无用文件 - docs: 更新 CLAUDE.md 至 v0.10.0,补充生产架构文档 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
2.1 KiB
Python
76 lines
2.1 KiB
Python
"""应用配置"""
|
||
import os
|
||
from pathlib import Path
|
||
from pydantic_settings import BaseSettings
|
||
|
||
# 项目根目录(config.py 位于 backend/app/core/,parent.parent.parent 即 backend/)
|
||
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
||
|
||
|
||
class Settings(BaseSettings):
|
||
APP_NAME: str = "H3C-ONU-MS"
|
||
DEBUG: bool = False
|
||
SECRET_KEY: str
|
||
|
||
DATABASE_URL: str
|
||
REDIS_URL: str
|
||
|
||
CASDOOR_ENDPOINT: str
|
||
CASDOOR_CLIENT_ID: str
|
||
CASDOOR_CLIENT_SECRET: str
|
||
CASDOOR_ORG_NAME: str
|
||
CASDOOR_APP_NAME: str
|
||
CASDOOR_CERTIFICATE: str = "" # 支持文件路径或直接填 PEM 内容
|
||
CASDOOR_REDIRECT_URL: str = ""
|
||
|
||
SSH_TIMEOUT: int = 30
|
||
CHECK_INTERVAL: int = 1800
|
||
MANUAL_COOLDOWN: int = 300
|
||
|
||
# CORS & 前端
|
||
CORS_ORIGINS: str = "" # 逗号分隔
|
||
FRONTEND_URL: str = "https://onu.dhdx.fun"
|
||
|
||
# NTP 同步配置
|
||
NTP_OLD_SERVER: str = "172.16.0.254"
|
||
NTP_NEW_SERVER: str = "172.16.1.252"
|
||
|
||
# iMC API 配置(用于 ONU 远程重启和光功率查询)
|
||
IMC_API_URL: str = ""
|
||
|
||
# 企业微信应用消息 API(用于发送告警)
|
||
WECHAT_CORPID: str = ""
|
||
WECHAT_CORPSECRET: str = ""
|
||
WECHAT_AGENTID: str = ""
|
||
WECHAT_TOKEN: str = ""
|
||
WECHAT_ENCODING_AES_KEY: str = ""
|
||
WECHAT_USE_PROXY: bool = True
|
||
WECHAT_PROXY_API_URL: str = ""
|
||
IMC_API_USERNAME: str = ""
|
||
IMC_API_PASSWORD: str = ""
|
||
IMC_API_VERIFY_SSL: bool = False
|
||
IMC_CONNECT_TIMEOUT: float = 5.0
|
||
IMC_READ_TIMEOUT: float = 20.0
|
||
|
||
class Config:
|
||
env_file = str(PROJECT_ROOT / ".env")
|
||
|
||
@property
|
||
def casdoor_cert_content(self) -> str:
|
||
"""读取证书文件内容或直接返回证书字符串"""
|
||
cert = self.CASDOOR_CERTIFICATE
|
||
if not cert:
|
||
return ""
|
||
cert_path = Path(cert)
|
||
if cert_path.is_absolute():
|
||
path = cert_path
|
||
else:
|
||
# 相对路径基于项目根目录解析
|
||
path = PROJECT_ROOT / cert
|
||
if path.is_file():
|
||
return path.read_text()
|
||
return cert # 直接是 PEM 内容
|
||
|
||
|
||
settings = Settings()
|