- Go API server with PostgreSQL + Redis - AI floor replacement (OpenRouter Gemini) - Product database (10 brands, 3539 products) - Recommendation engine, calculator, articles - Redis async queue + worker pool - Hot product caching, brand view tracking - JWT auth, favorites, projects - Docker deployment ready Co-Authored-By: Claude <noreply@anthropic.com>
2331 lines
66 KiB
JSON
2331 lines
66 KiB
JSON
{
|
||
"openapi": "3.0.3",
|
||
"info": {
|
||
"title": "FloorVisualizer API",
|
||
"description": "FloorVisualizer 后端接口文档\n\n## 全局响应格式\n所有 API 统一返回 JSON 信封格式:\n```\n成功: {\"code\": 200, \"data\": {...}}\n失败: {\"code\": 400, \"error\": \"错误描述\"}\n```\n\n认证方式:注册/登录获取 JWT token,在需要认证的接口中设置 Header: Authorization: Bearer {token}\n\n---\n## 产品筛选层层递进说明\n产品列表支持 category / material / color_tone / finish / wood_species / brand / series_name 多维度组合筛选。\n前端实现层层递进:用户每选一个筛选项,将已选参数传给 /products 获取结果,再根据返回的 filter_options 动态更新其他筛选项的可选范围。\n\n---\n## AI换地板对接说明\n1. GET /floor/options 获取可用的地板样式(从产品库动态加载,每个样式对应真实SKU)\n2. POST /floor/generate 上传图片 + floor_id(产品SKU)+ pattern_code(1-9)+ room_code(0-7)→ 返回 job_id\n3. GET /floor/progress?job_id=xxx(SSE)跟踪进度 → check → mask → inpaint → done\n4. 生成完成后保存到用户项目:POST /user/projects\n\n---\n## 数字编码对照\n\n### 铺设方式 (pattern_code)\n| code | 木地板 | 瓷砖 |\n|------|--------|------|\n| 1 | Straight Lay | — |\n| 2 | Horizontal Lay | — |\n| 3 | Herringbone | — |\n| 4 | Chevron | — |\n| 5 | — | Straight Grid |\n| 6 | — | Running Bond |\n| 7 | — | 1/3 Offset |\n| 8 | — | Hexagonal |\n| 9 | — | Diagonal (45°) |\n\n### 房间类型 (room_code)\n| code | 房间 |\n|------|------|\n| 0 | Auto Detect(不传房间信息给AI) |\n| 1 | Living Room |\n| 2 | Bedroom |\n| 3 | Kitchen |\n| 4 | Dining Room |\n| 5 | Bathroom |\n| 6 | Study Room |\n| 7 | Hallway |\n\n---\n## 静态文件路径\n- 上传图片: /static/images/\n- 知识图片: /knowledge_images/ 或 /images/knowledge/\n- 生成结果: /outputs/\n- 用户上传: /uploads/",
|
||
"version": "1.0.0"
|
||
},
|
||
"servers": [
|
||
{
|
||
"url": "http://localhost:8099",
|
||
"description": "本地开发环境"
|
||
}
|
||
],
|
||
"components": {
|
||
"securitySchemes": {
|
||
"BearerAuth": {
|
||
"type": "http",
|
||
"scheme": "bearer",
|
||
"bearerFormat": "JWT",
|
||
"description": "注册或登录后获取的 JWT token"
|
||
}
|
||
},
|
||
"schemas": {
|
||
"AuthResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"token": {
|
||
"type": "string",
|
||
"description": "JWT token,后续请求放 Authorization header"
|
||
},
|
||
"user": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
},
|
||
"example": {
|
||
"username": "demo",
|
||
"password": "123456",
|
||
"name": "Demo User"
|
||
}
|
||
},
|
||
"User": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "string",
|
||
"description": "用户唯一ID (UUID)"
|
||
},
|
||
"username": {
|
||
"type": "string",
|
||
"description": "用户名"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "显示名称"
|
||
},
|
||
"avatar_url": {
|
||
"type": "string",
|
||
"description": "头像URL"
|
||
},
|
||
"created_at": {
|
||
"type": "string",
|
||
"format": "date-time",
|
||
"description": "注册时间"
|
||
},
|
||
"updated_at": {
|
||
"type": "string",
|
||
"format": "date-time",
|
||
"description": "更新时间"
|
||
}
|
||
}
|
||
},
|
||
"Favorite": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "integer",
|
||
"description": "收藏记录ID"
|
||
},
|
||
"user_id": {
|
||
"type": "string",
|
||
"description": "用户ID"
|
||
},
|
||
"sku": {
|
||
"type": "string",
|
||
"description": "产品SKU编码"
|
||
},
|
||
"brand": {
|
||
"type": "string",
|
||
"description": "品牌"
|
||
},
|
||
"series_name": {
|
||
"type": "string",
|
||
"description": "系列名称"
|
||
},
|
||
"style_name": {
|
||
"type": "string",
|
||
"description": "花色/款式名称"
|
||
},
|
||
"main_image_url": {
|
||
"type": "string",
|
||
"description": "产品主图URL"
|
||
},
|
||
"category": {
|
||
"type": "string",
|
||
"description": "分类"
|
||
},
|
||
"material": {
|
||
"type": "string",
|
||
"description": "材质"
|
||
},
|
||
"color_tone": {
|
||
"type": "string",
|
||
"description": "色调"
|
||
},
|
||
"price_per_sqft": {
|
||
"type": "number",
|
||
"description": "每平方英尺价格"
|
||
},
|
||
"created_at": {
|
||
"type": "string",
|
||
"format": "date-time",
|
||
"description": "收藏时间"
|
||
}
|
||
}
|
||
},
|
||
"Project": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "string",
|
||
"description": "项目唯一ID (UUID)"
|
||
},
|
||
"user_id": {
|
||
"type": "string",
|
||
"description": "用户ID"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "项目名称"
|
||
},
|
||
"original_image_url": {
|
||
"type": "string",
|
||
"description": "换地板前的原图URL"
|
||
},
|
||
"generated_image_url": {
|
||
"type": "string",
|
||
"description": "AI生成后的效果图URL"
|
||
},
|
||
"floor_style": {
|
||
"type": "string",
|
||
"description": "使用的款式(如 Light Oak)"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"description": "铺设方式(如 Herringbone, Straight Lay)"
|
||
},
|
||
"room_type": {
|
||
"type": "string",
|
||
"description": "房间类型(如 Living Room)"
|
||
},
|
||
"created_at": {
|
||
"type": "string",
|
||
"format": "date-time",
|
||
"description": "创建时间"
|
||
},
|
||
"updated_at": {
|
||
"type": "string",
|
||
"format": "date-time",
|
||
"description": "更新时间"
|
||
}
|
||
}
|
||
},
|
||
"ProductItem": {
|
||
"type": "object",
|
||
"properties": {
|
||
"brand": {
|
||
"type": "string",
|
||
"description": "品牌"
|
||
},
|
||
"series_name": {
|
||
"type": "string",
|
||
"description": "系列名称"
|
||
},
|
||
"style_name": {
|
||
"type": "string",
|
||
"description": "花色/款式名称"
|
||
},
|
||
"sku": {
|
||
"type": "string",
|
||
"description": "产品SKU编码"
|
||
},
|
||
"category": {
|
||
"type": "string",
|
||
"description": "分类(Hardwood / Laminate / SPC/LVP / Engineered Wood / Wood-Look Tile)"
|
||
},
|
||
"material": {
|
||
"type": "string",
|
||
"description": "材质(如 Oak, Porcelain, Walnut)"
|
||
},
|
||
"color_tone": {
|
||
"type": "string",
|
||
"description": "色调(如 Light Gray, Natural Oak, Dark Brown)"
|
||
},
|
||
"finish": {
|
||
"type": "string",
|
||
"description": "表面处理(如 Matte, Gloss, Textured)"
|
||
},
|
||
"price_per_sqft": {
|
||
"type": "number",
|
||
"description": "每平方英尺价格(美元)"
|
||
},
|
||
"price_tier": {
|
||
"type": "string",
|
||
"description": "价格段位(Budget/Value, Mid-Range, Upper Mid-Range, Premium)"
|
||
},
|
||
"main_image_url": {
|
||
"type": "string",
|
||
"description": "产品主图URL"
|
||
},
|
||
"size_label": {
|
||
"type": "string",
|
||
"description": "Size label"
|
||
},
|
||
"coverage_sqft_per_box": {
|
||
"type": "number",
|
||
"description": "Coverage per box (sqft)"
|
||
},
|
||
"is_favorited": {
|
||
"type": "boolean",
|
||
"description": "当前用户是否已收藏。未登录时始终为 false"
|
||
},
|
||
"spec_count": {
|
||
"type": "integer",
|
||
"description": "该花色的规格数量(同品牌同花色的SKU数,含自身)。>1 表示有多种尺寸可选"
|
||
}
|
||
}
|
||
},
|
||
"ProductListResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"products": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ProductItem"
|
||
},
|
||
"description": "产品列表"
|
||
},
|
||
"total": {
|
||
"type": "integer",
|
||
"description": "总数"
|
||
},
|
||
"page": {
|
||
"type": "integer",
|
||
"description": "当前页码"
|
||
},
|
||
"limit": {
|
||
"type": "integer",
|
||
"description": "每页数量"
|
||
},
|
||
"total_pages": {
|
||
"type": "integer",
|
||
"description": "总页数"
|
||
},
|
||
"filter_options": {
|
||
"type": "object",
|
||
"properties": {
|
||
"categories": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "所有分类"
|
||
},
|
||
"series_names": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "所有系列"
|
||
},
|
||
"brands": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/BrandInfo"
|
||
},
|
||
"description": "所有品牌(含logo、款式数、类型数)"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"RecommendResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"source": {
|
||
"": "#/components/schemas/ProductDetail",
|
||
"description": "源产品信息"
|
||
},
|
||
"products": {
|
||
"type": "array",
|
||
"items": {
|
||
"": "#/components/schemas/ProductItem"
|
||
},
|
||
"description": "推荐产品列表"
|
||
},
|
||
"scores": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "匹配度(如 90%)"
|
||
},
|
||
"total": {
|
||
"type": "integer",
|
||
"description": "推荐总数"
|
||
}
|
||
}
|
||
},
|
||
"ProductDetail": {
|
||
"type": "object",
|
||
"properties": {
|
||
"brand": {
|
||
"type": "string"
|
||
},
|
||
"group_name": {
|
||
"type": "string"
|
||
},
|
||
"sku": {
|
||
"type": "string"
|
||
},
|
||
"series_name": {
|
||
"type": "string"
|
||
},
|
||
"style_name": {
|
||
"type": "string"
|
||
},
|
||
"category": {
|
||
"type": "string"
|
||
},
|
||
"material": {
|
||
"type": "string"
|
||
},
|
||
"color_tone": {
|
||
"type": "string"
|
||
},
|
||
"finish": {
|
||
"type": "string"
|
||
},
|
||
"price_per_sqft": {
|
||
"type": "number"
|
||
},
|
||
"price_tier": {
|
||
"type": "string"
|
||
},
|
||
"price_source": {
|
||
"type": "string"
|
||
},
|
||
"main_image_url": {
|
||
"type": "string"
|
||
},
|
||
"room_image_url": {
|
||
"type": "string"
|
||
},
|
||
"source_url": {
|
||
"type": "string"
|
||
},
|
||
"description": {
|
||
"type": "string"
|
||
},
|
||
"status": {
|
||
"type": "string"
|
||
},
|
||
"coverage_sqft_per_box": {
|
||
"type": "number",
|
||
"description": "Coverage per box (sqft)"
|
||
},
|
||
"wood_species": {
|
||
"type": "string",
|
||
"description": "Wood species"
|
||
},
|
||
"size_label": {
|
||
"type": "string",
|
||
"description": "Size label (e.g. 6 x 48 in)"
|
||
},
|
||
"width_in": {
|
||
"type": "number",
|
||
"description": "Width (inches)"
|
||
},
|
||
"length_in": {
|
||
"type": "number",
|
||
"description": "Length (inches)"
|
||
},
|
||
"variants": {
|
||
"type": "array",
|
||
"description": "同款不同尺寸的完整产品数据。仅当同品牌同花色的其他SKU存在时返回(旧格式,建议使用 specs)",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ProductVariant"
|
||
}
|
||
},
|
||
"specs": {
|
||
"type": "array",
|
||
"description": "规格列表:该花色的所有尺寸+价格。包含主产品自身(至少1条)。多规格时前端可展示尺寸选择器",
|
||
"items": {
|
||
"$ref": "#/components/schemas/ProductSpec"
|
||
}
|
||
},
|
||
"is_favorited": {
|
||
"type": "boolean",
|
||
"description": "当前用户是否已收藏。未登录时始终为 false"
|
||
}
|
||
}
|
||
},
|
||
"ProductSpec": {
|
||
"type": "object",
|
||
"description": "单个规格(尺寸+价格)",
|
||
"properties": {
|
||
"sku": {
|
||
"type": "string",
|
||
"description": "该规格对应的SKU"
|
||
},
|
||
"size_label": {
|
||
"type": "string",
|
||
"description": "尺寸标签,如 6 x 48 in"
|
||
},
|
||
"width_in": {
|
||
"type": "number",
|
||
"description": "宽度(英寸)"
|
||
},
|
||
"length_in": {
|
||
"type": "number",
|
||
"description": "长度(英寸)"
|
||
},
|
||
"price_per_sqft": {
|
||
"type": "number",
|
||
"description": "每平方英尺价格(美元)"
|
||
},
|
||
"price_tier": {
|
||
"type": "string",
|
||
"description": "价格段位"
|
||
},
|
||
"coverage_sqft_per_box": {
|
||
"type": "number",
|
||
"description": "每箱覆盖面积(平方英尺)"
|
||
},
|
||
"main_image_url": {
|
||
"type": "string",
|
||
"description": "该规格产品图片URL"
|
||
}
|
||
}
|
||
},
|
||
"ProductVariant": {
|
||
"type": "object",
|
||
"description": "Product variant (same style, different size/price)",
|
||
"properties": {
|
||
"sku": {
|
||
"type": "string"
|
||
},
|
||
"size_label": {
|
||
"type": "string"
|
||
},
|
||
"width_in": {
|
||
"type": "number"
|
||
},
|
||
"length_in": {
|
||
"type": "number"
|
||
},
|
||
"price_per_sqft": {
|
||
"type": "number"
|
||
},
|
||
"price_tier": {
|
||
"type": "string"
|
||
},
|
||
"series_name": {
|
||
"type": "string"
|
||
},
|
||
"main_image_url": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
},
|
||
"FilterHierarchy": {
|
||
"type": "object",
|
||
"properties": {
|
||
"filters": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FilterGroup"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"FilterGroup": {
|
||
"type": "object",
|
||
"properties": {
|
||
"key": {
|
||
"type": "string",
|
||
"description": "Filter parameter name (used with /products)"
|
||
},
|
||
"label": {
|
||
"type": "string",
|
||
"description": "Display label"
|
||
},
|
||
"options": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "Available values (flat structure)"
|
||
},
|
||
"groups": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FilterGroup"
|
||
},
|
||
"description": "Sub-groups (hierarchical, e.g. Material > Wood/Porcelain/Vinyl)"
|
||
}
|
||
}
|
||
},
|
||
"BrandInfo": {
|
||
"type": "object",
|
||
"description": "品牌信息(含统计和logo)",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "品牌名称"
|
||
},
|
||
"logo_url": {
|
||
"type": "string",
|
||
"description": "品牌 logo 图片 URL(存在 static/brand_logos/ 下),可能为空"
|
||
},
|
||
"style_count": {
|
||
"type": "integer",
|
||
"description": "该品牌下的款式数量(distinct style_name)"
|
||
},
|
||
"collection_count": {
|
||
"type": "integer",
|
||
"description": "该品牌下的产品合集数量(distinct category)"
|
||
}
|
||
},
|
||
"example": {
|
||
"name": "Shaw Floors",
|
||
"logo_url": "/static/brand_logos/shaw_floors.webp",
|
||
"style_count": 1797,
|
||
"collection_count": 4
|
||
}
|
||
},
|
||
"Article": {
|
||
"type": "object",
|
||
"properties": {
|
||
"id": {
|
||
"type": "integer"
|
||
},
|
||
"title": {
|
||
"type": "string"
|
||
},
|
||
"summary": {
|
||
"type": "string"
|
||
},
|
||
"content": {
|
||
"type": "string",
|
||
"description": "Full article text"
|
||
},
|
||
"cover_url": {
|
||
"type": "string",
|
||
"description": "Cover image URL"
|
||
},
|
||
"image_urls": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "Article images"
|
||
},
|
||
"created_at": {
|
||
"type": "string",
|
||
"format": "date-time"
|
||
}
|
||
}
|
||
},
|
||
"ArticleListResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"articles": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Article"
|
||
}
|
||
},
|
||
"total": {
|
||
"type": "integer"
|
||
},
|
||
"page": {
|
||
"type": "integer"
|
||
},
|
||
"limit": {
|
||
"type": "integer"
|
||
},
|
||
"total_pages": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
},
|
||
"ArticleRecommendResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"articles": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Article"
|
||
}
|
||
},
|
||
"total": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
},
|
||
"FloorStyleOption": {
|
||
"type": "object",
|
||
"description": "Floor style loaded from product database",
|
||
"properties": {
|
||
"id": {
|
||
"type": "string",
|
||
"description": "Product SKU(用于 floor_id 参数)"
|
||
},
|
||
"sku": {
|
||
"type": "string",
|
||
"description": "Product SKU(同 id,兼容旧版)"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "Style name"
|
||
},
|
||
"material": {
|
||
"type": "string",
|
||
"description": "Material (used in AI prompt)"
|
||
},
|
||
"color_tone": {
|
||
"type": "string",
|
||
"description": "Color tone (used in AI prompt)"
|
||
},
|
||
"finish": {
|
||
"type": "string",
|
||
"description": "Finish (used in AI prompt)"
|
||
},
|
||
"size_label": {
|
||
"type": "string",
|
||
"description": "Size label, e.g. 6 x 48 in"
|
||
},
|
||
"image_url": {
|
||
"type": "string",
|
||
"description": "Preview image URL"
|
||
},
|
||
"category": {
|
||
"type": "string",
|
||
"description": "Product category"
|
||
}
|
||
}
|
||
},
|
||
"FloorOptionsResponse": {
|
||
"type": "object",
|
||
"properties": {
|
||
"wood_floors": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FloorStyleOption"
|
||
},
|
||
"description": "Hardwood + Engineered Wood products"
|
||
},
|
||
"tile_floors": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FloorStyleOption"
|
||
},
|
||
"description": "Wood-Look Tile + Laminate products"
|
||
},
|
||
"vinyl_floors": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FloorStyleOption"
|
||
},
|
||
"description": "SPC/LVP products"
|
||
},
|
||
"wood_patterns": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/PatternOption"
|
||
}
|
||
},
|
||
"tile_patterns": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/PatternOption"
|
||
}
|
||
},
|
||
"rooms": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/RoomOption"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"PatternOption": {
|
||
"type": "object",
|
||
"description": "铺设方式选项。code 1-4 为木地板,5-9 为瓷砖",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"description": "铺设方式编码(1-9),见文档顶部数字编码对照表"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "铺设方式名称"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"description": "AI提示词用的铺设描述"
|
||
},
|
||
"category": {
|
||
"type": "string",
|
||
"description": "所属类型:wood 或 tile"
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 3,
|
||
"name": "Herringbone",
|
||
"pattern": "herringbone/zigzag pattern with rectangular planks arranged in a broken V shape",
|
||
"category": "wood"
|
||
}
|
||
},
|
||
"RoomOption": {
|
||
"type": "object",
|
||
"description": "房间类型选项。code 0 为自动检测",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"description": "房间编码(0-7),见文档顶部数字编码对照表"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "房间名称"
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 1,
|
||
"name": "Living Room"
|
||
}
|
||
},
|
||
"CalcInput": {
|
||
"type": "object",
|
||
"required": [
|
||
"floor_type",
|
||
"rooms",
|
||
"piece_length",
|
||
"piece_width"
|
||
],
|
||
"properties": {
|
||
"floor_type": {
|
||
"type": "string",
|
||
"enum": [
|
||
"wood",
|
||
"tile"
|
||
],
|
||
"description": "地板类型"
|
||
},
|
||
"rooms": {
|
||
"type": "array",
|
||
"description": "房间列表,至少一个",
|
||
"items": {
|
||
"type": "object",
|
||
"required": [
|
||
"length",
|
||
"width"
|
||
],
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "房间名称,如 Living Room"
|
||
},
|
||
"length": {
|
||
"type": "number",
|
||
"description": "长(米),如 5"
|
||
},
|
||
"width": {
|
||
"type": "number",
|
||
"description": "宽(米),如 4"
|
||
},
|
||
"deductions": {
|
||
"type": "array",
|
||
"description": "扣减区域,如柜子、壁炉等不铺地板的区域",
|
||
"items": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "区域名称,如 Fireplace / Kitchen Island"
|
||
},
|
||
"shape": {
|
||
"type": "string",
|
||
"enum": [
|
||
"rectangle",
|
||
"circle",
|
||
"custom"
|
||
],
|
||
"description": "形状类型:rectangle=矩形(填length+width) / circle=圆形(填radius直径) / custom=自定义(填area)"
|
||
},
|
||
"length": {
|
||
"type": "number",
|
||
"description": "长(米),仅 rectangle 矩形时填写"
|
||
},
|
||
"width": {
|
||
"type": "number",
|
||
"description": "宽(米),仅 rectangle 矩形时填写"
|
||
},
|
||
"radius": {
|
||
"type": "number",
|
||
"description": "半径(米),仅 circle 圆形时填写,直径=radius*2"
|
||
},
|
||
"area": {
|
||
"type": "number",
|
||
"description": "面积(平方米),仅 custom 自定义时填写"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"pattern_index": {
|
||
"type": "integer",
|
||
"default": 0,
|
||
"description": "铺设方式索引(0-5)"
|
||
},
|
||
"piece_length": {
|
||
"type": "number",
|
||
"description": "单片长度(米),必填,如 1.2"
|
||
},
|
||
"piece_width": {
|
||
"type": "number",
|
||
"description": "单片宽度(米),必填,如 0.19"
|
||
},
|
||
"pieces_per_box": {
|
||
"type": "integer",
|
||
"description": "每箱片数,选填,如 8"
|
||
},
|
||
"price_per_sqm": {
|
||
"type": "number",
|
||
"description": "每平方米单价,选填,如 45"
|
||
},
|
||
"joint_width": {
|
||
"type": "number",
|
||
"description": "缝宽(米),瓷砖用,如 0.002"
|
||
}
|
||
},
|
||
"example": {
|
||
"floor_type": "wood",
|
||
"rooms": [
|
||
{
|
||
"name": "Living Room",
|
||
"length": 5,
|
||
"width": 4,
|
||
"deductions": [
|
||
{
|
||
"name": "Fireplace",
|
||
"shape": "rectangle",
|
||
"length": 1.5,
|
||
"width": 0.8
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"name": "Hallway",
|
||
"length": 3,
|
||
"width": 1.2,
|
||
"deductions": []
|
||
}
|
||
],
|
||
"pattern_index": 0,
|
||
"piece_length": 1.2,
|
||
"piece_width": 0.19,
|
||
"pieces_per_box": 8,
|
||
"price_per_sqm": 45
|
||
}
|
||
},
|
||
"CalcRoomInput": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "房间名称"
|
||
},
|
||
"length": {
|
||
"type": "number",
|
||
"description": "长(米)"
|
||
},
|
||
"width": {
|
||
"type": "number",
|
||
"description": "宽(米)"
|
||
},
|
||
"deductions": {
|
||
"type": "array",
|
||
"items": {
|
||
"": "#/components/schemas/CalcDeduction"
|
||
},
|
||
"description": "扣减区域(柜子/壁炉等不铺地板的区域)"
|
||
}
|
||
}
|
||
},
|
||
"CalcDeduction": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string"
|
||
},
|
||
"shape": {
|
||
"type": "string",
|
||
"enum": [
|
||
"rectangle",
|
||
"circle",
|
||
"custom"
|
||
],
|
||
"description": "形状"
|
||
},
|
||
"length": {
|
||
"type": "number",
|
||
"description": "长(rectangle时用)"
|
||
},
|
||
"width": {
|
||
"type": "number",
|
||
"description": "宽(rectangle时用)"
|
||
},
|
||
"radius": {
|
||
"type": "number",
|
||
"description": "半径(circle时用)"
|
||
},
|
||
"area": {
|
||
"type": "number",
|
||
"description": "自定义面积(custom时用)"
|
||
}
|
||
}
|
||
},
|
||
"CalcResult": {
|
||
"type": "object",
|
||
"properties": {
|
||
"floor_type": {
|
||
"type": "string"
|
||
},
|
||
"rooms": {
|
||
"type": "array",
|
||
"items": {
|
||
"": "#/components/schemas/CalcRoomResult"
|
||
}
|
||
},
|
||
"total_room_area": {
|
||
"type": "number",
|
||
"description": "房间总面积"
|
||
},
|
||
"total_deduct": {
|
||
"type": "number",
|
||
"description": "总扣减面积"
|
||
},
|
||
"total_net_area": {
|
||
"type": "number",
|
||
"description": "总净面积(需铺地板)"
|
||
},
|
||
"waste_rate": {
|
||
"type": "number",
|
||
"description": "损耗率(%)"
|
||
},
|
||
"waste_area": {
|
||
"type": "number",
|
||
"description": "损耗面积"
|
||
},
|
||
"total_area": {
|
||
"type": "number",
|
||
"description": "含损耗总面积"
|
||
},
|
||
"pieces_needed": {
|
||
"type": "integer",
|
||
"description": "需要片数"
|
||
},
|
||
"boxes_needed": {
|
||
"type": "number",
|
||
"description": "需要箱数(仅传入pieces_per_box时返回)"
|
||
},
|
||
"joint_width": {
|
||
"type": "number"
|
||
},
|
||
"grout_kg": {
|
||
"type": "number",
|
||
"description": "填缝剂重量kg(仅瓷砖模式返回)"
|
||
},
|
||
"grout_bags": {
|
||
"type": "integer",
|
||
"description": "填缝剂袋数(仅瓷砖模式返回)"
|
||
},
|
||
"price_per_sqm": {
|
||
"type": "number"
|
||
},
|
||
"total_price": {
|
||
"type": "number",
|
||
"description": "总价(仅传入price_per_sqm时返回)"
|
||
},
|
||
"pattern_name": {
|
||
"type": "string"
|
||
},
|
||
"piece_length": {
|
||
"type": "number"
|
||
},
|
||
"piece_width": {
|
||
"type": "number"
|
||
}
|
||
}
|
||
},
|
||
"CalcRoomResult": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string"
|
||
},
|
||
"length": {
|
||
"type": "number"
|
||
},
|
||
"width": {
|
||
"type": "number"
|
||
},
|
||
"area": {
|
||
"type": "number"
|
||
},
|
||
"deductions": {
|
||
"type": "array",
|
||
"items": {
|
||
"": "#/components/schemas/CalcDeduction"
|
||
}
|
||
},
|
||
"deduction_total": {
|
||
"type": "number"
|
||
},
|
||
"net_area": {
|
||
"type": "number"
|
||
}
|
||
}
|
||
},
|
||
"FrequentBrand": {
|
||
"type": "object",
|
||
"description": "用户常用品牌",
|
||
"properties": {
|
||
"brand": {
|
||
"type": "string",
|
||
"description": "品牌名称"
|
||
},
|
||
"view_count": {
|
||
"type": "integer",
|
||
"description": "浏览次数"
|
||
},
|
||
"fav_count": {
|
||
"type": "integer",
|
||
"description": "收藏次数"
|
||
},
|
||
"logo_url": {
|
||
"type": "string",
|
||
"description": "品牌logo URL"
|
||
},
|
||
"style_count": {
|
||
"type": "integer",
|
||
"description": "该品牌款式总数"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"paths": {
|
||
"/auth/register": {
|
||
"post": {
|
||
"tags": [
|
||
"认证"
|
||
],
|
||
"summary": "用户注册",
|
||
"description": "使用用户名和密码注册新账号,返回 JWT token 和用户信息",
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"required": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"properties": {
|
||
"username": {
|
||
"type": "string",
|
||
"description": "用户名"
|
||
},
|
||
"password": {
|
||
"type": "string",
|
||
"description": "密码"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"description": "显示名称(选填)"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"201": {
|
||
"description": "注册成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/AuthResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "参数错误(用户名或密码为空/用户名已存在)"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/auth/login": {
|
||
"post": {
|
||
"tags": [
|
||
"认证"
|
||
],
|
||
"summary": "用户登录",
|
||
"description": "用户名+密码登录,返回 JWT token 和用户信息",
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"required": [
|
||
"username",
|
||
"password"
|
||
],
|
||
"properties": {
|
||
"username": {
|
||
"type": "string",
|
||
"description": "用户名"
|
||
},
|
||
"password": {
|
||
"type": "string",
|
||
"description": "密码"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "登录成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/AuthResponse"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "用户名或密码错误"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/me": {
|
||
"get": {
|
||
"tags": [
|
||
"用户"
|
||
],
|
||
"summary": "获取个人信息",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "用户信息",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"401": {
|
||
"description": "未登录或token过期"
|
||
}
|
||
}
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"用户"
|
||
],
|
||
"summary": "更新个人信息",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "显示名称"
|
||
},
|
||
"avatar_url": {
|
||
"type": "string",
|
||
"description": "头像URL"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "更新成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/User"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/favorites": {
|
||
"get": {
|
||
"tags": [
|
||
"收藏"
|
||
],
|
||
"summary": "获取收藏列表",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "收藏列表",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"favorites": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Favorite"
|
||
}
|
||
},
|
||
"total": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"收藏"
|
||
],
|
||
"summary": "添加收藏",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"responses": {
|
||
"201": {
|
||
"description": "收藏成功"
|
||
}
|
||
},
|
||
"description": "传入产品SKU,后端自动查库补全产品信息",
|
||
"parameters": [
|
||
{
|
||
"name": "sku",
|
||
"in": "query",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "产品SKU编码"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/user/favorites/{sku}": {
|
||
"delete": {
|
||
"tags": [
|
||
"收藏"
|
||
],
|
||
"summary": "取消收藏",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"parameters": [
|
||
{
|
||
"name": "sku",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "产品SKU编码"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "取消成功"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/projects": {
|
||
"get": {
|
||
"tags": [
|
||
"项目"
|
||
],
|
||
"summary": "获取项目列表",
|
||
"description": "获取当前用户的所有AI换地板项目记录",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "项目列表",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"projects": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/Project"
|
||
}
|
||
},
|
||
"total": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"post": {
|
||
"tags": [
|
||
"项目"
|
||
],
|
||
"summary": "创建项目",
|
||
"description": "保存一次AI换地板记录",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "项目名称,默认 Untitled",
|
||
"default": "Untitled"
|
||
},
|
||
"original_image_url": {
|
||
"type": "string",
|
||
"description": "换地板前原图URL"
|
||
},
|
||
"generated_image_url": {
|
||
"type": "string",
|
||
"description": "AI生成效果图URL"
|
||
},
|
||
"floor_style": {
|
||
"type": "string",
|
||
"description": "使用的款式"
|
||
},
|
||
"pattern": {
|
||
"type": "string",
|
||
"description": "铺设方式"
|
||
},
|
||
"room_type": {
|
||
"type": "string",
|
||
"description": "房间类型"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"201": {
|
||
"description": "创建成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Project"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/projects/{id}": {
|
||
"get": {
|
||
"tags": [
|
||
"项目"
|
||
],
|
||
"summary": "获取单个项目",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "项目UUID"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "项目详情",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Project"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "项目不存在"
|
||
}
|
||
}
|
||
},
|
||
"put": {
|
||
"tags": [
|
||
"项目"
|
||
],
|
||
"summary": "重命名项目",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "项目UUID"
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"required": [
|
||
"name"
|
||
],
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"description": "新名称"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "更新成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Project"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"delete": {
|
||
"tags": [
|
||
"项目"
|
||
],
|
||
"summary": "删除项目",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "项目UUID"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "删除成功"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/products": {
|
||
"get": {
|
||
"tags": [
|
||
"产品"
|
||
],
|
||
"summary": "产品列表(多维度筛选+搜索+分页)",
|
||
"parameters": [
|
||
{
|
||
"name": "category",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "类目:Hardwood / Engineered Wood / Laminate / SPC/LVP / Wood-Look Tile"
|
||
},
|
||
{
|
||
"name": "material",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "材质:Oak / Porcelain / Luxury Vinyl / Maple / Hickory 等"
|
||
},
|
||
{
|
||
"name": "color_tone",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "色调:Light Gray / Natural Oak / Dark Brown / Taupe 等"
|
||
},
|
||
{
|
||
"name": "finish",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "表面处理:Matte / Gloss / Textured / Wire-Brushed 等"
|
||
},
|
||
{
|
||
"name": "wood_species",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "木种:Oak / Maple / Hickory / Walnut / Birch 等"
|
||
},
|
||
{
|
||
"name": "brand",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "品牌筛选"
|
||
},
|
||
{
|
||
"name": "series_name",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "系列名称筛选"
|
||
},
|
||
{
|
||
"name": "search",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "模糊搜索(匹配款式名称/编号/品牌)"
|
||
},
|
||
{
|
||
"name": "page",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "integer",
|
||
"default": 1
|
||
},
|
||
"description": "页码"
|
||
},
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "integer",
|
||
"default": 20
|
||
},
|
||
"description": "每页数量"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "产品列表",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProductListResponse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"description": "所有筛选参数可任意组合。\n\n前端层层递进实现方式:用户每选择一个筛选项,将已选参数传给本接口,根据返回结果中的 filter_options 动态收窄其他筛选项的可选范围。"
|
||
}
|
||
},
|
||
"/product-options": {
|
||
"get": {
|
||
"tags": [
|
||
"产品"
|
||
],
|
||
"summary": "筛选选项(扁平结构)",
|
||
"description": "返回分类/系列/品牌列表。品牌包含名称、logo、款式数、类型数。",
|
||
"responses": {
|
||
"200": {
|
||
"description": "筛选项",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 200
|
||
},
|
||
"data": {
|
||
"type": "object",
|
||
"properties": {
|
||
"categories": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "分类列表"
|
||
},
|
||
"series_names": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "系列名称列表"
|
||
},
|
||
"brands": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/BrandInfo"
|
||
},
|
||
"description": "品牌列表(含统计和logo)"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 200,
|
||
"data": {
|
||
"categories": [
|
||
"Hardwood",
|
||
"Laminate",
|
||
"SPC/LVP",
|
||
"Engineered Wood",
|
||
"Wood-Look Tile"
|
||
],
|
||
"series_names": [
|
||
"American Retreat",
|
||
"Nature's Splendor",
|
||
"Timeless Design"
|
||
],
|
||
"brands": [
|
||
{
|
||
"name": "Shaw Floors",
|
||
"logo_url": "/static/brand_logos/shaw_floors.webp",
|
||
"style_count": 1797,
|
||
"collection_count": 4
|
||
},
|
||
{
|
||
"name": "Bruce",
|
||
"logo_url": "/static/brand_logos/bruce.jpg",
|
||
"style_count": 224,
|
||
"collection_count": 4
|
||
},
|
||
{
|
||
"name": "Karndean",
|
||
"logo_url": "/static/brand_logos/karndean.jpg",
|
||
"style_count": 251,
|
||
"collection_count": 1
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/recommend": {
|
||
"post": {
|
||
"tags": [
|
||
"推荐"
|
||
],
|
||
"summary": "智能推荐",
|
||
"description": "输入产品SKU,返回跨品牌相似地板推荐",
|
||
"responses": {
|
||
"200": {
|
||
"description": "推荐结果",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/RecommendResponse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"parameters": [
|
||
{
|
||
"name": "sku",
|
||
"in": "query",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "产品SKU编码",
|
||
"example": "CB218LG"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"/calculator/calc": {
|
||
"post": {
|
||
"tags": [
|
||
"计算器"
|
||
],
|
||
"summary": "地板面积计算",
|
||
"description": "支持多房间、扣减区域、单片尺寸、铺设方式损耗、每箱片数、缝宽、单价。报告由前端根据返回结果自行生成。",
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/CalcInput"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "计算结果",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"": "#/components/schemas/CalcResult"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "参数错误"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/floor/options": {
|
||
"get": {
|
||
"tags": [
|
||
"地板更换"
|
||
],
|
||
"summary": "获取地板样式选项(从产品库动态加载)",
|
||
"description": "从产品数据库(3600+产品)动态加载地板样式选项。\n\n每个样式对应一个真实产品SKU,/floor/generate 的 floor_id 参数必须传真实SKU。\n\n分类说明:\n- wood_floors:实木+实木复合产品\n- tile_floors:瓷砖仿木纹+强化复合产品\n- vinyl_floors:SPC/LVP产品\n- wood_patterns / tile_patterns:铺设方式\n- rooms:房间类型",
|
||
"responses": {
|
||
"200": {
|
||
"description": "成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 200
|
||
},
|
||
"data": {
|
||
"$ref": "#/components/schemas/FloorOptionsResponse"
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 200,
|
||
"data": {
|
||
"wood_floors": [],
|
||
"tile_floors": [],
|
||
"vinyl_floors": [],
|
||
"wood_patterns": [
|
||
{
|
||
"code": 1,
|
||
"name": "Straight Lay",
|
||
"pattern": "straight/parallel planks...",
|
||
"category": "wood"
|
||
},
|
||
{
|
||
"code": 2,
|
||
"name": "Horizontal Lay",
|
||
"pattern": "horizontal planks...",
|
||
"category": "wood"
|
||
},
|
||
{
|
||
"code": 3,
|
||
"name": "Herringbone",
|
||
"pattern": "herringbone/zigzag pattern...",
|
||
"category": "wood"
|
||
},
|
||
{
|
||
"code": 4,
|
||
"name": "Chevron",
|
||
"pattern": "chevron pattern...",
|
||
"category": "wood"
|
||
}
|
||
],
|
||
"tile_patterns": [
|
||
{
|
||
"code": 5,
|
||
"name": "Straight Grid",
|
||
"pattern": "straight grid layout...",
|
||
"category": "tile"
|
||
},
|
||
{
|
||
"code": 6,
|
||
"name": "Running Bond",
|
||
"pattern": "running bond/brick pattern...",
|
||
"category": "tile"
|
||
}
|
||
],
|
||
"rooms": [
|
||
{
|
||
"code": 0,
|
||
"name": "Auto Detect"
|
||
},
|
||
{
|
||
"code": 1,
|
||
"name": "Living Room"
|
||
},
|
||
{
|
||
"code": 2,
|
||
"name": "Bedroom"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/floor/generate": {
|
||
"post": {
|
||
"tags": [
|
||
"地板更换"
|
||
],
|
||
"summary": "AI换地板(使用真实产品数据)",
|
||
"description": "上传房间照片 + 地板选项,加入 Redis 异步队列,返回 job_id。3 个 worker 并发处理。用 GET /floor/status?job_id=xxx 查询进度",
|
||
"requestBody": {
|
||
"content": {
|
||
"multipart/form-data": {
|
||
"schema": {
|
||
"type": "object",
|
||
"required": [
|
||
"image",
|
||
"floor_id",
|
||
"pattern_code"
|
||
],
|
||
"properties": {
|
||
"image": {
|
||
"type": "string",
|
||
"format": "binary",
|
||
"description": "房间照片"
|
||
},
|
||
"floor_id": {
|
||
"type": "string",
|
||
"description": "产品SKU,从 /floor/options 获取(如 \"CB218LG\"),必须是真实产品SKU"
|
||
},
|
||
"pattern_code": {
|
||
"type": "integer",
|
||
"description": "铺设方式编码(1-9),见文档顶部数字编码对照表",
|
||
"example": 3
|
||
},
|
||
"room_code": {
|
||
"type": "integer",
|
||
"description": "房间类型编码(0-7),见文档顶部数字编码对照表。0 或省略表示自动检测",
|
||
"example": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "成功返回 job_id",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 200
|
||
},
|
||
"data": {
|
||
"type": "object",
|
||
"properties": {
|
||
"job_id": {
|
||
"type": "string",
|
||
"description": "用于查询进度的 job_id"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 200,
|
||
"data": {
|
||
"job_id": "1750123456789000000"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"400": {
|
||
"description": "参数错误",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 400
|
||
},
|
||
"error": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
},
|
||
"example": {
|
||
"code": 400,
|
||
"error": "Invalid options"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/products/{sku}": {
|
||
"get": {
|
||
"tags": [
|
||
"Products"
|
||
],
|
||
"summary": "产品详情(含同花色多尺寸变体)",
|
||
"description": "返回产品完整信息。如果该产品有同品牌+同花色(style_name)的其他SKU(不同尺寸/价格),会自动聚合到 variants 数组中,形成父子关系展示。\n\n例如:查询 Matte White 3×6 in,variants 返回 4×16 / 12×24 / 24×24 等其他尺寸。",
|
||
"parameters": [
|
||
{
|
||
"name": "sku",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "Product SKU code"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Product with variants",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ProductDetail"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Product not found"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/filter-options": {
|
||
"get": {
|
||
"tags": [
|
||
"Products"
|
||
],
|
||
"summary": "分级筛选选项(层级结构)",
|
||
"description": "返回所有可用的筛选值,支持层级结构(Material 下分 Wood / Porcelain / Vinyl / Other 子组)。\n\n前端层层递进实现方式:\n1. 页面加载时调用本接口获取全部选项\n2. 用户选择某个筛选项后,将已选参数传给 /products 接口\n3. 根据 /products 返回的 filter_options 动态收窄其他筛选项的可选范围",
|
||
"responses": {
|
||
"200": {
|
||
"description": "Filter hierarchy",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/FilterHierarchy"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/articles": {
|
||
"get": {
|
||
"tags": [
|
||
"Knowledge"
|
||
],
|
||
"summary": "科普文章列表(分页)",
|
||
"parameters": [
|
||
{
|
||
"name": "page",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "integer",
|
||
"default": 1
|
||
}
|
||
},
|
||
{
|
||
"name": "limit",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "integer",
|
||
"default": 10
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Article list",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ArticleListResponse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/articles/{id}": {
|
||
"get": {
|
||
"tags": [
|
||
"Knowledge"
|
||
],
|
||
"summary": "文章详情",
|
||
"parameters": [
|
||
{
|
||
"name": "id",
|
||
"in": "path",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Article detail",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/Article"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"404": {
|
||
"description": "Article not found"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/articles/recommend": {
|
||
"get": {
|
||
"tags": [
|
||
"Knowledge"
|
||
],
|
||
"summary": "随机推荐文章(默认6篇)",
|
||
"description": "每次随机返回指定数量的文章,默认6篇,最多20篇",
|
||
"parameters": [
|
||
{
|
||
"name": "count",
|
||
"in": "query",
|
||
"schema": {
|
||
"type": "integer",
|
||
"default": 6
|
||
},
|
||
"description": "Count (1-20)"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "Recommended articles",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"$ref": "#/components/schemas/ArticleRecommendResponse"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/avatar": {
|
||
"post": {
|
||
"tags": [
|
||
"用户"
|
||
],
|
||
"summary": "上传头像",
|
||
"description": "上传用户头像图片,自动替换旧头像。最大5MB。头像存储在 uploads/avatars/ 目录。",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"multipart/form-data": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"image": {
|
||
"type": "string",
|
||
"format": "binary",
|
||
"description": "头像图片文件"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "上传成功,返回用户信息(含avatar_url)"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/floor/status": {
|
||
"get": {
|
||
"tags": [
|
||
"地板更换"
|
||
],
|
||
"summary": "查询生成进度(HTTP 轮询)",
|
||
"description": "Redis 异步队列任务状态查询。status: pending | processing | done | error",
|
||
"parameters": [
|
||
{
|
||
"name": "job_id",
|
||
"in": "query",
|
||
"required": true,
|
||
"schema": {
|
||
"type": "string"
|
||
},
|
||
"description": "floor-generate 返回的 job_id"
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "SSE 事件流"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/upload": {
|
||
"post": {
|
||
"tags": [
|
||
"Upload"
|
||
],
|
||
"summary": "通用图片上传",
|
||
"description": "上传图片文件,返回访问URL。最大20MB,自动检测图片类型。存于 static/images/ 目录",
|
||
"requestBody": {
|
||
"required": true,
|
||
"content": {
|
||
"multipart/form-data": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"image": {
|
||
"type": "string",
|
||
"format": "binary",
|
||
"description": "图片文件"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "上传成功",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 200
|
||
},
|
||
"data": {
|
||
"type": "object",
|
||
"properties": {
|
||
"url": {
|
||
"type": "string",
|
||
"example": "/static/images/abc123.jpg"
|
||
},
|
||
"filename": {
|
||
"type": "string",
|
||
"example": "abc123.jpg"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"/user/frequent-brands": {
|
||
"get": {
|
||
"tags": [
|
||
"Brand Tracking"
|
||
],
|
||
"summary": "获取常用品牌",
|
||
"description": "返回浏览≥3次或收藏≥2次的品牌。需登录。按权重排序",
|
||
"security": [
|
||
{
|
||
"BearerAuth": []
|
||
}
|
||
],
|
||
"responses": {
|
||
"200": {
|
||
"description": "常用品牌列表",
|
||
"content": {
|
||
"application/json": {
|
||
"schema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"code": {
|
||
"type": "integer",
|
||
"example": 200
|
||
},
|
||
"data": {
|
||
"type": "object",
|
||
"properties": {
|
||
"brands": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/components/schemas/FrequentBrand"
|
||
}
|
||
},
|
||
"total": {
|
||
"type": "integer"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |