chore: update code 周一-2025-11 17:11
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
// 分析功能脚本
|
// 营养分析功能脚本
|
||||||
|
|
||||||
let currentUserId = null;
|
let currentUserId = null;
|
||||||
|
|
||||||
// DOM元素
|
// DOM元素
|
||||||
const loginSection = document.getElementById('loginSection');
|
const loginSection = document.getElementById('loginSection');
|
||||||
const requestSection = document.getElementById('requestSection');
|
const requestSection = document.getElementById('requestSection');
|
||||||
const analysisSection = document.getElementById('analysisSection');
|
const analysisSection = document.getElementById('analysisSection');
|
||||||
@@ -14,27 +14,28 @@ const analyzeBtn = document.getElementById('analyzeBtn');
|
|||||||
const mealDataTextarea = document.getElementById('mealData');
|
const mealDataTextarea = document.getElementById('mealData');
|
||||||
const analysisResult = document.getElementById('analysisResult');
|
const analysisResult = document.getElementById('analysisResult');
|
||||||
|
|
||||||
// 显示消息
|
// 显示消息
|
||||||
function showMessage(message, type = 'info') {
|
function showMessage(message, type = 'info') {
|
||||||
messageArea.textContent = message;
|
messageArea.textContent = message;
|
||||||
messageArea.className = `message-area ${type}`;
|
messageArea.className = `message-area ${type}`;
|
||||||
|
messageArea.style.display = 'block';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
messageArea.className = 'message-area';
|
messageArea.className = 'message-area';
|
||||||
messageArea.style.display = 'none';
|
messageArea.style.display = 'none';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户登录
|
// 用户登录
|
||||||
loginBtn.addEventListener('click', async () => {
|
loginBtn.addEventListener('click', async () => {
|
||||||
const userId = userIdInput.value.trim();
|
const userId = userIdInput.value.trim();
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
showMessage('请输入用户ID', 'error');
|
showMessage('请输入用户ID', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginBtn.disabled = true;
|
loginBtn.disabled = true;
|
||||||
loginBtn.textContent = '登录中...';
|
loginBtn.textContent = '登录中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/user/login', {
|
const response = await fetch('/api/user/login', {
|
||||||
@@ -53,30 +54,30 @@ loginBtn.addEventListener('click', async () => {
|
|||||||
currentUserId = userId;
|
currentUserId = userId;
|
||||||
loginSection.style.display = 'none';
|
loginSection.style.display = 'none';
|
||||||
requestSection.style.display = 'block';
|
requestSection.style.display = 'block';
|
||||||
showMessage(`欢迎,${data.name || userId}!`, 'success');
|
showMessage(`欢迎,${data.name || userId}!`, 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '登录失败', 'error');
|
showMessage(data.message || '登录失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('登录失败:', error);
|
console.error('登录失败:', error);
|
||||||
showMessage('登录失败,请检查网络连接', 'error');
|
showMessage('登录失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
loginBtn.disabled = false;
|
loginBtn.disabled = false;
|
||||||
loginBtn.textContent = '登录';
|
loginBtn.textContent = '登录';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 开始分析
|
// 开始分析
|
||||||
analyzeBtn.addEventListener('click', async () => {
|
analyzeBtn.addEventListener('click', async () => {
|
||||||
const mealDataText = mealDataTextarea.value.trim();
|
const mealDataText = mealDataTextarea.value.trim();
|
||||||
|
|
||||||
if (!mealDataText) {
|
if (!mealDataText) {
|
||||||
showMessage('请输入餐食信息', 'error');
|
showMessage('请输入餐食信息', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzeBtn.disabled = true;
|
analyzeBtn.disabled = true;
|
||||||
analyzeBtn.textContent = '分析中...';
|
analyzeBtn.textContent = '分析中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/analysis/nutrition', {
|
const response = await fetch('/api/analysis/nutrition', {
|
||||||
@@ -97,37 +98,47 @@ analyzeBtn.addEventListener('click', async () => {
|
|||||||
if (data.success && data.analysis) {
|
if (data.success && data.analysis) {
|
||||||
displayAnalysis(data.analysis);
|
displayAnalysis(data.analysis);
|
||||||
analysisSection.style.display = 'block';
|
analysisSection.style.display = 'block';
|
||||||
showMessage('分析完成!', 'success');
|
showMessage('分析完成!', 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '分析失败', 'error');
|
showMessage(data.message || '分析失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('分析失败:', error);
|
console.error('分析失败:', error);
|
||||||
showMessage('分析失败,请检查网络连接', 'error');
|
showMessage('分析失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
analyzeBtn.disabled = false;
|
analyzeBtn.disabled = false;
|
||||||
analyzeBtn.textContent = '开始分析';
|
analyzeBtn.textContent = '开始分析';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 显示分析结果
|
// 显示分析结果
|
||||||
function displayAnalysis(analysis) {
|
function displayAnalysis(analysis) {
|
||||||
analysisResult.innerHTML = '';
|
analysisResult.innerHTML = '';
|
||||||
|
|
||||||
if (typeof analysis === 'string') {
|
if (typeof analysis === 'string') {
|
||||||
// 如果是字符串,直接显示
|
// 如果是字符串,直接显示
|
||||||
analysisResult.innerHTML = `<div class="analysis-section"><p>${analysis.replace(/\n/g, '<br>')}</p></div>`;
|
analysisResult.innerHTML = `<div class="analysis-section"><p>${escapeHtml(analysis).replace(/\n/g, '<br>')}</p></div>`;
|
||||||
} else if (analysis.analysis) {
|
} else if (analysis.analysis) {
|
||||||
// 如果包含analysis字段
|
// 如果有analysis字段
|
||||||
analysisResult.innerHTML = `<div class="analysis-section"><h4>分析结果</h4><p>${analysis.analysis.replace(/\n/g, '<br>')}</p></div>`;
|
analysisResult.innerHTML = `<div class="analysis-section"><h4>营养分析</h4><p>${escapeHtml(analysis.analysis).replace(/\n/g, '<br>')}</p></div>`;
|
||||||
} else {
|
} else {
|
||||||
// 如果是对象,格式化显示
|
// 如果是对象,格式化显示
|
||||||
for (const [key, value] of Object.entries(analysis)) {
|
for (const [key, value] of Object.entries(analysis)) {
|
||||||
const section = document.createElement('div');
|
const section = document.createElement('div');
|
||||||
section.className = 'analysis-section';
|
section.className = 'analysis-section';
|
||||||
section.innerHTML = `<h4>${key}</h4><p>${typeof value === 'string' ? value.replace(/\n/g, '<br>') : JSON.stringify(value, null, 2)}</p>`;
|
const displayKey = escapeHtml(key);
|
||||||
|
const displayValue = typeof value === 'string'
|
||||||
|
? escapeHtml(value).replace(/\n/g, '<br>')
|
||||||
|
: escapeHtml(JSON.stringify(value, null, 2));
|
||||||
|
section.innerHTML = `<h4>${displayKey}</h4><p>${displayValue}</p>`;
|
||||||
analysisResult.appendChild(section);
|
analysisResult.appendChild(section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTML转义函数,防止XSS攻击
|
||||||
|
function escapeHtml(text) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.textContent = text;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// 数据采集功能脚本
|
// 数据采集功能脚本
|
||||||
|
|
||||||
let currentUserId = null;
|
let currentUserId = null;
|
||||||
|
|
||||||
// DOM元素
|
// DOM元素
|
||||||
const loginSection = document.getElementById('loginSection');
|
const loginSection = document.getElementById('loginSection');
|
||||||
const basicQuestionnaire = document.getElementById('basicQuestionnaire');
|
const basicQuestionnaire = document.getElementById('basicQuestionnaire');
|
||||||
const mealRecord = document.getElementById('mealRecord');
|
const mealRecord = document.getElementById('mealRecord');
|
||||||
@@ -15,28 +15,29 @@ const userNameInput = document.getElementById('userName');
|
|||||||
const submitBasicBtn = document.getElementById('submitBasicBtn');
|
const submitBasicBtn = document.getElementById('submitBasicBtn');
|
||||||
const submitMealBtn = document.getElementById('submitMealBtn');
|
const submitMealBtn = document.getElementById('submitMealBtn');
|
||||||
|
|
||||||
// 显示消息
|
// 显示消息
|
||||||
function showMessage(message, type = 'info') {
|
function showMessage(message, type = 'info') {
|
||||||
messageArea.textContent = message;
|
messageArea.textContent = message;
|
||||||
messageArea.className = `message-area ${type}`;
|
messageArea.className = `message-area ${type}`;
|
||||||
|
messageArea.style.display = 'block';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
messageArea.className = 'message-area';
|
messageArea.className = 'message-area';
|
||||||
messageArea.style.display = 'none';
|
messageArea.style.display = 'none';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户登录
|
// 用户登录/注册
|
||||||
loginBtn.addEventListener('click', async () => {
|
loginBtn.addEventListener('click', async () => {
|
||||||
const userId = userIdInput.value.trim();
|
const userId = userIdInput.value.trim();
|
||||||
const userName = userNameInput.value.trim();
|
const userName = userNameInput.value.trim();
|
||||||
|
|
||||||
if (!userId || !userName) {
|
if (!userId || !userName) {
|
||||||
showMessage('请输入用户ID和姓名', 'error');
|
showMessage('请输入用户ID和姓名', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginBtn.disabled = true;
|
loginBtn.disabled = true;
|
||||||
loginBtn.textContent = '登录中...';
|
loginBtn.textContent = '登录中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/user/register', {
|
const response = await fetch('/api/user/register', {
|
||||||
@@ -57,20 +58,20 @@ loginBtn.addEventListener('click', async () => {
|
|||||||
loginSection.style.display = 'none';
|
loginSection.style.display = 'none';
|
||||||
basicQuestionnaire.style.display = 'block';
|
basicQuestionnaire.style.display = 'block';
|
||||||
mealRecord.style.display = 'block';
|
mealRecord.style.display = 'block';
|
||||||
showMessage('登录成功!', 'success');
|
showMessage('注册成功!', 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '登录失败', 'error');
|
showMessage(data.message || '注册失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('登录失败:', error);
|
console.error('注册失败:', error);
|
||||||
showMessage('登录失败,请检查网络连接', 'error');
|
showMessage('注册失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
loginBtn.disabled = false;
|
loginBtn.disabled = false;
|
||||||
loginBtn.textContent = '登录/注册';
|
loginBtn.textContent = '登录/注册';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交基础信息
|
// 提交基础信息
|
||||||
submitBasicBtn.addEventListener('click', async () => {
|
submitBasicBtn.addEventListener('click', async () => {
|
||||||
const age = document.getElementById('age').value;
|
const age = document.getElementById('age').value;
|
||||||
const gender = document.getElementById('gender').value;
|
const gender = document.getElementById('gender').value;
|
||||||
@@ -79,12 +80,12 @@ submitBasicBtn.addEventListener('click', async () => {
|
|||||||
const activityLevel = document.getElementById('activityLevel').value;
|
const activityLevel = document.getElementById('activityLevel').value;
|
||||||
|
|
||||||
if (!age || !gender || !height || !weight || !activityLevel) {
|
if (!age || !gender || !height || !weight || !activityLevel) {
|
||||||
showMessage('请填写完整的基础信息', 'error');
|
showMessage('请填写完整的基础信息', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
submitBasicBtn.disabled = true;
|
submitBasicBtn.disabled = true;
|
||||||
submitBasicBtn.textContent = '提交中...';
|
submitBasicBtn.textContent = '提交中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/questionnaire/submit', {
|
const response = await fetch('/api/questionnaire/submit', {
|
||||||
@@ -108,20 +109,20 @@ submitBasicBtn.addEventListener('click', async () => {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
showMessage('基础信息提交成功!', 'success');
|
showMessage('基础信息提交成功!', 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '提交失败', 'error');
|
showMessage(data.message || '提交失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交失败:', error);
|
console.error('提交失败:', error);
|
||||||
showMessage('提交失败,请检查网络连接', 'error');
|
showMessage('提交失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
submitBasicBtn.disabled = false;
|
submitBasicBtn.disabled = false;
|
||||||
submitBasicBtn.textContent = '提交基础信息';
|
submitBasicBtn.textContent = '提交基础信息';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 记录餐食
|
// 记录餐食
|
||||||
submitMealBtn.addEventListener('click', async () => {
|
submitMealBtn.addEventListener('click', async () => {
|
||||||
const mealDate = document.getElementById('mealDate').value || new Date().toISOString().split('T')[0];
|
const mealDate = document.getElementById('mealDate').value || new Date().toISOString().split('T')[0];
|
||||||
const mealType = document.getElementById('mealType').value;
|
const mealType = document.getElementById('mealType').value;
|
||||||
@@ -130,20 +131,20 @@ submitMealBtn.addEventListener('click', async () => {
|
|||||||
const satisfaction = document.getElementById('satisfaction').value;
|
const satisfaction = document.getElementById('satisfaction').value;
|
||||||
|
|
||||||
if (!foodsText || !calories) {
|
if (!foodsText || !calories) {
|
||||||
showMessage('请填写完整的餐食信息', 'error');
|
showMessage('请填写完整的餐食信息', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析食物列表
|
// 解析食物列表
|
||||||
const foods = foodsText.split('\n').filter(line => line.trim());
|
const foods = foodsText.split('\n').filter(line => line.trim());
|
||||||
const quantities = foods.map(f => {
|
const quantities = foods.map(f => {
|
||||||
const parts = f.trim().split(/\s+/);
|
const parts = f.trim().split(/\s+/);
|
||||||
return parts.length > 1 ? parts.slice(1).join(' ') : '适量';
|
return parts.length > 1 ? parts.slice(1).join(' ') : '适量';
|
||||||
});
|
});
|
||||||
const foodNames = foods.map(f => f.trim().split(/\s+/)[0]);
|
const foodNames = foods.map(f => f.trim().split(/\s+/)[0]);
|
||||||
|
|
||||||
submitMealBtn.disabled = true;
|
submitMealBtn.disabled = true;
|
||||||
submitMealBtn.textContent = '记录中...';
|
submitMealBtn.textContent = '记录中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/meal/record', {
|
const response = await fetch('/api/meal/record', {
|
||||||
@@ -166,28 +167,27 @@ submitMealBtn.addEventListener('click', async () => {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
showMessage('餐食记录成功!', 'success');
|
showMessage('餐食记录成功!', 'success');
|
||||||
// 清空表单
|
// 清空表单
|
||||||
document.getElementById('foods').value = '';
|
document.getElementById('foods').value = '';
|
||||||
document.getElementById('calories').value = '';
|
document.getElementById('calories').value = '';
|
||||||
document.getElementById('satisfaction').value = '3';
|
document.getElementById('satisfaction').value = '3';
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '记录失败', 'error');
|
showMessage(data.message || '记录失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('记录失败:', error);
|
console.error('记录失败:', error);
|
||||||
showMessage('记录失败,请检查网络连接', 'error');
|
showMessage('记录失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
submitMealBtn.disabled = false;
|
submitMealBtn.disabled = false;
|
||||||
submitMealBtn.textContent = '记录餐食';
|
submitMealBtn.textContent = '记录餐食';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置默认日期为今天
|
// 设置默认日期为今天
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const mealDateInput = document.getElementById('mealDate');
|
const mealDateInput = document.getElementById('mealDate');
|
||||||
if (mealDateInput) {
|
if (mealDateInput) {
|
||||||
mealDateInput.value = new Date().toISOString().split('T')[0];
|
mealDateInput.value = new Date().toISOString().split('T')[0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// 推荐功能脚本
|
// 推荐功能脚本
|
||||||
|
|
||||||
let currentUserId = null;
|
let currentUserId = null;
|
||||||
|
|
||||||
// DOM元素
|
// DOM元素
|
||||||
const loginSection = document.getElementById('loginSection');
|
const loginSection = document.getElementById('loginSection');
|
||||||
const requestSection = document.getElementById('requestSection');
|
const requestSection = document.getElementById('requestSection');
|
||||||
const recommendationsSection = document.getElementById('recommendationsSection');
|
const recommendationsSection = document.getElementById('recommendationsSection');
|
||||||
@@ -14,27 +14,28 @@ const getRecommendationBtn = document.getElementById('getRecommendationBtn');
|
|||||||
const mealTypeSelect = document.getElementById('mealType');
|
const mealTypeSelect = document.getElementById('mealType');
|
||||||
const recommendationsList = document.getElementById('recommendationsList');
|
const recommendationsList = document.getElementById('recommendationsList');
|
||||||
|
|
||||||
// 显示消息
|
// 显示消息
|
||||||
function showMessage(message, type = 'info') {
|
function showMessage(message, type = 'info') {
|
||||||
messageArea.textContent = message;
|
messageArea.textContent = message;
|
||||||
messageArea.className = `message-area ${type}`;
|
messageArea.className = `message-area ${type}`;
|
||||||
|
messageArea.style.display = 'block';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
messageArea.className = 'message-area';
|
messageArea.className = 'message-area';
|
||||||
messageArea.style.display = 'none';
|
messageArea.style.display = 'none';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户登录
|
// 用户登录
|
||||||
loginBtn.addEventListener('click', async () => {
|
loginBtn.addEventListener('click', async () => {
|
||||||
const userId = userIdInput.value.trim();
|
const userId = userIdInput.value.trim();
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
showMessage('请输入用户ID', 'error');
|
showMessage('请输入用户ID', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginBtn.disabled = true;
|
loginBtn.disabled = true;
|
||||||
loginBtn.textContent = '登录中...';
|
loginBtn.textContent = '登录中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/user/login', {
|
const response = await fetch('/api/user/login', {
|
||||||
@@ -53,25 +54,25 @@ loginBtn.addEventListener('click', async () => {
|
|||||||
currentUserId = userId;
|
currentUserId = userId;
|
||||||
loginSection.style.display = 'none';
|
loginSection.style.display = 'none';
|
||||||
requestSection.style.display = 'block';
|
requestSection.style.display = 'block';
|
||||||
showMessage(`欢迎,${data.name || userId}!`, 'success');
|
showMessage(`欢迎,${data.name || userId}!`, 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '登录失败', 'error');
|
showMessage(data.message || '登录失败', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('登录失败:', error);
|
console.error('登录失败:', error);
|
||||||
showMessage('登录失败,请检查网络连接', 'error');
|
showMessage('登录失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
loginBtn.disabled = false;
|
loginBtn.disabled = false;
|
||||||
loginBtn.textContent = '登录';
|
loginBtn.textContent = '登录';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取推荐
|
// 获取推荐
|
||||||
getRecommendationBtn.addEventListener('click', async () => {
|
getRecommendationBtn.addEventListener('click', async () => {
|
||||||
const mealType = mealTypeSelect.value;
|
const mealType = mealTypeSelect.value;
|
||||||
|
|
||||||
getRecommendationBtn.disabled = true;
|
getRecommendationBtn.disabled = true;
|
||||||
getRecommendationBtn.textContent = '获取中...';
|
getRecommendationBtn.textContent = '获取中...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/recommendation/get', {
|
const response = await fetch('/api/recommendation/get', {
|
||||||
@@ -92,20 +93,20 @@ getRecommendationBtn.addEventListener('click', async () => {
|
|||||||
if (data.success && data.recommendations && data.recommendations.length > 0) {
|
if (data.success && data.recommendations && data.recommendations.length > 0) {
|
||||||
displayRecommendations(data.recommendations);
|
displayRecommendations(data.recommendations);
|
||||||
recommendationsSection.style.display = 'block';
|
recommendationsSection.style.display = 'block';
|
||||||
showMessage('推荐获取成功!', 'success');
|
showMessage('推荐获取成功!', 'success');
|
||||||
} else {
|
} else {
|
||||||
showMessage(data.message || '暂无推荐,请先完善个人数据', 'info');
|
showMessage(data.message || '暂无推荐内容,请先完善个人数据', 'info');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取推荐失败:', error);
|
console.error('获取推荐失败:', error);
|
||||||
showMessage('获取推荐失败,请检查网络连接', 'error');
|
showMessage('获取推荐失败,请检查网络连接', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
getRecommendationBtn.disabled = false;
|
getRecommendationBtn.disabled = false;
|
||||||
getRecommendationBtn.textContent = '获取推荐';
|
getRecommendationBtn.textContent = '获取推荐';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 显示推荐结果
|
// 显示推荐结果
|
||||||
function displayRecommendations(recommendations) {
|
function displayRecommendations(recommendations) {
|
||||||
recommendationsList.innerHTML = '';
|
recommendationsList.innerHTML = '';
|
||||||
|
|
||||||
@@ -120,16 +121,34 @@ function displayRecommendations(recommendations) {
|
|||||||
foods = [rec.food];
|
foods = [rec.food];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const foodsHtml = foods.map(food =>
|
||||||
|
`<div class="food-item">${escapeHtml(food)}</div>`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
const confidenceHtml = rec.confidence
|
||||||
|
? `<div class="confidence">置信度: ${(rec.confidence * 100).toFixed(1)}%</div>`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
const reasonHtml = rec.reason
|
||||||
|
? `<div style="margin-top: 10px; color: #666;">推荐理由: ${escapeHtml(rec.reason)}</div>`
|
||||||
|
: '';
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<h3>推荐方案 ${index + 1}</h3>
|
<h3>推荐方案 ${index + 1}</h3>
|
||||||
<div class="food-list">
|
<div class="food-list">
|
||||||
${foods.map(food => `<div class="food-item">${food}</div>`).join('')}
|
${foodsHtml}
|
||||||
</div>
|
</div>
|
||||||
${rec.confidence ? `<div class="confidence">置信度: ${(rec.confidence * 100).toFixed(1)}%</div>` : ''}
|
${confidenceHtml}
|
||||||
${rec.reason ? `<div style="margin-top: 10px; color: #666;">推荐理由: ${rec.reason}</div>` : ''}
|
${reasonHtml}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
recommendationsList.appendChild(card);
|
recommendationsList.appendChild(card);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTML转义函数,防止XSS攻击
|
||||||
|
function escapeHtml(text) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.textContent = text;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,47 +3,47 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Ӫ - ԻʳƼ</title>
|
<title>营养分析 - 个性化饮食推荐助手</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/analysis.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/analysis.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<h1>? Ӫ</h1>
|
<h1>🍎 营养分析</h1>
|
||||||
<p class="subtitle">AIӪ뽨</p>
|
<p class="subtitle">AI智能营养分析</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<a href="/" class="nav-item">ҳ</a>
|
<a href="/" class="nav-item">首页</a>
|
||||||
<a href="/data-collection" class="nav-item">ݲɼ</a>
|
<a href="/data-collection" class="nav-item">数据采集</a>
|
||||||
<a href="/recommendation" class="nav-item">Ƽ</a>
|
<a href="/recommendation" class="nav-item">智能推荐</a>
|
||||||
<a href="/analysis" class="nav-item active">Ӫ</a>
|
<a href="/analysis" class="nav-item active">营养分析</a>
|
||||||
<a href="/recitation" class="nav-item"></a>
|
<a href="/recitation" class="nav-item">背诵排序</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div class="analysis-container">
|
<div class="analysis-container">
|
||||||
<div id="loginSection" class="section">
|
<div id="loginSection" class="section">
|
||||||
<h2>û¼</h2>
|
<h2>用户登录</h2>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="userId">ûID</label>
|
<label for="userId">用户ID:</label>
|
||||||
<input type="text" id="userId" class="form-input" placeholder="ûID">
|
<input type="text" id="userId" class="form-input" placeholder="请输入用户ID">
|
||||||
</div>
|
</div>
|
||||||
<button id="loginBtn" class="btn btn-primary">¼</button>
|
<button id="loginBtn" class="btn btn-primary">登录</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="requestSection" class="section" style="display: none;">
|
<div id="requestSection" class="section" style="display: none;">
|
||||||
<h2>Ӫ</h2>
|
<h2>营养分析</h2>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>ʳϢ</label>
|
<label>餐食信息:</label>
|
||||||
<textarea id="mealData" class="form-textarea" rows="5" placeholder="ʳϢ磺 ͣࡢ㽶ţ 350"></textarea>
|
<textarea id="mealData" class="form-textarea" rows="5" placeholder="请输入餐食信息: 例如:燕麦粥、香蕉、牛奶 热量:350大卡"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button id="analyzeBtn" class="btn btn-primary">ʼ</button>
|
<button id="analyzeBtn" class="btn btn-primary">开始分析</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="analysisSection" class="section" style="display: none;">
|
<div id="analysisSection" class="section" style="display: none;">
|
||||||
<h2></h2>
|
<h2>分析结果</h2>
|
||||||
<div id="analysisResult" class="analysis-result"></div>
|
<div id="analysisResult" class="analysis-result"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<p>© 2024 ԻʳƼ</p>
|
<p>© 2024 个性化饮食推荐助手</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user