FloorVisualizer/apifox-import.json

2455 lines
73 KiB
JSON
Raw Normal View History

{
"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_code1-9+ room_code0-7→ 返回 job_id\n3. GET /floor/progress?job_id=xxxSSE跟踪进度 → 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 表示有多种尺寸可选"
},
"is_official_price": {
"type": "boolean",
"description": "是否为官方定价。true=品牌官网标价false=市场估价或未找到"
}
}
},
"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"
},
"is_official_price": {
"type": "boolean",
"description": "是否为官方定价。true=品牌官网标价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. Each entry = one unique style (dedup by brand+style_name). Variants list different sizes.",
"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 (材质,如 Oak/Porcelain/Luxury Vinyl)"
},
"color_tone": {
"type": "string",
"description": "Color tone (色调,如 Light Gray/Natural Oak/Dark Brown)"
},
"finish": {
"type": "string",
"description": "Finish (表面处理,如 Matte/Gloss/Textured)"
},
"size_label": {
"type": "string",
"description": "Size label, e.g. 6 x 48 in. 多尺寸时为首个尺寸"
},
"width_in": {
"type": "number",
"description": "Width in inches. Used in AI prompt for physical scale"
},
"length_in": {
"type": "number",
"description": "Length in inches. Used in AI prompt for physical scale"
},
"image_url": {
"type": "string",
"description": "Preview image URL"
},
"category": {
"type": "string",
"description": "Product category (Solid Hardwood / Engineered Hardwood / Tile/Stone / SPC-LVP / Laminate)"
},
"description": {
"type": "string",
"description": "Product description. Used in AI prompt for richer visual detail"
},
"variants": {
"type": "array",
"description": "Size variants of the same style (same brand+style_name, different SKU/size). Empty array if only one size.",
"items": {
"type": "object",
"properties": {
"sku": { "type": "string", "description": "Variant SKU" },
"size_label": { "type": "string", "description": "Variant size label" },
"width_in": { "type": "number" },
"length_in": { "type": "number" }
}
}
}
}
},
"FloorOptionsResponse": {
"type": "object",
"properties": {
"wood_floors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FloorStyleOption"
},
"description": "Wood products (Oak/Ash/Hickory/Maple etc.) — classified by material field"
},
"tile_floors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FloorStyleOption"
},
"description": "Tile/Stone (Porcelain/Stone Look/Glass) + Laminate products"
},
"vinyl_floors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FloorStyleOption"
},
"description": "Vinyl products (Luxury Vinyl/Rigid Core)"
},
"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": "从产品数据库动态加载地板样式选项。每个样式对应一个真实产品SKU含 width_in/length_in/description/variants 等字段。\n\n材质分类按 material 字段自动归类):\n- wood_floorsOak/Ash/Hickory/Maple 等木材\n- tile_floorsPorcelain/Stone Look/Glass + Laminate\n- vinyl_floorsLuxury Vinyl/Rigid Core\n\n前端应使用 variants 渲染尺寸选择面板。",
"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_floors": [
{
"id": "CB218LG",
"sku": "CB218LG",
"name": "Cherry",
"material": "Oak",
"color_tone": "Natural Oak",
"finish": "Matte",
"size_label": "2.25 x 84 in",
"width_in": 2.25,
"length_in": 84.0,
"image_url": "https://...",
"category": "Solid Hardwood",
"description": "Natural cherry oak with subtle grain",
"variants": [
{ "sku": "CB4218", "size_label": "4 x 84 in", "width_in": 4.0, "length_in": 84.0 },
{ "sku": "CB5218", "size_label": "5 x 84 in", "width_in": 5.0, "length_in": 84.0 }
]
}
],
"tile_floors": [],
"vinyl_floors": [],
"wood_patterns": [
{
"code": 1,
"name": "直铺工字拼Straight Lay",
"pattern": "straight/parallel planks running from front to back with staggered joints",
"category": "wood"
},
{
"code": 2,
"name": "横铺 Horizontal Lay",
"pattern": "horizontal planks running side to side across the width of the room",
"category": "wood"
},
{
"code": 3,
"name": "人字拼 Herringbone",
"pattern": "herringbone/zigzag pattern with rectangular planks arranged in a broken V shape",
"category": "wood"
},
{
"code": 4,
"name": "鱼骨拼 Chevron",
"pattern": "chevron pattern with planks cut at an angle forming a continuous V shape",
"category": "wood"
}
],
"tile_patterns": [
{
"code": 5,
"name": "直铺网格对缝Straight Grid",
"pattern": "straight grid layout with tiles perfectly aligned in rows and columns, clean orthogonal grout lines",
"category": "tile"
},
{
"code": 6,
"name": "工字铺1/2错缝Running Bond",
"pattern": "running bond/brick pattern with each row offset by 50%, staggered brickwork appearance",
"category": "tile"
},
{
"code": 7,
"name": "三七错铺 1/3 Offset",
"pattern": "tiles offset by 1/3 of their length in each row, subtle stepped pattern",
"category": "tile"
},
{
"code": 8,
"name": "六边形 Hexagonal",
"pattern": "hexagonal/honeycomb tiles fitted together in a seamless honeycomb mesh",
"category": "tile"
},
{
"code": 9,
"name": "斜铺45度对角Diagonal",
"pattern": "tiles laid at a 45-degree diagonal angle to the walls, diamond orientation",
"category": "tile"
}
],
"rooms": [
{ "code": 0, "name": "自动识别" },
{ "code": 1, "name": "客厅" },
{ "code": 2, "name": "卧室" },
{ "code": 3, "name": "厨房" },
{ "code": 4, "name": "餐厅" },
{ "code": 5, "name": "浴室" },
{ "code": 6, "name": "书房" },
{ "code": 7, "name": "走廊" }
]
}
}
}
}
}
}
}
},
"/floor/generate": {
"post": {
"tags": [
"地板更换"
],
"summary": "AI换地板使用真实产品数据含尺寸/变体)",
"description": "上传房间照片 + 地板选项,加入 Redis 异步队列,返回 job_id。用 GET /floor/status?job_id=xxx 查询进度。\n\nfloor_id 支持有尺寸变体的产品——选择变体对应 SKU 即可AI 会根据 width_in/length_in 生成对应物理尺寸的地板。",
"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
},
"grout_lines": {
"type": "boolean",
"description": "Optional. Tile floors only. true adds realistic visible grout lines between tiles.",
"example": false
},
"white_baseboard": {
"type": "boolean",
"description": "Optional. true adds or refreshes a realistic white baseboard/skirting board along visible wall-floor edges.",
"example": false
}
}
}
}
}
},
"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 invariants 返回 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。\n\n返回 timings_ms 字段包含每步耗时check/mask/inpaint/cleanup/total。elapsed_ms 为总运行时间。",
"parameters": [
{
"name": "job_id",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "floor-generate 返回的 job_id"
}
],
"responses": {
"200": {
"description": "Job status with timing",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"code": { "type": "integer", "example": 200 },
"data": {
"type": "object",
"properties": {
"job_id": { "type": "string" },
"status": { "type": "string", "description": "pending | processing | done | error" },
"step": { "type": "string", "description": "check | mask | inpaint | done | error" },
"message": { "type": "string" },
"result": { "type": "string", "description": "Generated image path, e.g. /outputs/result_xxx.png" },
"error": { "type": "string" },
"elapsed_ms": { "type": "integer", "description": "Total elapsed milliseconds since job start" },
"timings_ms": {
"type": "object",
"description": "Per-step duration in milliseconds",
"properties": {
"check": { "type": "integer" },
"mask": { "type": "integer" },
"inpaint": { "type": "integer" },
"total": { "type": "integer" }
}
}
}
}
}
},
"example": {
"code": 200,
"data": {
"job_id": "1784530075874083600",
"status": "done",
"step": "done",
"message": "Done",
"result": "/outputs/result_1784530075874083600.png",
"elapsed_ms": 100340,
"timings_ms": { "check": 5148, "mask": 25971, "inpaint": 69218, "total": 100340 }
}
}
}
}
}
}
}
},
"/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"
}
}
}
}
}
}
}
}
}
}
}
}
}