# AI 健康报告接口文档 ## 接口概述 生成用户的 AI 健康报告图片接口,基于用户的健康数据(体重、饮食、运动等)生成可视化的健康分析报告图片。 --- ## 接口信息 - **接口名称**: 生成 AI 健康报告 - **接口路径**: `/users/ai-report` - **请求方法**: `POST` - **认证方式**: JWT Token (Bearer Token) - **内容类型**: `application/json` --- ## 请求说明 ### 请求头 (Headers) | 参数名 | 类型 | 必填 | 说明 | 示例 | | ------------- | ------ | ---- | ------------ | ------------------------------------------------ | | Authorization | string | 是 | JWT 访问令牌 | `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` | | Content-Type | string | 是 | 请求内容类型 | `application/json` | ### 请求体 (Body) | 参数名 | 类型 | 必填 | 说明 | 示例 | | ------ | ------ | ---- | ------------------------------------------------------------- | -------------- | | date | string | 否 | 指定生成报告的日期,格式 YYYY-MM-DD。不传则默认生成今天的报告 | `"2024-01-15"` | ### 请求示例 #### 示例 1: 生成今天的报告 ```bash curl -X POST 'https://api.example.com/users/ai-report' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \ -H 'Content-Type: application/json' \ -d '{}' ``` #### 示例 2: 生成指定日期的报告 ```bash curl -X POST 'https://api.example.com/users/ai-report' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \ -H 'Content-Type: application/json' \ -d '{ "date": "2024-01-15" }' ``` #### JavaScript/TypeScript 示例 ```typescript // 使用 fetch async function generateHealthReport(date?: string) { const response = await fetch("https://api.example.com/users/ai-report", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify(date ? { date } : {}), }); const result = await response.json(); return result; } // 使用 axios import axios from "axios"; async function generateHealthReport(date?: string) { const response = await axios.post( "https://api.example.com/users/ai-report", date ? { date } : {}, { headers: { Authorization: `Bearer ${accessToken}`, }, } ); return response.data; } ``` #### Swift 示例 ```swift func generateHealthReport(date: String? = nil, completion: @escaping (Result) -> Void) { let url = URL(string: "https://api.example.com/users/ai-report")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") var body: [String: Any] = [:] if let date = date { body["date"] = date } if !body.isEmpty { request.httpBody = try? JSONSerialization.data(withJSONObject: body) } URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { completion(.failure(error)) return } guard let data = data else { completion(.failure(NSError(domain: "", code: -1, userInfo: nil))) return } do { let decoder = JSONDecoder() let result = try decoder.decode(HealthReportResponse.self, from: data) completion(.success(result)) } catch { completion(.failure(error)) } }.resume() } // 响应模型 struct HealthReportResponse: Codable { let code: Int let message: String let data: HealthReportData } struct HealthReportData: Codable { let imageUrl: String } ``` --- ## 响应说明 ### 响应格式 所有响应都遵循统一的响应格式: ```typescript { code: number; // 响应码: 0-成功, 1-失败 message: string; // 响应消息 data: { imageUrl: string; // 生成的报告图片 URL } } ``` ### 成功响应 **HTTP 状态码**: `200 OK` **响应体示例**: ```json { "code": 0, "message": "AI健康报告生成成功", "data": { "imageUrl": "https://pilates-1234567890.cos.ap-guangzhou.myqcloud.com/health-reports/user-123/2024-01-15/report-xxxxx.png" } } ``` **字段说明**: | 字段 | 类型 | 说明 | | ------------- | ------ | -------------------------------------------- | | code | number | 响应码,0 表示成功 | | message | string | 响应消息,成功时为 "AI健康报告生成成功" | | data.imageUrl | string | 生成的健康报告图片完整 URL,可直接访问和下载 | ### 失败响应 **HTTP 状态码**: `200 OK` (业务失败也返回 200,通过 code 字段判断) **响应体示例**: ```json { "code": 1, "message": "生成失败: 用户健康数据不足", "data": { "imageUrl": "" } } ``` **常见错误消息**: | 错误消息 | 说明 | 解决方案 | | ----------------------------- | ------------------------------ | ---------------------------------------------- | | `生成失败: 用户健康数据不足` | 用户没有足够的健康数据生成报告 | 引导用户添加更多健康数据(体重、饮食、运动等) | | `生成失败: 日期格式不正确` | date 参数格式错误 | 确保日期格式为 YYYY-MM-DD | | `生成失败: 未找到用户信息` | 用户不存在或 Token 无效 | 检查认证 Token 是否有效 | | `生成失败: AI 服务暂时不可用` | AI 模型服务异常 | 稍后重试 | ### 认证失败响应 **HTTP 状态码**: `401 Unauthorized` **响应体示例**: ```json { "statusCode": 401, "message": "Unauthorized" } ``` --- ## 业务逻辑说明 ### 报告内容 AI 健康报告会基于用户的以下数据生成: 1. **体重数据**: 当天或最近的体重记录 2. **饮食数据**: 当天的饮食记录和营养摄入 3. **运动数据**: 当天的运动记录和卡路里消耗 4. **围度数据**: 身体各部位的围度测量数据 5. **目标进度**: 用户设定的健康目标完成情况 ### 报告生成逻辑 - 如果不传 `date` 参数,默认生成今天的报告 - 如果指定日期没有数据,会返回数据不足的提示 - 报告图片为 PNG 格式,尺寸适配移动端展示 - 图片会存储在腾讯云 COS,有效期永久(或根据策略定期清理) ### 缓存策略 - 同一天同一用户的报告会缓存,重复请求会返回相同的图片 URL - 如果用户更新了当天的数据,可以重新生成覆盖旧报告 --- ## 错误处理 ### 客户端错误处理示例 ```typescript async function fetchHealthReport(date?: string) { try { const response = await fetch("https://api.example.com/users/ai-report", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify(date ? { date } : {}), }); // 检查 HTTP 状态码 if (response.status === 401) { // Token 失效,需要重新登录 throw new Error("认证失败,请重新登录"); } const result = await response.json(); // 检查业务状态码 if (result.code !== 0) { // 业务失败 throw new Error(result.message); } // 成功,返回图片 URL return result.data.imageUrl; } catch (error) { console.error("生成健康报告失败:", error); throw error; } } // 使用示例 try { const imageUrl = await fetchHealthReport(); console.log("报告生成成功:", imageUrl); // 在 UI 中展示图片 } catch (error) { // 向用户展示错误提示 alert(error.message); } ``` --- ## 使用建议 ### 1. 前置检查 在调用接口前,建议先检查: - 用户是否已登录(有有效的 JWT Token) - 用户是否有足够的健康数据(可通过其他接口查询) - 网络连接是否正常 ### 2. 加载提示 由于报告生成需要调用 AI 服务,可能需要几秒钟时间,建议: - 显示加载动画或进度提示 - 设置合理的超时时间(建议 30-60 秒) - 提供取消操作的选项 ### 3. 图片展示 获取到图片 URL 后: - 可以直接在 Image 组件中使用该 URL - 支持下载保存到本地相册 - 支持分享到社交媒体 ### 4. 错误处理 - 网络错误:提示用户检查网络连接 - 数据不足:引导用户添加健康数据 - Token 过期:自动刷新 Token 或引导重新登录 --- ## 完整示例 ### React Native 完整示例 ```typescript import React, { useState } from 'react'; import { View, Image, Button, Text, ActivityIndicator } from 'react-native'; import axios from 'axios'; const HealthReportScreen = () => { const [loading, setLoading] = useState(false); const [imageUrl, setImageUrl] = useState(null); const [error, setError] = useState(null); const generateReport = async (date?: string) => { setLoading(true); setError(null); try { const response = await axios.post( 'https://api.example.com/users/ai-report', date ? { date } : {}, { headers: { 'Authorization': `Bearer ${accessToken}`, }, timeout: 60000, // 60秒超时 } ); if (response.data.code === 0) { setImageUrl(response.data.data.imageUrl); } else { setError(response.data.message); } } catch (err) { if (axios.isAxiosError(err)) { if (err.response?.status === 401) { setError('登录已过期,请重新登录'); } else if (err.code === 'ECONNABORTED') { setError('请求超时,请检查网络连接'); } else { setError(err.response?.data?.message || '生成报告失败'); } } else { setError('未知错误'); } } finally { setLoading(false); } }; return (