HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • AI 训练手册

    • AI UI生成系统 - 完整学习手册
    • 项目概述与架构设计
    • 环境搭建与快速开始
    • 核心概念与术语
    • 数据生成系统
    • UI-DSL数据格式详解
    • 数据质量与评估
    • LoRA微调技术
    • 完整的模型训练流程
    • 模型推理与优化
    • PNG图片渲染实现
    • Vue页面渲染系统
    • 多主题支持架构
    • FastAPI服务设计
    • Docker部署实践
    • 生产环境运维
    • 项目实战案例
    • 性能优化指南
    • 扩展开发指南
    • API参考文档
    • 配置参数说明
    • 故障排查指南

API参考文档

1. API概述

1.1 基础信息

基础URL: http://localhost:8000
API版本: v1.0.0
协议: HTTP/HTTPS
数据格式: JSON
字符编码: UTF-8

1.2 认证方式

当前版本支持以下认证方式:

  1. API Key认证(推荐)

    Authorization: Bearer your-api-key
    
  2. 无认证(开发环境)

    • 仅用于开发和测试
    • 生产环境建议启用认证

1.3 请求/响应格式

请求格式:

POST /api/v1/generate-ui
Content-Type: application/json
Authorization: Bearer your-api-key

{
  "prompt": "黑金风格的电商首页",
  "output_format": "json"
}

响应格式:

{
  "success": true,
  "message": "UI生成成功",
  "data": {
    "page": {
      "name": "home_page",
      "theme": "obsidian-gold",
      "sections": [...]
    }
  },
  "method": "model",
  "timestamp": "2024-01-15T10:30:00Z"
}

1.4 错误处理

错误响应格式:

{
  "success": false,
  "error": "错误类型",
  "message": "详细错误信息",
  "code": "ERROR_CODE",
  "timestamp": "2024-01-15T10:30:00Z"
}

HTTP状态码:

  • 200 - 成功
  • 400 - 请求参数错误
  • 401 - 未授权
  • 404 - 资源不存在
  • 429 - 请求频率限制
  • 500 - 服务器内部错误
  • 503 - 服务不可用

2. 核心端点详解

2.1 UI生成端点

POST /generate-ui

生成UI设计的主要端点。

请求参数:

参数类型必需默认值描述
promptstring是-中文描述Prompt
output_formatstring否"json"输出格式:json, png, vue
model_pathstring否null自定义模型路径
lora_pathstring否nullLoRA权重路径
use_rulesboolean否false强制使用规则生成

请求示例:

curl -X POST "http://localhost:8000/generate-ui" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "prompt": "黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航",
    "output_format": "png"
  }'

响应示例:

JSON格式响应:

{
  "success": true,
  "message": "UI-DSL生成成功",
  "data": {
    "page": {
      "name": "home_page",
      "theme": "obsidian-gold",
      "layout": {
        "grid": 12,
        "gutter": 16,
        "padding": 16,
        "bg": "#0E0E0E"
      },
      "sections": [
        {
          "type": "topbar",
          "props": {
            "logo": "品牌",
            "actions": ["search", "bell"]
          }
        },
        {
          "type": "card-list",
          "props": {
            "columns": 2,
            "card": {
              "type": "product-card"
            }
          }
        }
      ]
    }
  },
  "method": "model"
}

PNG格式响应:

{
  "success": true,
  "message": "UI图片生成成功",
  "data": {
    "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    "dsl": {
      "page": {...}
    }
  },
  "method": "model"
}

Vue格式响应:

{
  "success": true,
  "message": "Vue页面生成成功",
  "data": {
    "vue_content": "<template>\n  <view class=\"page\">\n    ...\n  </view>\n</template>",
    "dsl": {
      "page": {...}
    }
  },
  "method": "model"
}

错误响应示例:

{
  "success": false,
  "error": "ValidationError",
  "message": "Prompt不能为空",
  "code": "INVALID_PROMPT",
  "timestamp": "2024-01-15T10:30:00Z"
}

2.2 UI渲染端点

POST /render

将UI-DSL渲染为指定格式。

请求参数:

参数类型必需默认值描述
dslobject是-UI-DSL数据
output_formatstring是"png"输出格式:png, vue

请求示例:

curl -X POST "http://localhost:8000/render" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "dsl": {
      "page": {
        "name": "home_page",
        "theme": "obsidian-gold",
        "sections": [...]
      }
    },
    "output_format": "png"
  }'

响应示例:

