Files
2026-moving-helper/README.md
T
2026-04-19 13:00:11 +02:00

266 lines
5.3 KiB
Markdown

# Moving Helper
这是一个面向可信家庭内网环境的小型搬家记录工具,当前采用轻量技术栈:
- FastAPI
- Jinja2 服务端渲染
- SQLAlchemy
- SQLite
- Pillow
- pytest / FastAPI TestClient
- Docker / Docker Compose
项目目标是小而稳、容易继续扩展。目前已经支持固定三层的数据结构、基础 CRUD、单图上传能力和全局搜索,但仍然没有加入 OCR、AI 识别或其他扩展功能。
## 当前数据模型
这个项目不是无限树结构,而是固定最多 3 级:
- `Box`
- `Item`
- `SubItem`
关系如下:
- 一个 `Box` 包含多个 `Item`
- 一个 `Item` 属于一个 `Box`
- `Item` 通过 `is_container` 区分是否为“小容器”
- 只有 `is_container = true``Item` 才允许拥有 `SubItem`
- `SubItem` 是最后一级,不允许继续向下嵌套
结构固定为:
```text
Box
└── Item
└── SubItem
```
## 当前已支持
目前已支持的基础能力:
- Box 列表、详情、新建、编辑、删除
- Item 新建、详情、编辑、删除
- SubItem 新建、编辑、删除
- Box / Item / SubItem 单张图片上传、替换、删除、展示
- Box / Item / SubItem 全局搜索
- `/` 重定向到 `/boxes`
- Jinja2 模板渲染
- 静态文件挂载
- SQLite 持久化
- Docker 长期运行
- 基础自动化测试
删除规则:
- 删除 `Box` 时,会级联删除其下全部 `Item` 和对应 `SubItem`
- 删除容器型 `Item` 时,会级联删除其下 `SubItem`
## 图片能力说明
这一阶段的图片系统保持简单直接:
- `Box` 最多支持 1 张图片
- `Item` 最多支持 1 张图片
- `SubItem` 最多支持 1 张图片
- 支持上传、替换、删除
- 不支持多图
图片的主要用途是帮助识别物品、提高浏览效率、方便手机拍照后直接附加到记录中。
它不是一个原图归档系统。
### 图片处理方式
上传图片后,系统会使用 Pillow 做统一处理:
- 读取上传图片
- 去除 EXIF 元数据
- 转换为 JPEG
- 按最长边缩放到不超过 `1600px`
- 使用约 `80` 质量保存
- 将处理后的 JPEG 二进制直接写入 SQLite `BLOB`
同时还会记录:
- `image_mime_type`
- `image_width`
- `image_height`
图片访问通过普通 HTTP 路由返回 JPEG 数据,例如:
- `/boxes/{id}/image`
- `/items/{id}/image`
- `/subitems/{id}/image`
## 全局搜索
当前已经支持一个轻量的全局搜索页:
- 路由:`/search`
- 使用 query parameter,例如:`/search?q=电源线`
搜索范围包括:
- `Box.name`
- `Box.note`
- `Item.name`
- `Item.note`
- `SubItem.name`
- `SubItem.note`
当前使用 SQLite 上的简单模糊匹配完成搜索,不引入外部搜索引擎或复杂全文系统。
搜索结果会尽量帮助你快速定位:
- 显示对象类型:`Box / Item / SubItem`
- 显示名称和备注
- 显示归属路径
-`Item` 展示所属 `Box`
-`SubItem` 展示所属 `Item``Box`
- 如果对象已有图片,会显示一个小缩略图
## 当前未实现
这一阶段仍然没有实现以下内容:
- 搜索
- 多图上传
- OCR
- AI 识别物品
- 图片标签
- 图片分类
- 登录 / 鉴权
- 标签系统
- 前后端分离
- 复杂 UI
## 项目结构
```text
.
├── app
│ ├── __init__.py
│ ├── config.py
│ ├── db.py
│ ├── images.py
│ ├── main.py
│ ├── models.py
│ ├── static
│ │ └── style.css
│ └── templates
│ ├── base.html
│ ├── boxes
│ ├── items
│ └── subitems
├── data
├── tests
│ ├── conftest.py
│ └── test_app.py
├── docker-compose.yml
├── Dockerfile
├── pytest.ini
├── README.md
└── requirements.txt
```
## 轻量配置
项目通过环境变量支持以下配置项:
- `DATABASE_URL`
- `HOST`
- `PORT`
默认值:
- `DATABASE_URL=sqlite:///./data/app.db`
- `HOST=0.0.0.0`
- `PORT=10000`
## 本地开发模式
推荐使用本地 Python `venv` 开发和调试。
### 1. 创建虚拟环境
```bash
python3 -m venv .venv
source .venv/bin/activate
```
### 2. 安装依赖
```bash
pip install -r requirements.txt
```
### 3. 启动开发服务器
```bash
uvicorn app.main:app --reload --host 0.0.0.0 --port 10000
```
访问:
```text
http://localhost:10000
```
本地默认数据库位置:
```text
./data/app.db
```
## Docker 部署模式
Docker / Compose 是这个项目面向长期运行环境的方式。
启动:
```bash
docker compose up --build
```
访问:
```text
http://localhost:10000
```
说明:
- 默认暴露 `10000` 端口
- `restart: unless-stopped`
- 容器使用 `1000:1000` 运行
- SQLite 文件持久化到宿主机 `./data/app.db`
- 容器重建不会丢失数据
备份时直接复制 SQLite 文件即可:
```text
./data/app.db
```
## 测试
运行测试:
```bash
python -m pytest
```
测试使用独立测试数据库,不会污染真实开发数据。
当前测试覆盖包括:
- Box / Item / SubItem 基础 CRUD
- 404 返回
- 非容器 Item 不能创建 SubItem
- Box / Item 删除后的级联删除
- 图片上传、转换为 JPEG、缩放、读取、替换、删除
- 全局搜索 name / note,并展示对象类型与归属路径
- 无图片访问和非法图片上传等错误路径
- 关键 POST 请求后的重定向行为