Files
msh-system/msh_single_uniapp/api/tool.js
scottpan 4be53dcd1b feat: 集成 KieAI 服务,移除 models-integration 子项目
- 添加 Gemini 2.5 Flash 对话接口(流式+非流式)
- 添加 NanoBanana 图像生成/编辑接口
- 添加 Sora2 视频生成接口(文生视频、图生视频、去水印)
- 移除 models-integration 子项目(功能已迁移至主后端)
- 新增测试文档和 Playwright E2E 配置
- 更新前端页面和 API 接口
- 更新后端配置和日志处理
2026-03-03 15:33:50 +08:00

534 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// +----------------------------------------------------------------------
// | Tool模块API接口
// +----------------------------------------------------------------------
// | 包含食谱计算器、AI营养师、饮食打卡、食物百科、营养知识等接口
// +----------------------------------------------------------------------
import request from "@/utils/request.js";
import { HTTP_REQUEST_URL, TOKENNAME } from "@/config/app.js";
import store from "@/store";
// ==================== 食谱计算器相关 ====================
/**
* 计算营养方案
* @param {Object} data - 计算参数
* @param {String} data.gender - 性别male/female
* @param {Number} data.age - 年龄
* @param {Number} data.height - 身高(cm)
* @param {Boolean} data.dialysis - 是否透析true/false
* @param {String} data.dialysisType - 透析类型hemodialysis/peritoneal (可选)
* @param {Number} data.dryWeight - 干体重(kg)
* @param {Number} data.creatinine - 血肌酐(μmol/L)
*/
export function calculateNutrition(data) {
return request.post('tool/calculator/calculate', data);
}
/**
* 获取计算结果详情
* @param {Number} id - 计算结果ID
*/
export function getCalculatorResult(id) {
return request.get('tool/calculator/result/' + id);
}
/**
* 采纳营养计划
* @param {Number} resultId - 计算结果ID
*/
export function adoptNutritionPlan(resultId) {
return request.post('tool/calculator/adopt', { resultId });
}
// ==================== AI营养师相关 ====================
/**
* 发送消息给AI营养师
* @param {Object} data - 消息数据
* @param {String} data.content - 消息内容
* @param {String} data.type - 消息类型text/image/voice
* @param {String} data.imageUrl - 图片URL当type为image时
* @param {String} data.voiceUrl - 语音URL当type为voice时
* @param {String} data.conversationId - 会话ID可选用于继续对话
*/
export function sendAIMessage(data) {
return request.post('tool/ai-nutritionist/message', data);
}
/**
* 获取AI回复
* @param {String} messageId - 消息ID
*/
export function getAIResponse(messageId) {
return request.get('tool/ai-nutritionist/response/' + messageId);
}
/**
* 获取对话历史
* @param {Object} data - 查询参数
* @param {String} data.conversationId - 会话ID可选
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getConversationHistory(data) {
return request.get('tool/ai-nutritionist/history', data);
}
/**
* 清空对话历史
* @param {String} conversationId - 会话ID可选
*/
export function clearConversation(conversationId) {
return request.post('tool/ai-nutritionist/clear', { conversationId });
}
// ==================== 饮食打卡相关 ====================
/**
* 提交打卡记录
* @param {Object} data - 打卡数据
* @param {String} data.mealType - 餐次breakfast/lunch/dinner/snack
* @param {String} data.date - 打卡日期YYYY-MM-DD
* @param {Array} data.images - 图片URL数组
* @param {String} data.remark - 备注
* @param {String} data.voiceUrl - 语音备注URL可选
* @param {String} data.taskId - 语音识别任务ID可选
* @param {String} data.dishes - 菜品清单JSON字符串
* @param {Object} data.nutrition - 营养数据(可选)
* @param {Boolean} data.enableAIVideo - 是否生成AI视频
* @param {Boolean} data.enableAIAnalysis - 是否开启AI识别
*/
export function submitCheckin(data) {
return request.post('tool/checkin/submit', data);
}
/**
* 获取打卡记录列表
* @param {Object} data - 查询参数
* @param {String} data.date - 日期YYYY-MM-DD可选
* @param {String} data.mealType - 餐次(可选)
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getCheckinList(data) {
return request.get('tool/checkin/list', data);
}
/**
* 获取打卡记录详情
* @param {Number} id - 打卡记录ID
*/
export function getCheckinDetail(id) {
return request.get('tool/checkin/detail/' + id);
}
/**
* 获取连续打卡统计
*/
export function getCheckinStreak() {
return request.get('tool/checkin/streak');
}
/**
* 获取打卡日历数据
* @param {String} yearMonth - 年月YYYY-MM
*/
export function getCheckinCalendar(yearMonth) {
return request.get('tool/checkin/calendar', { yearMonth });
}
/**
* 获取打卡任务列表
*/
export function getCheckinTasks() {
return request.get('tool/checkin/tasks');
}
/**
* 查询视频任务状态
* @param {String} taskId - 任务ID
*/
export function getVideoTaskStatus(taskId) {
return request.get(`kieai/video/task/${taskId}`);
}
/**
* 一键复制打卡
* @param {Number} sourceRecordId - 源打卡记录ID
* @param {Object} data - 修改后的数据(可选)
*/
export function copyCheckin(sourceRecordId, data) {
return request.post('tool/checkin/copy', {
sourceRecordId,
...data
});
}
/**
* 一键借鉴打卡
* @param {Number} sourcePostId - 源社区内容ID
* @param {Object} data - 修改后的数据(可选)
*/
export function learnCheckin(sourcePostId, data) {
return request.post('tool/checkin/learn', {
sourcePostId,
...data
});
}
// ==================== 食物百科相关 ====================
/**
* 搜索食物
* @param {Object} data - 搜索参数
* @param {String} data.keyword - 搜索关键词
* @param {String} data.category - 分类(可选)
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function searchFood(data) {
return request.get('tool/food/search', data);
}
/**
* 获取食物列表(按分类)
* @param {Object} data - 查询参数
* @param {String} data.category - 分类all/grain/vegetable/fruit/meat/seafood
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getFoodList(data) {
return request.get('tool/food/list', data);
}
/**
* 获取食物详情
* @param {String} id - 食物ID或名称
*/
export function getFoodDetail(id) {
return request.get('tool/food/detail/' + id);
}
/**
* 获取相似食物推荐
* @param {String} foodId - 食物ID
*/
export function getSimilarFoods(foodId) {
return request.get('tool/food/similar/' + foodId);
}
// ==================== 营养知识相关 ====================
/**
* 获取营养知识列表
* @param {Object} data - 查询参数
* @param {String} data.type - 类型nutrients/guide/article
* @param {String} data.category - 分类(可选)
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getKnowledgeList(data) {
return request.get('tool/knowledge/list', data);
}
/**
* 获取营养知识详情
* @param {Number} id - 知识ID
*/
export function getKnowledgeDetail(id) {
return request.get('tool/knowledge/detail/' + id);
}
/**
* 获取营养素详情
* @param {String} name - 营养素名称
*/
export function getNutrientDetail(name) {
return request.get('tool/knowledge/nutrient/' + name);
}
// ==================== 打卡社区相关 ====================
/**
* 获取社区内容列表
* @param {Object} data - 查询参数
* @param {String} data.tab - Tab类型recommend/latest/follow/hot
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getCommunityList(data) {
return request.get('tool/community/list', data);
}
/**
* 获取社区内容详情
* @param {Number} id - 内容ID
*/
export function getCommunityDetail(id) {
return request.get('tool/community/detail/' + id);
}
/**
* 发布社区内容
* @param {Object} data - 内容数据
* @param {String} data.title - 标题
* @param {String} data.content - 内容
* @param {Array} data.images - 图片URL数组
* @param {Array} data.tags - 标签数组
* @param {Number} data.checkInRecordId - 关联的打卡记录ID可选
*/
export function publishCommunityPost(data) {
return request.post('tool/community/publish', data);
}
/**
* 点赞/取消点赞
* @param {Number} postId - 内容ID
* @param {Boolean} isLike - 是否点赞true/false
*/
export function toggleLike(postId, isLike) {
return request.post('tool/community/like', { postId, isLike });
}
/**
* 收藏/取消收藏
* @param {Number} postId - 内容ID
* @param {Boolean} isCollect - 是否收藏true/false
*/
export function toggleCollect(postId, isCollect) {
return request.post('tool/community/collect', { postId, isCollect });
}
/**
* 发表评论
* @param {Object} data - 评论数据
* @param {Number} data.postId - 内容ID
* @param {String} data.content - 评论内容
* @param {Number} data.parentCommentId - 父评论ID可选用于回复
* @param {Number} data.replyToUserId - 回复的用户ID可选
*/
export function addComment(data) {
return request.post('tool/community/comment', data);
}
/**
* 获取评论列表
* @param {Number} postId - 内容ID
* @param {Object} data - 查询参数
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getCommentList(postId, data) {
return request.get('tool/community/comment/list/' + postId, data);
}
/**
* 关注/取消关注用户
* @param {Number} userId - 用户ID
* @param {Boolean} isFollow - 是否关注true/false
*/
export function toggleFollow(userId, isFollow) {
return request.post('tool/community/follow', { userId, isFollow });
}
/**
* 分享内容
* @param {Number} postId - 内容ID
*/
export function sharePost(postId) {
return request.post('tool/community/share', { postId });
}
// ==================== 积分系统相关 ====================
/**
* 获取用户积分信息
*/
export function getUserPoints() {
return request.get('tool/points/info');
}
/**
* 获取积分规则
*/
export function getPointsRules() {
return request.get('tool/points/rules');
}
/**
* 获取积分流水
* @param {Object} data - 查询参数
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
* @param {String} data.type - 类型earn/consume可选
*/
export function getPointsHistory(data) {
return request.get('tool/points/history', data);
}
/**
* 获取积分兑换列表
*/
export function getPointsExchangeList() {
return request.get('tool/points/exchange/list');
}
/**
* 积分兑换
* @param {Number} exchangeId - 兑换项ID
*/
export function exchangePoints(exchangeId) {
return request.post('tool/points/exchange', { exchangeId });
}
// ==================== 首页数据相关 ====================
/**
* 获取首页数据
*/
export function getHomeData() {
return request.get('tool/home/data');
}
/**
* 获取推荐食谱列表(首页展示,无需登录即可浏览)
* @param {Object} data - 查询参数
* @param {Number} data.limit - 数量限制
*/
export function getRecommendedRecipes(data) {
return request.get('tool/home/recipes', data, { noAuth: true });
}
/**
* 获取推荐营养知识(首页展示,无需登录即可浏览)
* @param {Object} data - 查询参数
* @param {Number} data.limit - 数量限制
*/
export function getRecommendedKnowledge(data) {
return request.get('tool/home/knowledge', data, { noAuth: true });
}
/**
* 获取用户健康档案状态(首页展示,未登录时返回默认状态)
*/
export function getUserHealthStatus() {
return request.get('tool/home/health-status', {}, { noAuth: true });
}
/**
* 获取首页展示配置(如四大功能入口是否显示,由系统配置 field01 控制1=显示)
*/
export function getHomeDisplayConfig() {
return request.get('tool/home/display-config', {}, { noAuth: true });
}
// ==================== 食谱相关 ====================
/**
* 获取食谱列表
* @param {Object} data - 查询参数
* @param {String} data.mealType - 餐次(可选)
* @param {Number} data.page - 页码
* @param {Number} data.limit - 每页数量
*/
export function getRecipeList(data) {
return request.get('tool/recipe/list', data);
}
/**
* 获取食谱详情
* @param {Number} id - 食谱ID
*/
export function getRecipeDetail(id) {
return request.get('tool/recipe/detail/' + id);
}
/**
* 收藏/取消收藏食谱
* @param {Number} recipeId - 食谱ID
* @param {Boolean} isFavorite - 是否收藏true/false
*/
export function toggleRecipeFavorite(recipeId, isFavorite) {
return request.post('tool/recipe/favorite', { recipeId, isFavorite });
}
// ==================== 文件上传相关 ====================
/**
* 上传图片
* @param {String} filePath - 图片临时路径
* @param {String} type - 上传类型checkin/community/avatar
*/
export function uploadImage(filePath, type = 'checkin') {
return new Promise((resolve, reject) => {
const token = store.state.app.token || '';
const header = {};
if (token) {
header[TOKENNAME] = token;
}
uni.uploadFile({
url: HTTP_REQUEST_URL + '/api/front/tool/upload/image',
filePath: filePath,
name: 'file',
formData: {
type: type
},
header: header,
success: (res) => {
try {
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
if (data.code === 200) {
resolve(data.data);
} else {
reject(data.message || '上传失败');
}
} catch (e) {
reject('解析响应失败');
}
},
fail: (err) => {
reject('上传失败:' + (err.errMsg || '网络错误'));
}
});
});
}
/**
* 上传语音
* @param {String} filePath - 语音临时路径
*/
export function uploadVoice(filePath) {
return new Promise((resolve, reject) => {
const token = store.state.app.token || '';
const header = {};
if (token) {
header[TOKENNAME] = token;
}
uni.uploadFile({
url: HTTP_REQUEST_URL + '/api/front/tool/upload/voice',
filePath: filePath,
name: 'file',
header: header,
success: (res) => {
try {
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
if (data.code === 200) {
resolve(data.data);
} else {
reject(data.message || '上传失败');
}
} catch (e) {
reject('解析响应失败');
}
},
fail: (err) => {
reject('上传失败:' + (err.errMsg || '网络错误'));
}
});
});
}