{
  "success": true,
  "message": "图片渲染成功",
  "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}

2.3 健康检查端点

GET /health

检查服务健康状态。

请求示例:

curl -X GET "http://localhost:8000/health"

响应示例:

{
  "status": "healthy",
  "version": "1.0.0",
  "model_loaded": true,
  "timestamp": "2024-01-15T10:30:00Z",
  "uptime": 3600
}

2.4 模板列表端点

GET /templates

获取可用的页面模板列表。

请求示例:

curl -X GET "http://localhost:8000/templates"

响应示例:

{
  "success": true,
  "templates": {
    "home": {
      "name": "首页",
      "description": "电商首页模板",
      "prompt": "黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航"
    },
    "detail": {
      "name": "详情页",
      "description": "商品详情页模板",
      "prompt": "黑金风格的商品详情页,顶部轮播图,展示价格、卖家信用和凭证区"
    },
    "search": {
      "name": "搜索页",
      "description": "搜索页面模板",
      "prompt": "黑金风格的搜索页面,搜索框和筛选条件,单列商品列表"
    }
  }
}

2.5 主题列表端点

GET /themes

获取可用的主题列表。

请求示例:

curl -X GET "http://localhost:8000/themes"

响应示例:

{
  "success": true,
  "themes": {
    "obsidian-gold": {
      "name": "黑金主题",
      "description": "高端奢华的黑金配色方案"
    },
    "silver-white": {
      "name": "白银主题",
      "description": "简洁优雅的白银配色方案"
    },
    "minimal": {
      "name": "简约主题",
      "description": "极简主义的设计风格"
    }
  }
}

2.6 DSL上传端点

POST /upload-dsl

上传DSL文件进行渲染。

请求参数:

参数类型必需描述
filefile是DSL JSON文件

请求示例:

curl -X POST "http://localhost:8000/upload-dsl" \
  -H "Authorization: Bearer your-api-key" \
  -F "file=@ui_design.json"

响应示例:

{
  "success": true,
  "message": "DSL文件上传成功",
  "dsl": {
    "page": {
      "name": "home_page",
      "theme": "obsidian-gold",
      "sections": [...]
    }
  }
}

2.7 文件下载端点

GET /download/{file_type}/{filename}

下载生成的文件。

路径参数:

参数类型必需描述
file_typestring是文件类型:image, vue, dsl
filenamestring是文件名

请求示例:

curl -X GET "http://localhost:8000/download/image/ui_design.png" \
  -H "Authorization: Bearer your-api-key" \
  --output ui_design.png

响应:

  • 成功:返回文件内容
  • 失败:返回JSON错误信息

3. 数据模型定义

3.1 请求模型

GenerateUIRequest

class GenerateUIRequest(BaseModel):
    prompt: str = Field(..., description="中文Prompt描述", min_length=1, max_length=500)
    model_path: Optional[str] = Field(None, description="模型路径")
    lora_path: Optional[str] = Field(None, description="LoRA权重路径")
    use_rules: bool = Field(False, description="是否强制使用规则生成")
    output_format: str = Field("json", description="输出格式", regex="^(json|png|vue)$")

RenderRequest

class RenderRequest(BaseModel):
    dsl: Dict[str, Any] = Field(..., description="UI-DSL数据")
    output_format: str = Field("png", description="输出格式", regex="^(png|vue)$")

3.2 响应模型

GenerateUIResponse

class GenerateUIResponse(BaseModel):
    success: bool
    message: str
    data: Optional[Dict[str, Any]] = None
    method: Optional[str] = None
    error: Optional[str] = None
    timestamp: Optional[str] = None

RenderResponse

class RenderResponse(BaseModel):
    success: bool
    message: str
    data: Optional[str] = None  # Base64编码的图片或Vue代码
    error: Optional[str] = None
    timestamp: Optional[str] = None

HealthResponse

class HealthResponse(BaseModel):
    status: str
    version: str
    model_loaded: bool
    timestamp: Optional[str] = None
    uptime: Optional[int] = None

3.3 UI-DSL数据模型

Page结构

class Page(BaseModel):
    name: str
    theme: str
    layout: Layout
    sections: List[Section]

class Layout(BaseModel):
    grid: int = 12
    gutter: int = 16
    padding: int = 16
    bg: str

class Section(BaseModel):
    type: str
    props: Dict[str, Any]

4. 错误码定义

4.1 错误码列表

错误码HTTP状态码描述解决方案
INVALID_PROMPT400Prompt参数无效检查Prompt格式和长度
INVALID_FORMAT400输出格式不支持使用支持的格式:json, png, vue
INVALID_DSL400DSL格式错误检查DSL结构是否正确
MODEL_LOAD_FAILED500模型加载失败检查模型路径和权限
RENDER_FAILED500渲染失败检查渲染器配置
RATE_LIMIT_EXCEEDED429请求频率超限降低请求频率
UNAUTHORIZED401未授权访问检查API密钥
SERVICE_UNAVAILABLE503服务不可用稍后重试或联系管理员

4.2 错误处理示例

# Python客户端错误处理
import requests

def generate_ui(prompt: str, api_key: str):
    try:
        response = requests.post(
            "http://localhost:8000/generate-ui",
            headers={"Authorization": f"Bearer {api_key}"},
            json={"prompt": prompt, "output_format": "json"},
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 400:
            error_data = e.response.json()
            print(f"请求错误: {error_data['message']}")
        elif e.response.status_code == 429:
            print("请求频率过高,请稍后重试")
        elif e.response.status_code == 500:
            print("服务器内部错误,请稍后重试")
        else:
            print(f"HTTP错误: {e.response.status_code}")
    
    except requests.exceptions.Timeout:
        print("请求超时,请稍后重试")
    
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")

5. 使用示例

5.1 cURL示例

生成UI设计:

# 生成JSON格式
curl -X POST "http://localhost:8000/generate-ui" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "prompt": "简约风格的登录页面,包含用户名密码输入框和登录按钮",
    "output_format": "json"
  }'

# 生成PNG图片
curl -X POST "http://localhost:8000/generate-ui" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "prompt": "黑金风格的电商首页",
    "output_format": "png"
  }' | jq -r '.data.image' | base64 -d > ui_design.png

