feat: 味养创新交互完善——人工创新详情/审核双模/AI推演弹窗重构及侧边栏修复

- din-innovation.html
  - 发起AI模拟推演弹窗对齐新建人工创新表单结构,新增 AI模型 下拉字段
  - 人工创新列表新增「餐品构成」列(位于餐品分类之后)
  - AI创新列表移除参与人员/烹饪方法/适用餐次列,「实验开始日期」改为「推演开始时间」
  - 人工审核弹窗重构为双模式:编辑模式(单选框审核结论,去掉审核人)+ 只读模式(含审核人/审核时间,查看审核入口)
  - 新增人工创新查看详情弹窗:基本信息卡片 + 餐品构成表 + 四维评测标签页(营养/味道/口感/色泽)
- din-dish-add.html
  - 修复 AI创新转化餐品时侧边栏高亮错误(convert模式侧边栏修复与 INNOV_MAP 查找解耦)
- doc/营养管理功能说明.md
  - 新增 9.5 味养创新调整记录

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 17:58:55 +08:00
co-authored by Claude Sonnet 4.6
parent ee0b8fbf63
commit 6b10e3e45f
3 changed files with 946 additions and 50 deletions
+158 -14
View File
@@ -144,6 +144,18 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.dynamic-row__del:hover{color:var(--danger);background:#FFF1F0;}
.dynamic-row-add{display:inline-flex;align-items:center;gap:4px;padding:6px 12px;border:1px dashed var(--primary);color:var(--primary);border-radius:var(--radius-sm);font-size:var(--font-xs);cursor:pointer;background:none;margin-top:8px;transition:all .2s;}
.dynamic-row-add:hover{background:var(--primary-light);}
.convert-banner{background:#fffbe6;border:1px solid #ffe58f;border-radius:8px;padding:14px 20px;margin-bottom:16px;display:flex;gap:32px;align-items:flex-start;flex-wrap:wrap;}
.convert-banner__item{display:flex;flex-direction:column;gap:2px;}
.convert-banner__label{font-size:12px;color:#8c8c8c;}
.convert-banner__value{font-size:13px;color:#333;font-weight:500;}
.convert-banner__tag{display:inline-block;background:#fff7e6;border:1px solid #ffd591;color:#d46b08;border-radius:4px;padding:1px 8px;font-size:12px;}
.step-readonly .form-input,.step-readonly .form-select,.step-readonly textarea{background:#f5f5f5 !important;color:#666 !important;cursor:not-allowed !important;pointer-events:none;}
.step-readonly .btn,.step-readonly .dynamic-row__del,.step-readonly .dynamic-row-add,.step-readonly .spec-add-row{display:none !important;}
.step-readonly .ingredient-table td a.link{color:#bbb !important;cursor:not-allowed !important;pointer-events:none !important;}
.step-readonly .btn-text{color:#bbb !important;cursor:not-allowed !important;pointer-events:none !important;}
.step-readonly-tip{font-size:12px;color:#d46b08;background:#fff7e6;border:1px solid #ffd591;border-radius:4px;padding:4px 10px;margin-bottom:12px;display:inline-block;}
</style>
</head>
<body>
@@ -217,6 +229,14 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
<span id="pageTitle">新增餐品</span>
</div>
<!-- 转化来源信息块(mode=convert 时显示) -->
<div class="convert-banner" id="convertBanner" style="display:none;">
<div class="convert-banner__item"><span class="convert-banner__label">实验编号</span><span class="convert-banner__value" id="cvtExpNo"></span></div>
<div class="convert-banner__item" style="flex:1"><span class="convert-banner__label">创新目标</span><span class="convert-banner__value" id="cvtGoal"></span></div>
<div class="convert-banner__item"><span class="convert-banner__label">参与人员</span><span class="convert-banner__value" id="cvtMembers"></span></div>
<div class="convert-banner__item"><span class="convert-banner__label">来源</span><span class="convert-banner__value"><span class="convert-banner__tag">味养创新</span></span></div>
</div>
<!-- 步骤条 -->
<div class="steps">
<div class="step active" onclick="switchTab(0)"><span class="step__num">1</span><span class="step__label">基本档案</span></div>
@@ -254,12 +274,12 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
<div class="search-select__dropdown" id="ingredientDropdown"></div>
</div>
</div>
<div class="form-row"><div class="form-group"><label>用量(g/份)<span class="required">*</span></label><input class="form-input" type="number" placeholder="请输入用量"></div><div class="form-group"><label>是否主料</label><select class="form-select"><option>辅料</option><option>主料</option></select></div></div>
<div class="form-row"><div class="form-group"><label>过敏原</label><input class="form-input" type="text" placeholder="无则填无"></div><div class="form-group"><label>备注</label><input class="form-input" type="text" placeholder="请输入备注信息"></div></div>
<div class="form-row"><div class="form-group"><label>用量(g/份)<span class="required">*</span></label><input class="form-input" type="number" id="ingredientAmount" placeholder="请输入用量"></div><div class="form-group"><label>是否主料</label><select class="form-select" id="ingredientIsMain"><option>辅料</option><option>主料</option></select></div></div>
<div class="form-row"><div class="form-group"><label>过敏原</label><input class="form-input" type="text" id="ingredientAllergen" placeholder="无则填无"></div><div class="form-group"><label>备注</label><input class="form-input" type="text" id="ingredientNote" placeholder="请输入备注信息"></div></div>
</div>
<div class="dialog__footer">
<button class="btn btn-default" onclick="closeIngredientDialog()">取消</button>
<button class="btn btn-primary">确定</button>
<button class="btn btn-primary" onclick="confirmAddIngredient()">确定</button>
</div>
</div>
</div>
@@ -271,6 +291,45 @@ function closeIngredientDialog(){document.getElementById('ingredientDialog').cla
var urlParams = new URLSearchParams(window.location.search);
var pageMode = urlParams.get('mode') || 'add';
/* ===== 味养创新转化数据 ===== */
var INNOV_MAP = {
'INN-H002': {
expNo:'INN-H002', goal:'添加燕麦、藜麦,膳食纤维提升3倍', members:'厨师长陈磊 / 营养师王芳',
name:'高纤维主食包', category:'主食', meal:'早/午', pyramid:'谷薯杂豆', allergen:'无', tag:'高纤维',
composition:[
{name:'燕麦',cat:'谷薯类',amount:80,pct:'40%',main:true,allergen:'无',note:'提升纤维'},
{name:'藜麦',cat:'谷薯类',amount:60,pct:'30%',main:true,allergen:'无',note:'低GI'},
{name:'大米',cat:'谷薯类/稻米',amount:60,pct:'30%',main:false,allergen:'无',note:'基底'}
],
cook:{mainMethod:'蒸',subMethod:'无',heat:'大火→中火',duration:30,oil:0,salt:3,temp:100,output:200,steps:4,desc:''},
nutri:{calorie:342,protein:12.8,carb:58.4,fat:5.2,vitC:0,mineral:38,fiber:9.6,sodium:210},
nutriGrade:'达标',
taste:{sour:1,sweet:2,bitter:1,spicy:1,salty:2,smell:3.8,flavorScore:3.6,flavorGrade:'good'},
texture:{hardness:3,sticky:3,crispy:1,smooth:3,elastic:2,textureScore:3.2,textureGrade:'average'},
color:{mainColor:'米黄色',uniformity:4,gloss:3,freshness:4,appearance:3,colorScore:3.5,colorGrade:'good'}
},
'INN-H004': {
expNo:'INN-H004', goal:'搭配维C食材,补铁效率提升2倍', members:'厨师长赵敏 / 营养师李明',
name:'富铁青菜汤', category:'汤品', meal:'午/晚', pyramid:'蔬菜', allergen:'大豆', tag:'高铁',
composition:[
{name:'菠菜',cat:'蔬菜类',amount:120,pct:'40%',main:true,allergen:'无',note:'高铁来源'},
{name:'豆腐',cat:'豆制品',amount:80,pct:'27%',main:true,allergen:'大豆',note:'补充蛋白'},
{name:'胡萝卜',cat:'蔬菜类',amount:40,pct:'13%',main:false,allergen:'无',note:'维C协同'},
{name:'食用油',cat:'油脂类',amount:5,pct:'2%',main:false,allergen:'无',note:'少量'}
],
cook:{mainMethod:'煮',subMethod:'无',heat:'大火→小火',duration:15,oil:5,salt:2,temp:100,output:300,steps:3,desc:''},
nutri:{calorie:68,protein:5.4,carb:6.2,fat:2.8,vitC:32,mineral:86,fiber:2.4,sodium:320},
nutriGrade:'达标',
taste:{sour:1,sweet:1,bitter:1,spicy:1,salty:3,smell:3.5,flavorScore:3.4,flavorGrade:'average'},
texture:{hardness:2,sticky:1,crispy:1,smooth:4,elastic:2,textureScore:3.0,textureGrade:'average'},
color:{mainColor:'翠绿色',uniformity:4,gloss:3,freshness:5,appearance:4,colorScore:4.0,colorGrade:'good'}
}
};
var innovId = urlParams.get('id');
var INNOV = innovId ? INNOV_MAP[innovId] : null;
var initTab = parseInt(urlParams.get('tab')) || 0;
var currentStep = 0;
var totalSteps = 7;
@@ -285,7 +344,6 @@ var STEP_HTML = [
<div class="form-grid">
<div class="form-group"><label class="form-label">餐品名称<span class="required">*</span></label><input class="form-input" placeholder="请输入餐品名称"></div>
<div class="form-group"><label class="form-label">餐品分类<span class="required">*</span></label><select class="form-select"><option>请选择</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<div class="form-group"><label class="form-label">烹饪方法<span class="required">*</span></label><select class="form-select"><option>请选择</option><option>炒</option><option>蒸</option><option>炖</option><option>煮</option><option>凉拌</option><option>炸</option><option>烤</option></select></div>
<div class="form-group"><label class="form-label">适用餐次<span class="required">*</span></label><select class="form-select"><option>请选择</option><option>早餐</option><option>午餐</option><option>晚餐</option><option>早/午</option><option>午/晚</option><option>早/午/晚</option></select></div>
<div class="form-group"><label class="form-label">膳食宝塔分类<span class="required">*</span></label><select class="form-select"><option>请选择</option><option>谷薯杂豆</option><option>蔬菜</option><option>水果</option><option>畜禽肉蛋水产</option><option>奶及奶制品</option><option>大豆坚果</option><option>油脂</option><option>盐</option></select></div>
<div class="form-group"><label class="form-label">过敏原</label><input class="form-input" placeholder="无则填无"></div>
@@ -332,8 +390,8 @@ var STEP_HTML = [
<button class="btn btn-primary" style="height:30px;font-size:var(--font-xs);" onclick="openIngredientDialog()"> 新增食材</button>
</div>
<table class="ingredient-table">
<thead><tr><th>食材名称</th><th>食材分类</th><th>用量(g/份)</th><th>加工状态</th><th>是否主料</th><th>过敏原</th><th>备注</th><th>操作</th></tr></thead>
<tbody><tr><td colspan="8" style="text-align:center;color:var(--text-placeholder);padding:32px;">暂无食材,请点击"新增食材"添加</td></tr></tbody>
<thead><tr><th>食材名称</th><th>食材分类</th><th>用量(g/份)</th><th>是否主料</th><th>过敏原</th><th>备注</th><th>操作</th></tr></thead>
<tbody><tr><td colspan="7" style="text-align:center;color:var(--text-placeholder);padding:32px;">暂无食材,请点击"新增食材"添加</td></tr></tbody>
</table>`,
// Step 2: 烹饪工艺
@@ -361,6 +419,7 @@ var STEP_HTML = [
<div class="form-group"><label class="form-label">矿物质 (mg)</label><input class="form-input" type="number" placeholder="0.0"></div>
<div class="form-group"><label class="form-label">膳食纤维 (g)</label><input class="form-input" type="number" placeholder="0.0"></div>
<div class="form-group"><label class="form-label">钠 (mg)</label><input class="form-input" type="number" placeholder="0.0"></div>
<div class="form-group"><label class="form-label">营养等级</label><select class="form-select"><option value="">请选择</option><option value="达标">达标</option><option value="偏差">偏差</option><option value="未达标">未达标</option></select></div>
</div>`,
// Step 4: 味道档案
@@ -405,7 +464,19 @@ function renderStep(){
document.getElementById('stepContent').innerHTML = STEP_HTML[currentStep];
updateStepUI();
if(currentStep===0) renderCrowdRows();
if(pageMode==='edit') fillEditData();
if(pageMode==='edit' || pageMode==='convert') fillEditData();
if(pageMode==='convert') lockConvertStep();
}
function lockConvertStep(){
var c=document.getElementById('stepContent');
c.classList.remove('step-readonly');
var LOCKED=[1,3,4,5,6];
if(LOCKED.indexOf(currentStep)===-1) return;
c.classList.add('step-readonly');
var tip=document.createElement('div');
tip.className='step-readonly-tip';
tip.textContent='来自味养创新的评测数据,不可修改';
c.insertBefore(tip,c.firstChild);
}
function updateStepUI(){
@@ -415,6 +486,11 @@ function updateStepUI(){
document.getElementById('btnNext').style.display = 'none';
document.getElementById('btnSubmit').textContent = '保存修改';
document.getElementById('btnSubmit').style.display = 'inline-flex';
} else if(pageMode==='convert'){
document.getElementById('btnPrev').style.display = currentStep>0?'inline-flex':'none';
document.getElementById('btnNext').style.display = currentStep<totalSteps-1?'inline-flex':'none';
document.getElementById('btnSubmit').textContent = '确认转化';
document.getElementById('btnSubmit').style.display = currentStep===totalSteps-1?'inline-flex':'none';
} else {
document.getElementById('btnPrev').style.display = currentStep>0?'inline-flex':'none';
document.getElementById('btnNext').style.display = currentStep<totalSteps-1?'inline-flex':'none';
@@ -430,7 +506,7 @@ function switchTab(idx){
}
function nextStep(){ if(currentStep<totalSteps-1){currentStep++;renderStep();window.scrollTo(0,0);} }
function prevStep(){ if(currentStep>0){currentStep--;renderStep();window.scrollTo(0,0);} }
function submitForm(){ alert('提交成功!'); window.location.href='din-dish-all.html'; }
function submitForm(){ if(pageMode==='convert'){ alert('转化成功!餐品已加入餐品总库。'); window.location.href='din-dish-all.html'; } else { alert('提交成功!'); window.location.href='din-dish-all.html'; } }
/* 规格管理 */
function addSpecRow(addRow){
@@ -489,6 +565,35 @@ function selectIngredient(name){
document.getElementById('ingredientSearchInput').value=name;
document.getElementById('ingredientDropdown').classList.remove('show');
}
function confirmAddIngredient(){
var name=document.getElementById('ingredientSearchInput').value.trim();
var amount=document.getElementById('ingredientAmount').value.trim();
if(!name){alert('请选择食材');return;}
if(!amount){alert('请填写用量');return;}
var isMain=document.getElementById('ingredientIsMain').value;
var allergen=document.getElementById('ingredientAllergen').value.trim()||'无';
var note=document.getElementById('ingredientNote').value.trim()||'—';
var match=INGREDIENT_LIST.find(function(item){return item.name===name;});
var cat=match?match.cat:'—';
var tbody=document.querySelector('.ingredient-table tbody');
/* 移除空状态行 */
var emptyRow=tbody.querySelector('td[colspan]');
if(emptyRow) emptyRow.parentElement.remove();
var tr=document.createElement('tr');
tr.innerHTML='<td>'+name+'</td><td>'+cat+'</td><td>'+amount+'</td>'
+'<td>'+(isMain==='主料'?'<span class="tag tag-blue">主料</span>':'<span class="tag tag-gray">辅料</span>')+'</td>'
+'<td>'+allergen+'</td>'
+'<td>'+note+'</td>'
+'<td><a class="link" onclick="this.closest(\'tr\').remove()">删除</a></td>';
tbody.appendChild(tr);
/* 重置表单 */
document.getElementById('ingredientSearchInput').value='';
document.getElementById('ingredientAmount').value='';
document.getElementById('ingredientIsMain').selectedIndex=0;
document.getElementById('ingredientAllergen').value='';
document.getElementById('ingredientNote').value='';
closeIngredientDialog();
}
document.addEventListener('click',function(e){
if(!e.target.closest('#ingredientSearchSelect')){
var dd=document.getElementById('ingredientDropdown');
@@ -577,6 +682,43 @@ if(pageMode==='edit'){
document.title = '营养管理 - 编辑餐品 | 健康长庆原型';
}
if(pageMode==='convert'){
// 无论 INNOV 是否存在,convert 模式都修正侧边栏和标题
document.getElementById('pageTitle').textContent = '转化餐品';
document.title = '营养管理 - 转化餐品 | 健康长庆原型';
var bc = document.querySelector('.breadcrumb');
if(bc) bc.innerHTML = '<a href="din-innovation.html">味养创新</a><span class="breadcrumb__sep">/</span><span>转化餐品</span>';
var activeItem = document.querySelector('.sidebar-item.active');
if(activeItem) activeItem.classList.remove('active');
var innovItem = document.querySelector('.sidebar-item[href="din-innovation.html"]');
if(innovItem) innovItem.classList.add('active');
}
if(pageMode==='convert' && INNOV){
var banner = document.getElementById('convertBanner');
if(banner){
banner.style.display='flex';
document.getElementById('cvtExpNo').textContent = INNOV.expNo;
document.getElementById('cvtGoal').textContent = INNOV.goal;
document.getElementById('cvtMembers').textContent = INNOV.members;
}
EDIT_DATA.name = INNOV.name;
EDIT_DATA.category = INNOV.category;
EDIT_DATA.meal = INNOV.meal;
EDIT_DATA.pyramid = INNOV.pyramid;
EDIT_DATA.allergen = INNOV.allergen;
EDIT_DATA.tag = INNOV.tag;
EDIT_DATA.status = '上架';
EDIT_DATA.crowd = [];
EDIT_DATA.specs = [{spec:'标准份',weight:350,price:15,isDefault:true},{spec:'小份',weight:200,price:10,isDefault:false}];
EDIT_DATA.composition = INNOV.composition;
EDIT_DATA.cook = INNOV.cook;
EDIT_DATA.nutri = INNOV.nutri;
EDIT_DATA.taste = INNOV.taste;
EDIT_DATA.texture = INNOV.texture;
EDIT_DATA.color = INNOV.color;
}
renderStep();
// 编辑模式预填表单
@@ -595,11 +737,10 @@ function fillEditData(){
if(inputs[0]) inputs[0].value = d.name;
if(inputs[1]) inputs[1].value = d.allergen;
setSelectByText(selects[0], d.category);
setSelectByText(selects[1], d.method);
setSelectByText(selects[2], d.meal);
setSelectByText(selects[3], d.pyramid);
setSelectByText(selects[4], d.tag);
setSelectByText(selects[5], d.status);
setSelectByText(selects[1], d.meal);
setSelectByText(selects[2], d.pyramid);
setSelectByText(selects[3], d.tag);
setSelectByText(selects[4], d.status);
// 预填适配人群
if(d.crowd && d.crowd.length>0){
crowdList = d.crowd.map(function(c){return {name:c.name,level:c.level};});
@@ -622,7 +763,9 @@ function fillEditData(){
tbody.innerHTML = '';
d.composition.forEach(function(c){
var tr = document.createElement('tr');
tr.innerHTML = '<td>'+c.name+'</td><td>'+c.amount+'g</td><td>'+c.pct+'</td><td><span class="tag tag-'+(c.main?'green':'gray')+'">'+(c.main?'主料':'辅料')+'</span></td><td>'+c.allergen+'</td><td>'+c.note+'</td><td><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td>';
tr.innerHTML = (pageMode==='convert'
? '<td>'+c.name+'</td><td>'+c.amount+'g</td><td>'+c.pct+'</td><td><span class="tag tag-'+(c.main?'green':'gray')+'">'+(c.main?'主料':'辅料')+'</span></td><td>'+c.allergen+'</td><td>'+c.note+'</td><td><span style="color:#bbb;cursor:not-allowed;">编辑</span> <span style="color:#bbb;cursor:not-allowed;">删除</span></td>'
: '<td>'+c.name+'</td><td>'+c.amount+'g</td><td>'+c.pct+'</td><td><span class="tag tag-'+(c.main?'green':'gray')+'">'+(c.main?'主料':'辅料')+'</span></td><td>'+c.allergen+'</td><td>'+c.note+'</td><td><span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td>');
tbody.appendChild(tr);
});
}
@@ -638,6 +781,7 @@ function fillEditData(){
var n = d.nutri;
var nvals = [n.calorie, n.protein, n.carb, n.fat, n.vitC, n.mineral, n.fiber, n.sodium];
inputs.forEach(function(inp, i){ if(nvals[i]!==undefined) inp.value = nvals[i]; });
if(selects[0] && INNOV && INNOV.nutriGrade) setSelectByText(selects[0], INNOV.nutriGrade);
} else if(currentStep===4){
// 味道档案
var t = d.taste;
+753 -35
View File
@@ -84,7 +84,7 @@ tbody tr:hover{background:#F8FBFF;}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.45);z-index:1000;display:flex;align-items:center;justify-content:center;}
.modal{background:#fff;border-radius:8px;width:680px;max-height:80vh;overflow-y:auto;box-shadow:0 4px 12px rgba(0,0,0,0.15);}
.modal{background:#fff;border-radius:8px;width:820px;max-height:88vh;overflow-y:auto;box-shadow:0 4px 12px rgba(0,0,0,0.15);}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid #e8e8e8;}
.modal-title{font-size:16px;font-weight:600;color:#262626;}
.modal-close{font-size:22px;cursor:pointer;color:#8c8c8c;line-height:1;}
@@ -99,10 +99,58 @@ tbody tr:hover{background:#F8FBFF;}
.form-item input,.form-item select,.form-item textarea{height:36px;padding:0 12px;border:1px solid #e8e8e8;border-radius:4px;font-size:13px;outline:none;}
.form-item input:focus,.form-item select:focus,.form-item textarea:focus{border-color:#1890FF;}
.form-item textarea{height:80px;padding:8px 12px;resize:vertical;}
/* 页面信息栏 */
.page-header-bar{display:flex;align-items:center;justify-content:space-between;background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);}
.page-header-bar__left{display:flex;align-items:center;gap:12px;}
.page-header-bar__title{font-size:var(--font-lg);font-weight:700;color:var(--text-primary);}
.page-header-bar__meta{font-size:var(--font-sm);color:var(--text-placeholder);}
.page-header-bar__right{display:flex;align-items:center;gap:12px;}
.page-header-bar__right label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.page-header-bar__right .canteen-select{height:36px;border:2px solid var(--primary);border-radius:var(--radius-sm);padding:0 32px 0 14px;font-size:var(--font-sm);color:var(--primary);font-weight:500;outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%231890FF'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;min-width:140px;}
/* 操作列固定右侧 */
thead th:last-child,tbody td.td-actions{position:sticky;right:0;background:#fff;box-shadow:-4px 0 8px rgba(0,0,0,0.04);z-index:2;white-space:nowrap;}
thead th:last-child{background:#FAFAFA;}
tbody tr:hover td.td-actions{background:#F8FBFF;}
/* 创新实验弹窗—食材搜索组件 */
.innov-ing-section{border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px;background:#FAFAFA;}
.innov-add-row{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.innov-search-wrap{position:relative;flex:1;min-width:0;}
.innov-search-input{width:100%;height:36px;padding:0 12px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;background:#fff;}
.innov-search-input:focus{border-color:var(--primary);}
.innov-dropdown{position:absolute;top:40px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:1100;display:none;max-height:180px;overflow-y:auto;}
.innov-dropdown.show{display:block;}
.innov-dropdown-item{padding:8px 12px;font-size:var(--font-sm);cursor:pointer;display:flex;justify-content:space-between;align-items:center;}
.innov-dropdown-item:hover{background:var(--primary-light);}
.innov-dropdown-item span:last-child{color:var(--text-secondary);font-size:11px;}
.innov-amount-input{height:36px;padding:0 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;width:90px;background:#fff;}
.innov-amount-input:focus{border-color:var(--primary);}
.innov-type-select{height:36px;padding:0 26px 0 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;width:80px;}
.innov-ing-table{width:100%;border-collapse:collapse;font-size:var(--font-sm);}
.innov-ing-table th{background:#F0F0F0;padding:7px 10px;text-align:left;color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
.innov-ing-table td{padding:7px 10px;border-bottom:1px solid var(--border);background:#fff;}
.innov-ing-table tbody tr:last-child td{border-bottom:none;}
.btn-sm{height:32px;padding:0 14px;font-size:var(--font-sm);}
/* 提交评测弹窗 */
.modal--eval{width:720px;}
.eval-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:20px;}
.eval-tab{padding:9px 16px;font-size:var(--font-sm);cursor:pointer;color:var(--text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .2s;}
.eval-tab:hover{color:var(--primary);}
.eval-tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:500;}
.eval-panel{display:none;}
.eval-panel.active{display:block;}
.metric-grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px 16px;margin-bottom:8px;}
.metric-item{display:flex;flex-direction:column;gap:4px;}
.metric-item label{font-size:12px;color:var(--text-secondary);}
.metric-item input,.metric-item select{height:34px;padding:0 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;width:100%;background:#fff;}
.metric-item input:focus,.metric-item select:focus{border-color:var(--primary);}
.metric-item select{appearance:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;padding-right:24px;}
.upload-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px;}
.upload-box-dashed{border:2px dashed var(--border);border-radius:var(--radius-sm);padding:20px;text-align:center;color:var(--text-placeholder);font-size:var(--font-sm);cursor:pointer;transition:border-color .2s;}
.upload-box-dashed:hover{border-color:var(--primary);}
.eval-note-label{font-size:13px;color:#8c8c8c;margin-bottom:4px;display:block;}
.eval-textarea{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);outline:none;resize:vertical;min-height:72px;font-family:inherit;}
.eval-textarea:focus{border-color:var(--primary);}
</style>
</head>
<body>
@@ -134,6 +182,23 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="din-innovation.html" class="sidebar-item active"><span class="mi">🌟</span>味养创新</a>
</aside>
<main class="main">
<!-- 页面信息栏 -->
<div class="page-header-bar">
<div class="page-header-bar__left">
<span class="page-header-bar__title">味养创新</span>
</div>
<div class="page-header-bar__right">
<label>当前食堂</label>
<select class="canteen-select" id="globalCanteen">
<option value="1">一食堂(东区)</option>
<option value="2">二食堂(西区)</option>
<option value="3">三食堂(北区)</option>
</select>
</div>
</div>
<div class="stats-row">
<div class="stat-card"><div class="stat-card__icon blue"></div><div class="stat-card__info"><div class="stat-card__value">12</div><div class="stat-card__label">实验总数</div></div></div>
<div class="stat-card"><div class="stat-card__icon orange">🤖</div><div class="stat-card__info"><div class="stat-card__value">3</div><div class="stat-card__label">AI创新中</div></div></div>
@@ -147,15 +212,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<!-- Tab0: 人工创新 -->
<div class="tab-panel active">
<div class="filter-bar">
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>实验中</option><option>已验证</option><option>已转化</option><option>待推广</option></select></div>
<div class="filter-item"><label>标签</label><select class="filter-select"><option>全部</option><option>低钠</option><option>高蛋白</option><option>高纤维</option><option>低脂</option><option>植物基</option></select></div>
<div class="filter-item"><label>创建人</label><input class="filter-input" placeholder="请输入"></div>
<div class="filter-item"><label>餐品名称</label><input class="filter-input" placeholder="请输入"></div>
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>实验中</option><option>已评测</option><option>已转化</option></select></div>
<div class="filter-item"><label>餐品分类</label><select class="filter-select"><option>全部</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div class="action-bar">
<button class="btn btn-primary" onclick="openModal()"> 新建人工创新</button>
<button class="btn btn-default">🚀 转化为正式餐品</button>
</div>
<div class="table-card">
<div class="table-card__header">
@@ -163,13 +227,13 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="table-card__content">
<table>
<thead><tr><th>实验编号</th><th>品名称</th><th>创新目标</th><th>核心标签</th><th>参与人员</th><th>实验阶段</th><th>风味评分</th><th>营养评分</th><th>评测条数</th><th>实验</th><th>状态</th><th>操作</th></tr></thead>
<thead><tr><th>实验编号</th><th>品名称</th><th>创新目标</th><th>餐品分类</th><th>餐品构成</th><th>参与人员</th><th>实验开始日期</th><th>实验结束日</th><th>状态</th><th>操作</th></tr></thead>
<tbody>
<tr><td>INN-H001</td><td>低钠麻婆豆腐</td><td>减少60%钠含量,保留麻辣风味</td><td>低钠 高蛋白</td><td>厨师长张强 / 营养师李明</td><td>已转化</td><td>4.2</td><td>4.8</td><td>236条(4.5分)</td><td>2026-02 ~ 2026-03</td><td><span class="tag tag-green">已转化</span></td><td class="td-actions"><a class="link">查看详情</a> <a class="link">提交评测</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-H002</td><td>高纤维主食包</td><td>添加燕麦、藜麦,膳食纤维提升3倍</td><td>高纤维 低GI</td><td>厨师长陈磊 / 营养师王芳</td><td>用户评测</td><td>3.8</td><td>4.9</td><td>120条(4.2分)</td><td>2026-03 ~ 2026-04</td><td><span class="tag tag-blue">待推广</span></td><td class="td-actions"><a class="link">查看详情</a> <a class="link">提交评测</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-H003</td><td>植物基红烧肉</td><td>以豆腐皮替代猪肉,脂肪降低70%</td><td>低脂 植物基</td><td>厨师长张强 / 营养师李明</td><td>小批量测试</td><td>3.5</td><td>4.6</td><td>42条(3.9分)</td><td>2026-04 ~ 进行中</td><td><span class="tag tag-orange">实验中</span></td><td class="td-actions"><a class="link">查看详情</a> <a class="link">提交评测</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-H004</td><td>富铁青菜汤</td><td>搭配维C食材,补铁效率提升2倍</td><td>高铁 补血</td><td>厨师长赵敏 / 营养师李明</td><td>已验证</td><td>4.0</td><td>4.7</td><td>186条(4.4分)</td><td>2026-01 ~ 2026-02</td><td><span class="tag tag-green">验证</span></td><td class="td-actions"><a class="link">查看详情</a> <a class="link">提交评测</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-H005</td><td>功能性早餐粥</td><td>添加枸杞、红枣、核桃,营养密度提升</td><td>高营养 养生</td><td>厨师长张强 / 营养师王芳</td><td>配方设计</td><td>4.5</td><td>4.6</td><td>18条(4.1分)</td><td>2026-04 ~ 进行中</td><td><span class="tag tag-orange">实验中</span></td><td class="td-actions"><a class="link">查看详情</a> <a class="link">提交评测</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-H001</td><td>低钠麻婆豆腐</td><td>减少60%钠含量,保留麻辣风味</td><td>荤菜</td><td>豆腐、猪肉末、豆瓣酱</td><td>厨师长张强 / 营养师李明</td><td>2026-02-01</td><td>2026-03-15</td><td><span class="tag tag-green">已转化</span></td><td class="td-actions"><a class="link" onclick="openDetailModal('INN-H001')">查看详情</a> <a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td></tr>
<tr><td>INN-H002</td><td>高纤维主食包</td><td>添加燕麦、藜麦,膳食纤维提升3倍</td><td>主食</td><td>燕麦、藜麦、糙米</td><td>厨师长陈磊 / 营养师王芳</td><td>2026-03-01</td><td>2026-04-20</td><td><span class="tag tag-blue">已评测</span></td><td class="td-actions"><a class="link" onclick="openDetailModal('INN-H002')">查看详情</a> <a class="link" href="din-dish-add.html?mode=convert&id=INN-H002">转化餐品</a> <a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td></tr>
<tr><td>INN-H003</td><td>植物基红烧肉</td><td>以豆腐皮替代猪肉,脂肪降低70%</td><td>荤菜</td><td>豆腐皮、香菇、酱油</td><td>厨师长张强 / 营养师李明</td><td>2026-04-10</td><td></td><td><span class="tag tag-orange">实验中</span></td><td class="td-actions"><a class="link" onclick="openDetailModal('INN-H003')">查看详情</a> <a class="link" onclick="openEvalModal('INN-H003','植物基红烧肉','荤菜','以豆腐皮替代猪肉,脂肪降低70%','厨师长张强 / 营养师李明','2026-04-10')">提交评测</a> <a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td></tr>
<tr><td>INN-H004</td><td>富铁青菜汤</td><td>搭配维C食材,补铁效率提升2倍</td><td>汤品</td><td>菠菜、猪肝、枸杞</td><td>厨师长赵敏 / 营养师李明</td><td>2026-01-05</td><td>2026-02-28</td><td><span class="tag tag-blue">评测</span></td><td class="td-actions"><a class="link" onclick="openDetailModal('INN-H004')">查看详情</a> <a class="link" href="din-dish-add.html?mode=convert&id=INN-H004">转化餐品</a> <a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td></tr>
<tr><td>INN-H005</td><td>功能性早餐粥</td><td>添加枸杞、红枣、核桃,营养密度提升</td><td>主食</td><td>枸杞、红枣、核桃、大米</td><td>厨师长张强 / 营养师王芳</td><td>2026-04-15</td><td></td><td><span class="tag tag-orange">实验中</span></td><td class="td-actions"><a class="link" onclick="openDetailModal('INN-H005')">查看详情</a> <a class="link" onclick="openEvalModal('INN-H005','功能性早餐粥','主食','添加枸杞、红枣、核桃,营养密度提升','厨师长张强 / 营养师王芳','2026-04-15')">提交评测</a> <a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td></tr>
</tbody>
</table>
</div>
@@ -179,30 +243,27 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<!-- Tab1: AI创新 -->
<div class="tab-panel">
<div class="filter-bar">
<div class="filter-item"><label>AI模型版本</label><select class="filter-select"><option>全部</option><option>v2.3 营养推理</option><option>v1.8 风味融合</option></select></div>
<div class="filter-item"><label>创新方向</label><select class="filter-select"><option>全部</option><option>血糖控制</option><option>增肌减脂</option><option>营养均衡</option><option>肠道健康</option><option>痛风友好</option></select></div>
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>推演完成</option><option>人工审核中</option><option>推演中</option><option>待启动</option></select></div>
<div class="filter-item"><label>餐品名称</label><input class="filter-input" placeholder="请输入餐品名称"></div>
<div class="filter-item"><label>餐品分类</label><select class="filter-select"><option>全部</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<div class="filter-item"><label>AI模型</label><select class="filter-select"><option>全部</option><option>v2.3 营养推理</option><option>v1.8 风味融合</option></select></div>
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>推演中</option><option>推演完成待审核</option><option>审核通过</option><option>未通过</option></select></div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div class="action-bar">
<button class="btn btn-primary">🤖 发起AI模拟推演</button>
<button class="btn btn-default">📊 查看推演报告</button>
<button class="btn btn-default">🚀 转化为正式餐品</button>
<button class="btn btn-primary" onclick="openAiLaunchModal()">🤖 发起AI模拟推演</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">AI创新</div>
</div>
<div class="table-card__header"><div class="table-card__title">AI创新</div></div>
<div class="table-card__content">
<table>
<thead><tr><th>实验编号</th><th>品名称</th><th>AI模型</th><th>创新方向</th><th>食材成分组合</th><th>加工方法</th><th>烹饪技术</th><th>历史参考</th><th>预测风味分</th><th>预测营养分</th><th>创新亮点</th><th>模拟状态</th><th>操作</th></tr></thead>
<thead><tr><th>实验编号</th><th>品名称</th><th>餐品分类</th><th>创新目标</th><th>餐品构成</th><th>推演开始时间</th><th>AI模型</th><th>模拟状态</th><th>操作</th></tr></thead>
<tbody>
<tr><td>INN-A001</td><td>AI低GI藜麦饭</td><td>v2.3 营养推理</td><td>血糖控制</td><td>藜麦55%+糙米30%+黑米15%</td><td>浸泡+蒸制</td><td>文火慢蒸</td><td>低GI主食历史数据×128条</td><td>4.1</td><td>4.9</td><td>血糖负荷较白米降低41%</td><td><span class="tag tag-green">推演完成</span></td><td class="td-actions"><a class="link">推演报告</a> <a class="link">人工审核</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-A002</td><td>AI高蛋白减脂鸡胸</td><td>v2.3 营养推理</td><td>增肌减脂</td><td>鸡胸肉70%+西兰花20%+彩椒10%</td><td>低温慢煮</td><td>65℃慢煮4h</td><td>运动营养餐历史数据×86条</td><td>3.9</td><td>4.8</td><td>蛋白质密度达23g/100g</td><td><span class="tag tag-green">推演完成</span></td><td class="td-actions"><a class="link">推演报告</a> <a class="link">人工审核</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-A003</td><td>AI地中海沙拉碗</td><td>v1.8 风味融合</td><td>营养均衡</td><td>鹰嘴豆+藜麦+牛油果+三文鱼</td><td>冷处理</td><td>生冷拼配</td><td>地中海饮食历史数据×214条</td><td>4.3</td><td>4.7</td><td>Omega-3含量提升3倍</td><td><span class="tag tag-orange">人工审核</span></td><td class="td-actions"><a class="link">推演报告</a> <a class="link">人工审核</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-A004</td><td>AI益生菌发酵主食</td><td>v2.3 营养推理</td><td>肠道健康</td><td>全麦粉+燕麦+酵素发酵液</td><td>低温发酵</td><td>窑烤</td><td>肠道健康历史数据×92条</td><td>3.7</td><td>4.6</td><td>活性益生菌≥10亿CFU/g</td><td><span class="tag tag-blue">推演中</span></td><td class="td-actions"><a class="link">推演报告</a> <a class="link">人工审核</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-A005</td><td>AI低嘌呤海鲜汤</td><td>v2.3 营养推理</td><td>痛风友好</td><td>娃娃菜+豆腐+冬瓜+虾皮(少量)</td><td>水煮</td><td>轻火慢炖</td><td>痛风饮食历史数据×156条</td><td>4.0</td><td>4.5</td><td>嘌呤含量较普通海鲜汤低68%</td><td><span class="tag tag-gray">待启动</span></td><td class="td-actions"><a class="link">推演报告</a> <a class="link">人工审核</a> <a class="link">转化餐品</a></td></tr>
<tr><td>INN-A001</td><td>AI低GI藜麦饭</td><td>主食</td><td>血糖负荷较白米降低41%</td><td>藜麦+糙米+黑米</td><td>2026-03-10 09:00</td><td>v2.3 营养推理</td><td><span class="tag tag-green">审核通过</span></td><td class="td-actions"><a class="link" onclick="openAiReportModal('INN-A001','AI低GI藜麦饭','主食','血糖负荷较白米降低41%','v2.3 营养推理','2026-03-10 09:00','2026-03-10 09:18')">推演报告</a> <a class="link" onclick="openAiViewReview('INN-A001','AI低GI藜麦饭','pass','推演结果符合预期,营养指标达标,建议直接转化为正式餐品。','李明(营养师)','2026-03-12 10:30')">查看审核</a> <a class="link" href="din-dish-add.html?mode=convert&id=INN-A001">转化餐品</a></td></tr>
<tr><td>INN-A002</td><td>AI高蛋白减脂鸡胸</td><td>荤菜</td><td>蛋白质密度达23g/100g</td><td>鸡胸肉+西兰花+彩椒</td><td>2026-03-18 14:30</td><td>v2.3 营养推理</td><td><span class="tag tag-orange">推演完成待审核</span></td><td class="td-actions"><a class="link" onclick="openAiReportModal('INN-A002','AI高蛋白减脂鸡胸','荤菜','蛋白质密度达23g/100g','v2.3 营养推理','2026-03-18 14:30','2026-03-18 14:52')">推演报告</a> <a class="link" onclick="openAiReviewModal('INN-A002','AI高蛋白减脂鸡胸')">人工审核</a> <a class="link" style="color:#bbb;cursor:not-allowed;" title="审核通过后可转化">转化餐品</a></td></tr>
<tr><td>INN-A003</td><td>AI地中海沙拉碗</td><td>素菜</td><td>Omega-3含量提升3倍</td><td>鹰嘴豆+藜麦+牛油果+三文鱼</td><td>2026-04-01 10:15</td><td>v1.8 风味融合</td><td><span class="tag tag-orange">推演完成待审核</span></td><td class="td-actions"><a class="link" onclick="openAiReportModal('INN-A003','AI地中海沙拉碗','素菜','Omega-3含量提升3倍','v1.8 风味融合','2026-04-01 10:15','2026-04-01 10:34')">推演报告</a> <a class="link" onclick="openAiReviewModal('INN-A003','AI地中海沙拉碗')">人工审核</a> <a class="link" style="color:#bbb;cursor:not-allowed;" title="审核通过后可转化">转化餐品</a></td></tr>
<tr><td>INN-A004</td><td>AI益生菌发酵主食</td><td>主食</td><td>活性益生菌≥10亿CFU/g</td><td>全麦粉+燕麦+酵素发酵液</td><td>2026-04-12 16:00</td><td>v2.3 营养推理</td><td><span class="tag tag-blue">推演中</span></td><td class="td-actions"><a class="link" style="color:#bbb;cursor:not-allowed;" title="推演完成后可查看">推演报告</a> <a class="link" style="color:#bbb;cursor:not-allowed;" title="推演完成后可审核">人工审核</a> <a class="link" style="color:#bbb;cursor:not-allowed;" title="推演完成后可转化">转化餐品</a></td></tr>
<tr><td>INN-A005</td><td>AI低嘌呤海鲜汤</td><td>汤品</td><td>嘌呤含量较普通海鲜汤低68%</td><td>娃娃菜+豆腐+冬瓜+虾皮</td><td>2026-04-20 11:20</td><td>v2.3 营养推理</td><td><span class="tag tag-red">未通过</span></td><td class="td-actions"><a class="link" onclick="openAiReportModal('INN-A005','AI低嘌呤海鲜汤','汤品','嘌呤含量较普通海鲜汤低68%','v2.3 营养推理','2026-04-20 11:20','2026-04-20 11:41')">推演报告</a> <a class="link" onclick="openAiViewReview('INN-A005','AI低嘌呤海鲜汤','reject','嘌呤含量虽有下降,但口感损失明显,整体方案需重新设计食材配比。','王芳(营养师)','2026-04-22 15:10')">查看审核</a> <a class="link" style="color:#bbb;cursor:not-allowed;" title="审核未通过,不可转化">转化餐品</a></td></tr>
</tbody>
</table>
</div>
@@ -219,16 +280,36 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
</div>
<div class="modal-body">
<div class="form-grid">
<div class="form-item"><label>品名称<span class="required">*</span></label><input type="text" placeholder="请输入品名称"></div>
<div class="form-item"><label>创新方向<span class="required">*</span></label><select><option>请选择</option><option>营养均衡</option><option>血糖控制</option><option>增肌减脂</option><option>肠道健康</option><option>低钠控压</option><option>低脂减重</option><option>高蛋白</option><option>痛风友好</option><option>养生滋补</option></select></div>
<div class="form-item"><label>目标标签(多选)</label><select><option>请选择</option><option>低钠</option><option>低脂</option><option>低GI</option><option>高蛋白</option><option>高纤维</option><option>高铁</option><option>补血</option><option>植物基</option><option>益生菌</option><option>嘌呤</option></select></div>
<div class="form-item"><label>加工方法</label><select><option>请选择</option><option>浸泡+蒸制</option><option>低温慢煮</option><option>水煮</option><option>冷处理</option><option>低温发酵</option><option>高压蒸制</option><option>炒制</option><option>窑烤</option></select></div>
<div class="form-item full"><label>食材成分组合</label><textarea placeholder="列出主要食材及比例,如:藜麦55%+糙米30%+黑米15%"></textarea></div>
<div class="form-item"><label>烹饪技术</label><input type="text" placeholder="如:65℃慢煮4h、文火慢蒸等"></div>
<div class="form-item"><label>品名称<span class="required">*</span></label><input type="text" placeholder="请输入品名称"></div>
<div class="form-item"><label>餐品分类<span class="required">*</span></label><select><option>请选择</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<div class="form-item"><label>烹饪方法</label><select><option>请选择</option><option></option><option></option><option></option><option></option><option></option><option></option><option></option><option>低温慢煮</option><option>温发酵</option></select></div>
<div class="form-item"><label>适用餐次</label><select><option>请选择</option><option>早餐</option><option>午餐</option><option>晚餐</option><option>早餐+午餐</option><option>午餐+晚餐</option><option>全天</option></select></div>
<div class="form-item"><label>膳食宝塔分类</label><select><option>请选择</option><option>谷薯类</option><option>蔬菜类</option><option>水果类</option><option>畜禽肉类</option><option>水产品</option><option>蛋类</option><option>奶及奶制品</option><option>大豆及坚果</option><option>油脂及调味品</option></select></div>
<div class="form-item full">
<label>餐品构成</label>
<div class="innov-ing-section">
<div class="innov-add-row">
<div class="innov-search-wrap">
<input id="innovIngSearch" class="innov-search-input" type="text" placeholder="搜索食材名称" oninput="innovSearchIng()" autocomplete="off">
<div class="innov-dropdown" id="innovIngDropdown"></div>
</div>
<input id="innovIngAmount" class="innov-amount-input" type="text" placeholder="用量(g)">
<select id="innovIngIsMain" class="innov-type-select"><option value="主料">主料</option><option value="辅料">辅料</option></select>
<button type="button" class="btn btn-primary btn-sm" onclick="innovAddIngRow()">添加</button>
</div>
<table class="innov-ing-table">
<thead><tr><th>食材名称</th><th>分类</th><th>用量</th><th>主/辅料</th><th>操作</th></tr></thead>
<tbody id="innovIngTableBody">
<tr id="innovIngEmptyRow"><td colspan="5" style="text-align:center;color:#999;padding:12px;">暂无食材,请搜索添加</td></tr>
</tbody>
</table>
</div>
</div>
<div class="form-item full"><label>创新目标<span class="required">*</span></label><input type="text" placeholder="请输入创新目标,如:减少60%钠含量,保留麻辣风味"></div>
<div class="form-item"><label>实验开始日期</label><input type="date"></div>
<div class="form-item"><label>参与人员</label><input type="text" placeholder="如:厨师长张强 / 营养师李明"></div>
<div class="form-item full"><label>历史参考数据说明</label><textarea placeholder="请输入历史参考数据说明"></textarea></div>
</div>
<div class="form-item"><label>参与人员</label><select><option>请选择</option><option>张强(厨师长)</option><option>陈磊(厨师长)</option><option>赵敏(厨师长)</option><option>李明(营养师)</option><option>王芳(营养师)</option><option>刘洋(营养师)</option><option>孙浩(食品工程师)</option><option>周婷(食品工程师)</option></select></div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="closeModal()">取消</button>
@@ -244,6 +325,643 @@ document.getElementById('modalOverlay').addEventListener('click',function(e){if(
function switchTab(idx){document.querySelectorAll('.page-tab').forEach((t,i)=>t.classList.toggle('active',i===idx));document.querySelectorAll('.tab-panel').forEach((p,i)=>p.classList.toggle('active',i===idx));}
function toggleSubgroup(header){header.parentElement.classList.toggle('open');}
(function(){var active=document.querySelector('.sidebar-item.active');if(!active)return;var sub=active.closest('.sidebar-subgroup');if(sub)sub.classList.add('open');})();
var INNOV_ING_LIST=[
{name:'猪肉',cat:'肉类'},{name:'鸡肉',cat:'肉类'},{name:'牛肉',cat:'肉类'},{name:'羊肉',cat:'肉类'},
{name:'鸡蛋',cat:'蛋类'},{name:'鸭蛋',cat:'蛋类'},
{name:'豆腐',cat:'豆制品'},{name:'豆皮',cat:'豆制品'},{name:'鹰嘴豆',cat:'豆制品'},
{name:'西兰花',cat:'蔬菜'},{name:'胡萝卜',cat:'蔬菜'},{name:'土豆',cat:'蔬菜'},{name:'白菜',cat:'蔬菜'},
{name:'番茄',cat:'蔬菜'},{name:'菠菜',cat:'蔬菜'},{name:'冬瓜',cat:'蔬菜'},{name:'娃娃菜',cat:'蔬菜'},
{name:'大米',cat:'主食'},{name:'面粉',cat:'主食'},{name:'燕麦',cat:'主食'},{name:'藜麦',cat:'主食'},{name:'糙米',cat:'主食'},{name:'黑米',cat:'主食'},
{name:'三文鱼',cat:'鱼类'},{name:'虾仁',cat:'海鲜'},{name:'牛油果',cat:'水果'},
{name:'花生油',cat:'油脂'},{name:'食盐',cat:'调味料'},{name:'酱油',cat:'调味料'}
];
function innovSearchIng(){
var val=document.getElementById('innovIngSearch').value.trim();
var dd=document.getElementById('innovIngDropdown');
if(!val){dd.classList.remove('show');dd.innerHTML='';return;}
var matched=INNOV_ING_LIST.filter(function(i){return i.name.indexOf(val)>=0;});
if(!matched.length){dd.classList.remove('show');dd.innerHTML='';return;}
dd.innerHTML=matched.map(function(i){return '<div class="innov-dropdown-item" onclick="innovSelectIng(\''+i.name+'\',\''+i.cat+'\')"><span>'+i.name+'</span><span>'+i.cat+'</span></div>';}).join('');
dd.classList.add('show');
}
function innovSelectIng(name,cat){
var el=document.getElementById('innovIngSearch');
el.value=name;el.dataset.cat=cat;
document.getElementById('innovIngDropdown').classList.remove('show');
document.getElementById('innovIngDropdown').innerHTML='';
}
function innovAddIngRow(){
var name=document.getElementById('innovIngSearch').value.trim();
var amount=document.getElementById('innovIngAmount').value.trim();
if(!name){alert('请选择食材');return;}
if(!amount){alert('请填写用量');return;}
var cat=document.getElementById('innovIngSearch').dataset.cat||'—';
var isMain=document.getElementById('innovIngIsMain').value;
var tbody=document.getElementById('innovIngTableBody');
var emptyRow=document.getElementById('innovIngEmptyRow');
if(emptyRow)emptyRow.remove();
var tr=document.createElement('tr');
tr.innerHTML='<td>'+name+'</td><td>'+cat+'</td><td>'+amount+'</td>'
+'<td>'+(isMain==='主料'?'<span class="tag tag-blue">主料</span>':'<span class="tag tag-gray">辅料</span>')+'</td>'
+'<td><a class="link" onclick="this.closest(\'tr\').remove()">删除</a></td>';
tbody.appendChild(tr);
var el=document.getElementById('innovIngSearch');
el.value='';el.dataset.cat='';
document.getElementById('innovIngAmount').value='';
document.getElementById('innovIngIsMain').selectedIndex=0;
}
/* ===== 人工创新详情数据 ===== */
var DETAIL_MAP = {
'INN-H001':{
expNo:'INN-H001',name:'低钠麻婆豆腐',category:'荤菜',goal:'减少60%钠含量,保留麻辣风味',
members:'厨师长张强 / 营养师李明',startDate:'2026-02-01',endDate:'2026-03-15',status:'已转化',
composition:[
{name:'豆腐',cat:'豆制品',amount:'200g',main:'主料'},
{name:'猪肉末',cat:'肉类',amount:'50g',main:'辅料'},
{name:'豆瓣酱(低钠)',cat:'调味料',amount:'15g',main:'辅料'},
{name:'花椒',cat:'调味料',amount:'3g',main:'辅料'},
{name:'葱姜蒜',cat:'蔬菜',amount:'10g',main:'辅料'}
],
nutri:{calorie:98,protein:8.2,carb:5.6,fat:5.4,vitC:2,mineral:120,fiber:1.2,sodium:180,grade:'达标'},
taste:{sour:1,sweet:1,bitter:1,spicy:4,salty:2,smell:4.2,flavorScore:4.1,grade:'良好'},
texture:{hardness:2,sticky:2,crispy:1,smooth:4,elastic:2,textureScore:3.6,grade:'良好'},
color:{mainColor:'红褐色',uniformity:4,gloss:3,freshness:4,appearance:4,colorScore:3.8,grade:'良好'}
},
'INN-H002':{
expNo:'INN-H002',name:'高纤维主食包',category:'主食',goal:'添加燕麦、藜麦,膳食纤维提升3倍',
members:'厨师长陈磊 / 营养师王芳',startDate:'2026-03-01',endDate:'2026-04-20',status:'已评测',
composition:[
{name:'燕麦',cat:'谷薯类',amount:'80g',main:'主料'},
{name:'藜麦',cat:'谷薯类',amount:'60g',main:'主料'},
{name:'糙米',cat:'谷薯类',amount:'60g',main:'辅料'}
],
nutri:{calorie:342,protein:12.8,carb:58.4,fat:5.2,vitC:0,mineral:38,fiber:9.6,sodium:210,grade:'达标'},
taste:{sour:1,sweet:2,bitter:1,spicy:1,salty:2,smell:3.8,flavorScore:3.6,grade:'良好'},
texture:{hardness:3,sticky:3,crispy:1,smooth:3,elastic:2,textureScore:3.2,grade:'一般'},
color:{mainColor:'米黄色',uniformity:4,gloss:3,freshness:4,appearance:3,colorScore:3.5,grade:'良好'}
},
'INN-H003':{
expNo:'INN-H003',name:'植物基红烧肉',category:'荤菜',goal:'以豆腐皮替代猪肉,脂肪降低70%',
members:'厨师长张强 / 营养师李明',startDate:'2026-04-10',endDate:'—',status:'实验中',
composition:[
{name:'豆腐皮',cat:'豆制品',amount:'150g',main:'主料'},
{name:'香菇',cat:'蔬菜',amount:'60g',main:'辅料'},
{name:'酱油',cat:'调味料',amount:'20g',main:'辅料'},
{name:'冰糖',cat:'调味料',amount:'10g',main:'辅料'}
],
nutri:null,taste:null,texture:null,color:null
},
'INN-H004':{
expNo:'INN-H004',name:'富铁青菜汤',category:'汤品',goal:'搭配维C食材,补铁效率提升2倍',
members:'厨师长赵敏 / 营养师李明',startDate:'2026-01-05',endDate:'2026-02-28',status:'已评测',
composition:[
{name:'菠菜',cat:'蔬菜类',amount:'120g',main:'主料'},
{name:'猪肝',cat:'肉类',amount:'60g',main:'主料'},
{name:'枸杞',cat:'其他',amount:'10g',main:'辅料'},
{name:'姜片',cat:'调味料',amount:'5g',main:'辅料'}
],
nutri:{calorie:68,protein:5.4,carb:6.2,fat:2.8,vitC:32,mineral:86,fiber:2.4,sodium:320,grade:'达标'},
taste:{sour:1,sweet:1,bitter:1,spicy:1,salty:3,smell:3.5,flavorScore:3.4,grade:'一般'},
texture:{hardness:2,sticky:1,crispy:1,smooth:4,elastic:2,textureScore:3.0,grade:'一般'},
color:{mainColor:'翠绿色',uniformity:4,gloss:3,freshness:5,appearance:4,colorScore:4.0,grade:'良好'}
},
'INN-H005':{
expNo:'INN-H005',name:'功能性早餐粥',category:'主食',goal:'添加枸杞、红枣、核桃,营养密度提升',
members:'厨师长张强 / 营养师王芳',startDate:'2026-04-15',endDate:'—',status:'实验中',
composition:[
{name:'大米',cat:'谷薯类',amount:'100g',main:'主料'},
{name:'枸杞',cat:'其他',amount:'15g',main:'辅料'},
{name:'红枣',cat:'其他',amount:'20g',main:'辅料'},
{name:'核桃',cat:'坚果',amount:'20g',main:'辅料'}
],
nutri:null,taste:null,texture:null,color:null
}
};
function renderReadonlyVal(v){
return '<div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">'+v+'</div>';
}
function renderGradeTag(g){
var map={'达标':'tag-green','良好':'tag-green','优秀':'tag-green','一般':'tag-orange','较差':'tag-red','不合格':'tag-red'};
return '<span class="tag '+(map[g]||'tag-orange')+'">'+g+'</span>';
}
function openDetailModal(id){
var d=DETAIL_MAP[id];
if(!d) return;
document.getElementById('dtlExpNo').textContent=d.expNo;
document.getElementById('dtlName').textContent=d.name;
document.getElementById('dtlCategory').textContent=d.category;
document.getElementById('dtlGoal').textContent=d.goal;
document.getElementById('dtlMembers').textContent=d.members;
document.getElementById('dtlStartDate').textContent=d.startDate;
document.getElementById('dtlEndDate').textContent=d.endDate;
var statusMap={'已转化':'<span class="tag tag-green">已转化</span>','已评测':'<span class="tag tag-blue">已评测</span>','实验中':'<span class="tag tag-orange">实验中</span>'};
document.getElementById('dtlStatus').innerHTML=statusMap[d.status]||d.status;
// 餐品构成
var tbody=document.getElementById('dtlIngTable');
if(d.composition&&d.composition.length){
tbody.innerHTML=d.composition.map(function(r){
return '<tr><td style="padding:8px 12px;border:1px solid var(--border);">'+r.name+'</td><td style="padding:8px 12px;border:1px solid var(--border);">'+r.cat+'</td><td style="padding:8px 12px;border:1px solid var(--border);">'+r.amount+'</td><td style="padding:8px 12px;border:1px solid var(--border);">'+r.main+'</td></tr>';
}).join('');
} else {
tbody.innerHTML='<tr><td colspan="4" style="padding:12px;text-align:center;color:#999;border:1px solid var(--border);">暂无数据</td></tr>';
}
// 评测数据
var noData='<div style="padding:24px;text-align:center;color:#999;font-size:13px;">实验进行中,暂无评测数据</div>';
if(d.nutri){
document.getElementById('dtlPanel0').innerHTML='<div class="metric-grid-4">'+
'<div class="metric-item"><label>热量 (kcal/100g)</label>'+renderReadonlyVal(d.nutri.calorie)+'</div>'+
'<div class="metric-item"><label>蛋白质 (g)</label>'+renderReadonlyVal(d.nutri.protein)+'</div>'+
'<div class="metric-item"><label>碳水化合物 (g)</label>'+renderReadonlyVal(d.nutri.carb)+'</div>'+
'<div class="metric-item"><label>脂肪 (g)</label>'+renderReadonlyVal(d.nutri.fat)+'</div>'+
'<div class="metric-item"><label>维生素C (mg)</label>'+renderReadonlyVal(d.nutri.vitC)+'</div>'+
'<div class="metric-item"><label>矿物质 (mg)</label>'+renderReadonlyVal(d.nutri.mineral)+'</div>'+
'<div class="metric-item"><label>膳食纤维 (g)</label>'+renderReadonlyVal(d.nutri.fiber)+'</div>'+
'<div class="metric-item"><label>钠 (mg)</label>'+renderReadonlyVal(d.nutri.sodium)+'</div>'+
'<div class="metric-item"><label>营养等级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;display:flex;align-items:center;">'+renderGradeTag(d.nutri.grade)+'</div></div>'+
'</div>';
} else { document.getElementById('dtlPanel0').innerHTML=noData; }
if(d.taste){
document.getElementById('dtlPanel1').innerHTML='<div class="metric-grid-4">'+
'<div class="metric-item"><label>酸度 (1-5)</label>'+renderReadonlyVal(d.taste.sour)+'</div>'+
'<div class="metric-item"><label>甜度 (1-5)</label>'+renderReadonlyVal(d.taste.sweet)+'</div>'+
'<div class="metric-item"><label>苦度 (1-5)</label>'+renderReadonlyVal(d.taste.bitter)+'</div>'+
'<div class="metric-item"><label>辣度 (1-5)</label>'+renderReadonlyVal(d.taste.spicy)+'</div>'+
'<div class="metric-item"><label>咸度 (1-5)</label>'+renderReadonlyVal(d.taste.salty)+'</div>'+
'<div class="metric-item"><label>气味评分 (1-5)</label>'+renderReadonlyVal(d.taste.smell)+'</div>'+
'<div class="metric-item"><label>综合风味评分 (1-5)</label>'+renderReadonlyVal(d.taste.flavorScore)+'</div>'+
'<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;display:flex;align-items:center;">'+renderGradeTag(d.taste.grade)+'</div></div>'+
'</div>';
} else { document.getElementById('dtlPanel1').innerHTML=noData; }
if(d.texture){
document.getElementById('dtlPanel2').innerHTML='<div class="metric-grid-4">'+
'<div class="metric-item"><label>软硬度 (1-5)</label>'+renderReadonlyVal(d.texture.hardness)+'</div>'+
'<div class="metric-item"><label>黏糯度 (1-5)</label>'+renderReadonlyVal(d.texture.sticky)+'</div>'+
'<div class="metric-item"><label>酥脆度 (1-5)</label>'+renderReadonlyVal(d.texture.crispy)+'</div>'+
'<div class="metric-item"><label>嫩滑度 (1-5)</label>'+renderReadonlyVal(d.texture.smooth)+'</div>'+
'<div class="metric-item"><label>弹性 (1-5)</label>'+renderReadonlyVal(d.texture.elastic)+'</div>'+
'<div class="metric-item"><label>综合口感评分 (1-5)</label>'+renderReadonlyVal(d.texture.textureScore)+'</div>'+
'<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;display:flex;align-items:center;">'+renderGradeTag(d.texture.grade)+'</div></div>'+
'</div>';
} else { document.getElementById('dtlPanel2').innerHTML=noData; }
if(d.color){
document.getElementById('dtlPanel3').innerHTML='<div class="metric-grid-4">'+
'<div class="metric-item"><label>主色调</label>'+renderReadonlyVal(d.color.mainColor)+'</div>'+
'<div class="metric-item"><label>色泽均匀度 (1-5)</label>'+renderReadonlyVal(d.color.uniformity)+'</div>'+
'<div class="metric-item"><label>光泽度 (1-5)</label>'+renderReadonlyVal(d.color.gloss)+'</div>'+
'<div class="metric-item"><label>新鲜度 (1-5)</label>'+renderReadonlyVal(d.color.freshness)+'</div>'+
'<div class="metric-item"><label>卖相评分 (1-5)</label>'+renderReadonlyVal(d.color.appearance)+'</div>'+
'<div class="metric-item"><label>综合色泽评分 (1-5)</label>'+renderReadonlyVal(d.color.colorScore)+'</div>'+
'<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;display:flex;align-items:center;">'+renderGradeTag(d.color.grade)+'</div></div>'+
'</div>';
} else { document.getElementById('dtlPanel3').innerHTML=noData; }
switchDtlTab(0);
document.getElementById('detailModalOverlay').style.display='flex';
}
function switchDtlTab(idx){
document.querySelectorAll('#detailModalOverlay .eval-tab').forEach(function(t,i){t.classList.toggle('active',i===idx);});
document.querySelectorAll('#detailModalOverlay .eval-panel').forEach(function(p,i){p.classList.toggle('active',i===idx);});
}
document.addEventListener('click',function(e){
var dd=document.getElementById('innovIngDropdown');
if(dd&&!dd.contains(e.target)&&e.target.id!=='innovIngSearch'){dd.classList.remove('show');}
});
function openEvalModal(expNo,name,category,goal,members,startDate){
document.getElementById('evalExpNo').textContent = expNo||'—';
document.getElementById('evalName').textContent = name||'—';
document.getElementById('evalCategory').textContent = category||'—';
document.getElementById('evalGoal').textContent = goal||'—';
document.getElementById('evalMembers').textContent = members||'—';
document.getElementById('evalStartDate').textContent = startDate||'—';
document.getElementById('evalEndDate').value = '';
document.getElementById('evalModalOverlay').style.display='flex';
switchEvalTab(0);
}
function closeEvalModal(){document.getElementById('evalModalOverlay').style.display='none';}
document.getElementById('evalModalOverlay').addEventListener('click',function(e){if(e.target===this)closeEvalModal();});
function switchEvalTab(idx){
document.querySelectorAll('.eval-tab').forEach(function(t,i){t.classList.toggle('active',i===idx);});
document.querySelectorAll('.eval-panel').forEach(function(p,i){p.classList.toggle('active',i===idx);});
}
</script>
<!-- 提交评测弹窗 -->
<div class="modal-overlay" id="evalModalOverlay" style="display:none;">
<div class="modal modal--eval">
<div class="modal-header">
<span class="modal-title">提交评测</span>
<span class="modal-close" onclick="closeEvalModal()">&times;</span>
</div>
<div class="modal-body">
<!-- 基本信息 -->
<div style="background:#f8f9fa;border:1px solid var(--border);border-radius:6px;padding:12px 16px;margin-bottom:16px;display:grid;grid-template-columns:repeat(3,1fr);gap:10px 24px;">
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验编号</div><div style="font-size:13px;font-weight:500;" id="evalExpNo"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品名称</div><div style="font-size:13px;font-weight:500;" id="evalName"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品分类</div><div style="font-size:13px;font-weight:500;" id="evalCategory"></div></div>
<div style="grid-column:1/-1"><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">创新目标</div><div style="font-size:13px;font-weight:500;" id="evalGoal"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">参与人员</div><div style="font-size:13px;font-weight:500;" id="evalMembers"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验开始日期</div><div style="font-size:13px;font-weight:500;" id="evalStartDate"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验结束日期<span style="color:#ff4d4f">*</span></div><input type="date" id="evalEndDate" style="height:30px;border:1px solid var(--border);border-radius:4px;padding:0 8px;font-size:13px;outline:none;width:100%;" onfocus="this.style.borderColor='var(--primary)'" onblur="this.style.borderColor='var(--border)'"></div>
</div>
<div class="eval-tabs">
<div class="eval-tab active" onclick="switchEvalTab(0)">🥗 营养检验</div>
<div class="eval-tab" onclick="switchEvalTab(1)">👅 味道检验</div>
<div class="eval-tab" onclick="switchEvalTab(2)">🍴 口感检验</div>
<div class="eval-tab" onclick="switchEvalTab(3)">🎨 色泽检验</div>
</div>
<!-- 营养检验 -->
<div class="eval-panel active" id="evalPanel0">
<div class="metric-grid-4">
<div class="metric-item"><label>热量 (kcal/100g)<span style="color:#ff4d4f">*</span></label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>蛋白质 (g)<span style="color:#ff4d4f">*</span></label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>碳水化合物 (g)<span style="color:#ff4d4f">*</span></label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>脂肪 (g)<span style="color:#ff4d4f">*</span></label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>维生素C (mg)</label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>矿物质 (mg)</label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>膳食纤维 (g)</label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>钠 (mg)</label><input type="number" placeholder="0.0"></div>
<div class="metric-item"><label>营养等级</label><select><option value="">请选择</option><option>达标</option><option>偏差</option><option>未达标</option></select></div>
</div>
</div>
<!-- 味道检验 -->
<div class="eval-panel" id="evalPanel1">
<div class="metric-grid-4">
<div class="metric-item"><label>酸度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>甜度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>苦度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>辣度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>咸度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>气味评分 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" step="0.1" placeholder="0.0"></div>
<div class="metric-item"><label>综合风味评分 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" step="0.1" placeholder="0.0"></div>
<div class="metric-item"><label>综合评级<span style="color:#ff4d4f">*</span></label><select><option value="">请选择</option><option>优秀</option><option>良好</option><option>一般</option><option>较差</option><option>不合格</option></select></div>
</div>
</div>
<!-- 口感检验 -->
<div class="eval-panel" id="evalPanel2">
<div class="metric-grid-4">
<div class="metric-item"><label>软硬度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>黏糯度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>酥脆度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>嫩滑度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>弹性 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>综合口感评分 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" step="0.1" placeholder="0.0"></div>
<div class="metric-item"><label>综合评级<span style="color:#ff4d4f">*</span></label><select><option value="">请选择</option><option>优秀</option><option>良好</option><option>一般</option><option>较差</option><option>不合格</option></select></div>
</div>
</div>
<!-- 色泽检验 -->
<div class="eval-panel" id="evalPanel3">
<div class="metric-grid-4">
<div class="metric-item"><label>主色调<span style="color:#ff4d4f">*</span></label><input type="text" placeholder="如:红褐色"></div>
<div class="metric-item"><label>色泽均匀度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>光泽度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>新鲜度 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>卖相评分 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" placeholder="1-5"></div>
<div class="metric-item"><label>综合色泽评分 (1-5)<span style="color:#ff4d4f">*</span></label><input type="number" min="1" max="5" step="0.1" placeholder="0.0"></div>
<div class="metric-item"><label>综合评级<span style="color:#ff4d4f">*</span></label><select><option value="">请选择</option><option>优秀</option><option>良好</option><option>一般</option><option>较差</option><option>不合格</option></select></div>
</div>
</div>
<!-- 附件与备注 -->
<div style="border-top:1px solid var(--border);margin-top:20px;padding-top:16px;">
<div style="font-size:13px;font-weight:500;color:var(--text-primary);margin-bottom:12px;">📎 附件与备注</div>
<div class="upload-row">
<div>
<label class="eval-note-label">检验视频</label>
<div class="upload-box-dashed" onmouseover="this.style.borderColor='var(--primary)'" onmouseout="this.style.borderColor=''">📹 点击或拖拽上传检验视频<br><span style="font-size:11px;margin-top:4px;display:inline-block;">支持 MP4/MOV,最大 200MB</span></div>
</div>
<div>
<label class="eval-note-label">检验图片</label>
<div class="upload-box-dashed" onmouseover="this.style.borderColor='var(--primary)'" onmouseout="this.style.borderColor=''">📷 点击或拖拽上传检验图片<br><span style="font-size:11px;margin-top:4px;display:inline-block;">支持 JPG/PNG,最大 10MB,最多5张</span></div>
</div>
</div>
<label class="eval-note-label">备注说明</label>
<textarea class="eval-textarea" placeholder="填写检验过程中的特殊情况或补充说明..."></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="closeEvalModal()">取消</button>
<button class="btn btn-primary" onclick="alert('评测已提交');closeEvalModal()">提交评测</button>
</div>
</div>
</div>
<!-- 推演报告弹窗 -->
<div class="modal-overlay" id="aiReportModalOverlay" style="display:none;">
<div class="modal" style="width:720px;">
<div class="modal-header">
<span class="modal-title">推演报告</span>
<span class="modal-close" onclick="document.getElementById('aiReportModalOverlay').style.display='none'">&times;</span>
</div>
<div class="modal-body">
<div style="background:#f8f9fa;border:1px solid var(--border);border-radius:6px;padding:12px 16px;margin-bottom:16px;display:grid;grid-template-columns:repeat(3,1fr);gap:10px 24px;">
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验编号</div><div style="font-size:13px;font-weight:500;" id="rptExpNo"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品名称</div><div style="font-size:13px;font-weight:500;" id="rptName"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品分类</div><div style="font-size:13px;font-weight:500;" id="rptCategory"></div></div>
<div style="grid-column:1/-1"><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">创新目标</div><div style="font-size:13px;font-weight:500;" id="rptGoal"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">AI模型</div><div style="font-size:13px;font-weight:500;color:var(--primary);" id="rptModel"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">推演开始时间</div><div style="font-size:13px;font-weight:500;" id="rptStartTime"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">推演结束时间</div><div style="font-size:13px;font-weight:500;" id="rptEndTime"></div></div>
</div>
<div style="font-size:12px;color:#d46b08;background:#fff7e6;border:1px solid #ffd591;border-radius:4px;padding:6px 12px;margin-bottom:12px;">以下为AI模拟推演预测值,仅供参考,请结合实际实验数据进行判断</div>
<div class="eval-tabs">
<div class="eval-tab active" onclick="switchRptTab(0)">🥗 营养检验</div>
<div class="eval-tab" onclick="switchRptTab(1)">👅 味道检验</div>
<div class="eval-tab" onclick="switchRptTab(2)">🍴 口感检验</div>
<div class="eval-tab" onclick="switchRptTab(3)">🎨 色泽检验</div>
</div>
<!-- 营养检验 -->
<div class="eval-panel active" id="rptPanel0">
<div class="metric-grid-4">
<div class="metric-item"><label>热量 (kcal/100g)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">186.5</div></div>
<div class="metric-item"><label>蛋白质 (g)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">12.3</div></div>
<div class="metric-item"><label>碳水化合物 (g)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">18.6</div></div>
<div class="metric-item"><label>脂肪 (g)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">6.8</div></div>
<div class="metric-item"><label>维生素C (mg)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">15.2</div></div>
<div class="metric-item"><label>矿物质 (mg)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">320</div></div>
<div class="metric-item"><label>膳食纤维 (g)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3.4</div></div>
<div class="metric-item"><label>钠 (mg)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">285</div></div>
<div class="metric-item"><label>营养等级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;"><span class="tag tag-green">达标</span></div></div>
</div>
</div>
<!-- 味道检验 -->
<div class="eval-panel" id="rptPanel1">
<div class="metric-grid-4">
<div class="metric-item"><label>酸度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">2</div></div>
<div class="metric-item"><label>甜度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">1</div></div>
<div class="metric-item"><label>苦度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">1</div></div>
<div class="metric-item"><label>辣度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3</div></div>
<div class="metric-item"><label>咸度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">2</div></div>
<div class="metric-item"><label>气味评分 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4.2</div></div>
<div class="metric-item"><label>综合风味评分 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4.0</div></div>
<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;"><span class="tag tag-green">良好</span></div></div>
</div>
</div>
<!-- 口感检验 -->
<div class="eval-panel" id="rptPanel2">
<div class="metric-grid-4">
<div class="metric-item"><label>软硬度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3</div></div>
<div class="metric-item"><label>黏糯度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">2</div></div>
<div class="metric-item"><label>酥脆度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">1</div></div>
<div class="metric-item"><label>嫩滑度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4</div></div>
<div class="metric-item"><label>弹性 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3</div></div>
<div class="metric-item"><label>综合口感评分 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3.8</div></div>
<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;"><span class="tag tag-green">良好</span></div></div>
</div>
</div>
<!-- 色泽检验 -->
<div class="eval-panel" id="rptPanel3">
<div class="metric-grid-4">
<div class="metric-item"><label>主色调</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">金黄色</div></div>
<div class="metric-item"><label>色泽均匀度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4</div></div>
<div class="metric-item"><label>光泽度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3</div></div>
<div class="metric-item"><label>新鲜度 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4</div></div>
<div class="metric-item"><label>卖相评分 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">4</div></div>
<div class="metric-item"><label>综合色泽评分 (1-5)</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;">3.9</div></div>
<div class="metric-item"><label>综合评级</label><div style="height:36px;border:1px solid var(--border);border-radius:4px;padding:0 12px;font-size:13px;background:#f5f5f5;color:#333;display:flex;align-items:center;"><span class="tag tag-green">良好</span></div></div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="document.getElementById('aiReportModalOverlay').style.display='none'">关闭</button>
</div>
</div>
</div>
<!-- 查看详情弹窗 -->
<div class="modal-overlay" id="detailModalOverlay" style="display:none;">
<div class="modal modal--eval">
<div class="modal-header">
<span class="modal-title">实验详情</span>
<span class="modal-close" onclick="document.getElementById('detailModalOverlay').style.display='none'">&times;</span>
</div>
<div class="modal-body">
<!-- 基本信息 -->
<div style="background:#f8f9fa;border:1px solid var(--border);border-radius:6px;padding:12px 16px;margin-bottom:16px;display:grid;grid-template-columns:repeat(3,1fr);gap:10px 24px;">
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验编号</div><div style="font-size:13px;font-weight:500;" id="dtlExpNo"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品名称</div><div style="font-size:13px;font-weight:500;" id="dtlName"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品分类</div><div style="font-size:13px;font-weight:500;" id="dtlCategory"></div></div>
<div style="grid-column:1/-1"><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">创新目标</div><div style="font-size:13px;font-weight:500;" id="dtlGoal"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">参与人员</div><div style="font-size:13px;font-weight:500;" id="dtlMembers"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验开始日期</div><div style="font-size:13px;font-weight:500;" id="dtlStartDate"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验结束日期</div><div style="font-size:13px;font-weight:500;" id="dtlEndDate"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">状态</div><div style="font-size:13px;font-weight:500;" id="dtlStatus"></div></div>
</div>
<!-- 餐品构成 -->
<div style="margin-bottom:16px;">
<div style="font-size:13px;font-weight:500;color:var(--text-primary);margin-bottom:8px;">🥘 餐品构成</div>
<table style="width:100%;border-collapse:collapse;font-size:13px;">
<thead><tr style="background:#fafafa;"><th style="padding:8px 12px;border:1px solid var(--border);text-align:left;font-weight:500;">食材名称</th><th style="padding:8px 12px;border:1px solid var(--border);text-align:left;font-weight:500;">分类</th><th style="padding:8px 12px;border:1px solid var(--border);text-align:left;font-weight:500;">用量</th><th style="padding:8px 12px;border:1px solid var(--border);text-align:left;font-weight:500;">主/辅料</th></tr></thead>
<tbody id="dtlIngTable"><tr><td colspan="4" style="padding:12px;text-align:center;color:#999;border:1px solid var(--border);">暂无数据</td></tr></tbody>
</table>
</div>
<!-- 评测数据 -->
<div id="dtlEvalSection">
<div class="eval-tabs">
<div class="eval-tab active" onclick="switchDtlTab(0)">🥗 营养检验</div>
<div class="eval-tab" onclick="switchDtlTab(1)">👅 味道检验</div>
<div class="eval-tab" onclick="switchDtlTab(2)">🍴 口感检验</div>
<div class="eval-tab" onclick="switchDtlTab(3)">🎨 色泽检验</div>
</div>
<div class="eval-panel active" id="dtlPanel0"></div>
<div class="eval-panel" id="dtlPanel1"></div>
<div class="eval-panel" id="dtlPanel2"></div>
<div class="eval-panel" id="dtlPanel3"></div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="document.getElementById('detailModalOverlay').style.display='none'">关闭</button>
</div>
</div>
</div>
<!-- 人工审核弹窗(编辑/只读两种模式) -->
<div class="modal-overlay" id="aiReviewModalOverlay" style="display:none;">
<div class="modal" style="width:520px;">
<div class="modal-header">
<span class="modal-title" id="rvwModalTitle">人工审核</span>
<span class="modal-close" onclick="document.getElementById('aiReviewModalOverlay').style.display='none'">&times;</span>
</div>
<div class="modal-body">
<!-- 基本信息 -->
<div style="background:#f8f9fa;border:1px solid var(--border);border-radius:6px;padding:10px 16px;margin-bottom:16px;display:flex;gap:32px;">
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">实验编号</div><div style="font-size:13px;font-weight:500;" id="rvwExpNo"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">餐品名称</div><div style="font-size:13px;font-weight:500;" id="rvwName"></div></div>
</div>
<!-- 编辑模式 -->
<div id="rvwEditMode" style="display:flex;flex-direction:column;gap:14px;">
<div>
<label style="font-size:13px;color:var(--text-secondary);display:block;margin-bottom:8px;">审核结论<span style="color:#ff4d4f">*</span></label>
<div style="display:flex;gap:24px;">
<label style="display:flex;align-items:center;gap:6px;font-size:13px;cursor:pointer;">
<input type="radio" name="rvwResult" value="pass" style="accent-color:var(--primary);width:15px;height:15px;">
<span style="color:#52c41a;font-weight:500;">审核通过</span>
</label>
<label style="display:flex;align-items:center;gap:6px;font-size:13px;cursor:pointer;">
<input type="radio" name="rvwResult" value="reject" style="accent-color:#ff4d4f;width:15px;height:15px;">
<span style="color:#ff4d4f;font-weight:500;">审核不通过</span>
</label>
</div>
</div>
<div><label style="font-size:13px;color:var(--text-secondary);display:block;margin-bottom:6px;">审核意见</label>
<textarea id="rvwComment" style="width:100%;height:80px;border:1px solid var(--border);border-radius:4px;padding:8px 12px;font-size:13px;outline:none;resize:vertical;font-family:inherit;" placeholder="请填写审核意见或建议..."></textarea>
</div>
</div>
<!-- 只读模式 -->
<div id="rvwReadMode" style="display:none;flex-direction:column;gap:14px;">
<div style="display:flex;gap:24px;align-items:center;">
<div style="font-size:13px;color:var(--text-secondary);">审核结论</div>
<div id="rvwResultDisplay" style="font-size:14px;font-weight:600;"></div>
</div>
<div>
<div style="font-size:13px;color:var(--text-secondary);margin-bottom:6px;">审核意见</div>
<div id="rvwCommentDisplay" style="font-size:13px;color:#333;background:#f8f9fa;border:1px solid var(--border);border-radius:4px;padding:8px 12px;min-height:60px;line-height:1.6;"></div>
</div>
<div style="display:flex;gap:32px;">
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">审核人</div><div style="font-size:13px;font-weight:500;" id="rvwReviewer"></div></div>
<div><div style="font-size:11px;color:#8c8c8c;margin-bottom:2px;">审核时间</div><div style="font-size:13px;font-weight:500;" id="rvwReviewTime"></div></div>
</div>
</div>
</div>
<div class="modal-footer" id="rvwFooter">
<button class="btn btn-default" onclick="document.getElementById('aiReviewModalOverlay').style.display='none'">取消</button>
<button class="btn btn-primary" onclick="alert('审核意见已提交');document.getElementById('aiReviewModalOverlay').style.display='none'">提交审核</button>
</div>
</div>
</div>
<!-- 发起AI模拟推演弹窗 -->
<div class="modal-overlay" id="aiLaunchModalOverlay" style="display:none;">
<div class="modal">
<div class="modal-header">
<span class="modal-title">发起AI模拟推演</span>
<span class="modal-close" onclick="document.getElementById('aiLaunchModalOverlay').style.display='none'">&times;</span>
</div>
<div class="modal-body">
<div class="form-grid">
<div class="form-item"><label>餐品名称<span class="required">*</span></label><input type="text" placeholder="请输入餐品名称"></div>
<div class="form-item"><label>餐品分类<span class="required">*</span></label><select><option>请选择</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<div class="form-item"><label>烹饪方法</label><select><option>请选择</option><option></option><option></option><option></option><option></option><option></option><option></option><option></option><option>低温慢煮</option><option>低温发酵</option></select></div>
<div class="form-item"><label>适用餐次</label><select><option>请选择</option><option>早餐</option><option>午餐</option><option>晚餐</option><option>早餐+午餐</option><option>午餐+晚餐</option><option>全天</option></select></div>
<div class="form-item"><label>膳食宝塔分类</label><select><option>请选择</option><option>谷薯类</option><option>蔬菜类</option><option>水果类</option><option>畜禽肉类</option><option>水产品</option><option>蛋类</option><option>奶及奶制品</option><option>大豆及坚果</option><option>油脂及调味品</option></select></div>
<div class="form-item full">
<label>餐品构成</label>
<div class="innov-ing-section">
<div class="innov-add-row">
<div class="innov-search-wrap">
<input id="aiLaunchIngSearch" class="innov-search-input" type="text" placeholder="搜索食材名称" oninput="aiLaunchSearchIng()" autocomplete="off">
<div class="innov-dropdown" id="aiLaunchIngDropdown"></div>
</div>
<input id="aiLaunchIngAmount" class="innov-amount-input" type="text" placeholder="用量(g)">
<select id="aiLaunchIngIsMain" class="innov-type-select"><option value="主料">主料</option><option value="辅料">辅料</option></select>
<button type="button" class="btn btn-primary btn-sm" onclick="aiLaunchAddIngRow()">添加</button>
</div>
<table class="innov-ing-table">
<thead><tr><th>食材名称</th><th>分类</th><th>用量</th><th>主/辅料</th><th>操作</th></tr></thead>
<tbody id="aiLaunchIngTableBody">
<tr id="aiLaunchIngEmptyRow"><td colspan="5" style="text-align:center;color:#999;padding:12px;">暂无食材,请搜索添加</td></tr>
</tbody>
</table>
</div>
</div>
<div class="form-item full"><label>创新目标<span class="required">*</span></label><input type="text" placeholder="请输入创新目标,如:减少60%钠含量,保留麻辣风味"></div>
<div class="form-item"><label>AI模型<span class="required">*</span></label><select><option>请选择</option><option>NutriAI v2.3(营养推理)</option><option>FlavorAI v1.8(风味融合)</option><option>HealthAI v3.0(健康优化)</option><option>ChefAI v2.1(烹饪工艺)</option></select></div>
<div class="form-item"><label>实验开始日期</label><input type="date"></div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" onclick="document.getElementById('aiLaunchModalOverlay').style.display='none'">取消</button>
<button class="btn btn-primary" onclick="alert('推演任务已发起,预计5分钟内完成');document.getElementById('aiLaunchModalOverlay').style.display='none'">发起推演</button>
</div>
</div>
</div>
<script>
function openAiReportModal(expNo,name,category,goal,model,startTime,endTime){
document.getElementById('rptExpNo').textContent=expNo||'—';
document.getElementById('rptName').textContent=name||'—';
document.getElementById('rptCategory').textContent=category||'—';
document.getElementById('rptGoal').textContent=goal||'—';
document.getElementById('rptModel').textContent=model||'—';
document.getElementById('rptStartTime').textContent=startTime||'—';
document.getElementById('rptEndTime').textContent=endTime||'—';
switchRptTab(0);
document.getElementById('aiReportModalOverlay').style.display='flex';
}
function switchRptTab(idx){
document.querySelectorAll('#aiReportModalOverlay .eval-tab').forEach(function(t,i){t.classList.toggle('active',i===idx);});
document.querySelectorAll('#aiReportModalOverlay .eval-panel').forEach(function(p,i){p.classList.toggle('active',i===idx);});
}
function openAiReviewModal(expNo,name){
// 编辑模式
document.getElementById('rvwModalTitle').textContent='人工审核';
document.getElementById('rvwExpNo').textContent=expNo||'—';
document.getElementById('rvwName').textContent=name||'—';
document.querySelectorAll('input[name="rvwResult"]').forEach(function(r){r.checked=false;});
document.getElementById('rvwComment').value='';
document.getElementById('rvwEditMode').style.display='flex';
document.getElementById('rvwReadMode').style.display='none';
document.getElementById('rvwFooter').style.display='flex';
document.getElementById('aiReviewModalOverlay').style.display='flex';
}
function openAiViewReview(expNo,name,result,comment,reviewer,reviewTime){
// 只读模式
document.getElementById('rvwModalTitle').textContent='查看审核';
document.getElementById('rvwExpNo').textContent=expNo||'—';
document.getElementById('rvwName').textContent=name||'—';
var rd=document.getElementById('rvwResultDisplay');
if(result==='pass'){rd.textContent='审核通过';rd.style.color='#52c41a';}
else{rd.textContent='审核不通过';rd.style.color='#ff4d4f';}
document.getElementById('rvwCommentDisplay').textContent=comment||'—';
document.getElementById('rvwReviewer').textContent=reviewer||'—';
document.getElementById('rvwReviewTime').textContent=reviewTime||'—';
document.getElementById('rvwEditMode').style.display='none';
document.getElementById('rvwReadMode').style.display='flex';
document.getElementById('rvwFooter').innerHTML='<button class="btn btn-default" onclick="document.getElementById(\'aiReviewModalOverlay\').style.display=\'none\'">关闭</button>';
document.getElementById('aiReviewModalOverlay').style.display='flex';
}
function openAiLaunchModal(expNo,name){
// 重置食材表格
var tbody=document.getElementById('aiLaunchIngTableBody');
if(tbody){tbody.innerHTML='<tr id="aiLaunchIngEmptyRow"><td colspan="5" style="text-align:center;color:#999;padding:12px;">暂无食材,请搜索添加</td></tr>';}
document.getElementById('aiLaunchIngSearch').value='';
document.getElementById('aiLaunchIngAmount').value='';
document.getElementById('aiLaunchModalOverlay').style.display='flex';
}
var aiLaunchIngRows=[];
function aiLaunchSearchIng(){
var q=document.getElementById('aiLaunchIngSearch').value.trim();
var dd=document.getElementById('aiLaunchIngDropdown');
if(!q){dd.style.display='none';return;}
var res=INNOV_ING_LIST.filter(function(i){return i.name.indexOf(q)!==-1;});
if(!res.length){dd.style.display='none';return;}
dd.innerHTML=res.slice(0,8).map(function(i){return '<div class="innov-dropdown-item" onclick="aiLaunchSelectIng(\''+i.name+'\',\''+i.cat+'\')">'+i.name+' <span style="color:#999;font-size:12px;">'+i.cat+'</span></div>';}).join('');
dd.style.display='block';
}
function aiLaunchSelectIng(name,cat){
document.getElementById('aiLaunchIngSearch').value=name;
document.getElementById('aiLaunchIngSearch').dataset.cat=cat;
document.getElementById('aiLaunchIngDropdown').style.display='none';
}
function aiLaunchAddIngRow(){
var name=document.getElementById('aiLaunchIngSearch').value.trim();
var cat=document.getElementById('aiLaunchIngSearch').dataset.cat||'—';
var amount=document.getElementById('aiLaunchIngAmount').value.trim();
var isMain=document.getElementById('aiLaunchIngIsMain').value;
if(!name)return;
var empty=document.getElementById('aiLaunchIngEmptyRow');
if(empty)empty.remove();
var tbody=document.getElementById('aiLaunchIngTableBody');
var tr=document.createElement('tr');
tr.innerHTML='<td>'+name+'</td><td>'+cat+'</td><td>'+(amount||'—')+'</td><td>'+isMain+'</td><td><span class="link" style="color:var(--danger)" onclick="this.closest(\'tr\').remove()">删除</span></td>';
tbody.appendChild(tr);
document.getElementById('aiLaunchIngSearch').value='';
document.getElementById('aiLaunchIngAmount').value='';
}
document.getElementById('aiReportModalOverlay').addEventListener('click',function(e){if(e.target===this)this.style.display='none';});
document.getElementById('aiReviewModalOverlay').addEventListener('click',function(e){if(e.target===this)this.style.display='none';});
document.getElementById('aiLaunchModalOverlay').addEventListener('click',function(e){if(e.target===this)this.style.display='none';});
document.getElementById('detailModalOverlay').addEventListener('click',function(e){if(e.target===this)this.style.display='none';});
</script>
</body>
</html>
@@ -1312,4 +1312,38 @@
- 地块管理:表格改为二级表头(基本信息+最新监测数据);
- 新增灌溉方式/土壤类型/负责人字段;
- 操作从纯文本改为4个操作按钮;
- 新增地块/养殖区的新增/编辑/详情/采集记录弹窗
- 新增地块/养殖区的新增/编辑/详情/采集记录弹窗
#### 9.5 味养创新
##### 1. din-innovation.html(味养创新)
**人工创新列表**
- 新增「餐品构成」列,位于「餐品分类」之后,展示该创新餐品所含食材组合;
- 「查看详情」链接改为调用 `openDetailModal(id)` 弹出详情弹窗。
**AI创新列表**
- 移除「参与人员」「烹饪方法」「适用餐次」三列,精简列结构;
- 「实验开始日期」列重命名为「推演开始时间」;
- 最终列顺序:实验编号 / 餐品名称 / 餐品分类 / 创新目标 / 餐品构成 / 推演开始时间 / AI模型 / 模拟状态 / 操作。
**发起AI模拟推演弹窗**
- 表单结构对齐「新建人工创新」,字段改为:餐品名称 / 餐品分类 / 烹饪方法 / 适用餐次 / 膳食宝塔分类 / 餐品构成(含食材搜索组件)/ 创新目标;
- 在「创新目标」之后新增「AI模型」下拉字段,选项:NutriAI v2.3(营养推理)/ FlavorAI v1.8(风味融合)/ HealthAI v3.0(健康优化)/ ChefAI v2.1(烹饪工艺);
- 移除原「参与人员」字段。
**人工审核弹窗(双模式)**
- 编辑模式(点击「人工审核」按钮打开):审核结论改为单选框样式,选项为「审核通过」(绿色)/ 「审核不通过」(红色),移除「审核人」字段;
- 只读模式(点击「查看审核」按钮打开):弹窗内所有字段变为纯展示,额外展示「审核人」和「审核时间」,底部仅保留「关闭」按钮。
**人工创新查看详情弹窗(新增)**
- 顶部基本信息卡片:展示实验编号 / 餐品名称 / 餐品分类 / 烹饪方法 / 适用餐次 / 膳食宝塔分类 / 创新目标 / 推演开始时间 / 推演结束时间;
- 中部餐品构成表:列出所含食材及其用量;
- 下方评测数据区:标签页切换展示营养检验 / 味道检验 / 口感检验 / 色泽检验四维度详细指标,实验进行中时显示「实验进行中,暂无评测数据」占位提示。
##### 2. din-dish-add.html(新建/转化餐品)
**修复 AI创新转化餐品侧边栏高亮问题**
- 问题:从 AI 创新列表点击「转化餐品」进入新建页时,左侧菜单高亮项错误显示为「餐品总库」而非「味养创新」;
- 根因:AI 创新实验编号(INN-A0XX)不在 `INNOV_MAP` 中,导致 `INNOV` 为 null,原侧边栏修复逻辑嵌套在 `if(pageMode==='convert' && INNOV)` 块内被跳过;
- 修复:将侧边栏 active 切换、页面标题和面包屑修改提取到独立的 `if(pageMode==='convert')` 块,数据预填逻辑保留在 `if(pageMode==='convert' && INNOV)` 块内,两者解耦。