Update README with current project structure and features

- Add api/ package, model/response.go, logger, queue docs
- Document environment variables (WORKER_COUNT, LOG_DIR, LOG_LEVEL)
- Add cache strategy and async queue sections
- Update project structure tree
- Add GORM + raw SQL hybrid approach doc

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
dindang 2026-07-16 10:39:55 +08:00
parent 01a579ab9c
commit a756c8c464

131
README.md
View File

@ -1,31 +1,33 @@
# FloorVisualizer # FloorVisualizer
AI 换地板可视化后端服务 — 上传房间照片AI 自动识别地面区域并生成换地板效果图。 AI 换地板可视化后端服务 — 上传房间照片AI 自动识别地面区域并生成换地板效果图。
## 技术栈 ## 技术栈
- **语言**: Go 1.23+ - **语言**: Go 1.23+
- **数据库**: PostgreSQL 15 - **数据库**: PostgreSQL 15GORM + 原生 SQL
- **缓存/队列**: Redis 7 - **缓存/队列**: Redis 7
- **AI**: OpenRouter API (Gemini 3 Pro / Flash) - **AI**: OpenRouter API (Gemini 3 Pro / Flash)
- **部署**: Docker Compose - **部署**: Docker Compose
## 快速开始 ## 快速开始
### 本地开发 ### 首次部署
```bash ```bash
# 1. 起依赖(仅 DB + Redis # 1. 初始化数据库(仅一次
docker compose -f docker-compose.dev.yml up -d psql -U postgres < schema.sql
# 2. 导入产品数据 # 2. 导入产品数据
go run cmd/import/main.go go run cmd/import/main.go # 3539 条产品
go run cmd/import_articles/main.go # 30 篇科普文章
# 3. 启动服务 # 3. 启动开发服务(本地 DB + Redis
docker compose -f docker-compose.dev.yml up -d
go run main.go go run main.go
``` ```
服务默认运行在 `http://localhost:8099` 服务运行在 `http://localhost:8099`
### 生产部署 ### 生产部署
@ -36,43 +38,54 @@ docker compose up -d --build
## 项目结构 ## 项目结构
``` ```
├── main.go # 入口 ├── main.go
├── schema.sql # 建表脚本(导入一次)
├── cmd/ ├── cmd/
│ ├── import/main.go # 产品数据导入 │ ├── import/main.go # 产品数据导入
│ ├── import_articles/main.go # 科普文章导入 │ ├── import_articles/main.go # 科普文章导入
│ └── scrape_logos/main.py # 品牌 Logo 刮取 │ └── scrape_logos/main.py # 品牌 Logo 刮取
├── internal/ ├── internal/
│ ├── handler/ # HTTP 处理器 │ ├── api/
│ │ ├── router.go # 路由注册 │ │ └── router.go # 路由注册 + 依赖注入 + 响应 helper
│ │ ├── product_handler.go # 产品列表/详情 │ ├── handler/ # HTTP 处理器(函数导出)
│ │ ├── floor_handler.go # AI 换地板 │ │ ├── router.go # writeJSON/writeErr
│ │ ├── auth_handler.go # 注册/登录 │ │ ├── auth_handler.go # Register / Login
│ │ ├── user_handler.go # 用户/收藏/项目/头像 │ │ ├── user_handler.go # Me / UploadAvatar / Favorites / Projects / FrequentBrands
│ │ ├── recommend_handler.go # 智能推荐 │ │ ├── product_handler.go # Products / ProductOptions / FilterOptions
│ │ ├── calc_handler.go # 面积计算 │ │ ├── recommend_handler.go # Recommend
│ │ ├── article_handler.go # 科普文章 │ │ ├── calc_handler.go # Calc
│ │ ├── upload_handler.go # 图片上传 │ │ ├── floor_handler.go # FloorGenerate / FloorStatus / FloorOptions
│ │ └── health_handler.go # 健康检查 │ │ ├── article_handler.go # Articles / ArticleRecommend
│ ├── model/ # 数据模型 │ │ ├── health_handler.go # Healthz
│ ├── repository/ # 数据库操作 │ │ └── upload_handler.go # Upload
│ ├── model/ # 数据模型 + 返回结构体
│ │ ├── response.go # ApiResponse / ApiError
│ │ ├── calc.go # CalcInput / CalcResult / CalcDeduction
│ │ ├── product.go # Product / ProductSpec
│ │ ├── brand.go # BrandInfo
│ │ └── ...
│ ├── repository/ # 数据访问GORM + 原生 SQL
│ │ ├── gorm.go # GORM 初始化
│ │ ├── db.go # PostgreSQL 连接
│ │ ├── product_repo.go # 产品查询(简单 GORM复杂 SQL
│ │ ├── brand_view_repo.go # 品牌浏览统计
│ │ └── ...
│ ├── service/ # 业务逻辑(推荐算法) │ ├── service/ # 业务逻辑(推荐算法)
│ ├── middleware/ # 中间件JWT、日志、访问记录 │ ├── middleware/ # JWT 认证 + 访问日志
│ ├── queue/ # Redis 队列(异步任务) │ ├── queue/ # Redis 异步任务队列
│ │ ├── redis.go # 入队/出队/状态管理
│ │ └── worker.go # Worker 池(并发消费)
│ ├── openrouter/ # OpenRouter API 客户端 │ ├── openrouter/ # OpenRouter API 客户端
│ └── logger/ # 分级日志 │ └── logger/ # 分级日志(日切 + 30 天清理)
├── data/products/ # 产品 JSON 数据3539 条) ├── data/products/ # 产品 JSON3539 条,不入 git
├── data/articles.json # 科普文章30 篇)
├── knowledge_images/ # 文章图片
├── Dockerfile ├── Dockerfile
├── docker-compose.yml # 生产部署 ├── docker-compose.yml
├── docker-compose.dev.yml # 本地开发 ├── docker-compose.dev.yml
└── apifox-import.json # API 文档 └── apifox-import.json # API 文档
``` ```
## 环境变量 ## 环境变量
### 服务配置
| 变量 | 默认值 | 说明 | | 变量 | 默认值 | 说明 |
|------|--------|------| |------|--------|------|
| `PORT` | `8099` | HTTP 端口 | | `PORT` | `8099` | HTTP 端口 |
@ -82,19 +95,9 @@ docker compose up -d --build
| `OPENROUTER_API_KEY` | 内置默认值 | OpenRouter API Key | | `OPENROUTER_API_KEY` | 内置默认值 | OpenRouter API Key |
| `PROXY_URL` | `127.0.0.1:7897` | HTTP 代理(留空禁用) | | `PROXY_URL` | `127.0.0.1:7897` | HTTP 代理(留空禁用) |
| `DISABLE_PROXY` | — | 设为 `true` 强制禁用代理 | | `DISABLE_PROXY` | — | 设为 `true` 强制禁用代理 |
### 队列
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `WORKER_COUNT` | `5` | AI 生成并发 worker 数1-20 | | `WORKER_COUNT` | `5` | AI 生成并发 worker 数1-20 |
### 日志
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `LOG_DIR` | `logs` | 日志目录 | | `LOG_DIR` | `logs` | 日志目录 |
| `LOG_LEVEL` | `INFO` | 日志级别:DEBUG / INFO / WARN / ERROR | | `LOG_LEVEL` | `INFO` | DEBUG / INFO / WARN / ERROR |
## API 总览 ## API 总览
@ -106,23 +109,23 @@ docker compose up -d --build
### 产品(公开) ### 产品(公开)
- `GET /products` — 列表(多维度筛选+搜索+分页) - `GET /products` — 列表(多维度筛选+搜索+分页)
- `GET /products/{sku}` — 详情(含规格 specs、收藏状态 - `GET /products/{sku}` — 详情(含 specs 规格、收藏状态、热点缓存
- `GET /product-options` — 筛选选项(含品牌 logo、款式数、合集数 - `GET /product-options` — 筛选选项(含品牌 logo、款式数、合集数
### 推荐(公开) ### 推荐(公开)
- `GET /recommend/api?sku=xxx` — 跨品牌相似推荐 - `GET /recommend/api?sku=xxx` — 跨品牌相似推荐specs 感知)
### 地板更换 ### 地板更换(需 Redis
- `GET /floor/options` — 地板样式+铺设方式+房间类型 - `GET /floor/options` — 地板样式+铺设方式+房间类型
- `POST /floor/generate` — 提交 AI 生成任务 → 返回 `job_id` - `POST /floor/generate` — 提交 AI 生成任务 → 返回 `job_id`
- `GET /floor/status?job_id=xxx` — 查询任务进度 - `GET /floor/status?job_id=xxx` — 查询异步任务进度
### 用户(需 JWT ### 用户(需 JWT
- `GET /user/me` / `PUT /user/me` — 个人信息 - `GET /user/me` / `PUT /user/me` — 个人信息
- `POST /user/avatar` — 上传头像 - `POST /user/avatar` — 上传头像
- `GET /user/favorites` / `POST` / `DELETE` — 收藏管理 - `GET /user/favorites` / `POST` / `DELETE` — 收藏管理
- `GET /user/projects` / `POST` / `PUT` / `DELETE` — 项目(生成记录) - `GET /user/projects` / `POST` / `PUT` / `DELETE` — 项目(生成记录)
- `GET /user/frequent-brands` — 常用品牌浏览≥3 或 收藏≥2 - `GET /user/frequent-brands` — 常用品牌(自动统计,浏览≥3 或 收藏≥2
### 计算器 ### 计算器
- `POST /calculator/calc` — 多房间面积+损耗+费用计算 - `POST /calculator/calc` — 多房间面积+损耗+费用计算
@ -133,7 +136,7 @@ docker compose up -d --build
- `GET /articles/recommend` — 随机推荐 - `GET /articles/recommend` — 随机推荐
### 其他 ### 其他
- `POST /upload` — 通用图片上传 - `POST /upload` — 通用图片上传20MB
- `GET /healthz` — 健康检查 - `GET /healthz` — 健康检查
## 数字编码 ## 数字编码
@ -165,12 +168,34 @@ docker compose up -d --build
## 产品数据 ## 产品数据
10 个品牌3539 条产品,盖 Hardwood / Engineered Wood / Laminate / SPC/LVP / Wood-Look Tile 五大品类。 10 个品牌3539 条产品,盖 Hardwood / Engineered Wood / Laminate / SPC/LVP / Wood-Look Tile 五大品类。
数据存储在 `data/products/*.json`,首次使用需运行 `go run cmd/import/main.go` 导入 PostgreSQL。 数据存储在 `data/products/*.json`(不入 git首次使用需运行 `go run cmd/import/main.go` 导入 PostgreSQL。
## 数据库
表结构统一管理在 `schema.sql`,服务启动时不再自动建表。修改表结构后更新此文件即可。
查询层使用 GORM + 原生 SQL 混合:
- 简单 CRUD`GetProductBySKU`)→ GORM
- 复杂查询(动态筛选 `DISTINCT ON`、批量统计)→ 原生 SQL
## 日志 ## 日志
- **格式**: `2026-07-10 16:30:01 [INFO] main.go:96 Server started` - **格式**: `2026-07-10 16:30:01.234 [INFO] main.go:96 Server started`
- **存储**: `logs/app-YYYY-MM-DD.log`,每天一个文件 - **存储**: `logs/app-YYYY-MM-DD.log`,每天自动切文件
- **清理**: 自动删除 30 天前的日志 - **清理**: 自动删除 30 天前的日志
- **输出**: 同时写 stdout + 文件
## 缓存
- **热点产品缓存**: Redis sorted set 统计浏览量Top 200 自动缓存TTL 1h ± 10min 随机抖动防雪崩
- **品牌浏览统计**: 自动记录(查询产品详情时触发)
## 异步队列
AI 图片生成使用 Redis List 做消息队列Worker 池消费:
- 提交任务 → RPUSH 入队 → 立即返回 `job_id`
- Worker 从 BRPOP 出队 → 调用 OpenRouter → 写入结果
- 并发数通过 `WORKER_COUNT` 控制,默认 5
- 进度查询: `GET /floor/status?job_id=xxx`