Files
cmbot/docs/05-project-architecture.md
adminandClaude Opus 4.8 51cefab2db docs: pivot update design from LAN/UNC to HTTP transport
- docs/10: HTTP source + Basic Auth; manifest url/sha256/size; download zip +
  verify SHA-256 + extract; HTTP security model; stage notes marked pending
- docs/02/05: add update_user/update_pass; update_source is now an HTTP(S) URL
- tasks 17.18: HTTP pivot task (docs done; code TODO)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 08:54:16 +08:00

10 KiB

项目架构

1. 文档定位

本文档定义项目代码结构、模块职责和依赖方向。后续 AI 或开发者在新增功能、修复问题、重构代码时,必须遵守本文档。

本文档不描述具体 UI 细节和图像编辑算法细节。拖动、缩放、旋转、坐标换算等细节应放在图像编辑器设计文档中。

2. 架构目标

  • 避免所有逻辑集中在一个窗口类或一个入口文件中。
  • 让 UI、图片合成、模板、配置、批量任务、日志职责清晰分离。
  • 让核心图片合成逻辑可以脱离 GUI 单独测试。
  • 让单张合成和批量合成复用同一套核心逻辑。
  • 让后续 AI 执行小任务时能快速定位应修改的模块。

3. 推荐目录结构

src/
  main.py
  version.py
  app/
    __init__.py
    main_window.py
    widgets/
      __init__.py
      image_canvas.py
      image_list_panel.py
      template_panel.py
      transform_panel.py
      export_panel.py
  core/
    __init__.py
    models.py
    composer.py
    batch.py
  services/
    __init__.py
    config_service.py
    template_service.py
    file_service.py
    log_service.py
  resources/
    icons/
    styles/
tests/
  test_composer.py
  test_templates.py
docs/

说明:

  • src/main.py 是程序入口,只负责创建应用和主窗口。
  • src/version.py 统一维护软件名称和版本号。
  • app/ 放 GUI 相关代码。
  • core/ 放与 GUI 无关的核心模型、合成和批量处理逻辑。
  • services/ 放配置、模板、文件扫描、日志等服务。
  • resources/ 放图标、样式等静态资源。
  • tests/ 放自动化测试。

4. 模块职责

4.1 src/main.py

职责:

  • 初始化 Qt 应用。
  • 初始化日志。
  • 创建并显示主窗口。
  • 进入应用事件循环。

禁止:

  • 禁止在入口文件中写图片合成逻辑。
  • 禁止在入口文件中写复杂 UI 布局。
  • 禁止在入口文件中直接读写模板和配置细节。

4.2 src/version.py

职责:

  • 统一定义软件名称。
  • 统一定义当前版本号。
  • 为标题栏、关于信息、打包发布配置提供版本来源。

建议字段:

APP_NAME
APP_VERSION

禁止:

  • 禁止在其他模块重复硬编码软件名称和版本号。
  • 禁止让 UI 显示版本号与打包发布版本号不一致。

4.3 app/main_window.py

职责:

  • 组织主界面布局。
  • 协调各 UI 面板。
  • 连接用户操作与服务调用。
  • 管理当前选中的衣服图、印花图和模板状态。

禁止:

  • 禁止直接实现底层图片合成算法。
  • 禁止直接写入配置文件细节。
  • 禁止堆叠大量按钮事件中的业务逻辑。

4.4 app/widgets/image_canvas.py

职责:

  • 显示衣服底图和印花图。
  • 承载印花拖动、缩放、旋转交互。
  • 将 UI 交互结果转换为统一的变换状态。
  • 通知外部坐标、尺寸、角度变化。

禁止:

  • 禁止直接导出最终图片文件。
  • 禁止直接管理批量任务。
  • 禁止把屏幕坐标直接作为最终合成坐标。

4.5 app/widgets/image_list_panel.py

职责:

  • 显示衣服图片列表和印花图片列表。
  • 支持选择文件夹、全选、取消全选。
  • 通知主窗口当前选择变化。

禁止:

  • 禁止直接执行图片合成。
  • 禁止直接修改图片文件。

4.6 app/widgets/template_panel.py

职责:

  • 显示内置模板和自定义模板。
  • 处理模板选择、新增、重命名、删除等 UI 操作。
  • 通过 template_service 读取和保存模板。

禁止:

  • 禁止在 UI 控件中硬编码所有模板逻辑。
  • 禁止直接绕过 template_service 修改模板文件。

4.7 app/widgets/transform_panel.py

职责:

  • 显示和编辑印花的 X/Y 坐标、宽度、高度、旋转角度。
  • 用户修改参数后通知预览区更新。
  • 预览区交互变化后同步显示最新参数。

禁止:

  • 禁止自己维护一套与预览区不一致的状态。
  • 禁止只更新输入框但不更新预览。

4.8 app/widgets/export_panel.py

职责:

  • 选择输出目录。
  • 设置输出格式和质量。
  • 触发单张合成和批量合成。
  • 显示合成进度和结果摘要。

禁止:

  • 禁止直接写底层图像合成算法。
  • 禁止批量处理时阻塞主界面且没有进度反馈。

4.9 core/models.py

职责:

  • 定义核心数据模型。
  • 统一表示图片文件、印花变换参数、模板、导出选项、批量任务结果。

建议模型:

ImageAsset
TransformState
Template
ExportOptions
BatchOptions
ComposeResult
BatchResult

禁止:

  • 禁止在模型文件中引入 PySide6 UI 控件。
  • 禁止在模型文件中执行文件扫描或图片导出。

