import os from pathlib import Path from dotenv import load_dotenv BASE_DIR = Path(__file__).resolve().parents[2] load_dotenv(BASE_DIR / ".env") class Settings: app_name = "问大家运营管理后台" database_url = os.getenv("DATABASE_URL", f"sqlite:///{BASE_DIR / 'data' / 'app.db'}") _screenshot_storage_value = Path(os.getenv("SCREENSHOT_STORAGE_DIR", "data/uploads/screenshots")) screenshot_storage_dir = ( _screenshot_storage_value if _screenshot_storage_value.is_absolute() else BASE_DIR / _screenshot_storage_value ) secret_key = os.getenv("SECRET_KEY", "change-this-secret-key-in-production") cookie_name = "admin_session" session_hours = int(os.getenv("SESSION_HOURS", "12")) cookie_secure = os.getenv("COOKIE_SECURE", "false").lower() == "true" admin_username = os.getenv("ADMIN_USERNAME", "admin") admin_password = os.getenv("ADMIN_PASSWORD", "admin123456") operator_username = os.getenv("OPERATOR_USERNAME", "operator") operator_password = os.getenv("OPERATOR_PASSWORD", "operator123456") llm_api_key = os.getenv("LLM_API_KEY", "") llm_base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1") llm_model = os.getenv("LLM_MODEL", "gpt-4o-mini") # OCR/识图可单独使用视觉模型,未配置时沿用普通问答模型。 llm_vision_model = os.getenv("LLM_VISION_MODEL", llm_model) llm_timeout_seconds = int(os.getenv("LLM_TIMEOUT_SECONDS", "90")) # 开发环境返回验证码,接入短信服务后请关闭并在发送函数中对接供应商。 sms_dev_mode = os.getenv("SMS_DEV_MODE", "true").lower() == "true" # DingTalk workbench SSO/OAuth settings. dingtalk_corp_id = os.getenv("DINGTALK_CORP_ID", "") dingtalk_agent_id = os.getenv("DINGTALK_AGENT_ID", "") dingtalk_client_id = os.getenv("DINGTALK_CLIENT_ID", "") dingtalk_client_secret = os.getenv("DINGTALK_CLIENT_SECRET", "") dingtalk_redirect_uri = os.getenv("DINGTALK_REDIRECT_URI", "http://localhost:8000/api/admin/auth/dingtalk/callback") frontend_url = os.getenv("FRONTEND_URL", "http://localhost:5173") dingtalk_allowed_union_ids = {item.strip() for item in os.getenv("DINGTALK_ALLOWED_UNION_IDS", "").split(",") if item.strip()} # New DingTalk users may enter only when they belong to one of these # business divisions (including child departments). Existing active # admin_users are grandfathered and continue to work. dingtalk_allowed_dept_ids = {item.strip() for item in os.getenv("DINGTALK_ALLOWED_DEPT_IDS", "").split(",") if item.strip()} dingtalk_allowed_dept_names = {item.strip() for item in os.getenv("DINGTALK_ALLOWED_DEPT_NAMES", "战狼事业部,雪狼事业部").split(",") if item.strip()} dingtalk_super_admin_union_ids = {item.strip() for item in os.getenv("DINGTALK_SUPER_ADMIN_UNION_IDS", "").split(",") if item.strip()} # Members of these departments receive the same access as super admins. # IDs are preferred; names are supported as a readable fallback. dingtalk_super_admin_dept_ids = {item.strip() for item in os.getenv("DINGTALK_SUPER_ADMIN_DEPT_IDS", "").split(",") if item.strip()} dingtalk_super_admin_dept_names = {item.strip() for item in os.getenv("DINGTALK_SUPER_ADMIN_DEPT_NAMES", "AI指挥部").split(",") if item.strip()} settings = Settings()