# 🎬 漫画资产管理器 (Comic Asset Manager)

本地漫画/漫剧资产管理器 —— **PySide6 原生桌面应用**。
管理漫画页、封面、角色设定、场景设定、剧本、分镜、音频等**全类型漫剧资产**，
数据全部存储在本地 SQLite 数据库，**无云端依赖**，可离线工作、随时拷贝备份。

![主界面](docs/screenshots/01-主界面.png)

| | |
|---|---|
| ![详情面板](docs/screenshots/02-详情面板.png) | ![列表视图](docs/screenshots/03-列表视图.png) |
| ![导入向导](docs/screenshots/04-导入向导.png) | ![编辑对话框](docs/screenshots/05-编辑对话框.png) |

---

## 功能特性

**资产组织**
- 📚 **系列 / 卷 / 章** 三级结构，对应一部作品的自然层级
- 🗂️ **9 种资产类型**：漫画页、封面、角色设定、场景设定、参考素材、剧本、分镜、音频、备注
- 🏷️ **标签系统**，标签名自动去重，任意交叉检索
- 🔢 **页序管理**，漫画页按文件名自动推导页码，支持按序翻页预览

**浏览与检索**
- ▦ **网格视图**：缩略图卡片，响应式列数，悬停显示元信息
- ☰ **列表视图**：表格批量核对，含类型色标与标签
- 🔍 **全文搜索**：标题 / 描述 / 正文 / 标签，280ms 防抖，SQLite `LIKE` 多字段命中
- ⏮ **分页**：60 项/页，130+ 资产不卡顿
- ↕ **6 种排序**：最近更新、创建时间、标题、页序、类型

**预览与播放**
- 🖼️ **图片预览**：滚轮缩放 5%–2000%、拖拽平移、适应窗口、原始大小、← → 按页序翻页
- 🔊 **音频播放**：基于 QtMultimedia，进度条定位、音量、时长显示
- 📝 **文本查看**：剧本 / 分镜 / 备注正文只读查看

**数据管理**
- ⬆ **三种导入**：文件夹批量、单文件、JSON 备份迁移
- ✂️ **两种存放策略**：复制到资产库（默认，原文件可自由移动）或仅引用原路径
- 💾 **数据库备份**：`PRAGMA wal_checkpoint` + SQLite backup API，一致性快照
- 📤 **JSON 导出 / 导入**：完整往返，含系列、章节、标签、资产、正文
- 🗑️ 删除资产只移除记录，**不删文件**（防误删）
- 🖐️ **拖拽导入**：直接拖文件夹或文件到窗口

**工程化**
- 42 个自动化测试（26 核心 + 16 UI 冒烟），`QT_QPA_PLATFORM=offscreen` 无头可跑
- 端到端验证脚本 `scripts/verify_e2e.py`：52 项检查覆盖 16 个使用环节
- GUI 全功能检查 `scripts/verify_ui.py`：79 项检查覆盖 8 组交互路径
- 深色主题，所有颜色集中在 `theme.py`，换肤只改一处
- 应用图标由 Qt 绘制，无外部资源依赖
- 依赖仅 2 个：`PySide6` + `Pillow`

### 界面设计原则

**简洁优先**：单行工具栏（44px）把垂直空间留给资产区；空值字段自动折叠而不是显示 `—`；
网格间距与卡片尺寸按 1400×880 窗口调校，5 列 × 4 行可容纳 20 张卡片无滚动。

---

## 安装

要求 **Python 3.10+**（推荐 3.12）。

```bash
cd comic-asset-manager

# 创建虚拟环境
python3.12 -m venv .venv
source .venv/bin/activate        # macOS / Linux
# .venv\Scripts\activate         # Windows

# 安装依赖
pip install -r requirements.txt

# 国内网络慢时，使用镜像
pip install -i https://mirrors.aliyun.com/pypi/simple/ PySide6 "Pillow>=10"
```

> **提示**：`pip install PySide6` 会连带安装约 500MB 的 QtWebEngine。
> 本项目不需要 Web 渲染，如需精简可只装 `PySide6-Essentials`，
> 音频播放会降级为系统播放器（QtMultimedia 位于 Addons）。

