Files
aitsc/src/flask_prompt_master/templates/meal_planning_mobile.html
2025-09-09 08:00:07 +08:00

499 lines
17 KiB
HTML
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.
{% extends "base.html" %}
{% block title %}智能饭菜规划 - 提示词大师{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- 移动端优化的页面标题 -->
<div class="page-header-mobile">
<h1 class="page-title-mobile">
<i class="fas fa-utensils"></i>
智能饭菜规划
</h1>
<p class="page-subtitle-mobile">AI驱动的个性化饭菜清单规划师</p>
</div>
<!-- 移动端优化的表单区域 -->
<div class="mobile-form-container">
<div class="card mobile-card">
<div class="card-header mobile-card-header">
<h5 class="card-title-mobile">
<i class="fas fa-cog"></i>
规划参数
</h5>
</div>
<div class="card-body mobile-card-body">
<form id="mealPlanningFormMobile">
<!-- 地区类型 -->
<div class="form-group-mobile mb-3">
<label for="regionType" class="form-label-mobile">地区类型</label>
<select class="form-select-mobile" id="regionType" name="region_type">
<option value="全国">全国</option>
<option value="北方">北方</option>
<option value="南方">南方</option>
<option value="川菜">川菜</option>
<option value="粤菜">粤菜</option>
<option value="鲁菜">鲁菜</option>
<option value="苏菜">苏菜</option>
<option value="浙菜">浙菜</option>
<option value="闽菜">闽菜</option>
<option value="湘菜">湘菜</option>
<option value="徽菜">徽菜</option>
</select>
</div>
<!-- 就餐人数 -->
<div class="form-group-mobile mb-3">
<label for="dinerCount" class="form-label-mobile">就餐人数</label>
<select class="form-select-mobile" id="dinerCount" name="diner_count">
<option value="1">1人</option>
<option value="2" selected>2人</option>
<option value="3">3人</option>
<option value="4">4人</option>
<option value="5">5人</option>
<option value="6">6人</option>
<option value="8">8人</option>
<option value="10">10人</option>
</select>
</div>
<!-- 用餐类型 -->
<div class="form-group-mobile mb-3">
<label for="mealType" class="form-label-mobile">用餐类型</label>
<select class="form-select-mobile" id="mealType" name="meal_type">
<option value="早餐">早餐</option>
<option value="午餐" selected>午餐</option>
<option value="晚餐">晚餐</option>
<option value="全天">全天</option>
</select>
</div>
<!-- 用餐者家乡 -->
<div class="form-group-mobile mb-3">
<label for="hometown" class="form-label-mobile">用餐者家乡 <span class="text-danger">*</span></label>
<input type="text" class="form-control-mobile" id="hometown" name="hometown"
placeholder="如:四川成都" required>
</div>
<!-- 个人喜好 -->
<div class="form-group-mobile mb-3">
<label for="preferences" class="form-label-mobile">个人喜好</label>
<textarea class="form-control-mobile" id="preferences" name="preferences" rows="3"
placeholder="如:喜欢辣味、偏爱素食、喜欢海鲜等"></textarea>
</div>
<!-- 饮食禁忌 -->
<div class="form-group-mobile mb-3">
<label for="dietaryRestrictions" class="form-label-mobile">饮食禁忌</label>
<textarea class="form-control-mobile" id="dietaryRestrictions" name="dietary_restrictions" rows="3"
placeholder="如:不吃猪肉、对花生过敏、素食主义等"></textarea>
</div>
<!-- 预算范围 -->
<div class="form-group-mobile mb-3">
<label for="budget" class="form-label-mobile">预算范围(元)</label>
<select class="form-select-mobile" id="budget" name="budget">
<option value="50">50元以下</option>
<option value="100" selected>50-100元</option>
<option value="150">100-150元</option>
<option value="200">150-200元</option>
<option value="300">200-300元</option>
<option value="500">300-500元</option>
<option value="1000">500元以上</option>
</select>
</div>
<!-- 生成按钮 -->
<div class="d-grid">
<button type="submit" class="btn btn-primary-mobile btn-lg" id="generateBtnMobile">
<i class="fas fa-magic"></i>
生成饭菜规划
</button>
</div>
</form>
</div>
</div>
</div>
<!-- 移动端优化的结果展示区域 -->
<div class="mobile-result-container" id="resultContainerMobile" style="display: none;">
<div class="card mobile-card">
<div class="card-header mobile-card-header">
<h5 class="card-title-mobile">
<i class="fas fa-clipboard-list"></i>
饭菜规划结果
</h5>
<div class="card-actions-mobile">
<button class="btn btn-sm btn-outline-primary-mobile" id="copyBtnMobile">
<i class="fas fa-copy"></i>
复制
</button>
<button class="btn btn-sm btn-outline-success-mobile" id="saveBtnMobile">
<i class="fas fa-save"></i>
保存
</button>
</div>
</div>
<div class="card-body mobile-card-body">
<div class="meal-plan-content-mobile" id="mealPlanContentMobile">
<!-- 结果内容将在这里显示 -->
</div>
</div>
</div>
</div>
</div>
<!-- 移动端优化的加载动画 -->
<div class="modal fade" id="loadingModalMobile" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content mobile-modal-content">
<div class="modal-body text-center py-4">
<div class="spinner-border text-primary mb-3" role="status">
<span class="visually-hidden">生成中...</span>
</div>
<h5>正在生成饭菜规划...</h5>
<p class="text-muted">AI正在为您制定个性化的饭菜清单请稍候</p>
</div>
</div>
</div>
</div>
<style>
/* 移动端专用样式 */
@media (max-width: 768px) {
.page-header-mobile {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1.5rem 1rem;
margin: -1rem -1rem 1.5rem -1rem;
border-radius: 0 0 20px 20px;
}
.page-title-mobile {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 0.5rem;
text-align: center;
}
.page-subtitle-mobile {
font-size: 1rem;
opacity: 0.9;
margin-bottom: 0;
text-align: center;
}
.mobile-form-container {
margin-bottom: 1.5rem;
}
.mobile-card {
border: none;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
border-radius: 15px;
margin-bottom: 1rem;
}
.mobile-card-header {
background: #f8f9fa;
border-bottom: 1px solid #dee2e6;
border-radius: 15px 15px 0 0 !important;
padding: 1rem;
}
.card-title-mobile {
margin-bottom: 0;
font-weight: 600;
color: #495057;
font-size: 1.1rem;
}
.mobile-card-body {
padding: 1rem;
}
.form-group-mobile {
margin-bottom: 1rem;
}
.form-label-mobile {
font-weight: 600;
color: #495057;
margin-bottom: 0.5rem;
font-size: 0.95rem;
}
.form-control-mobile, .form-select-mobile {
border-radius: 10px;
border: 1px solid #ced4da;
padding: 0.75rem;
font-size: 1rem;
width: 100%;
}
.form-control-mobile:focus, .form-select-mobile:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
}
.btn-primary-mobile {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 10px;
padding: 1rem 1.5rem;
font-weight: 600;
font-size: 1.1rem;
width: 100%;
}
.btn-primary-mobile:hover {
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
}
.mobile-result-container {
margin-bottom: 2rem;
}
.card-actions-mobile {
display: flex;
gap: 0.5rem;
margin-top: 0.5rem;
}
.btn-outline-primary-mobile, .btn-outline-success-mobile {
border-radius: 8px;
padding: 0.5rem 1rem;
font-size: 0.9rem;
flex: 1;
}
.meal-plan-content-mobile {
background: #f8f9fa;
border-radius: 10px;
padding: 1rem;
border-left: 4px solid #667eea;
font-size: 0.95rem;
line-height: 1.6;
}
.meal-plan-content-mobile h1,
.meal-plan-content-mobile h2,
.meal-plan-content-mobile h3 {
color: #495057;
margin-top: 1rem;
margin-bottom: 0.5rem;
font-size: 1.1rem;
}
.meal-plan-content-mobile h1:first-child,
.meal-plan-content-mobile h2:first-child,
.meal-plan-content-mobile h3:first-child {
margin-top: 0;
}
.meal-plan-content-mobile ul,
.meal-plan-content-mobile ol {
padding-left: 1.2rem;
}
.meal-plan-content-mobile li {
margin-bottom: 0.3rem;
}
.meal-plan-content-mobile strong {
color: #667eea;
}
.mobile-modal-content {
border-radius: 15px;
border: none;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
/* 触摸优化 */
.btn, .form-control, .form-select {
min-height: 44px; /* iOS推荐的最小触摸目标 */
}
/* 防止双击缩放 */
input, select, textarea, button {
touch-action: manipulation;
}
}
/* 超小屏幕优化 */
@media (max-width: 480px) {
.page-title-mobile {
font-size: 1.5rem;
}
.mobile-card-body {
padding: 0.75rem;
}
.form-control-mobile, .form-select-mobile {
padding: 0.6rem;
font-size: 0.95rem;
}
.btn-primary-mobile {
padding: 0.8rem 1rem;
font-size: 1rem;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('mealPlanningFormMobile');
const generateBtn = document.getElementById('generateBtnMobile');
const resultContainer = document.getElementById('resultContainerMobile');
const copyBtn = document.getElementById('copyBtnMobile');
const saveBtn = document.getElementById('saveBtnMobile');
const loadingModal = new bootstrap.Modal(document.getElementById('loadingModalMobile'));
// 表单提交处理
form.addEventListener('submit', function(e) {
e.preventDefault();
// 验证必填字段
const hometown = document.getElementById('hometown').value.trim();
if (!hometown) {
showAlert('请输入用餐者家乡', 'danger');
return;
}
// 收集表单数据
const formData = new FormData(form);
const data = Object.fromEntries(formData.entries());
// 显示加载动画
loadingModal.show();
generateBtn.disabled = true;
// 发送请求
fetch('/api/meal-planning/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
loadingModal.hide();
generateBtn.disabled = false;
if (result.success) {
displayResult(result.data.meal_plan);
resultContainer.style.display = 'block';
showAlert('饭菜规划生成成功!', 'success');
// 滚动到结果区域
resultContainer.scrollIntoView({ behavior: 'smooth' });
} else {
showAlert(result.message || '生成失败,请重试', 'danger');
}
})
.catch(error => {
loadingModal.hide();
generateBtn.disabled = false;
console.error('Error:', error);
showAlert('网络错误,请检查网络连接后重试', 'danger');
});
});
// 显示结果
function displayResult(mealPlan) {
// 简单的Markdown转HTML函数
function simpleMarkdownToHtml(text) {
return text
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
.replace(/\*\*(.*)\*\*/gim, '<strong>$1</strong>')
.replace(/\*(.*)\*/gim, '<em>$1</em>')
.replace(/^\* (.*$)/gim, '<li>$1</li>')
.replace(/^\d+\. (.*$)/gim, '<li>$1</li>')
.replace(/\n\n/gim, '</p><p>')
.replace(/\n/gim, '<br>')
.replace(/^(.*)$/gim, '<p>$1</p>');
}
document.getElementById('mealPlanContentMobile').innerHTML = simpleMarkdownToHtml(mealPlan);
}
// 复制功能
copyBtn.addEventListener('click', function() {
const content = document.getElementById('mealPlanContentMobile').textContent;
navigator.clipboard.writeText(content).then(() => {
showAlert('饭菜规划已复制到剪贴板', 'success');
}).catch(() => {
showAlert('复制失败,请手动复制', 'danger');
});
});
// 保存功能
saveBtn.addEventListener('click', function() {
const content = document.getElementById('mealPlanContentMobile').textContent;
// 获取当前表单参数
const formData = {
meal_plan_content: content,
region_type: document.getElementById('regionType').value,
diner_count: document.getElementById('dinerCount').value,
meal_type: document.getElementById('mealType').value,
hometown: document.getElementById('hometown').value,
preferences: document.getElementById('preferences').value,
dietary_restrictions: document.getElementById('dietaryRestrictions').value,
budget: document.getElementById('budget').value
};
fetch('/api/meal-planning/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(result => {
if (result.success) {
showAlert('饭菜规划保存成功!', 'success');
console.log('保存成功规划ID:', result.data.meal_plan_id);
} else {
showAlert(result.message || '保存失败', 'danger');
}
})
.catch(error => {
console.error('Error:', error);
showAlert('保存失败,请重试', 'danger');
});
});
// 显示提示信息
function showAlert(message, type) {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
// 插入到页面顶部
const container = document.querySelector('.container-fluid');
container.insertBefore(alertDiv, container.firstChild);
// 自动消失
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}
});
</script>
{% endblock %}