457 lines
12 KiB
Markdown
457 lines
12 KiB
Markdown
# 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<HealthReportResponse, Error>) -> 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<string | null>(null);
|
||
const [error, setError] = useState<string | null>(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 (
|
||
<View style={{ flex: 1, padding: 20 }}>
|
||
<Button
|
||
title="生成今天的健康报告"
|
||
onPressed={() => generateReport()}
|
||
disabled={loading}
|
||
/>
|
||
|
||
{loading && (
|
||
<View style={{ marginTop: 20, alignItems: 'center' }}>
|
||
<ActivityIndicator size="large" />
|
||
<Text style={{ marginTop: 10 }}>正在生成报告...</Text>
|
||
</View>
|
||
)}
|
||
|
||
{error && (
|
||
<Text style={{ color: 'red', marginTop: 20 }}>
|
||
{error}
|
||
</Text>
|
||
)}
|
||
|
||
{imageUrl && (
|
||
<Image
|
||
source={{ uri: imageUrl }}
|
||
style={{ width: '100%', height: 400, marginTop: 20 }}
|
||
resizeMode="contain"
|
||
/>
|
||
)}
|
||
</View>
|
||
);
|
||
};
|
||
|
||
export default HealthReportScreen;
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **认证要求**: 必须携带有效的 JWT Token,否则返回 401
|
||
2. **请求频率**: 建议不要频繁调用,同一用户同一天建议缓存结果
|
||
3. **图片有效期**: 图片 URL 长期有效,可以缓存在客户端
|
||
4. **数据依赖**: 需要用户有足够的健康数据才能生成有意义的报告
|
||
5. **网络要求**: AI 报告生成需要调用外部服务,需要稳定的网络连接
|
||
6. **超时设置**: 建议设置 30-60 秒的请求超时时间
|
||
|
||
---
|
||
|
||
## 相关接口
|
||
|
||
- [用户信息接口](./API-USER-INFO.md)
|
||
- [体重记录接口](./API-WEIGHT-RECORDS.md)
|
||
- [饮食记录接口](./API-DIET-RECORDS.md)
|
||
- [运动记录接口](./API-WORKOUT-RECORDS.md)
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
| 版本 | 日期 | 更新内容 |
|
||
| ---- | ---------- | ------------------------------ |
|
||
| v1.0 | 2024-01-15 | 初始版本,支持基础健康报告生成 |
|
||
|
||
---
|
||
|
||
## 技术支持
|
||
|
||
如有问题,请联系技术支持团队。
|