2026-04-19 13:00:11 +02:00
2026-04-19 13:00:11 +02:00
2026-04-19 13:00:11 +02:00
2026-04-19 12:54:25 +02:00
2026-04-19 12:13:07 +02:00
2026-04-19 12:13:07 +02:00
2026-04-19 12:13:07 +02:00
2026-04-19 12:13:07 +02:00
2026-04-19 13:00:11 +02:00
2026-04-19 12:54:25 +02:00

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 = trueItem 才允许拥有 SubItem
  • SubItem 是最后一级,不允许继续向下嵌套

结构固定为:

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 展示所属 ItemBox
  • 如果对象已有图片,会显示一个小缩略图

当前未实现

这一阶段仍然没有实现以下内容:

  • 搜索
  • 多图上传
  • OCR
  • AI 识别物品
  • 图片标签
  • 图片分类
  • 登录 / 鉴权
  • 标签系统
  • 前后端分离
  • 复杂 UI

项目结构

.
├── 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. 创建虚拟环境

python3 -m venv .venv
source .venv/bin/activate

2. 安装依赖

pip install -r requirements.txt

3. 启动开发服务器

uvicorn app.main:app --reload --host 0.0.0.0 --port 10000

访问:

http://localhost:10000

本地默认数据库位置:

./data/app.db

Docker 部署模式

Docker / Compose 是这个项目面向长期运行环境的方式。

启动:

docker compose up --build

访问:

http://localhost:10000

说明:

  • 默认暴露 10000 端口
  • restart: unless-stopped
  • 容器使用 1000:1000 运行
  • SQLite 文件持久化到宿主机 ./data/app.db
  • 容器重建不会丢失数据

备份时直接复制 SQLite 文件即可:

./data/app.db

测试

运行测试:

python -m pytest

测试使用独立测试数据库,不会污染真实开发数据。

当前测试覆盖包括:

  • Box / Item / SubItem 基础 CRUD
  • 404 返回
  • 非容器 Item 不能创建 SubItem
  • Box / Item 删除后的级联删除
  • 图片上传、转换为 JPEG、缩放、读取、替换、删除
  • 全局搜索 name / note,并展示对象类型与归属路径
  • 无图片访问和非法图片上传等错误路径
  • 关键 POST 请求后的重定向行为
S
Description
No description provided
Readme 267 KiB
2026-04-27 20:44:28 +02:00
Languages
Python 69.2%
HTML 19.2%
CSS 5.8%
Shell 5.4%
Dockerfile 0.3%
Other 0.1%