Files
tongjiweb/server/public/assets/Dashboard-CewBG_Ld.js
T

2 lines
27 KiB
JavaScript

import{_ as ut,p as me,q as ct,s as pt,h as p,f as I,E as ee,c as v,a,b as d,w as m,v as _e,r as k,j as G,x as mt,o as u,e as f,y as Z,k as R,t as h,F as U,i as A,n as Ge,z as te}from"./index-B5IUyHJe.js";import{b as x}from"./index-OKS9XN2R.js";import{i as Ze,L as _t}from"./index-Bn9PLWWT.js";const vt={class:"dashboard-page"},ft={class:"page-header",style:{display:"flex","justify-content":"space-between","align-items":"flex-end"}},ht={style:{display:"flex",gap:"12px","align-items":"center"}},gt={class:"filter-bar"},yt={class:"two-col-layout"},bt={class:"table-col"},wt={style:{padding:"10px 40px",background:"rgba(0,0,0,0.2)"}},kt={style:{"margin-bottom":"8px","font-weight":"bold",color:"var(--text-secondary)"}},xt={class:"chart-col"},Dt={class:"chart-card"},Rt={class:"chart-card",style:{"margin-top":"16px"}},St={class:"filter-bar"},Mt={class:"two-col-layout"},$t={class:"table-col"},Vt={class:"chart-col"},Ct={class:"chart-card"},jt={class:"chart-card",style:{"margin-top":"16px"}},zt={class:"filter-bar"},Lt={class:"two-col-layout"},Yt={class:"table-col"},Et={style:{padding:"10px 40px",background:"rgba(0,0,0,0.2)"}},Ut={style:{"margin-bottom":"8px","font-weight":"bold",color:"var(--text-secondary)"}},At={class:"chart-col"},Ot={class:"chart-card"},Ft={class:"chart-card",style:{"margin-top":"16px"}},Nt={class:"filter-bar"},Pt={class:"content-card",style:{"margin-top":"16px","overflow-x":"auto"}},Wt={key:0,class:"matrix-table"},Bt={class:"row-header"},Ht={class:"total-col"},Tt={class:"filter-bar"},Gt={key:0,class:"content-card",style:{"margin-top":"16px","overflow-x":"auto"}},Zt={class:"card-title"},Kt={key:0,class:"grid-table"},qt={class:"day-weekday"},Xt=["onClick"],Jt=["title"],Qt={class:"cell-hours"},It={class:"total-cell"},ea={key:1,class:"two-col-layout",style:{"margin-top":"16px"}},ta={class:"table-col",style:{flex:"1.5"}},aa={class:"content-card",style:{"margin-bottom":"0"}},la={class:"card-title"},sa=["onClick"],oa={class:"day-header"},na={class:"day-num"},da={key:0,class:"weekend-tag"},ra={key:0,class:"day-body"},ia={key:0,class:"status-badge filled"},ua={key:1,class:"status-badge partial"},ca={key:2,class:"status-badge unfilled"},pa={class:"chart-col",style:{flex:"1","min-width":"320px"}},ma={class:"content-card"},_a={class:"mini-stats-grid"},va={class:"mini-stat-item green-glow"},fa={class:"value green-text"},ha={class:"mini-stat-item yellow-glow"},ga={class:"value yellow-text"},ya={class:"mini-stat-item red-glow"},ba={class:"value red-text"},wa={class:"mini-stat-item purple-glow"},ka={class:"value purple-text"},xa={class:"content-card",style:{"margin-top":"16px"}},Da={class:"card-title"},Ra={__name:"Dashboard",setup(Sa){const ve=p("sales"),Ye=p([]),D=p([]),fe=p(null),he=p(null),ge=p(null),ye=p(null),be=p(null),we=p(null);let $=null,V=null,C=null,j=null,z=null,L=null;const ae=p(!1),K=(()=>{const t=new Date,e=new Date;e.setMonth(e.getMonth()-1);const l=s=>String(s).padStart(2,"0"),n=s=>`${s.getFullYear()}-${l(s.getMonth()+1)}-${l(s.getDate())}`;return[n(e),n(t)]})(),N=p(K),Y=I({dateRange:K}),Ee=p([]),Ue=p([]),ke=p(!1),le=G(()=>{const t={};return Ue.value.forEach(e=>{t[e.sales_id]||(t[e.sales_id]={sales_id:e.sales_id,sales_name:e.sales_name,projects:new Set,rdMap:{},total_hours:0});const l=t[e.sales_id];l.rdMap[e.rd_id]||(l.rdMap[e.rd_id]={rd_name:e.rd_name,total_hours:0,work_days:0}),l.rdMap[e.rd_id].total_hours+=e.total_hours,l.rdMap[e.rd_id].work_days+=e.work_days}),Ee.value.forEach(e=>{t[e.sales_id]||(t[e.sales_id]={sales_id:e.sales_id,sales_name:e.sales_name,projects:new Set,rdMap:{},total_hours:0}),t[e.sales_id].projects.add(e.client_id),t[e.sales_id].total_hours+=e.total_hours}),Object.values(t).map(e=>({sales_name:e.sales_name,project_count:e.projects.size,rd_count:Object.keys(e.rdMap).length,total_hours:Math.round(e.total_hours*10)/10,rdList:Object.values(e.rdMap).sort((l,n)=>n.total_hours-l.total_hours)}))});async function Ae(){ke.value=!0;try{const t={};Y.dateRange&&(t.start_date=Y.dateRange[0],t.end_date=Y.dateRange[1]);const[e,l]=await Promise.all([x.getSalesStats(t),x.getSalesDetail(t)]);Ee.value=e.data,Ue.value=l.data,await _e();const n=le.value.filter(i=>i.total_hours>0).map(i=>({name:i.sales_name,value:i.total_hours}));W(fe,$,"sales",n);const s=le.value.filter(i=>i.total_hours>0);B(ye,j,"sales",s.map(i=>i.sales_name),s.map(i=>i.total_hours))}finally{ke.value=!1}}const w=I({dateRange:K,user_id:""}),xe=p([]),De=p(!1),P=G(()=>{const t={};return xe.value.forEach(e=>{t[e.user_id]||(t[e.user_id]={name:e.user_name,value:0}),t[e.user_id].value+=e.hours}),Object.values(t).filter(e=>e.value>0)});async function Oe(){De.value=!0;try{const t={};w.dateRange&&(t.start_date=w.dateRange[0],t.end_date=w.dateRange[1]),w.user_id&&(t.user_id=w.user_id);const e=await x.getRdStats(t);xe.value=e.data,await _e(),W(he,V,"rd",P.value),B(be,z,"rd",P.value.map(l=>l.name),P.value.map(l=>l.value))}finally{De.value=!1}}const y=I({dateRange:K,sales_id:""}),q=p([]),Re=p(!1);async function Fe(){Re.value=!0;try{const t={};y.dateRange&&(t.start_date=y.dateRange[0],t.end_date=y.dateRange[1]),y.sales_id&&(t.sales_id=y.sales_id);const[e,l]=await Promise.all([x.getProjectStats(t),x.getProjectDetail(t)]),n={};l.data.forEach(r=>{n[r.client_id]||(n[r.client_id]=[]),n[r.client_id].push(r)}),q.value=e.data.map(r=>(r.rdList=n[r.client_id]||[],r)),await _e();const s=q.value.filter(r=>r.total_hours>0).map(r=>({name:r.client_name,value:r.total_hours}));W(ge,C,"project",s);const i=q.value.filter(r=>r.total_hours>0);B(we,L,"project",i.map(r=>r.client_name),i.map(r=>r.total_hours))}finally{Re.value=!1}}function W(t,e,l,n){if(!t.value||t.value.clientWidth===0)return;e&&e.dispose();let s=Ze(t.value,"dark");l==="sales"&&($=s),l==="rd"&&(V=s),l==="project"&&(C=s),s.setOption({backgroundColor:"transparent",tooltip:{trigger:"item",formatter:"{b}: {c}h ({d}%)",confine:!0},legend:{type:"scroll",bottom:10,textStyle:{color:"#94a3b8"}},series:[{type:"pie",radius:["35%","65%"],center:["50%","45%"],avoidLabelOverlap:!0,itemStyle:{borderRadius:8,borderColor:"#1e293b",borderWidth:2},label:{color:"#f1f5f9",fontSize:13},emphasis:{label:{show:!0,fontSize:16,fontWeight:"bold"},itemStyle:{shadowBlur:10,shadowOffsetX:0,shadowColor:"rgba(0,0,0,0.5)"}},data:n}]})}function B(t,e,l,n,s){if(!t.value||t.value.clientWidth===0)return;e&&e.dispose();let i=Ze(t.value,"dark");l==="sales"&&(j=i),l==="rd"&&(z=i),l==="project"&&(L=i),i.setOption({backgroundColor:"transparent",tooltip:{trigger:"axis",formatter:r=>`${r[0].name}: ${r[0].value}h`,confine:!0},grid:{left:"3%",right:"4%",bottom:"15%",containLabel:!0},xAxis:{type:"category",data:n,axisLabel:{color:"#94a3b8",interval:0,rotate:n.length>5?30:0,fontSize:12}},yAxis:{type:"value",name:"工时(h)",axisLabel:{color:"#94a3b8"}},series:[{type:"bar",barMaxWidth:50,data:s,itemStyle:{color:new _t(0,0,0,1,[{offset:0,color:"#818cf8"},{offset:1,color:"#4f46e5"}]),borderRadius:[4,4,0,0]},label:{show:!0,position:"top",color:"#f1f5f9",fontSize:12,formatter:"{c}h"},markLine:l==="rd"&&s.length>0?{data:[{type:"average",name:"平均值"}],lineStyle:{type:"dashed",color:"#f59e0b",width:2},label:{formatter:"平均: {c}h",position:"end",color:"#f59e0b",fontWeight:"bold"}}:void 0}]})}function Ne(){$==null||$.resize(),V==null||V.resize(),C==null||C.resize(),j==null||j.resize(),z==null||z.resize(),L==null||L.resize()}async function se(t){try{if(t==="all"){ae.value=!0;let r={},b="开始",c="至今";N.value&&N.value.length===2&&(r.start_date=N.value[0],r.end_date=N.value[1],b=r.start_date,c=r.end_date);const g=await x.exportAllExcel(r);Se(g.data,`总报表_${b}${c}.xlsx`),ee.success("全导成功"),ae.value=!1;return}let e={},l="开始",n="至今",s="";t==="sales"?(s="销售视角",Y.dateRange&&Y.dateRange.length===2&&(e.start_date=Y.dateRange[0],e.end_date=Y.dateRange[1],l=e.start_date,n=e.end_date)):t==="rd"?(s="研发视角",w.dateRange&&w.dateRange.length===2&&(e.start_date=w.dateRange[0],e.end_date=w.dateRange[1],l=e.start_date,n=e.end_date)):t==="project"&&(s="项目视角",y.dateRange&&y.dateRange.length===2&&(e.start_date=y.dateRange[0],e.end_date=y.dateRange[1],l=e.start_date,n=e.end_date),y.sales_id&&(e.sales_id=y.sales_id));const i=await x.exportExcel(t,e);Se(i.data,`${s}_${l}${n}.xlsx`),ee.success("导出成功")}catch{ae.value=!1,ee.error("导出失败")}}function Se(t,e){const l=URL.createObjectURL(new Blob([t])),n=document.createElement("a");n.href=l,n.download=e,n.click(),URL.revokeObjectURL(l)}me(ve,t=>{_e(()=>{if(t==="sales"){const e=le.value.filter(l=>l.total_hours>0);W(fe,$,"sales",e.map(l=>({name:l.sales_name,value:l.total_hours}))),B(ye,j,"sales",e.map(l=>l.sales_name),e.map(l=>l.total_hours))}else if(t==="rd")W(he,V,"rd",P.value),B(be,z,"rd",P.value.map(e=>e.name),P.value.map(e=>e.value));else if(t==="project"){const e=q.value.filter(l=>l.total_hours>0);W(ge,C,"project",e.map(l=>({name:l.client_name,value:l.total_hours}))),B(we,L,"project",e.map(l=>l.client_name),e.map(l=>l.total_hours))}else t==="matrix"?ze():t==="calendar"&&(D.value.length&&!_.user_id&&(_.user_id=D.value[0].id),re().then(()=>{S.value==="individual"&&O()}))})}),ct(async()=>{window.addEventListener("resize",Ne);try{const[t,e]=await Promise.all([x.getSalesUsers(),x.getRdUsers()]);Ye.value=t.data,D.value=e.data,D.value.length&&!_.user_id&&(_.user_id=D.value[0].id)}catch{}Ae(),Oe(),Fe(),ze(),re().then(()=>{S.value==="individual"&&O()})}),pt(()=>{window.removeEventListener("resize",Ne),$==null||$.dispose(),V==null||V.dispose(),C==null||C.dispose(),j==null||j.dispose(),z==null||z.dispose(),L==null||L.dispose()});const S=p("grid"),oe=p(!1),ne=p(new Date().toLocaleDateString("sv-SE",{timeZone:"Asia/Shanghai"})),_=I({month:new Date().toLocaleDateString("sv-SE",{timeZone:"Asia/Shanghai"}).substring(0,7),user_id:""}),X=p(new Date),J=p(new Date().toLocaleDateString("sv-SE",{timeZone:"Asia/Shanghai"})),Me=p([]),$e=p([]),Ve=p({}),Ce=p(0),Ke=G(()=>{const t=D.value.find(e=>e.id===_.user_id);return t?t.realname:""}),Pe=G(()=>{const[t,e]=_.month.split("-").map(Number),l=new Date(t,e,0).getDate();return Array.from({length:l},(n,s)=>s+1)}),qe=t=>{const[e,l]=_.month.split("-").map(Number),n=new Date(e,l-1,t);return["日","一","二","三","四","五","六"][n.getDay()]},Xe=(t,e)=>{var s;const l=`${_.month}-${String(e).padStart(2,"0")}`,n=((s=t.dates[l])==null?void 0:s.hours)||0;return n>0?n:""},de=p({}),We=p(null);async function Je(t){try{const e=await x.getHolidays(t);de.value=e.data||{},Ce.value++}catch(e){console.error("Failed to load holidays:",e)}}const Qe=(t,e)=>{var s;const l=`${_.month}-${String(e).padStart(2,"0")}`,n=((s=t.dates[l])==null?void 0:s.hours)||0;return n>=8?"cell-filled":n>0?"cell-partial":l<ne.value&&!Q(l)?"cell-unfilled":"cell-neutral"},Ie=(t,e)=>{var s;const l=`${_.month}-${String(e).padStart(2,"0")}`,n=((s=t.dates[l])==null?void 0:s.hours)||0;return n>0?`${t.user_name}${l} 已填报 ${n}h`:l<ne.value&&!Q(l)?`${t.user_name}${l} 漏填报`:`${t.user_name}${l} 无需填报/未到期`},et=t=>new Date(t+"T00:00:00").getDay(),tt=t=>{const e=t.substring(5);if(de.value&&de.value[e])return!de.value[e].holiday;const l=et(t);return l!==0&&l!==6},Q=t=>!tt(t),H=t=>{var e;return((e=Ve.value[t])==null?void 0:e.hours)||0},at=t=>t>=ne.value||Q(t)?!1:H(t)===0,Be=G(()=>{var t;return((t=Ve.value[J.value])==null?void 0:t.list)||[]});async function re(){oe.value=!0;try{const[t,e]=_.month.split("-"),l=parseInt(t),n=parseInt(e),s=new Date(l,n,0).getDate(),i=`${_.month}-01`,r=`${_.month}-${String(s).padStart(2,"0")}`;We.value!==l&&(We.value=l,await Je(l));const b=await x.getRdStats({start_date:i,end_date:r});Me.value=b.data||[],He()}catch{ee.error("获取填报日历数据失败")}finally{oe.value=!1}}function He(){const t={};D.value.forEach(e=>{t[e.id]={user_id:e.id,user_name:e.realname,dates:{},total_hours:0}}),Me.value.forEach(e=>{const l=e.user_id;t[l]||(t[l]={user_id:l,user_name:e.user_name||"未知研发",dates:{},total_hours:0});const n=e.work_date;t[l].dates[n]||(t[l].dates[n]={hours:0,records:[]}),t[l].dates[n].hours+=e.hours,t[l].dates[n].records.push(e),t[l].total_hours+=e.hours}),$e.value=Object.values(t).map(e=>(e.total_hours=Math.round(e.total_hours*10)/10,e)).filter(e=>e.total_hours>0)}function lt(){re().then(()=>{S.value==="individual"&&O()})}function st(t){_.user_id=t,S.value="individual",O()}function O(){if(!_.user_id)return;const t={};Me.value.forEach(s=>{s.user_id===_.user_id&&(t[s.work_date]||(t[s.work_date]={hours:0,list:[]}),t[s.work_date].hours+=s.hours,t[s.work_date].list.push(s))}),Ve.value=t,Ce.value++;const[e,l]=_.month.split("-").map(Number),n=X.value;(n.getFullYear()!==e||n.getMonth()+1!==l)&&(X.value=new Date(e,l-1,1)),nt()}function ot(t){J.value=t}function nt(){const t=new Date().toLocaleDateString("sv-SE",{timeZone:"Asia/Shanghai"});t.startsWith(_.month)?J.value=t:J.value=`${_.month}-01`}me(X,t=>{if(t&&S.value==="individual"){const e=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),n=`${e}-${l}`;_.month!==n&&(_.month=n,re().then(()=>{O()}))}}),me(D,()=>{He()}),me(S,t=>{t==="individual"&&(!_.user_id&&D.value.length&&(_.user_id=D.value[0].id),O())});const ie=G(()=>{const[t,e]=_.month.split("-").map(Number),l=new Date(t,e,0).getDate();let n=0,s=0,i=0,r=0;for(let b=1;b<=l;b++){const c=`${_.month}-${String(b).padStart(2,"0")}`,g=H(c);r+=g,g>=8?n++:g>0?s++:c<ne.value&&!Q(c)&&i++}return{fullDays:n,partialDays:s,unfilledDays:i,totalHours:Math.round(r*10)/10}}),M=I({dateRange:K}),je=p(!1),ue=p([]),ce=p([]);async function ze(){je.value=!0;try{const t={};M.dateRange&&M.dateRange.length===2&&(t.start_date=M.dateRange[0],t.end_date=M.dateRange[1]);const l=(await x.getSummaryMatrix(t)).data,n=new Set(l.map(c=>c.sub_project?`${c.client_name}-${c.sub_project}`:c.client_name));ue.value=[...n].sort();const s={};l.forEach(c=>{const g=c.sub_project?`${c.client_name}-${c.sub_project}`:c.client_name;s[c.user_name]||(s[c.user_name]={}),s[c.user_name][g]=(s[c.user_name][g]||0)+c.hours});const i=Object.entries(s).map(([c,g])=>{const F=Object.values(g).reduce((pe,Le)=>pe+Le,0);return{label:c,cells:g,total:Math.round(F*10)/10}}),r={};ue.value.forEach(c=>{r[c]=Math.round(i.reduce((g,F)=>g+(F.cells[c]||0),0)*10)/10});const b=Math.round(i.reduce((c,g)=>c+g.total,0)*10)/10;i.push({label:"合计",cells:r,total:b}),ce.value=i}finally{je.value=!1}}async function dt(){const t={};let e="开始",l="至今";M.dateRange&&M.dateRange.length===2&&(t.start_date=M.dateRange[0],t.end_date=M.dateRange[1],e=t.start_date,l=t.end_date);const n=await x.exportMatrixExcel(t);Se(n.data,`研发工时汇总_${e}${l}.xlsx`),ee.success("导出成功")}return(t,e)=>{const l=k("el-date-picker"),n=k("el-button"),s=k("el-table-column"),i=k("el-table"),r=k("el-tab-pane"),b=k("el-option"),c=k("el-select"),g=k("el-tag"),F=k("el-empty"),pe=k("el-radio-button"),Le=k("el-radio-group"),rt=k("el-calendar"),it=k("el-tabs"),T=mt("loading");return u(),v("div",vt,[a("div",ft,[e[17]||(e[17]=a("div",null,[a("h1",null,"全局统计看板"),a("p",null,"多维度查看工时数据:销售视角 / 研发视角 / 项目视角")],-1)),a("div",ht,[d(l,{modelValue:N.value,"onUpdate:modelValue":e[0]||(e[0]=o=>N.value=o),type:"daterange","range-separator":"至","start-placeholder":"全部时间起","end-placeholder":"全部时间止","value-format":"YYYY-MM-DD",size:"large"},null,8,["modelValue"]),d(n,{type:"success",onClick:e[1]||(e[1]=o=>se("all")),loading:ae.value,size:"large"},{default:m(()=>[...e[16]||(e[16]=[f(" 📊 总导出 (All in One) ",-1)])]),_:1},8,["loading"])])]),d(it,{modelValue:ve.value,"onUpdate:modelValue":e[15]||(e[15]=o=>ve.value=o),type:"border-card",class:"dashboard-tabs"},{default:m(()=>[d(r,{label:"📈 销售视角",name:"sales"},{default:m(()=>[a("div",gt,[d(l,{modelValue:Y.dateRange,"onUpdate:modelValue":e[2]||(e[2]=o=>Y.dateRange=o),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",size:"default"},null,8,["modelValue"]),d(n,{type:"primary",onClick:Ae},{default:m(()=>[...e[18]||(e[18]=[f("查询",-1)])]),_:1}),d(n,{onClick:e[3]||(e[3]=o=>se("sales"))},{default:m(()=>[...e[19]||(e[19]=[f("📥 导出该页",-1)])]),_:1})]),a("div",yt,[a("div",bt,[e[20]||(e[20]=a("div",{class:"section-title"},"📋 销售人员汇总 (点击展开查看研发明细)",-1)),Z((u(),R(i,{data:le.value,stripe:"",style:{width:"100%"},"row-key":"sales_name"},{default:m(()=>[d(s,{type:"expand"},{default:m(o=>[a("div",wt,[a("div",kt," [ "+h(o.row.sales_name)+" ] 的研发工时消耗明细: ",1),d(i,{data:o.row.rdList,border:"",style:{width:"100%"},size:"small"},{default:m(()=>[d(s,{prop:"rd_name",label:"研发人员",width:"150"}),d(s,{prop:"total_hours",label:"消耗工时(h)",width:"120"}),d(s,{prop:"work_days",label:"工作天数",width:"120"})]),_:1},8,["data"])])]),_:1}),d(s,{prop:"sales_name",label:"销售人员","min-width":"140"}),d(s,{prop:"project_count",label:"项目数","min-width":"100"}),d(s,{prop:"rd_count",label:"涉及研发","min-width":"120"}),d(s,{prop:"total_hours",label:"总消耗工时(h)","min-width":"130",sortable:""})]),_:1},8,["data"])),[[T,ke.value]])]),a("div",xt,[a("div",Dt,[e[21]||(e[21]=a("div",{class:"chart-title"},"销售占用工时占比(饼图)",-1)),a("div",{ref_key:"salesChartRef",ref:fe,class:"big-chart"},null,512)]),a("div",Rt,[e[22]||(e[22]=a("div",{class:"chart-title"},"各销售工时对比(柱状图)",-1)),a("div",{ref_key:"salesBarRef",ref:ye,class:"big-chart"},null,512)])])])]),_:1}),d(r,{label:"👨‍💻 研发视角",name:"rd"},{default:m(()=>[a("div",St,[d(l,{modelValue:w.dateRange,"onUpdate:modelValue":e[4]||(e[4]=o=>w.dateRange=o),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",size:"default"},null,8,["modelValue"]),d(c,{modelValue:w.user_id,"onUpdate:modelValue":e[5]||(e[5]=o=>w.user_id=o),placeholder:"全部研发",clearable:"",size:"default",style:{width:"150px"}},{default:m(()=>[(u(!0),v(U,null,A(D.value,o=>(u(),R(b,{key:o.id,label:o.realname,value:o.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),d(n,{type:"primary",onClick:Oe},{default:m(()=>[...e[23]||(e[23]=[f("查询",-1)])]),_:1}),d(n,{onClick:e[6]||(e[6]=o=>se("rd"))},{default:m(()=>[...e[24]||(e[24]=[f("📥 导出该页",-1)])]),_:1})]),a("div",Mt,[a("div",$t,[e[25]||(e[25]=a("div",{class:"section-title"},"📋 研发人员填报明细",-1)),Z((u(),R(i,{data:xe.value,stripe:"",style:{width:"100%"}},{default:m(()=>[d(s,{prop:"user_name",label:"研发人员","min-width":"120"}),d(s,{prop:"client_name",label:"客户/项目","min-width":"180"}),d(s,{prop:"work_date",label:"日期","min-width":"120"}),d(s,{prop:"hours",label:"工时(h)","min-width":"100"}),d(s,{prop:"remark",label:"备注","min-width":"180"})]),_:1},8,["data"])),[[T,De.value]])]),a("div",Vt,[a("div",Ct,[e[26]||(e[26]=a("div",{class:"chart-title"},"研发人员工时产出占比(饼图)",-1)),a("div",{ref_key:"rdChartRef",ref:he,class:"big-chart"},null,512)]),a("div",jt,[e[27]||(e[27]=a("div",{class:"chart-title"},"各研发人员工时对比(柱状图)",-1)),a("div",{ref_key:"rdBarRef",ref:be,class:"big-chart"},null,512)])])])]),_:1}),d(r,{label:"🏢 项目视角",name:"project"},{default:m(()=>[a("div",zt,[d(l,{modelValue:y.dateRange,"onUpdate:modelValue":e[7]||(e[7]=o=>y.dateRange=o),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",size:"default",style:{"margin-right":"12px"}},null,8,["modelValue"]),d(c,{modelValue:y.sales_id,"onUpdate:modelValue":e[8]||(e[8]=o=>y.sales_id=o),clearable:"",placeholder:"全部销售",style:{width:"140px","margin-right":"12px"}},{default:m(()=>[(u(!0),v(U,null,A(Ye.value,o=>(u(),R(b,{key:o.id,label:o.realname,value:o.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),d(n,{type:"primary",onClick:Fe},{default:m(()=>[...e[28]||(e[28]=[f("查询",-1)])]),_:1}),d(n,{onClick:e[9]||(e[9]=o=>se("project"))},{default:m(()=>[...e[29]||(e[29]=[f("📥 导出该页",-1)])]),_:1})]),a("div",Lt,[a("div",Yt,[e[30]||(e[30]=a("div",{class:"section-title"},"📋 项目总览 (点击展开查看研发明细)",-1)),Z((u(),R(i,{data:q.value,stripe:"",style:{width:"100%"},"row-key":"client_id"},{default:m(()=>[d(s,{type:"expand"},{default:m(o=>[a("div",Et,[a("div",Ut," [ "+h(o.row.client_name)+" ] 的参与研发明细: ",1),d(i,{data:o.row.rdList,border:"",style:{width:"100%"},size:"small"},{default:m(()=>[d(s,{prop:"rd_name",label:"研发人员",width:"150"}),d(s,{prop:"total_hours",label:"消耗工时(h)",width:"120",sortable:""}),d(s,{prop:"work_days",label:"工作天数",width:"120"}),d(s,{prop:"first_date",label:"首次介入",width:"120"}),d(s,{prop:"last_date",label:"最近介入",width:"120"})]),_:1},8,["data"])])]),_:1}),d(s,{prop:"client_name",label:"客户/项目","min-width":"200"}),d(s,{prop:"sales_name",label:"所属销售","min-width":"120"}),d(s,{prop:"client_status",label:"状态","min-width":"90"},{default:m(({row:o})=>[d(g,{type:o.client_status===1?"success":"info",effect:"dark",round:""},{default:m(()=>[f(h(o.client_status===1?"进行中":"已结算"),1)]),_:2},1032,["type"])]),_:1}),d(s,{prop:"total_hours",label:"总工时(h)","min-width":"110",sortable:""}),d(s,{prop:"rd_count",label:"研发人数","min-width":"100"})]),_:1},8,["data"])),[[T,Re.value]])]),a("div",At,[a("div",Ot,[e[31]||(e[31]=a("div",{class:"chart-title"},"项目工时分布(饼图)",-1)),a("div",{ref_key:"projectChartRef",ref:ge,class:"big-chart"},null,512)]),a("div",Ft,[e[32]||(e[32]=a("div",{class:"chart-title"},"各项目工时对比(柱状图)",-1)),a("div",{ref_key:"projectBarRef",ref:we,class:"big-chart"},null,512)])])])]),_:1}),d(r,{label:"📊 研发工时汇总",name:"matrix"},{default:m(()=>[a("div",Nt,[d(l,{modelValue:M.dateRange,"onUpdate:modelValue":e[10]||(e[10]=o=>M.dateRange=o),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",size:"default"},null,8,["modelValue"]),d(n,{type:"primary",onClick:ze},{default:m(()=>[...e[33]||(e[33]=[f("查询",-1)])]),_:1}),d(n,{onClick:dt},{default:m(()=>[...e[34]||(e[34]=[f("📥 导出该页",-1)])]),_:1})]),Z((u(),v("div",Pt,[ce.value.length?(u(),v("table",Wt,[a("thead",null,[a("tr",null,[e[35]||(e[35]=a("th",{class:"row-header"},"研发人员",-1)),(u(!0),v(U,null,A(ue.value,o=>(u(),v("th",{key:o},h(o),1))),128)),e[36]||(e[36]=a("th",{class:"total-col"},"合计",-1))])]),a("tbody",null,[(u(!0),v(U,null,A(ce.value,(o,E)=>(u(),v("tr",{key:E,class:Ge({"total-row":E===ce.value.length-1})},[a("td",Bt,h(o.label),1),(u(!0),v(U,null,A(ue.value,Te=>(u(),v("td",{key:Te},h(o.cells[Te]||"-"),1))),128)),a("td",Ht,h(o.total),1)],2))),128))])])):(u(),R(F,{key:1,description:"暂无工时数据"}))])),[[T,je.value]])]),_:1}),d(r,{label:"📅 填报日历",name:"calendar"},{default:m(()=>[a("div",Tt,[d(l,{modelValue:_.month,"onUpdate:modelValue":e[11]||(e[11]=o=>_.month=o),type:"month",placeholder:"选择月份","value-format":"YYYY-MM",size:"default",clearable:!1,onChange:lt,style:{width:"140px","margin-right":"12px"}},null,8,["modelValue"]),d(Le,{modelValue:S.value,"onUpdate:modelValue":e[12]||(e[12]=o=>S.value=o),size:"default",style:{"margin-right":"12px"}},{default:m(()=>[d(pe,{value:"grid"},{default:m(()=>[...e[37]||(e[37]=[f("全员概览",-1)])]),_:1}),d(pe,{value:"individual"},{default:m(()=>[...e[38]||(e[38]=[f("个人日历",-1)])]),_:1})]),_:1},8,["modelValue"]),S.value==="individual"?(u(),R(c,{key:0,modelValue:_.user_id,"onUpdate:modelValue":e[13]||(e[13]=o=>_.user_id=o),placeholder:"选择研发人员",size:"default",style:{width:"150px"},onChange:O},{default:m(()=>[(u(!0),v(U,null,A(D.value,o=>(u(),R(b,{key:o.id,label:o.realname,value:o.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])):te("",!0)]),S.value==="grid"?Z((u(),v("div",Gt,[a("div",Zt,[a("span",null,"👥 R&D 全员填报状态矩阵 ("+h(_.month)+")",1),e[39]||(e[39]=a("div",{class:"calendar-legends"},[a("span",{class:"legend-item"},[a("span",{class:"dot green"}),f("已满8h")]),a("span",{class:"legend-item"},[a("span",{class:"dot yellow"}),f("未满8h")]),a("span",{class:"legend-item"},[a("span",{class:"dot red"}),f("漏填报")]),a("span",{class:"legend-item"},[a("span",{class:"dot gray"}),f("周末/未到期")])],-1))]),$e.value.length?(u(),v("table",Kt,[a("thead",null,[a("tr",null,[e[40]||(e[40]=a("th",{class:"name-header"},"姓名",-1)),(u(!0),v(U,null,A(Pe.value,o=>(u(),v("th",{key:o,class:"day-col"},[f(h(o)+" ",1),a("span",qt,h(qe(o)),1)]))),128)),e[41]||(e[41]=a("th",{class:"total-header"},"累计工时",-1))])]),a("tbody",null,[(u(!0),v(U,null,A($e.value,o=>(u(),v("tr",{key:o.user_id,class:"grid-row"},[a("td",{class:"name-header clickable",onClick:E=>st(o.user_id)},[f(h(o.user_name)+" ",1),e[42]||(e[42]=a("span",{class:"arrow-tip"},"📅",-1))],8,Xt),(u(!0),v(U,null,A(Pe.value,E=>(u(),v("td",{key:E,class:Ge(["status-cell",Qe(o,E)]),title:Ie(o,E)},[a("span",Qt,h(Xe(o,E)),1)],10,Jt))),128)),a("td",It,h(o.total_hours)+"h",1)]))),128))])])):(u(),R(F,{key:1,description:"暂无研发人员数据"}))])),[[T,oe.value]]):Z((u(),v("div",ea,[a("div",ta,[a("div",aa,[a("div",la,[a("span",null,"📅 "+h(Ke.value)+" 的个人日历 ("+h(_.month)+")",1),e[43]||(e[43]=a("div",{class:"calendar-legends"},[a("span",{class:"legend-item"},[a("span",{class:"dot green"}),f("已满8h")]),a("span",{class:"legend-item"},[a("span",{class:"dot yellow"}),f("未满8h")]),a("span",{class:"legend-item"},[a("span",{class:"dot red"}),f("漏填")]),a("span",{class:"legend-item"},[a("span",{class:"dot gray"}),f("周末/未到期")])],-1))]),(u(),R(rt,{modelValue:X.value,"onUpdate:modelValue":e[14]||(e[14]=o=>X.value=o),key:Ce.value},{"date-cell":m(({data:o})=>[a("div",{class:"day-cell-content",onClick:E=>ot(o.day)},[a("div",oa,[a("span",na,h(o.day.split("-")[2]),1),o.type==="current-month"&&Q(o.day)?(u(),v("span",da,"休")):te("",!0)]),o.type==="current-month"?(u(),v("div",ra,[H(o.day)>=8?(u(),v("div",ia,h(H(o.day))+"h ",1)):H(o.day)>0?(u(),v("div",ua,h(H(o.day))+"h ",1)):at(o.day)?(u(),v("div",ca," 未填报 ")):te("",!0)])):te("",!0)],8,sa)]),_:1},8,["modelValue"]))])]),a("div",pa,[a("div",ma,[e[52]||(e[52]=a("div",{class:"card-title"},"📊 月度数据汇总",-1)),a("div",_a,[a("div",va,[e[45]||(e[45]=a("div",{class:"label"},"满额填报",-1)),a("div",fa,[f(h(ie.value.fullDays),1),e[44]||(e[44]=a("span",{class:"unit"},"天",-1))])]),a("div",ha,[e[47]||(e[47]=a("div",{class:"label"},"部分填报",-1)),a("div",ga,[f(h(ie.value.partialDays),1),e[46]||(e[46]=a("span",{class:"unit"},"天",-1))])]),a("div",ya,[e[49]||(e[49]=a("div",{class:"label"},"漏填工作日",-1)),a("div",ba,[f(h(ie.value.unfilledDays),1),e[48]||(e[48]=a("span",{class:"unit"},"天",-1))])]),a("div",wa,[e[51]||(e[51]=a("div",{class:"label"},"累计总工时",-1)),a("div",ka,[f(h(ie.value.totalHours),1),e[50]||(e[50]=a("span",{class:"unit"},"小时",-1))])])])]),a("div",xa,[a("div",Da,"📋 "+h(J.value)+" 工时明细",1),d(i,{data:Be.value,stripe:"",style:{width:"100%"},size:"small"},{default:m(()=>[d(s,{prop:"client_name",label:"客户/项目","min-width":"130"}),d(s,{prop:"hours",label:"工时",width:"70"}),d(s,{prop:"remark",label:"备注","min-width":"120","show-overflow-tooltip":""})]),_:1},8,["data"]),Be.value.length?te("",!0):(u(),R(F,{key:0,description:"当天暂无工时记录","image-size":50}))])])])),[[T,oe.value]])]),_:1})]),_:1},8,["modelValue"])])}}},ja=ut(Ra,[["__scopeId","data-v-a878b42e"]]);export{ja as default};