194 lines
6.2 KiB
JavaScript
194 lines
6.2 KiB
JavaScript
|
|
// <20><><EFBFBD>ݲɼ<DDB2><C9BC><EFBFBD><EFBFBD>ܽű<DCBD>
|
|||
|
|
|
|||
|
|
let currentUserId = null;
|
|||
|
|
|
|||
|
|
// DOMԪ<4D><D4AA>
|
|||
|
|
const loginSection = document.getElementById('loginSection');
|
|||
|
|
const basicQuestionnaire = document.getElementById('basicQuestionnaire');
|
|||
|
|
const mealRecord = document.getElementById('mealRecord');
|
|||
|
|
const messageArea = document.getElementById('messageArea');
|
|||
|
|
|
|||
|
|
const loginBtn = document.getElementById('loginBtn');
|
|||
|
|
const userIdInput = document.getElementById('userId');
|
|||
|
|
const userNameInput = document.getElementById('userName');
|
|||
|
|
|
|||
|
|
const submitBasicBtn = document.getElementById('submitBasicBtn');
|
|||
|
|
const submitMealBtn = document.getElementById('submitMealBtn');
|
|||
|
|
|
|||
|
|
// <20><>ʾ<EFBFBD><CABE>Ϣ
|
|||
|
|
function showMessage(message, type = 'info') {
|
|||
|
|
messageArea.textContent = message;
|
|||
|
|
messageArea.className = `message-area ${type}`;
|
|||
|
|
setTimeout(() => {
|
|||
|
|
messageArea.className = 'message-area';
|
|||
|
|
messageArea.style.display = 'none';
|
|||
|
|
}, 3000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20>û<EFBFBD><C3BB><EFBFBD>¼
|
|||
|
|
loginBtn.addEventListener('click', async () => {
|
|||
|
|
const userId = userIdInput.value.trim();
|
|||
|
|
const userName = userNameInput.value.trim();
|
|||
|
|
|
|||
|
|
if (!userId || !userName) {
|
|||
|
|
showMessage('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>', 'error');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
loginBtn.disabled = true;
|
|||
|
|
loginBtn.textContent = '<27><>¼<EFBFBD><C2BC>...';
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const response = await fetch('/api/user/register', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json; charset=utf-8'
|
|||
|
|
},
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
user_id: userId,
|
|||
|
|
name: userName
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const data = await response.json();
|
|||
|
|
|
|||
|
|
if (data.success) {
|
|||
|
|
currentUserId = userId;
|
|||
|
|
loginSection.style.display = 'none';
|
|||
|
|
basicQuestionnaire.style.display = 'block';
|
|||
|
|
mealRecord.style.display = 'block';
|
|||
|
|
showMessage('<27><>¼<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>', 'success');
|
|||
|
|
} else {
|
|||
|
|
showMessage(data.message || '<27><>¼ʧ<C2BC><CAA7>', 'error');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('<27><>¼ʧ<C2BC><CAA7>:', error);
|
|||
|
|
showMessage('<27><>¼ʧ<C2BC>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>', 'error');
|
|||
|
|
} finally {
|
|||
|
|
loginBtn.disabled = false;
|
|||
|
|
loginBtn.textContent = '<27><>¼/ע<><D7A2>';
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// <20>ύ<EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|||
|
|
submitBasicBtn.addEventListener('click', async () => {
|
|||
|
|
const age = document.getElementById('age').value;
|
|||
|
|
const gender = document.getElementById('gender').value;
|
|||
|
|
const height = document.getElementById('height').value;
|
|||
|
|
const weight = document.getElementById('weight').value;
|
|||
|
|
const activityLevel = document.getElementById('activityLevel').value;
|
|||
|
|
|
|||
|
|
if (!age || !gender || !height || !weight || !activityLevel) {
|
|||
|
|
showMessage('<27><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>Ϣ', 'error');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
submitBasicBtn.disabled = true;
|
|||
|
|
submitBasicBtn.textContent = '<27>ύ<EFBFBD><E1BDBB>...';
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const response = await fetch('/api/questionnaire/submit', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json; charset=utf-8'
|
|||
|
|
},
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
user_id: currentUserId,
|
|||
|
|
type: 'basic',
|
|||
|
|
answers: {
|
|||
|
|
age: parseInt(age),
|
|||
|
|
gender: gender,
|
|||
|
|
height: parseFloat(height),
|
|||
|
|
weight: parseFloat(weight),
|
|||
|
|
activity_level: activityLevel
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const data = await response.json();
|
|||
|
|
|
|||
|
|
if (data.success) {
|
|||
|
|
showMessage('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ύ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>', 'success');
|
|||
|
|
} else {
|
|||
|
|
showMessage(data.message || '<27>ύʧ<E1BDBB><CAA7>', 'error');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('<27>ύʧ<E1BDBB><CAA7>:', error);
|
|||
|
|
showMessage('<27>ύʧ<E1BDBB>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>', 'error');
|
|||
|
|
} finally {
|
|||
|
|
submitBasicBtn.disabled = false;
|
|||
|
|
submitBasicBtn.textContent = '<27>ύ<EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ';
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// <20><>¼<EFBFBD><C2BC>ʳ
|
|||
|
|
submitMealBtn.addEventListener('click', async () => {
|
|||
|
|
const mealDate = document.getElementById('mealDate').value || new Date().toISOString().split('T')[0];
|
|||
|
|
const mealType = document.getElementById('mealType').value;
|
|||
|
|
const foodsText = document.getElementById('foods').value;
|
|||
|
|
const calories = document.getElementById('calories').value;
|
|||
|
|
const satisfaction = document.getElementById('satisfaction').value;
|
|||
|
|
|
|||
|
|
if (!foodsText || !calories) {
|
|||
|
|
showMessage('<27><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD>ʳ<EFBFBD><CAB3>Ϣ', 'error');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ʳ<EFBFBD><CAB3><EFBFBD>б<EFBFBD>
|
|||
|
|
const foods = foodsText.split('\n').filter(line => line.trim());
|
|||
|
|
const quantities = foods.map(f => {
|
|||
|
|
const parts = f.trim().split(/\s+/);
|
|||
|
|
return parts.length > 1 ? parts.slice(1).join(' ') : '<27><><EFBFBD><EFBFBD>';
|
|||
|
|
});
|
|||
|
|
const foodNames = foods.map(f => f.trim().split(/\s+/)[0]);
|
|||
|
|
|
|||
|
|
submitMealBtn.disabled = true;
|
|||
|
|
submitMealBtn.textContent = '<27><>¼<EFBFBD><C2BC>...';
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const response = await fetch('/api/meal/record', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json; charset=utf-8'
|
|||
|
|
},
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
user_id: currentUserId,
|
|||
|
|
date: mealDate,
|
|||
|
|
meal_type: mealType,
|
|||
|
|
foods: foodNames,
|
|||
|
|
quantities: quantities,
|
|||
|
|
calories: parseFloat(calories),
|
|||
|
|
satisfaction_score: parseInt(satisfaction),
|
|||
|
|
notes: ''
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const data = await response.json();
|
|||
|
|
|
|||
|
|
if (data.success) {
|
|||
|
|
showMessage('<27><>ʳ<EFBFBD><CAB3>¼<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>', 'success');
|
|||
|
|
// <20><><EFBFBD>ձ<EFBFBD><D5B1><EFBFBD>
|
|||
|
|
document.getElementById('foods').value = '';
|
|||
|
|
document.getElementById('calories').value = '';
|
|||
|
|
document.getElementById('satisfaction').value = '3';
|
|||
|
|
} else {
|
|||
|
|
showMessage(data.message || '<27><>¼ʧ<C2BC><CAA7>', 'error');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('<27><>¼ʧ<C2BC><CAA7>:', error);
|
|||
|
|
showMessage('<27><>¼ʧ<C2BC>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>', 'error');
|
|||
|
|
} finally {
|
|||
|
|
submitMealBtn.disabled = false;
|
|||
|
|
submitMealBtn.textContent = '<27><>¼<EFBFBD><C2BC>ʳ';
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
|||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|||
|
|
const mealDateInput = document.getElementById('mealDate');
|
|||
|
|
if (mealDateInput) {
|
|||
|
|
mealDateInput.value = new Date().toISOString().split('T')[0];
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|