const $=s=>document.querySelector(s),$$=s=>[...document.querySelectorAll(s)];let state={tasks:[],projects:[],leads:[],reports:[],selected:null};
const api=async(url,opt={})=>{const r=await fetch(url,{headers:{'Content-Type':'application/json'},...opt});const b=await r.json();if(!r.ok)throw Error(b.error||'操作失败');return b};const note=t=>{let n=$('#notice');n.textContent=t;n.style.display='block';setTimeout(()=>n.style.display='none',2200)};const tag=s=>`<span class="tag ${['正常','已完成'].includes(s)?'normal':''}">${s||'待处理'}</span>`;const projectName=id=>state.projects.find(x=>x.id===id)?.name||'未归属';
async function load(){let [d,t,p,l,r]=await Promise.all(['/api/dashboard','/api/tasks','/api/projects','/api/leads','/api/reports'].map(api));Object.assign(state,{tasks:t,projects:p,leads:l,reports:r});$('#metrics').innerHTML=[['任务总数',d.taskCount],['风险任务',d.overdueCount],['进行中项目',d.projectCount],['销售线索/商机',d.leadCount]].map(x=>`<div class="metric"><span>${x[0]}</span><b>${x[1]}</b></div>`).join('');$('#risk-list').innerHTML=d.risks.map(x=>`<div class="row"><strong>${x.name}</strong><span>${x.owner}</span><span>${x.nextMilestone||''}</span>${tag(x.status)}<button data-project-id="${x.id}">查看</button></div>`).join('')||'暂无风险项目';renderTasks();renderProjects();renderLeads();renderReports();$('#task-project').innerHTML='<option value="">请选择项目</option>'+p.map(x=>`<option value="${x.id}">${x.name}</option>`).join('')}
function renderTasks(){$('#task-list').innerHTML=state.tasks.map(x=>`<div class="row"><strong>${x.title}<small> · ${projectName(x.projectId)}</small></strong><span>${x.owner}</span><span>${x.due||'未设置'}</span>${tag(x.status)}<button data-task-id="${x.id}">详情</button></div>`).join('')||'暂无任务'}
function renderProjects(){$('#project-list').innerHTML=state.projects.map(x=>`<article class="project-card"><h3>${x.name}</h3><div class="project-meta"><span>${x.category}</span>${tag(x.status)}</div><progress value="${x.progress||0}" max="100"></progress><div class="project-meta"><span>负责人 ${x.owner}</span><span>${x.progress||0}%</span></div><p>下一里程碑：${x.nextMilestone||'未设置'}</p><button data-project-id="${x.id}">查看项目</button></article>`).join('')}
function renderLeads(){$('#lead-list').innerHTML=state.leads.map(x=>`<div class="row"><strong>${x.name}<small> · ${x.company}</small></strong><span>${x.owner}</span><span>${x.stage}</span>${tag(x.intention)}<button data-lead-id="${x.id}">推进阶段</button></div>`).join('')}
function renderReports(){$('#report-list').innerHTML=state.reports.map(x=>`<article class="report-card"><b>${x.author}的${x.type}</b><small> ${x.period||''}</small><p>${x.content}</p><div>${tag('已提交')} <button>评论</button></div></article>`).join('')}
function showPage(id){$$('#nav button').forEach(x=>x.classList.toggle('active',x.dataset.page===id));$$('.page').forEach(x=>x.classList.toggle('active',x.id===id))}function closeOverlays(){$$('.overlay').forEach(x=>x.classList.add('hidden'))}function openTask(){closeOverlays();$('#task-create').classList.remove('hidden')}
function taskDetail(id){let x=state.tasks.find(t=>t.id===id);if(!x)return;state.selected=x;$('#detail-title').textContent=x.title;$('#detail-status').textContent=x.status||'待处理';$('#detail-owner').textContent='负责人 '+(x.owner||'待确认');$('#detail-time').textContent=(x.start||'未设置')+' — '+(x.due||'未设置');$('#detail-priority').textContent=x.priority||'P3 普通';$('#detail-progress').value=Number(x.progress||0);$('#detail-progress-text').textContent=(x.progress||0)+'%';$('#detail-project').textContent=projectName(x.projectId);$('#detail-description').textContent=x.description||'未填写';$('#detail-target').textContent=x.target||'未设置';$('#detail-participants').textContent=x.participants||'暂无';$('#detail-creator').textContent=x.creator||'当前用户';$('#detail-approver').textContent=x.approver||'暂无';$('#subtask-list').innerHTML=(x.subtasks||[]).map(s=>`<div class="subtask">☐ ${s.title||s}</div>`).join('')||'<p>暂无子任务</p>';$('#comment-list').innerHTML=(x.comments||[]).map(c=>`<div class="comment"><b>${c.author}</b> ${c.content}</div>`).join('')||'<p>暂无互动</p>';$('#progress-log').innerHTML=`<div class="log">当前进度 ${x.progress||0}% · 状态 ${x.status||'待处理'}</div>`;closeOverlays();$('#task-detail').classList.remove('hidden')}
$$('#nav button').forEach(b=>b.onclick=()=>showPage(b.dataset.page));$$('[data-page-jump]').forEach(b=>b.onclick=()=>showPage(b.dataset.pageJump));$$('[data-open-task]').forEach(b=>b.onclick=openTask);$$('[data-close]').forEach(b=>b.onclick=closeOverlays);
$('#task-form').onsubmit=async e=>{e.preventDefault();let b=Object.fromEntries(new FormData(e.target));b.progress=0;b.status='待处理';b.subtasks=[];b.comments=[];delete b.attachment;await api('/api/tasks',{method:'POST',body:JSON.stringify(b)});if(!b.createNext){closeOverlays();e.target.reset()}note('任务已创建');await load()};
$('#ai-fill-task').onclick=()=>{let f=$('#task-form');if(!f.description.value)f.description.value='请补充任务背景、交付要求、完成标准和风险说明。';if(!f.target.value)f.target.value='按约定时间完成并由审批人确认';note('AI已补充任务草稿')};
$('#add-subtask').onclick=async()=>{let title=prompt('请输入子任务名称');if(!title)return;let list=[...(state.selected.subtasks||[]),{title,status:'待处理'}];state.selected=await api('/api/tasks/'+state.selected.id,{method:'PATCH',body:JSON.stringify({subtasks:list})});taskDetail(state.selected.id);note('子任务已添加')};
$('#update-progress').onclick=async()=>{let value=prompt('请输入进度 0-100',state.selected.progress||0);if(value===null)return;value=Math.max(0,Math.min(100,Number(value)));state.selected=await api('/api/tasks/'+state.selected.id,{method:'PATCH',body:JSON.stringify({progress:value,status:value===100?'已完成':'进行中'})});await load();taskDetail(state.selected.id)};
$('#send-comment').onclick=async()=>{let content=$('#comment-input').value.trim();if(!content)return;let comments=[...(state.selected.comments||[]),{author:'刘祖伟',content,time:new Date().toISOString()}];state.selected=await api('/api/tasks/'+state.selected.id,{method:'PATCH',body:JSON.stringify({comments})});$('#comment-input').value='';taskDetail(state.selected.id)};
$('#detail-ai').onclick=async()=>{let r=await api('/api/ai',{method:'POST',body:JSON.stringify({prompt:'分析任务风险：'+state.selected.title})});alert(r.message)};
document.body.addEventListener('click',async e=>{let b=e.target.closest('button');if(!b)return;if(b.dataset.taskId)taskDetail(b.dataset.taskId);if(b.dataset.projectId){showPage('projects');note('已定位项目')}if(b.dataset.leadId){let stages=['线索','需求确认','方案确认','商务谈判','已签约','进入交付'],x=state.leads.find(v=>v.id===b.dataset.leadId),next=stages[Math.min(stages.length-1,stages.indexOf(x.stage)+1)];await api('/api/leads/'+x.id,{method:'PATCH',body:JSON.stringify({stage:next})});load();note('销售阶段已推进')}});
function simple(title,fields,onSubmit){$('#simple-title').textContent=title;let f=$('#simple-form');f.innerHTML=fields+'<div class="modal-actions"><button type="button" data-close>取消</button><button class="primary">保存</button></div>';f.onsubmit=onSubmit;$('#simple-modal').classList.remove('hidden');f.querySelector('[data-close]').onclick=closeOverlays}
$('#new-project').onclick=()=>simple('新建项目','<label>项目名称<input name="name" required></label><label>分类<select name="category"><option>销售交付</option><option>产品研发</option><option>市场活动</option><option>客户实施</option><option>内部管理</option></select></label><label>负责人<input name="owner" required></label><label>下一里程碑<input name="nextMilestone"></label>',async e=>{e.preventDefault();let b=Object.fromEntries(new FormData(e.target));b.progress=0;b.status='正常';await api('/api/projects',{method:'POST',body:JSON.stringify(b)});closeOverlays();load()});
$('#new-lead').onclick=()=>simple('新建销售线索','<label>线索名称<input name="name" required></label><label>客户名称<input name="company" required></label><label>负责人<input name="owner" required></label><label>阶段<select name="stage"><option>线索</option><option>需求确认</option></select></label>',async e=>{e.preventDefault();let b=Object.fromEntries(new FormData(e.target));b.intention='待判断';await api('/api/leads',{method:'POST',body:JSON.stringify(b)});closeOverlays();load()});
$('#new-report').onclick=()=>simple('写汇报','<label>类型<select name="type"><option>日报</option><option>周报</option><option>月报</option></select></label><label>汇报人<input name="author" value="刘祖伟" required></label><label>周期<input name="period"></label><label class="wide">内容<textarea name="content" required></textarea></label>',async e=>{e.preventDefault();await api('/api/reports',{method:'POST',body:JSON.stringify(Object.fromEntries(new FormData(e.target)))});closeOverlays();load()});
$('#msg-send').onclick=async()=>{let r=await api('/api/wecom/simulate',{method:'POST',body:JSON.stringify({userId:'demo-user',text:$('#msg-input').value})});$('#msg-result').textContent=r.reply;await load()};$('#ai-send').onclick=async()=>{let r=await api('/api/ai',{method:'POST',body:JSON.stringify({prompt:$('#ai-input').value})});$('#ai-result').textContent=r.message+(r.draft?'\n'+JSON.stringify(r.draft,null,2):'')};$('#refresh').onclick=()=>load().then(()=>note('已刷新'));load().catch(e=>note(e.message));
