Files
plates-server/docs/API-AI-HEALTH-REPORT.md
richarjiang 5b89a07751 stash
2025-12-01 18:12:09 +08:00

12 KiB
Raw Blame History

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: 生成今天的报告

curl -X POST 'https://api.example.com/users/ai-report' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  -H 'Content-Type: application/json' \
  -d '{}'

示例 2: 生成指定日期的报告

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 示例

// 使用 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 示例

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
}

响应说明

响应格式

所有响应都遵循统一的响应格式:

{
  code: number; // 响应码: 0-成功, 1-失败
  message: string; // 响应消息
  data: {
    imageUrl: string; // 生成的报告图片 URL
  }
}

成功响应

HTTP 状态码: 200 OK

响应体示例:

{
  "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 字段判断)

响应体示例:

{
  "code": 1,
  "message": "生成失败: 用户健康数据不足",
  "data": {
    "imageUrl": ""
  }
}

常见错误消息:

错误消息 说明 解决方案
生成失败: 用户健康数据不足 用户没有足够的健康数据生成报告 引导用户添加更多健康数据(体重、饮食、运动等)
生成失败: 日期格式不正确 date 参数格式错误 确保日期格式为 YYYY-MM-DD
生成失败: 未找到用户信息 用户不存在或 Token 无效 检查认证 Token 是否有效
生成失败: AI 服务暂时不可用 AI 模型服务异常 稍后重试

认证失败响应

HTTP 状态码: 401 Unauthorized

响应体示例:

{
  "statusCode": 401,
  "message": "Unauthorized"
}

业务逻辑说明

报告内容

AI 健康报告会基于用户的以下数据生成:

  1. 体重数据: 当天或最近的体重记录
  2. 饮食数据: 当天的饮食记录和营养摄入
  3. 运动数据: 当天的运动记录和卡路里消耗
  4. 围度数据: 身体各部位的围度测量数据
  5. 目标进度: 用户设定的健康目标完成情况

报告生成逻辑

  • 如果不传 date 参数,默认生成今天的报告
  • 如果指定日期没有数据,会返回数据不足的提示
  • 报告图片为 PNG 格式,尺寸适配移动端展示
  • 图片会存储在腾讯云 COS有效期永久或根据策略定期清理

缓存策略

  • 同一天同一用户的报告会缓存,重复请求会返回相同的图片 URL
  • 如果用户更新了当天的数据,可以重新生成覆盖旧报告

错误处理

客户端错误处理示例

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 完整示例

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 秒的请求超时时间

相关接口


更新日志

版本 日期 更新内容
v1.0 2024-01-15 初始版本,支持基础健康报告生成

技术支持

如有问题,请联系技术支持团队。