# ============================================================================= # 企微IT智能服务台 — 外部系统连接配置管理 # ============================================================================= # 说明: # 1. 统一管理联软/火绒/aTrust/eHR四个系统的连接配置 # 2. 支持从环境变量或 .env 文件读取 # 3. 支持运行时切换 Mock 模式(所有请求走 MockAdapter) # # 配置优先级:环境变量 > .env 文件 > 默认值 # ============================================================================= import os from typing import Optional from pydantic import BaseModel, Field class ExternalSystemConfig(BaseModel): """外部系统连接配置 做什么:集中管理所有外部系统的连接参数 为什么:避免在代码中硬编码,支持环境隔离(开发/测试/生产) """ # ── 联软LV7000 ── lianruan_base_url: str = Field( default="http://192.168.3.200:30098", description="联软API基础地址(端口30098)", ) lianruan_api_account: Optional[str] = Field( default=None, description="联软API账号(ApiAccount参数)", ) lianruan_api_password: Optional[str] = Field( default=None, description="联软API密码(ApiPassword参数)", ) lianruan_enabled: bool = Field( default=False, description="联软适配器是否启用(凭证配置后自动启用)", ) # ── 火绒企业版 ── huorong_base_url: str = Field( default="http://huorong.oa.servyou-it.com:8080", description="火绒API基础地址(内网地址)", ) huorong_access_key_id: Optional[str] = Field( default=None, description="火绒AccessKey ID", ) huorong_access_key_secret: Optional[str] = Field( default=None, description="火绒AccessKey Secret(HMAC-SHA1签名用)", ) huorong_enabled: bool = Field( default=False, description="火绒适配器是否启用", ) # ── aTrust零信任 ── atrust_base_url: str = Field( default="https://atrust.servyou-it.com:4433", description="aTrust API基础地址(HTTPS端口4433)", ) atrust_api_id: Optional[str] = Field( default=None, description="aTrust API ID(x-ca-key Header)", ) atrust_api_secret: Optional[str] = Field( default=None, description="aTrust API Secret(HMAC-SHA256签名密钥)", ) atrust_directory_domain: Optional[str] = Field( default=None, description="aTrust用户目录域名(V3 API需要此参数)", ) atrust_enabled: bool = Field( default=False, description="aTrust适配器是否启用", ) # ── 北森eHR ── ehr_base_url: Optional[str] = Field( default=None, description="eHR API基础地址", ) ehr_client_id: Optional[str] = Field( default=None, description="eHR OAuth2.0 Client ID", ) ehr_client_secret: Optional[str] = Field( default=None, description="eHR OAuth2.0 Client Secret", ) ehr_enabled: bool = Field( default=False, description="eHR适配器是否启用", ) # ── 全局配置 ── cache_enabled: bool = Field( default=True, description="是否启用外部数据缓存(Redis)", ) mock_mode: bool = Field( default=False, description="Mock模式 — True时所有请求走MockAdapter,不调真实API", ) class Config: env_prefix = "EXT_" # 环境变量前缀,如 EXT_LIANRUAN_BASE_URL def load_external_config() -> ExternalSystemConfig: """从环境变量加载外部系统配置 做什么:读取 EXT_ 前缀的环境变量,构建配置对象 为什么:生产环境通过环境变量注入敏感配置,不写入代码或文件 Returns: ExternalSystemConfig 实例 """ config_dict = {} # 映射关系:环境变量名 → 配置字段名 env_mapping = { "EXT_LIANRUAN_BASE_URL": "lianruan_base_url", "EXT_LIANRUAN_API_ACCOUNT": "lianruan_api_account", "EXT_LIANRUAN_API_PASSWORD": "lianruan_api_password", "EXT_HUORONG_BASE_URL": "huorong_base_url", "EXT_HUORONG_ACCESS_KEY_ID": "huorong_access_key_id", "EXT_HUORONG_ACCESS_KEY_SECRET": "huorong_access_key_secret", "EXT_ATRUST_BASE_URL": "atrust_base_url", "EXT_ATRUST_API_ID": "atrust_api_id", "EXT_ATRUST_API_SECRET": "atrust_api_secret", "EXT_ATRUST_DIRECTORY_DOMAIN": "atrust_directory_domain", "EXT_EHR_BASE_URL": "ehr_base_url", "EXT_EHR_CLIENT_ID": "ehr_client_id", "EXT_EHR_CLIENT_SECRET": "ehr_client_secret", "EXT_CACHE_ENABLED": "cache_enabled", "EXT_MOCK_MODE": "mock_mode", } for env_key, field_name in env_mapping.items(): value = os.environ.get(env_key) if value is not None: # 布尔类型特殊处理 if field_name in ("cache_enabled", "mock_mode"): config_dict[field_name] = value.lower() in ("true", "1", "yes") else: config_dict[field_name] = value config = ExternalSystemConfig(**config_dict) # 自动启用已有凭证的系统 if config.lianruan_api_account and config.lianruan_api_password: config.lianruan_enabled = True if config.huorong_access_key_id and config.huorong_access_key_secret: config.huorong_enabled = True if config.atrust_api_id and config.atrust_api_secret: config.atrust_enabled = True if config.ehr_client_id and config.ehr_client_secret: config.ehr_enabled = True return config