4.10 core/composer.py

职责:

  • 实现单张图片合成。
  • 根据衣服底图、印花图、变换参数和导出选项生成结果图。
  • 保证透明 PNG 正确叠加。
  • 保证导出结果与预览参数一致。

禁止:

  • 禁止依赖 PySide6 UI 控件。
  • 禁止读取 UI 输入框。
  • 禁止处理文件夹批量遍历逻辑。

4.11 core/batch.py

职责:

  • 实现批量合成任务编排。
  • 支持一一匹配和全组合模式。
  • 复用 core/composer.py 的单张合成能力。
  • 汇总成功、失败和错误信息。

禁止:

  • 禁止复制一套独立于 composer.py 的合成算法。
  • 禁止因单个文件失败中断整个批量任务。

4.12 services/config_service.py

职责:

  • 读取和保存应用配置。
  • 管理默认配置。
  • 在配置损坏或缺失时提供安全默认值。
  • 持久化用户偏好:输出设置、上次的衣服/印花文件夹(last_garment_dir/last_print_dir)、上次选择的模板(last_template)、上次选择的批量模式(last_batch_mode)、在线更新源(update_source 及凭据 update_user/update_pass)等。

由主窗口集中使用:启动时加载一次并把初值分发给各面板,面板选择变化时「改一次存一次」回写。各 UI 控件不直接读写配置文件,避免分散解析。

禁止:

  • 禁止在多个模块中重复解析同一个配置文件。
  • 禁止启动时无提示清空用户配置。
  • 禁止 UI 控件绕过本服务直接读写配置文件。

4.13 services/template_service.py

职责:

  • 加载内置模板。
  • 加载、保存、重命名、删除自定义模板。
  • 校验模板字段是否合法。

禁止:

  • 禁止让 UI 直接操作模板 JSON 文件。
  • 禁止单个模板损坏导致全部模板不可用。

4.14 services/file_service.py

职责:

  • 扫描图片文件夹。
  • 过滤支持的图片格式。
  • 生成安全输出文件名。
  • 处理 Windows 中文路径。

禁止:

  • 禁止在 UI 层重复实现文件扫描规则。
  • 禁止默认覆盖已有输出文件,除非用户确认。

4.15 services/log_service.py

职责:

  • 初始化日志系统。
  • 统一日志格式。
  • 管理日志文件路径。

禁止:

  • 禁止业务模块各自创建不一致的日志配置。
  • 禁止用 print 代替正式日志。

5. 依赖方向

允许的依赖方向:

main.py -> app
app -> core
app -> services
core -> services 仅限必要的纯工具能力
services -> core models 可选
tests -> core
tests -> services

推荐依赖关系:

UI 层负责收集用户输入
UI 层把输入转换为 core models
core 层执行合成或批量任务
services 层处理配置、模板、文件和日志
UI 层展示结果和错误信息

禁止的依赖方向:

core -> app
services -> app
models -> app
composer -> PySide6 UI 控件
batch -> PySide6 UI 控件

6. 状态管理

主窗口维护当前工作状态:

  • 当前衣服图片。
  • 当前印花图片。
  • 当前印花变换参数。
  • 当前模板。
  • 当前输出配置。

印花变换参数必须使用统一模型表示,例如:

TransformState
  x
  y
  width
  height
  rotation
  keep_aspect_ratio

规则:

  • 预览区变化后更新 TransformState。
  • 参数面板变化后更新同一个 TransformState。
  • 单张导出和批量导出都读取同一个 TransformState 或模板转换结果。
  • 不允许 UI 面板各自维护互不一致的状态。

7. 单张合成流程

用户选择衣服图和印花图
-> 主窗口更新当前状态
-> 预览区显示衣服和印花
-> 用户拖动、缩放、旋转或输入参数
-> 更新 TransformState
-> 用户点击单张导出
-> export_panel 构造 ExportOptions
-> core.composer 执行合成
-> file_service 生成输出路径
-> 保存结果
-> UI 显示成功或失败

8. 批量合成流程

用户选择多张衣服图和印花图
-> 用户选择批量模式
-> 用户选择模板或当前参数
-> export_panel 构造 BatchOptions
-> core.batch 生成任务列表
-> 每个任务调用 core.composer
-> 失败项记录错误并继续
-> UI 显示进度
-> 任务完成后显示成功数量和失败数量

9. 错误处理

错误处理分两层:

  • 用户提示:简洁、可理解,说明用户可以做什么。
  • 日志信息:详细记录异常类型、文件路径、调用阶段和堆栈信息。

规则:

  • 文件不存在、格式不支持、输出目录不可写必须提示用户。
  • 单张导出失败应提示用户并记录日志。
  • 批量任务中单个文件失败应记录失败原因并继续处理。
  • 全局不可恢复错误才允许终止批量任务。

10. 测试边界

优先测试:

  • core/composer.py 的单张合成。
  • 透明 PNG 印花叠加。
  • 坐标、尺寸、旋转参数应用。
  • 输出文件名生成。
  • 模板 JSON 读写。
  • 批量一一匹配模式。
  • 批量全组合模式。

UI 测试可以后置,但核心合成逻辑必须尽量可测试。

11. 后续扩展点

架构应允许后续增加:

  • 图像编辑器专项模块。
  • 局域网版本分发模块。
  • 多版本启动器。
  • 更多输出格式。
  • 更多模板类型。
  • 素材目录记忆。

新增扩展时必须遵守现有依赖方向,不得让核心模块依赖 UI。