# ERPAuto 配置系统架构分析 ## 1. 概述 ERPAuto 是一个基于 Electron 的桌面应用程序,采用多层次配置管理系统来支持 ERP 系统自动化数据处理。配置系统采用 `.env` 文件作为持久化存储,通过 `ConfigManager` 统一管理,支持运行时动态修改和持久化保存。 ## 2. 配置系统整体架构 ```mermaid graph TB subgraph "配置数据源" ENV[.env 文件] ENV_EXAMPLE[.env.example 模板] CACHE[内存缓存 ConfigCache] end subgraph "配置管理层 ConfigManager" CM_LOAD[loadEnvFile] CM_GET[get/getBoolean/getNumber] CM_SET[set] CM_SAVE[save/saveAllSettings] CM_PARTIAL[savePartialSettings] CM_MERGE[deepMerge 深度合并] end subgraph "IPC 通信层" SETTINGS_HANDLER[settings-handler.ts] IPC_GET[settings:getSettings] IPC_SAVE[settings:saveSettings] IPC_TEST[settings:testErpConnection/testDbConnection] end subgraph "业务服务层" ERP_SVC[ERP 服务] DB_SVC[数据库服务] USER_SVC[用户服务] EXTRACTOR[ExtractorService] CLEANER[CleanerService] end subgraph "UI 呈现层" SETTINGS_UI[设置界面] LOGIN_UI[登录界面] MAIN_UI[主界面] end ENV -->|读取 | CM_LOAD ENV_EXAMPLE -.->|模板参考 | ENV CM_LOAD -->|填充 | CACHE CACHE --> CM_GET CM_SET --> CACHE CM_PARTIAL --> CM_MERGE --> CM_SAVE --> ENV CM_GET --> SETTINGS_HANDLER SETTINGS_HANDLER --> IPC_GET SETTINGS_HANDLER --> IPC_SAVE SETTINGS_HANDLER --> IPC_TEST IPC_GET --> SETTINGS_UI IPC_SAVE --> SETTINGS_UI IPC_TEST --> SETTINGS_UI CACHE --> ERP_SVC CACHE --> DB_SVC CACHE --> USER_SVC CACHE --> EXTRACTOR CACHE --> CLEANER SETTINGS_UI --> MAIN_UI LOGIN_UI --> USER_SVC ``` ## 3. 配置文件结构 ### 3.1 .env 文件组织 ```mermaid graph LR subgraph "ERP 系统配置" ERP_URL[ERP_URL] ERP_USER[ERP_USERNAME] ERP_PASS[ERP_PASSWORD] ERP_HEADLESS[ERP_HEADLESS] ERP_HTTPS[ERP_IGNORE_HTTPS_ERRORS] ERP_CLOSE[ERP_AUTO_CLOSE_BROWSER] end subgraph "数据库配置 - SQL Server" SQL_DRIVER[DB_SQLSERVER_DRIVER] SQL_TRUST[DB_TRUST_SERVER_CERTIFICATE] end subgraph "数据库配置 - MySQL" DB_TYPE[DB_TYPE] DB_NAME[DB_NAME] DB_USER[DB_USERNAME] DB_PASS[DB_PASSWORD] MYSQL_HOST[DB_MYSQL_HOST] MYSQL_PORT[DB_MYSQL_PORT] MYSQL_CHARSET[DB_MYSQL_CHARSET] end subgraph "订单号解析表配置" TABLE_NAME[DB_TABLE_NAME] FIELD_PROD_ID[DB_FIELD_PRODUCTION_ID] FIELD_ORDER[DB_FIELD_ORDER_NUMBER] end subgraph "路径配置" DATA_DIR[PATH_DATA_DIR] PROD_ID_FILE[PATH_PRODUCTION_ID_FILE] DEFAULT_OUT[PATH_DEFAULT_OUTPUT] VALID_OUT[PATH_VALIDATION_OUTPUT] end subgraph "数据提取配置" BATCH_SIZE[EXTRACTION_BATCH_SIZE] VERBOSE[EXTRACTION_VERBOSE] AUTO_CONVERT[EXTRACTION_AUTO_CONVERT] MERGE_BATCHES[EXTRACTION_MERGE_BATCHES] DB_PERSIST[EXTRACTION_ENABLE_DB_PERSISTENCE] end subgraph "校验配置" DATA_SOURCE[VALIDATION_DATA_SOURCE] USE_DB[VALIDATION_USE_DATABASE] VAL_BATCH[VALIDATION_BATCH_SIZE] ENABLE_CRUD[VALIDATION_ENABLE_CRUD] DEFAULT_MGR[VALIDATION_DEFAULT_MANAGER] MATCH_MODE[VALIDATION_MATCH_MODE] end subgraph "UI 配置" FONT_FAMILY[UI_FONT_FAMILY] FONT_SIZE[UI_FONT_SIZE] INPUT_WIDTH[UI_PRODUCTION_ID_INPUT_WIDTH] end subgraph "执行配置" DRY_RUN[EXECUTION_DRYRUN] end ``` ### 3.2 默认配置值 | 配置类别 | 配置项 | 默认值 | 说明 | | ---------- | ----------------- | --------------------------- | -------------------- | | ERP | url | `https://68.11.34.30:8082/` | ERP 系统地址 | | ERP | headless | `true` | 无头浏览器模式 | | ERP | ignoreHttpsErrors | `true` | 忽略 HTTPS 证书错误 | | ERP | autoCloseBrowser | `true` | 操作后自动关闭浏览器 | | Database | dbType | `mysql` | 数据库类型 | | Database | mysqlHost | `192.168.31.83` | MySQL 主机地址 | | Database | mysqlPort | `3306` | MySQL 端口 | | Database | database | `BLD_DB` | 数据库名 | | Database | username | `remote_user` | 数据库用户名 | | Paths | dataDir | `D:/python/playwrite/data/` | 数据目录 | | Extraction | batchSize | `100` | 批次大小 | | Extraction | verbose | `true` | 详细日志 | | Validation | dataSource | `database_full` | 校验数据源 | | Validation | batchSize | `2000` | 校验批次大小 | | Validation | matchMode | `substring` | 匹配模式 | | UI | fontFamily | `Microsoft YaHei UI` | 字体 | | UI | fontSize | `10` | 字体大小 | | Execution | dryRun | `false` | 干运行模式 | ## 4. ConfigManager 核心类设计 ### 4.1 类结构与单例模式 ```mermaid classDiagram class ConfigManager { -static instance: ConfigManager | null -envPath: string -backupPath: string -configCache: Map -initialized: boolean +static getInstance(): ConfigManager +initialize(): Promise +get(key: string): string | undefined +getBoolean(key: string, default: boolean): boolean +getNumber(key: string, default: number): number +set(key: string, value: string|number|boolean): void +save(): Promise +getAllSettings(): SettingsData +saveAllSettings(settings: SettingsData): Promise +savePartialSettings(settings: Partial): Promise +resetToDefaults(): SettingsData +getDefaultSettings(): SettingsData -loadEnvFile(): Promise -backupEnvFile(): Promise -restoreBackup(): Promise } class SettingsData { +erp: ErpConfig +database: DatabaseConfig +paths: PathsConfig +extraction: ExtractionConfig +validation: ValidationConfig +ui: UiConfig +execution: ExecutionConfig } ConfigManager --> SettingsData: 返回/接收 ``` ### 4.2 核心方法流程图 ```mermaid sequenceDiagram participant Client as 客户端/IPC participant CM as ConfigManager participant Cache as ConfigCache participant FS as 文件系统 participant Backup as Backup 文件 Client->>CM: savePartialSettings(settings) activate CM CM->>CM: validateEditableFields() alt 包含非白名单字段 CM-->>Client: 返回错误 (不允许修改) else 验证通过 CM->>FS: loadEnvFile() FS-->>Cache: 填充缓存 CM->>CM: getAllSettings() CM->>Cache: 读取当前配置 CM->>CM: deepMerge(current, settings) CM->>FS: backupEnvFile() FS-->>Backup: 创建备份 CM->>FS: saveAllSettings(merged) alt 保存成功 FS-->>Cache: 重新加载 CM-->>Client: 返回成功 else 保存失败 CM->>FS: restoreBackup() FS-->>Cache: 恢复配置 CM-->>Client: 返回错误 end end deactivate CM ``` ### 4.3 深度合并算法 ```mermaid graph TD A[deepMerge 函数] --> B{遍历 target 键值对} B --> C{targetValue 是对象?} C -->|是 | D{sourceValue 也是对象?} D -->|是 | E[递归调用 deepMerge] D -->|否 | F[直接使用 targetValue] C -->|否 | G{targetValue !== undefined?} G -->|是 | H[更新该键值] G -->|否 | I[跳过该键] E --> J[合并结果存入 result] F --> J H --> J B --> K[遍历完成] K --> L[返回合并后的对象] ``` ## 5. 配置读取与使用模式 ### 5.1 环境变量直接读取模式 各业务服务通过 `process.env` 直接读取配置: ```mermaid graph LR subgraph "环境变量读取点" MAIN[main/index.ts
dotenv.config] end subgraph "服务模块" DB_INDEX[database/index.ts] DB_MYSQL[database/mysql.ts] DB_SQL[database/sql-server.ts] BIP_DAO[bip-users-dao.ts] ORDER_RES[order-resolver.ts] EXTRACTOR[extractor-handler.ts] CLEANER[cleaner-handler.ts] VALIDATION[validation-handler.ts] end MAIN -->|初始化加载 | ENV[process.env] ENV --> DB_INDEX ENV --> DB_MYSQL ENV --> DB_SQL ENV --> BIP_DAO ENV --> ORDER_RES ENV --> EXTRACTOR ENV --> CLEANER ENV --> VALIDATION ``` ### 5.2 ConfigManager 获取模式 通过 IPC 层统一获取: ```mermaid sequenceDiagram participant UI as 设置界面 participant Preload as Preload 脚本 participant IPC as IPC Handler participant CM as ConfigManager UI->>Preload: window.api.settings.getSettings() Preload->>IPC: ipcRenderer.invoke('settings:getSettings') IPC->>IPC: SessionManager.getUserType() IPC->>CM: getAllSettings() CM->>IPC: SettingsData IPC->>IPC: filterSettingsByUserType() IPC-->>Preload: 过滤后的 SettingsData Preload-->>UI: SettingsData ``` ### 5.3 数据库配置工厂模式 ```mermaid graph TB subgraph "配置创建" GET_TYPE[getDatabaseType] -->|DB_TYPE env| TYPE_CHECK{数据库类型} TYPE_CHECK -->|mysql| CREATE_MYSQL[createMySqlConfig] TYPE_CHECK -->|sqlserver| CREATE_SQL[createSqlServerConfig] end subgraph "服务创建" CREATE_MYSQL --> MYSQL_SVC[MySqlService] CREATE_SQL --> SQL_SVC[SqlServerService] end subgraph "单例缓存" MYSQL_SVC --> CACHE[instances Map] SQL_SVC --> CACHE CACHE -->|返回已连接实例 | CLIENT[调用方] end CREATE_MYSQL --> CONNECT_MYSQL[service.connect] CREATE_SQL --> CONNECT_SQL[service.connect] CONNECT_MYSQL --> CACHE CONNECT_SQL --> CACHE ``` ## 6. 用户权限与配置访问控制 ### 6.1 用户类型与权限 ```mermaid graph TB subgraph "用户类型 UserType" ADMIN[Admin
管理员] USER[User
普通用户] GUEST[Guest
访客] end subgraph "配置访问权限" ADMIN_SETTINGS[全部配置可访问
可修改 ERP 配置
可恢复默认设置] USER_SETTINGS[有限配置访问
可修改 ERP 配置
可查看执行配置] GUEST_SETTINGS[只读访问] end ADMIN --> ADMIN_SETTINGS USER --> USER_SETTINGS GUEST --> GUEST_SETTINGS subgraph "SessionManager 会话管理" SM_LOGIN[login] SM_SILENT[loginByComputerName] SM_SWITCH[switchUser - Admin only] SM_GET[getUserType/getUserInfo] end SM_LOGIN --> USER SM_SILENT --> USER SM_SWITCH --> USER ``` ### 6.2 配置过滤机制 ```mermaid flowchart TD A[getSettings 请求] --> B[获取当前用户类型] B --> C{用户类型判断} C -->|Admin| D[返回全部配置] C -->|User| E[过滤配置] E --> F[返回 ERP 配置
username/password/headless/url/...
paths 配置
execution 配置
最小化其他配置] C -->|Guest| G[返回空配置或只读配置] D --> H[返回给 UI] E --> H G --> H ``` ## 7. 配置修改白名单机制 ### 7.1 可编辑字段白名单 ```javascript const UI_EDITABLE_FIELDS: string[] = [ 'erp.url', 'erp.username', 'erp.password' // 可根据需要扩展 ] ``` ### 7.2 白名单验证流程 ```mermaid flowchart TD A[savePartialSettings 调用] --> B[遍历 settings 中的字段] B --> C[构建字段路径 section.field] C --> D{字段在白名单中?} D -->|否 | E[添加到 invalidFields] D -->|是 | F[继续检查下一字段] E --> B F --> B B --> G{所有字段检查完成} G --> H{invalidFields 为空?} H -->|否 | I[返回错误
包含不允许修改的字段] H -->|是 | J[继续保存流程] ``` ## 8. 数据库配置详解 ### 8.1 双数据库支持架构 ```mermaid graph TB subgraph "数据库抽象层" IDB[IDatabaseService 接口
connect/disconnect
query/transaction
isConnected] end subgraph "MySQL 实现" MYSQL[MySqlService
mysql2/promise
createConnection
execute/transaction] end subgraph "SQL Server 实现" MSSQL[SqlServerService
mssql
ConnectionPool
request.query
Transaction] end IDB -.->|实现 | MYSQL IDB -.->|实现 | MSSQL MYSQL --> ENV_MYSQL[DB_MYSQL_HOST
DB_MYSQL_PORT
DB_NAME
DB_USERNAME
DB_PASSWORD] MSSQL --> ENV_MSSQL[DB_SERVER
DB_SQLSERVER_PORT
DB_NAME
DB_USERNAME
DB_PASSWORD
DB_TRUST_SERVER_CERTIFICATE] ``` ### 8.2 数据库配置参数映射 | 环境变量 | MySQL 用途 | SQL Server 用途 | | --------------------------- | ----------- | ----------------- | | DB_TYPE | mysql | sqlserver/mssql | | DB_NAME | 数据库名 | 数据库名 | | DB_USERNAME | 用户名 | 用户名 | | DB_PASSWORD | 密码 | 密码 | | DB_MYSQL_HOST | 主机地址 | - | | DB_MYSQL_PORT | 端口 (3306) | - | | DB_SERVER | - | 服务器地址 | | DB_SQLSERVER_PORT | - | 端口 (1433) | | DB_TRUST_SERVER_CERTIFICATE | - | 信任证书 (yes/no) | ## 9. ERP 配置与浏览器自动化 ### 9.1 ERP 认证配置流程 ```mermaid sequenceDiagram participant UI as 设置界面 participant IPC as settings-handler participant CM as ConfigManager participant ERP_AUTH as ErpAuthService participant PW as Playwright UI->>IPC: testErpConnection IPC->>CM: getAllSettings CM-->>IPC: SettingsData(含 erp 配置) IPC->>ERP_AUTH: new ErpAuthService(erpConfig) ERP_AUTH->>PW: chromium.launch Note over PW: headless=erpConfig.headless
args=[--ignore-certificate-errors] PW-->>ERP_AUTH: Browser Context ERP_AUTH->>PW: page.goto(loginUrl) PW-->>ERP_AUTH: 加载登录页面 ERP_AUTH->>PW: fill username/password ERP_AUTH->>PW: click login button PW-->>ERP_AUTH: 登录成功 ERP_AUTH-->>IPC: ErpSession IPC-->>UI: {success: true} ERP_AUTH->>PW: close ``` ### 9.2 ERP 配置项说明 | 配置项 | 类型 | 默认值 | 说明 | | ----------------- | ------- | ------ | -------------- | | url | string | - | ERP 系统 URL | | username | string | - | ERP 用户名 | | password | string | - | ERP 密码 | | headless | boolean | true | 无头模式 | | ignoreHttpsErrors | boolean | true | 忽略 SSL 错误 | | autoCloseBrowser | boolean | true | 自动关闭浏览器 | ## 10. 订单号解析表配置 ### 10.1 配置结构 ```mermaid graph LR subgraph "订单号解析配置" TABLE[DB_TABLE_NAME
表名] FIELD_ID[DB_FIELD_PRODUCTION_ID
总排号字段] FIELD_ORDER[DB_FIELD_ORDER_NUMBER
生产订单号字段] end TABLE --> ORDER_RESOLVER[OrderResolverService] FIELD_ID --> ORDER_RESOLVER FIELD_ORDER --> ORDER_RESOLVER ORDER_RESOLVER --> DB_QUERY[查询映射关系] DB_QUERY --> PRODUCTION_ID[productionID] DB_QUERY --> ORDER_NUMBER[生产订单号] ``` ### 10.2 默认配置示例 ```env DB_TABLE_NAME=productionContractData_26 年压力表合同数据 DB_FIELD_PRODUCTION_ID=总排号 DB_FIELD_ORDER_NUMBER=生产订单号 ``` ## 11. 配置持久化与备份机制 ### 11.1 保存流程 ```mermaid flowchart TD A[saveAllSettings] --> B[设置写入 configCache] B --> C[构建.env 文件内容] C --> D[按分类组织配置
ERP/数据库/路径/提取/校验/UI/执行] D --> E[写入.env 文件] E --> F{写入成功?} F -->|是 | G[返回 true] F -->|否 | H[返回 false] ``` ### 11.2 备份与恢复流程 ```mermaid sequenceDiagram participant Caller as 调用方 participant CM as ConfigManager participant ENV as .env participant BAK as .env.backup Caller->>CM: savePartialSettings CM->>CM: validateEditableFields CM->>ENV: loadEnvFile CM->>CM: deepMerge 合并配置 CM->>ENV: backupEnvFile ENV->>BAK: copyFileSync CM->>ENV: writeFileSync 新配置 ENV-->>CM: 保存结果 alt 保存成功 CM->>ENV: loadEnvFile 重新加载 CM-->>Caller: success: true else 保存失败 CM->>BAK: restoreBackup BAK->>ENV: copyFileSync 恢复 CM->>ENV: loadEnvFile CM-->>Caller: success: false + error end ``` ## 12. 配置系统初始化时序 ```mermaid sequenceDiagram participant App as Electron App participant Main as main/index.ts participant Dotenv as dotenv participant CM as ConfigManager participant IPC as registerIpcHandlers participant SM as SessionManager App->>Main: 应用启动 Main->>Dotenv: config .env Dotenv-->>Main: process.env 已加载 Main->>IPC: registerIpcHandlers Note over IPC: 注册所有 IPC 处理器
settings/extractor/cleaner/auth... App->>Main: app.whenReady Main->>SM: silent login 尝试 SM->>SM: loginByComputerName alt 静默登录成功 SM-->>Main: 用户已认证 else 静默登录失败 Main->>Main: 显示登录对话框 end Main->>CM: initialize 按需加载 ``` ## 13. 关键代码模式 ### 13.1 环境变量读取模式 ```typescript // 直接读取 process.env const dbType = process.env.DB_TYPE?.toLowerCase() const mysqlHost = process.env.DB_MYSQL_HOST || 'localhost' const mysqlPort = parseInt(process.env.DB_MYSQL_PORT || '3306', 10) ``` ### 13.2 ConfigManager 读取模式 ```typescript // 通过 ConfigManager 获取结构化配置 const configManager = ConfigManager.getInstance() const settings = configManager.getAllSettings() const erpUrl = settings.erp.url const batchSize = settings.extraction.batchSize ``` ### 13.3 部分保存模式 ```typescript // 只更新允许修改的字段 const result = await configManager.savePartialSettings({ erp: { url: 'http://new-url.com', username: 'newuser', password: 'newpass' } }) ``` ## 14. 配置类别与业务模块映射 ```mermaid graph TB subgraph "配置类别" ERP_CONF[ERP 配置] DB_CONF[数据库配置] PATH_CONF[路径配置] EXTRACT_CONF[提取配置] VALID_CONF[校验配置] UI_CONF[UI 配置] EXEC_CONF[执行配置] end subgraph "业务模块" ERP_AUTH[ErpAuthService] ERP_EXTRACT[ExtractorService] ERP_CLEAN[CleanerService] ERP_ORDER[OrderResolverService] DB_MYSQL[MySqlService] DB_SQL[SqlServerService] DB_DAO[各种 DAO 类] EXCEL[Excel Parser/Exporter] UI[React 界面] end ERP_CONF --> ERP_AUTH ERP_CONF --> ERP_EXTRACT ERP_CONF --> ERP_CLEAN DB_CONF --> DB_MYSQL DB_CONF --> DB_SQL DB_CONF --> DB_DAO PATH_CONF --> EXCEL PATH_CONF --> UI EXTRACT_CONF --> ERP_EXTRACT EXTRACT_CONF --> DB_DAO VALID_CONF --> ERP_EXTRACT VALID_CONF --> DB_DAO UI_CONF --> UI EXEC_CONF --> ERP_CLEAN ``` ## 15. 配置系统特点总结 ### 15.1 优点 1. **集中化管理**: ConfigManager 单例模式统一管理所有配置 2. **类型安全**: TypeScript 类型定义确保配置结构正确 3. **权限控制**: 基于用户类型的配置访问和修改权限控制 4. **备份恢复**: 自动备份机制防止配置丢失 5. **双数据库支持**: MySQL 和 SQL Server 灵活切换 6. **部分更新**: deepMerge 支持配置部分字段更新 ### 15.2 可扩展性 1. **新增配置项**: 在 `.env.example` 添加 → `DEFAULT_SETTINGS` 定义 → `SettingsData` 类型 → `save` 方法输出 2. **新增用户权限**: 扩展 `UserType` → 更新 `filterSettingsByUserType` 逻辑 3. **新增白名单字段**: 在 `UI_EDITABLE_FIELDS` 数组添加路径 ### 15.3 注意事项 1. 修改配置后需要重新加载 `.env` 文件使 `process.env` 生效 2. 非白名单字段只能通过 `saveAllSettings` 或 `resetToDefaults` 修改 3. 数据库服务使用单例缓存,配置变更需重启应用或手动重连 4. ERP 配置变更需重启浏览器才能生效