# 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 请求后的重定向行为