# 生成Vue页面
curl -X POST "http://localhost:8000/generate-ui" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "prompt": "白银风格的商品列表页",
    "output_format": "vue"
  }' | jq -r '.data.vue_content' > product_list.vue

渲染现有DSL:

curl -X POST "http://localhost:8000/render" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{
    "dsl": {
      "page": {
        "name": "home_page",
        "theme": "obsidian-gold",
        "sections": [...]
      }
    },
    "output_format": "png"
  }'

5.2 Python客户端示例

import requests
import json
import base64
from typing import Dict, Any, Optional

class AIUIClient:
    def __init__(self, base_url: str = "http://localhost:8000", api_key: str = None):
        self.base_url = base_url
        self.headers = {
            "Content-Type": "application/json"
        }
        if api_key:
            self.headers["Authorization"] = f"Bearer {api_key}"
    
    def generate_ui(self, prompt: str, output_format: str = "json", 
                   model_path: str = None, use_rules: bool = False) -> Dict[str, Any]:
        """生成UI设计"""
        data = {
            "prompt": prompt,
            "output_format": output_format,
            "use_rules": use_rules
        }
        
        if model_path:
            data["model_path"] = model_path
        
        response = requests.post(
            f"{self.base_url}/generate-ui",
            headers=self.headers,
            json=data,
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    
    def render_ui(self, dsl: Dict[str, Any], output_format: str = "png") -> Dict[str, Any]:
        """渲染UI设计"""
        data = {
            "dsl": dsl,
            "output_format": output_format
        }
        
        response = requests.post(
            f"{self.base_url}/render",
            headers=self.headers,
            json=data,
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    
    def get_templates(self) -> Dict[str, Any]:
        """获取模板列表"""
        response = requests.get(f"{self.base_url}/templates", headers=self.headers)
        response.raise_for_status()
        return response.json()
    
    def get_themes(self) -> Dict[str, Any]:
        """获取主题列表"""
        response = requests.get(f"{self.base_url}/themes", headers=self.headers)
        response.raise_for_status()
        return response.json()
    
    def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        response = requests.get(f"{self.base_url}/health", headers=self.headers)
        response.raise_for_status()
        return response.json()
    
    def save_image(self, image_data: str, filename: str):
        """保存Base64图片"""
        image_bytes = base64.b64decode(image_data)
        with open(filename, 'wb') as f:
            f.write(image_bytes)
    
    def save_vue(self, vue_content: str, filename: str):
        """保存Vue代码"""
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(vue_content)

# 使用示例
if __name__ == "__main__":
    client = AIUIClient(api_key="your-api-key")
    
    # 生成UI设计
    result = client.generate_ui(
        prompt="黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航",
        output_format="png"
    )
    
    if result["success"]:
        # 保存图片
        client.save_image(result["data"]["image"], "ui_design.png")
        print("UI设计已保存为 ui_design.png")
    else:
        print(f"生成失败: {result['message']}")

5.3 JavaScript客户端示例

class AIUIClient {
    constructor(baseUrl = 'http://localhost:8000', apiKey = null) {
        this.baseUrl = baseUrl;
        this.headers = {
            'Content-Type': 'application/json'
        };
        if (apiKey) {
            this.headers['Authorization'] = `Bearer ${apiKey}`;
        }
    }
    
    async generateUI(prompt, outputFormat = 'json', options = {}) {
        const data = {
            prompt,
            output_format: outputFormat,
            use_rules: options.useRules || false
        };
        
        if (options.modelPath) {
            data.model_path = options.modelPath;
        }
        
        const response = await fetch(`${this.baseUrl}/generate-ui`, {
            method: 'POST',
            headers: this.headers,
            body: JSON.stringify(data)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async renderUI(dsl, outputFormat = 'png') {
        const data = {
            dsl,
            output_format: outputFormat
        };
        
        const response = await fetch(`${this.baseUrl}/render`, {
            method: 'POST',
            headers: this.headers,
            body: JSON.stringify(data)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async getTemplates() {
        const response = await fetch(`${this.baseUrl}/templates`, {
            headers: this.headers
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async getThemes() {
        const response = await fetch(`${this.baseUrl}/themes`, {
            headers: this.headers
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async healthCheck() {
        const response = await fetch(`${this.baseUrl}/health`, {
            headers: this.headers
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }
    
    saveImage(imageData, filename) {
        const link = document.createElement('a');
        link.href = `data:image/png;base64,${imageData}`;
        link.download = filename;
        link.click();
    }
    
    saveVue(vueContent, filename) {
        const blob = new Blob([vueContent], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = filename;
        link.click();
        URL.revokeObjectURL(url);
    }
}

// 使用示例
async function generateUI() {
    const client = new AIUIClient('http://localhost:8000', 'your-api-key');
    
    try {
        const result = await client.generateUI(
            '黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航',
            'png'
        );
        
        if (result.success) {
            client.saveImage(result.data.image, 'ui_design.png');
            console.log('UI设计已保存');
        } else {
            console.error('生成失败:', result.message);
        }
    } catch (error) {
        console.error('请求失败:', error);
    }
}

// 调用函数
generateUI();

6. 高级用法

6.1 批量处理

# 批量生成UI设计
def batch_generate_ui(client: AIUIClient, prompts: List[str], output_format: str = "json"):
    """批量生成UI设计"""
    results = []
    
    for i, prompt in enumerate(prompts):
        try:
            result = client.generate_ui(prompt, output_format)
            results.append({
                "index": i,
                "prompt": prompt,
                "result": result
            })
            print(f"完成 {i+1}/{len(prompts)}: {prompt[:50]}...")
        except Exception as e:
            results.append({
                "index": i,
                "prompt": prompt,
                "error": str(e)
            })
            print(f"失败 {i+1}/{len(prompts)}: {e}")
    
    return results

# 使用示例
prompts = [
    "黑金风格的电商首页",
    "简约风格的商品详情页",
    "白银风格的搜索页面"
]

client = AIUIClient(api_key="your-api-key")
results = batch_generate_ui(client, prompts, "png")

# 保存所有结果
for result in results:
    if "result" in result and result["result"]["success"]:
        filename = f"ui_design_{result['index']}.png"
        client.save_image(result["result"]["data"]["image"], filename)

6.2 异步处理

import asyncio
import aiohttp

async def async_generate_ui(session: aiohttp.ClientSession, prompt: str, api_key: str):
    """异步生成UI设计"""
    data = {
        "prompt": prompt,
        "output_format": "json"
    }
    
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    
    async with session.post(
        "http://localhost:8000/generate-ui",
        json=data,
        headers=headers
    ) as response:
        return await response.json()

async def batch_async_generate(prompts: List[str], api_key: str):
    """批量异步生成"""
    async with aiohttp.ClientSession() as session:
        tasks = [
            async_generate_ui(session, prompt, api_key)
            for prompt in prompts
        ]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        return results

# 使用示例
prompts = [
    "黑金风格的电商首页",
    "简约风格的商品详情页",
    "白银风格的搜索页面"
]

results = asyncio.run(batch_async_generate(prompts, "your-api-key"))

6.3 错误重试机制

import time
from functools import wraps

def retry(max_attempts: int = 3, delay: float = 1.0):
    """重试装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    last_exception = e
                    if attempt < max_attempts - 1:
                        print(f"尝试 {attempt + 1} 失败,{delay}秒后重试...")
                        time.sleep(delay)
                    else:
                        print(f"所有尝试都失败了: {e}")
            
            raise last_exception
        return wrapper
    return decorator

class RobustAIUIClient(AIUIClient):
    @retry(max_attempts=3, delay=2.0)
    def generate_ui(self, prompt: str, output_format: str = "json", **kwargs):
        """带重试的UI生成"""
        return super().generate_ui(prompt, output_format, **kwargs)
    
    @retry(max_attempts=3, delay=1.0)
    def render_ui(self, dsl: Dict[str, Any], output_format: str = "png"):
        """带重试的UI渲染"""
        return super().render_ui(dsl, output_format)

通过以上API参考文档,开发者可以全面了解AI UI生成系统的API接口,并能够快速集成到自己的应用中。

Prev
扩展开发指南
Next
配置参数说明