# 系统架构 ## 1. 技术栈 | 层 | 技术 | 版本 | |----|------|------| | GUI 框架 | PySide6 (Qt6) | >= 6.5.0 | | ORM | SQLAlchemy | >= 2.0.0 | | 数据处理 | pandas / openpyxl / python-calamine | - | | PDF 生成 | reportlab / pypdf | - | | 日志 | loguru | >= 0.7.0 | | 配置 | PyYAML + pydantic | - | | CLI | click | >= 8.0 | | 打包 | PyInstaller / Nuitka | - | | 包管理 | uv | - | ## 2. 分层架构 ```text ┌─────────────────────────────────────────────┐ │ views/ GUI 视图层(PySide6 QWidget) │ │ widgets/ 可复用控件 │ ├─────────────────────────────────────────────┤ │ controllers/ 控制器层(业务编排) │ │ actions/ action 注册表(统一派发) │ │ handlers/ 事件处理器 / 文件处理器 │ ├─────────────────────────────────────────────┤ │ services/ 服务层(业务逻辑,无 Qt 依赖) │ │ services/printer/ 打印子系统 │ ├─────────────────────────────────────────────┤ │ models/ 数据模型(SQLAlchemy ORM) │ │ config/ 配置加载(pydantic 模型) │ │ utils/ 工具函数 │ └─────────────────────────────────────────────┘ ``` **层纯度门禁**:`scripts/check_layer_purity.py` 强制约束依赖方向(views → controllers → services → models),禁止反向引用。 ## 3. 启动流程(main.py) ```text main() ├── 读取 config.yaml → debug_modules 黑名单 ├── setup_logger(debug_modules) ├── check_data_sources() # 销售计划路径/基线库检查(仅 warning) ├── StatusInference.init_from_config() ├── 高 DPI 适配 ├── QApplication(sys.argv) ├── init_database_manager() │ ├── setup_webdav_config() # 从 .env 读坚果云配置 │ ├── DatabaseManager(webdav_config) │ ├── db_manager.init_db(create_tables=True, sync_from_webdav=...) │ ├── _maybe_seed_base_data(db_manager) # 空库播种基础字典 │ └── db_manager.warn_if_base_data_empty() ├── session = db_manager.get_session() ├── BaseController.set_shared_db_manager(db_manager) ├── 读取 print/printer/templates 配置 ├── SettingsController() # 主题/语言/自动保存 ├── MainWindow(session, config, db_manager, settings_controller) └── app.exec() # Qt 事件循环 ``` ## 4. 应用装配(bootstrap.py) `AppContext` 收口"数据库管理器从哪来、会话从哪来、Service 如何构造": - `build_context(db_manager=None) -> AppContext` — 工厂入口 - `get_default_context() -> AppContext` — 进程内惰性单例 - `context.get_service(ServiceCls, *args)` — 以当前会话为首个参数构造 Service - `context.close()` — 释放资源 消除原先散落在 `BaseController` 里的隐式 `DatabaseManager()` 兜底。 ## 5. 模块清单 ### 5.1 controllers/(17 个) | 控制器 | 职责 | |--------|------| | `base_controller` | 基类,持有共享 db_manager | | `import_controller` | 销售计划导入编排 | | `query_controller` | 查询、字段编辑、批量操作 | | `certificate_controller` | 合格证生成/预览 | | `print_queue_controller` | 打印队列管理 | | `printer_controller` | 打印机选择与状态 | | `report_controller` | 报告生成 | | `output_controller` | 导出(Excel/Access) | | `scan_controller` | 扫描枪输入 | | `correction_queue_controller` | 校正队列 | | `history_controller` | 打印历史 | | `settings_controller` | 系统设置(主题/语言) | | `bom_material_controller` | BOM 物料维护 | | `material_grade_controller` | 材质牌号维护 | | `model_param_mapping_controller` | 型号参数映射维护 | | `caliber_mapping_controller` | 口径映射维护 | ### 5.2 services/(46 个,含 printer/ 子包) 核心服务见 [`04-operator-guide.md`](./04-operator-guide.md) 各子流程文档。 ### 5.3 views/(42 个) | 视图 | 职责 | |------|------| | `main_window` | 主窗口,导航栏 + StackedWidget | | `import_page` / `import_dialog` / `import_confirm_dialog` | 导入流程 | | `query_view` / `query_hub_view` / `sale_plan_query_view` | 查询 | | `correction_queue_view` / `correction_flag_query_view` | 校正队列 | | `print_view` / `print_dialog` | 打印 | | `report_view` | 报告 | | `output_view` | 导出 | | `history_view` | 历史 | | `scan_view` | 扫描 | | `settings_view` | 设置 | | `*_manager_view` | 基础字典维护(4 个) | | `bases/` | 视图基类(11 个) | ### 5.4 handlers/(12 个) 文件 I/O 与事件处理:Excel 读写、CSV 导出、模板处理、扫描处理、排序、保存、数据清理、报告生成、发货导出。 ### 5.5 actions/ `registry.py` — 统一 action 注册表,将工具栏/右键菜单/导航按钮的派发收敛为单一信源(`dispatch(view, action_name, item)`)。 ## 6. 数据库四库模型 `start.sh` 阶段10 定义: | 库 | 路径 | 用途 | Git 管理 | |----|------|------|----------| | A 主库 | `database/certflow.db` | 生产数据 | gitignore | | B 调试库 | `database/debug/certflow-debug.db` | 本脚本使用 | gitignore | | C 本地基线 | `database/baseline.db` | 私有基线(含真实数据) | gitignore | | D 匿名基线 | `database/samples/baseline.sample.db` | 脱敏模板 | Git LFS | 基线源选择策略:C 优先 → D 回退。LFS 拉取策略:仅当 C 不存在且 B 需重建时才拉取 D 真实内容。 ## 7. CI/CD `ci/` 目录含 16 个 yml + 1 个 txt,覆盖: - 环境搭建(Linux apt 依赖 / Windows / macOS) - 依赖同步(uv sync 各 group) - 层纯度门禁 - pytest(offscreen 后端) - ruff lint - pyright / mypy 类型检查 - 覆盖率上报 ## 8. 打包 `scripts/builder/` 提供构建脚本: - 入口:`src/certflow/main.py` - 输出:`dist/CertFlow` - 配置:`scripts/builder/build_config.yaml` - 工具:PyInstaller(默认)/ Nuitka(备选)