## 运行

```bash
python -m comic_asset_manager.main      # 推荐
python comic_asset_manager/main.py
./start.command                          # macOS 双击
```

首次运行会提示导入资产。默认数据库位于 `data/library.db`，
可用环境变量覆盖：`CAM_DB=/path/to/lib.db`。

## 使用要点

1. **导入**：工具栏「导入」→ 选择文件夹 → 选目标系列 → 确认「复制到资产库」→ 开始导入
2. **新建系列**：菜单「资产库 → 系列与章节管理」，或工具栏侧边栏的 `+`
3. **搜索**：顶部搜索框，支持模糊匹配
4. **翻页**：选中漫画页后按 `←` `→` 按页序切换
5. **备份**：菜单「文件 → 备份数据库」，导出到任意目录

### 快捷键

| 按键 | 功能 |
|---|---|
| `Ctrl+N` | 新建资产 |
| `Ctrl+O` | 导入 |
| `Ctrl+F` / 搜索框 | 搜索 |
| `Ctrl+1` / `Ctrl+2` | 网格 / 列表视图 |
| `Ctrl+0` | 全部资产 |
| `F5` | 刷新 |
| `←` `→` | 按页序翻页 |
| `F` | 全屏预览图片 |
| `Delete` | 删除选中资产 |

---

## 架构

```
comic_asset_manager/
├── models.py          # 数据模型：Asset / Series / Chapter / Tag + 9 种类型常量
├── db.py              # SQLite 仓储层：CRUD、过滤、搜索、分页、统计、备份、导出
├── thumbnail.py       # 缩略图生成（Pillow，EXIF 修正、缓存）+ 文件元信息
├── library.py         # 导入导出：文件夹扫描、自然排序、复制入库、JSON 往返
├── main.py            # 启动入口：高 DPI、全局样式、数据库、首次欢迎
└── ui/
    ├── theme.py       # 深色主题色板 + 全局 QSS（换肤入口）
    ├── widgets.py     # AssetCard / 类型徽章 / 标签 chips / 空状态 / 分页
    ├── sidebar.py     # 侧边栏：类型 + 系列 + 标签三级导航
    ├── grid_view.py   # 网格视图 + 后台缩略图任务（QThreadPool）
    ├── list_view.py   # 表格视图
    ├── viewer.py      # ImageViewer（缩放/平移）+ AudioPlayer（QtMultimedia）+ TextViewer
    ├── detail_panel.py# 详情面板：预览 Tab + 属性表 + 操作
    ├── asset_dialog.py# 资产新建/编辑
    ├── series_dialog.py# 系列/章节管理
    ├── import_dialog.py # 导入向导（后台线程执行，进度条）
    └── main_window.py # 主窗口：布局、菜单、快捷键、拖拽导入
```

**分层原则**：`db.py` 只暴露方法不暴露 SQL 给 UI；`models.py` 只有数据无 IO；
`ui/*` 只调用仓库方法。缩略图与导入都在后台线程执行，UI 不冻结。

**数据库 schema**（SQLite）：`series` / `chapters` / `assets` / `tags` / `meta`，
外键级联，`assets.tags` 存 JSON 数组，配合 `json_each()` 做标签检索。

## 测试

```bash
QT_QPA_PLATFORM=offscreen python -m unittest discover tests -v
```

- `tests/test_core.py`：模型、CRUD、过滤、分页、注入白名单、备份、导出往返、缩略图、文本正文提取
- `tests/test_ui_smoke.py`：无头构建主窗口，驱动数据流验证渲染、分页、搜索、对话框

端到端流程验证（模拟真实用户使用）：

```bash
python scripts/verify_e2e.py      # 52 项检查，16 个环节
```

GUI 全功能检查（驱动每一个交互路径）：

```bash
python scripts/verify_ui.py       # 79 项检查，8 组
```

生成界面截图：

```bash
QT_QPA_PLATFORM=offscreen python scripts/make_screenshots.py
```

## 许可证

LGPL-3.0（随 PySide6）。个人与商用均无需授权费。
