# 晨风书舍 — 家庭图书管理系统

> 当前版本：V2.0（云端迁移版） | 最后更新：2026-06-28
> 线上地址：https://chenningbo.com/library/

---

## 目录

1. [项目概述](#项目概述)
2. [功能总览](#功能总览)
3. [架构设计](#架构设计)
4. [实现细节](#实现细节)
5. [版本演进](#版本演进)
6. [部署策略](#部署策略)
7. [开发约定](#开发约定)

---

## 项目概述

晨风书舍是一个家庭图书管理系统，核心流程：**扫描 ISBN → 自动查询书目 + CLC 分类 → 5 秒倒计时确认 → 自动上架虚拟书架（云端持久化）**。

### 定位

- 替代纸质藏书登记 + Excel 管理
- 支持 USB 扫码枪批量录入（5 秒/本）
- 云端多设备实时同步
- 访客只读 + 管理员写权限

### 技术栈

| 层 | 技术 | 说明 |
|:---|:---|:---|
| UI | HTML5 + CSS3（暗色主题，CSS Grid 3D 书架） | 单文件无框架 |
| 逻辑 | Vanilla JavaScript (ES2020+) | 无构建工具 |
| 存储 | 服务端 SQLite（V2.0 新增） | IndexedDB 已退役 |
| 后端 | Python Flask（Blueprint） | port 5099 |
| 运行 | systemd `chenningbo-api.service` | 开机自启 |
| 反代 | Nginx | `/library` 静态 + `/api/home-library/` → Flask |
| 分类 | 出版社映射 + 关键词引擎 + DeepSeek API | 三级推断 |
| 封面 | OpenLibrary + 豆瓣 CORS | 双源回退 + 占位图过滤 |
| 书目 | 国图 OPAC 代理 + 豆瓣搜索代理 | 同域 Flask 服务 |

---

## 功能总览

### 核心工作流

```
USB 扫码枪扫 ISBN
    ↓
国图 OPAC (5s) → 豆瓣服务端 (5s) → CORS 豆瓣 → OpenLibrary → Google Books
    ↓
填入书名/作者/出版社 → 三级 CLC 推断
    ↓
5 秒倒计时 → 自动上架到对应 CLC 分类的书格
```

### 书架结构

| 列 | 用途 | 层 | 用途 |
|:---|:---|:---|:---|
| G1-G13 | CLC A→Z 自动分配（主书区） | L1-L2 | 保留层（虚线显示） |
| G14 | 儿童读物（固定列） | L3-L8 | 活跃层（78 格） |
| G15 | 相册（固定列） | L9 | 底层收藏区（标签可编辑） |

每格容量 15 本，活跃容量 1170 本。

### 管理员功能

锁图标 🔒 输入密码后解锁（sessionStorage 存储，关标签页自动登出）：

- 录入新书（扫码 / 手动 / 书名搜索）
- 编辑 / 删除已有书籍
- 全局重排（重新分配所有书位置）
- 批量 CLC 修正（国图校对）
- 批量补封面
- JSON 导入（全量替换）
- CSV 导出（UTF-8 BOM，兼容 Excel）

### 访客功能

无需登录：

- 搜索（书名/作者/ISBN，实时下拉）
- 浏览书架（3D 透视 + 拖拽 + 键盘 + 滚轮缩放）
- 查看统计面板（饼图 + 柱状图 + KPI 卡片）
- JSON 导出备份
- DeepSeek API Key 配置

---

## 架构设计

### 前后端分离

```
用户浏览器
    ↓ HTTPS
Nginx (chenningbo.com)
    ├── /library/         → alias /var/www/chenningbo/library/index.html（静态单页应用）
    └── /api/home-library/*  → proxy_pass http://127.0.0.1:5099（Flask）
```

### Flask 服务结构

```
chenningbo_api.py（主入口，port 5099）
├── nlc_api.py（导入 app 对象）
│   ├── GET /api/isbn/<isbn>      国图 OPAC 代理
│   ├── GET /api/douban/<isbn>    豆瓣搜索代理
│   └── GET /api/search?q=        书名搜索
└── home_library_bp（注册到 app）
    ├── GET    /api/home-library/books        全量获取
    ├── POST   /api/home-library/books        新增
    ├── PUT    /api/home-library/books/<id>   更新
    ├── DELETE /api/home-library/books/<id>   删除
    ├── POST   /api/home-library/books/bulk   批量重排
    ├── POST   /api/home-library/import       全量导入
    └── GET    /api/home-library/ping         健康检查
```

### 权限模型

| 身份 | 认证方式 | 可操作 |
|:---|:---|:---|
| 访客 | 无 | 浏览、搜索、导出、统计 |
| 管理员 | 点 🔒 输入密码 → sessionStorage 存 token | 全部写操作 |

写操作请求头携带 `X-Admin-Token`，服务端 `require_admin` 装饰器校验，失败返回 401。

### 数据模型

```sql
CREATE TABLE books (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    isbn        TEXT,
    title       TEXT NOT NULL,
    author      TEXT,
    publisher   TEXT,
    clc_main    TEXT,       -- CLC 大类代码
    clc_code    TEXT,       -- 同 clc_main（历史冗余）
    grid        INTEGER,    -- 书架列号 1-15
    layer       INTEGER,    -- 层号 1-9
    position    INTEGER,    -- 格内序号 1-15
    location    TEXT,       -- "G03-L05-12"
    added_at    TEXT,       -- "YYYY-MM-DD"
    cover       TEXT,       -- 封面图 URL
    note        TEXT,
    corrected   INTEGER DEFAULT 0  -- 批量修正标记
);
```

字段名映射：DB 用下划线（`clc_main`），前端用驼峰（`clcMain`），`_row_to_dict()` / `_dict_to_row()` 负责转换。

---

## 实现细节

### CLC 三级推断策略

| 优先级 | 方法 | 准确率 | 说明 |
|:---|:---|:---|:---|
| 1 | 出版社精确映射 | ≈100% | 50+ 家出版社映射表，如人民文学→I |
| 2 | 离线关键词匹配 | 75-85% | 每分类 30-40 个关键词，书名+作者综合打分 |
| 3 | DeepSeek API | ≈90% | 需用户在页面配置 API Key |

### ISBN 查询链路

```
[1] 国图 OPAC 代理 /api/isbn/{isbn}    5s（常被屏蔽，快速失败）
[2] 豆瓣服务端代理 /api/douban/{isbn}  5s（主力来源）
[3] 豆瓣 CORS 代理（cors.zme.ink）     8s
[4] OpenLibrary                         4s
[5] Google Books                        3s（国内不通）
```

### 封面抓取

- 双源：OpenLibrary → 豆瓣 CORS
- 占位图过滤：`tryImg` 校验宽高 > 10px，OpenLibrary 加 `?default=false`
- 批量补封面：8 本一批并行请求

### 书架分配算法（两步比例分配）

1. **保底**：每个有书的 CLC 类 → `ceil(count / 15)` 格
2. **缓冲**：剩余格数按各类录入量占比分配，小数部分最大者优先

### 5 秒倒计时自动录入

扫码/搜索完成且书名+CLC 都齐全后：
- 按钮变为 `✓ 录入 (5s)`，底部有收缩进度条
- 5 秒后自动调用 `saveBook()`
- 点按钮立即保存，点「取消」停止倒计时供修改

---

## 版本演进

### 阶段一：本地 IndexedDB 时代（V1.0-V1.12.15）

| 版本 | 日期 | 里程碑 |
|:---|:---|:---|
| V1.0 | 2026-05-25 | 初始版本，15×10 书架，CLC 手动选择 |
| V1.5 | 2026-05-30 | ISBN 扫码自动查询，双源 API 回退 |
| V1.7 | 2026-05-31 | 自动 CLC 推断（关键词引擎），3D 透视 + 拖拽 |
| V1.9 | 2026-05-31 | 搜索定位、CSV 导入导出 |
| V1.11 | 2026-06-01 | 9 层书架全活跃，统计面板（饼图+柱状图），倒计时录入 |
| V1.12.7 | 2026-06-01 | 比例分配算法稳定版 |
| V1.12.15 | 2026-06-02 | 占位图根治（`?default=false` + 尺寸校验） |

关键修复记录：
- OpenLibrary 1×1 占位图被误存（V1.12.13）
- 豆瓣封面也可能返回小占位图（V1.12.14）
- `?default=false` 根治（V1.12.15）

### 阶段二：云端迁移（V2.0，2026-06-28）

| 变动 | 说明 |
|:---|:---|
| 存储 | IndexedDB → 服务端 SQLite（Flask + systemd） |
| 新 Logo | 开卷 + 晨曦 SVG 品牌标识 |
| 5 秒倒计时 | 扫码后自动倒计时上架，可提前确认或取消修改 |
| 权限分离 | 访客只读 vs 管理员（sessionStorage token） |
| CLC 三级推断 | 出版社映射 → 关键词 → DeepSeek AI 兜底 |
| 封面过滤 | OpenLibrary `?default=false` + 豆瓣尺寸校验 |

### 阶段三：合并到 P09（2026-06-30）

- P22_HomeLibrary 项目删除
- 前端 HTML 归入 `P09/src/library/index.html`
- API 文件归入 `P09/src/api/`
- 项目资料归入 `P09/src/docs/chenfengshushe/`
- 部署统一走 `sync-website.sh`

---

## 部署策略

### 部署命令

```bash
cd /mnt/d/WorkSpace/01_Windows_Projects/P09_PersonalWebsite
bash sync-website.sh
```

### 服务器文件位置

| 内容 | 路径 |
|:---|:---|
| 前端 HTML | `/var/www/chenningbo/library/index.html` |
| Flask 主入口 | `/var/www/chenningbo/api/chenningbo_api.py` |
| 图书 Blueprint | `/var/www/chenningbo/api/home_library_api.py` |
| 国图/豆瓣代理 | `/var/www/chenningbo/api/nlc_api.py` |
| SQLite 数据库 | `/var/www/data/home_library.db` |
| systemd 服务 | `/etc/systemd/system/chenningbo-api.service` |
| Nginx 配置 | `/etc/nginx/sites-enabled/chenningbo.conf` |

### API 重启

```bash
ssh root@8.218.185.122 "systemctl restart chenningbo-api"
```

### Nginx 关键配置

```nginx
location /library {
    alias /var/www/chenningbo/library/;
    index index.html;
    try_files $uri $uri/ /library/index.html;
}
location ^~ /api/home-library/ {
    proxy_pass http://127.0.0.1:5099;
}
```

### 验证

```bash
curl -s https://www.chenningbo.com/api/home-library/ping
# {"ok":true,"total":42}
```

---

## 开发约定

### 源码位置

- 主程序：`src/library/index.html`（单文件，约 2200+ 行 JS）
- API：`src/api/chenningbo_api.py` + `home_library_api.py` + `nlc_api.py`
- 项目资料：`src/docs/chenfengshushe/`
- 项目介绍页：`src/projects/cangshuge.html`

### 修改规则

1. 修改前端 HTML 直接改 `src/library/index.html`，`sync-website.sh` 自动同步
2. 修改 API 在 `src/api/` 下操作，改完后需 `systemctl restart chenningbo-api`
3. 版本号写在 HTML 的 logo 后（`📚 晨风书舍 Vx.x.x`）和 `VERSION` 文件中
4. 部署前验证 API 正常运行

### 文件说明

| 文件 | 内容 |
|:---|:---|
| `CHANGELOG.md` | 完整版本更新日志（V1.0 至今） |
| `DEPLOY.md` | 服务器部署操作记录 |
| `DESIGN.md` | 详细设计文档 |
| `PROJECT_SPEC.md` | 项目完整规格说明书 |
| `TEST_REPORT.md` | 末次测试报告 |
| `TEST_REPORT_V1.7.2.md` | 历史测试报告 |
| `工程记录.md` | 早期架构记录 |

---

> 本文档由 P22_HomeLibrary 合并到 P09_PersonalWebsite 时统一整理。
> 后续所有维护均在 P09 中进行。
