const defaults={
products:[{name:'SlimFit Balance',spec:'60粒 / 30天',price:'$39.90',stock:'999',url:'https://example.com/buy/slimfit'}],
faqs:[
{q:'产品主要成分是什么?',a:'仅根据产品标签回答:绿茶提取物、膳食纤维和维生素复合配方。实际成分请以包装标签为准。'},
{q:'怎么使用?',a:'建议按照包装说明使用,不得自行增加用量。若正在服药或有基础疾病,请先咨询专业医疗人员。'},
{q:'多久能看到效果?',a:'个体情况不同,不能承诺固定时间或固定减重数字。饮食、运动、睡眠和个人体质都会影响结果。'},
{q:'孕妇可以使用吗?',a:'不建议。孕妇、哺乳期、未成年人、慢性病患者或正在服药者需要先咨询医生,并转人工处理。'}
],
intents:[
{name:'价格咨询',keywords:'多少钱,价格,优惠',action:'自动回复'},
{name:'成分/用法',keywords:'成分,怎么吃,使用',action:'查知识库'},
{name:'购买意向',keywords:'我要买,怎么付款,下单',action:'发送购买链接'},
{name:'健康风险',keywords:'怀孕,哺乳,未成年,慢性病,吃药,副作用',action:'转人工'},
{name:'投诉退款',keywords:'退款,投诉,没效果,骗人',action:'转人工'},
{name:'普通寒暄',keywords:'你好,在吗,hello',action:'自动回复'}
],
followups:[
{condition:'问过价格后未回复',wait:'6小时',max:'1',text:'您好,刚才您咨询了 SlimFit 的价格,还有哪一点需要我帮您确认?',enabled:true},
{condition:'发送购买链接后未付款',wait:'12小时',max:'2',text:'您好,之前的购买链接仍然有效。需要我帮您确认规格、价格或配送信息吗?',enabled:true},
{condition:'客户明确拒绝或要求勿扰',wait:'停止',max:'0',text:'不再发送任何自动回访。',enabled:true}
],
logs:[]
};
let state=load();
function load(){try{return {...defaults,...JSON.parse(localStorage.getItem('slimfit-demo')||'{}')}}catch{return structuredClone(defaults)}}
function save(){document.querySelectorAll('[data-key]').forEach(el=>state[el.dataset.key]=el.type==='checkbox'?el.checked:el.value);localStorage.setItem('slimfit-demo',JSON.stringify(state));toast('配置已保存')}
function toast(t){const el=document.getElementById('toast');el.textContent=t;el.classList.add('show');setTimeout(()=>el.classList.remove('show'),1800)}
const meta={dashboard:['总览','查看客服系统当前配置与运行状态'],project:['项目配置','配置模型、语言、渠道和系统提示词'],products:['产品资料','维护 AI 可以读取的商品信息'],faq:['FAQ 知识库','维护常见问题的标准答案'],rules:['AI 规则','设置意图识别、动作和禁止表达'],followup:['回访规则','设置主动回访的条件、时间和次数'],test:['对话测试','模拟客户消息并查看 AI 判定'],logs:['运行日志','查看最近的测试和动作记录']};
document.querySelectorAll('.nav-item').forEach(btn=>btn.onclick=()=>{document.querySelectorAll('.nav-item,.view').forEach(x=>x.classList.remove('active'));btn.classList.add('active');document.getElementById(btn.dataset.view).classList.add('active');pageTitle.textContent=meta[btn.dataset.view][0];pageDesc.textContent=meta[btn.dataset.view][1]});
function bind(){document.querySelectorAll('[data-key]').forEach(el=>{if(state[el.dataset.key]!==undefined){if(el.type==='checkbox')el.checked=state[el.dataset.key];else el.value=state[el.dataset.key]}})}
function renderProducts(){productRows.innerHTML='';state.products.forEach((p,i)=>{const tr=document.createElement('tr');tr.innerHTML=`
`;const inputs=tr.querySelectorAll('input');['name','spec','price','stock','url'].forEach((k,j)=>inputs[j].oninput=e=>state.products[i][k]=e.target.value);tr.querySelector('button').onclick=()=>{state.products.splice(i,1);renderProducts()};productRows.appendChild(tr)})}
function renderFaq(){faqList.innerHTML='';state.faqs.forEach((f,i)=>{const el=document.createElement('div');el.className='faq-item';el.innerHTML=`
问答 ${i+1}
`;el.querySelector('input').oninput=e=>f.q=e.target.value;el.querySelector('textarea').oninput=e=>f.a=e.target.value;el.querySelector('button').onclick=()=>{state.faqs.splice(i,1);renderFaq()};faqList.appendChild(el)})}
function renderIntents(){intentRules.innerHTML='';state.intents.forEach((r,i)=>{const el=document.createElement('div');el.className='rule-item';el.innerHTML=``;const [a,b]=el.querySelectorAll('input');a.oninput=e=>r.name=e.target.value;b.oninput=e=>r.keywords=e.target.value;const s=el.querySelector('select');s.value=r.action;s.onchange=e=>r.action=e.target.value;intentRules.appendChild(el)})}
function renderFollowups(){followupRows.innerHTML='';state.followups.forEach((r,i)=>{const tr=document.createElement('tr');tr.innerHTML=`
`;const inputs=tr.querySelectorAll('input');inputs[0].oninput=e=>r.condition=e.target.value;inputs[1].oninput=e=>r.wait=e.target.value;inputs[2].oninput=e=>r.max=e.target.value;inputs[3].onchange=e=>r.enabled=e.target.checked;tr.querySelector('textarea').oninput=e=>r.text=e.target.value;followupRows.appendChild(tr)})}
function renderLogs(){logRows.innerHTML='';(state.logs||[]).slice().reverse().forEach(l=>{const tr=document.createElement('tr');tr.innerHTML=`