You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1 lines
17 KiB

import{_ as Ot}from"./CDB8L8go.js";import{u as dt}from"./BgasD__e.js";import{h as Vt,R as Tt,a as zt}from"./PN667bHc.js";import{g as _t,C as vt,o,c as l,a,t as r,l as f,m as pt,b as Q,w as it,d as q,F as k,r as E,n as G,y as _,A as w,_ as mt,j as It,q as H,s as P,z as ct,L as U}from"./6O01ZZML.js";import{n as qt,R as ut}from"./7m3DvxFn.js";const Ht={class:"ab-head"},Pt={class:"ab-ico"},Ut={class:"ab-title"},Gt={key:0,class:"ab-sub"},jt={class:"ab-sub"},Yt={key:0,class:"ab-list"},Wt={class:"ab-name"},Jt={key:0,class:"ab-chip"},Zt={class:"ab-chip ab-chip-scope"},Kt={class:"ab-msg"},Qt={key:1,class:"ab-streak"},Xt={key:0,class:"ab-more"},te=12,ee=_t({__name:"SvcAlertBanner",setup(ft,{expose:y}){const{webApi:D}=dt(),x=_([]),m=_(0),b=_(0),S=_(0),g=_(!1),F=_(!1),M=w(()=>Vt(S.value));function j(u){const p=u.app_name?u.app_name:"全局";return u.region?`${p} · ${Tt[u.region]||"区域"+u.region}`:p}function R(u){return zt(u)}async function B(){try{const u=await D("getsvcalerts",{limit:te});x.value=u.alerts||[],m.value=u.error_count||0,b.value=u.warn_count||0,S.value=u.last_run||0,F.value=m.value+b.value>x.value.length,g.value=m.value>0}catch{x.value=[],m.value=0,b.value=0}}return vt(B),y({load:B}),(u,p)=>{const O=Ot;return m.value+b.value>0?(o(),l("div",{key:0,class:G(["alert-banner",m.value>0?"lv-error":"lv-warn"])},[a("div",Ht,[a("span",Pt,r(m.value>0?"🚨":"⚠️"),1),a("div",Ut,[a("strong",null,r(m.value>0?`${m.value} 项第三方服务不可用`:`${b.value} 项第三方服务存在隐患`),1),m.value>0&&b.value>0?(o(),l("span",Gt,",另有 "+r(b.value)+" 项隐患",1)):f("",!0),a("span",jt," · 最近巡检 "+r(pt(M)),1)]),a("button",{class:"ab-btn",onClick:p[0]||(p[0]=d=>g.value=!g.value)},r(g.value?"收起":"展开详情"),1),Q(O,{to:"/svcinspect",class:"ab-btn ab-btn-primary"},{default:it(()=>[...p[1]||(p[1]=[q("前往巡检",-1)])]),_:1})]),g.value?(o(),l("div",Yt,[(o(!0),l(k,null,E(x.value,d=>(o(),l("div",{key:`${d.app_name}/${d.svc_id}/${d.region}`,class:"ab-item"},[a("span",{class:G(["ab-dot",d.status==="error"?"d-error":"d-warn"])},null,2),a("span",Wt,r(d.name||d.svc_id),1),d.provider?(o(),l("span",Jt,r(d.provider),1)):f("",!0),a("span",Zt,r(j(d)),1),a("span",Kt,r(R(d)),1),d.fail_streak>1?(o(),l("span",Qt,"连续失败 "+r(d.fail_streak)+" 次",1)):f("",!0)]))),128)),F.value?(o(),l("div",Xt,[q(" 仅显示前 "+r(x.value.length)+" 条,其余请到",1),Q(O,{to:"/svcinspect",class:"ab-link"},{default:it(()=>[...p[2]||(p[2]=[q("服务巡检",-1)])]),_:1}),p[3]||(p[3]=q("查看 ",-1))])):f("",!0)])):f("",!0)],2)):f("",!0)}}}),se=Object.assign(mt(ee,[["__scopeId","data-v-3dd2fb7c"]]),{__name:"SvcAlertBanner"}),ae={class:"panel p-4 mb-5"},ne={class:"flex flex-wrap items-end gap-3"},oe={key:0,class:"form-control"},le=["value"],re={key:1,class:"form-control"},ie=["value"],ce={class:"form-control"},ue=["value"],de={key:2,class:"form-control"},_e=["value"],ve={class:"grid grid-cols-2 md:grid-cols-4 gap-3 mb-8"},pe={class:"body"},me={class:"lbl"},fe={class:"val"},ye={class:"today-wrap mb-8"},be={class:"sec-title hero",style:{"margin-bottom":"16px"}},ge={class:"tag",style:{color:"#0369a1",background:"#dbeafe"}},he={class:"grid grid-cols-2 md:grid-cols-4 gap-4"},ke={class:"today-card-top"},Ee={class:"lbl"},we={class:"val"},Fe={class:"foot"},xe={key:0,class:"delta up"},Ce={class:"grid grid-cols-1 xl:grid-cols-2 gap-6"},De={class:"panel-head"},Ae=["stroke"],Se=["d"],Me={class:"font-semibold text-slate-700 text-sm"},Be={key:0,class:"ml-auto text-xs text-slate-400"},Ne={key:1,class:"ml-auto flex items-center gap-1"},Le=["onClick"],$e={class:"px-5 py-4"},Re={class:"grid grid-cols-2 sm:grid-cols-3 gap-2.5"},Oe={class:"stat-label"},Ve={class:"stat-val"},Te={key:0,style:{height:"170px","margin-top":"1rem"}},ze=_t({__name:"dashboard",setup(ft){const y=It(),{webApi:D,consoleApi:x}=dt(),m={new_user_count:["👥","#EEF2FF","#6366F1"],active_user_count:["🟢","#ECFDF5","#10B981"],bind_device_count:["📱","#E0F2FE","#0EA5E9"],qr_active_count:["🔳","#FCE7F3","#EC4899"],order_paid_count:["🧾","#FEF3C7","#F59E0B"],order_paid_amount:["💰","#FEE2E2","#EF4444"],pay_user_count:["⭐","#FFF7ED","#F97316"],meet_second:["🎙️","#CFFAFE","#22D3EE"],trade_second:["🌐","#F3E8FF","#8B5CF6"]},b=[["new_user_count","累计用户",!1],["bind_device_count","累计绑定设备",!1],["qr_active_count","累计二维码激活",!1],["order_paid_count","累计支付订单",!1],["order_paid_amount","累计支付金额",!0],["meet_second","累计会议时长",!1],["trade_second","累计翻译时长",!1]],S=[["new_user_count","新增用户",!1],["active_user_count","活跃用户",!1],["qr_active_count","二维码激活",!1],["order_paid_count","支付订单",!1],["order_paid_amount","支付金额",!0],["pay_user_count","付费用户",!1],["meet_second","会议时长",!1,!0],["trade_second","翻译时长",!1,!0]],g=[{key:"user",title:"用户增长",color:"#6366F1",tint:"#EEF2FF",icon:"M17 20h5v-2a4 4 0 00-3-3.87M9 20H4v-2a4 4 0 013-3.87m6-1.13a4 4 0 10-4-4 4 4 0 004 4z",stats:[["new_user_count","新增用户"],["active_user_count","活跃用户"],["login_user_count","登录用户"],["login_count","登录次数"]],lines:[["new_user_count","新增用户","#6366F1"],["active_user_count","活跃用户","#34D399"]]},{key:"device",title:"设备激活绑定",color:"#0EA5E9",tint:"#E0F2FE",icon:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z",stats:[["active_device_count","已激活"],["bind_device_count","已绑定"]],lines:[["active_device_count","已激活","#0EA5E9"],["bind_device_count","已绑定","#818CF8"]]},{key:"qrcode",title:"二维码激活",color:"#EC4899",tint:"#FCE7F3",icon:"M12 4v1m6 11h2m-6 0h-1v4m-6-4H5m14 0h-2m-6-7H5m0 0V5m0 4v6m14-6V5h-4M5 5h4M5 19h4m6 0h4v-4M4 4h6v6H4V4zm10 0h6v6h-6V4zM4 14h6v6H4v-6z",stats:[["qr_active_count","二维码激活次数"]],lines:[["qr_active_count","二维码激活","#EC4899"]]},{key:"order",title:"订单支付",color:"#F59E0B",tint:"#FEF3C7",icon:"M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z",stats:[["order_create_count","创建订单"],["order_paid_count","支付订单"],["order_failed_count","失败订单"],["pay_user_count","付费用户"],["order_paid_amount","支付金额",!0],["order_create_amount","创建金额",!0]],lines:[["order_paid_count","支付订单","#F59E0B"],["order_create_count","创建订单","#FCD34D"]]},{key:"meeting",title:"会议",color:"#22D3EE",tint:"#CFFAFE",icon:"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z",stats:[["meet_count","会议次数"],["meet_second","会议时长",!1,!0],["grant_meet_second","发放会议时长",!1,!0]],lines:[["meet_count","会议次数","#22D3EE"],["meet_second","会议时长(秒)","#0EA5E9"]]},{key:"translate",title:"翻译",color:"#8B5CF6",tint:"#F3E8FF",icon:"M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129",stats:[["trade_count","翻译次数"],["trade_second","翻译时长",!1,!0],["trade_words","翻译字数"],["grant_trade_second","发放翻译时长",!1,!0]],lines:[["trade_count","翻译次数","#8B5CF6"],["trade_second","翻译时长(秒)","#A78BFA"]]}],F=w(()=>y.identity===3&&!y.brandid),M=w(()=>y.isBrandAccount||y.isDealer),j=w(()=>y.apps),R=w(()=>y.regions),B=w(()=>y.products.map(t=>parseInt(t)).filter(t=>!isNaN(t))),u=["new_user_count","active_user_count","qr_active_count"],p=w(()=>F.value?b.filter(t=>!u.includes(t[0])):b),O=w(()=>F.value?S.filter(t=>!u.includes(t[0])):S),d=w(()=>F.value?g.filter(t=>t.key!=="user"&&t.key!=="qrcode"):g),yt=[[7,"7天"],[30,"30天"],[90,"90天"],[0,"全部"]],c=ct({app:"",region:"",product:"",channel:""}),C=_([]),Y=_([]),W=_([]),bt=w(()=>{if(F.value&&R.value.length){const t=new Set(R.value.map(e=>qt(e)));return ut.filter(e=>t.has(e.value))}return ut}),X=_({}),tt=_({}),J=_({}),et=_({}),st=_("实时"),Z=_({}),V=ct({});g.forEach(t=>{V[t.key]=30});function T(t){const e=t.getFullYear(),n=("0"+(t.getMonth()+1)).slice(-2),s=("0"+t.getDate()).slice(-2);return parseInt(e+n+s)}function gt(t){if(!t)return{start:0,end:0};const e=new Date,n=new Date;return n.setDate(n.getDate()-(t-1)),{start:T(n),end:T(e)}}function ht(t,e){return t=Number(t)||0,e?"¥"+(t/100).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2}):t.toLocaleString()}function kt(t){t=Math.max(0,Math.floor(Number(t)||0));const e=Math.floor(t/3600),n=Math.floor(t%3600/60),s=t%60;return e>0?e+"时"+n+"分":n>0?n+"分"+s+"秒":s+"秒"}function K(t,e,n){return n?kt(t):ht(t,e)}function Et(t){const e=String(t);return e.length===8?e.slice(4,6)+"-"+e.slice(6,8):e}function wt(t,e){return t=Number(t)||0,e=Number(e)||0,e===0?t>0?null:0:(t-e)/e*100}function N(t){return m[t]||["📊","#f1f5f9","#94a3b8"]}function Ft(t){const e=t[0]==="bind_device_count"||t[0]==="active_device_count"?tt.value:X.value,n=t[0]==="meet_second"||t[0]==="trade_second";return K(e[t[0]],t[2],n)}function xt(t){return K(J.value[t[0]],t[2],!!t[3])}function L(t){const e=wt(J.value[t[0]],et.value[t[0]]);if(e===null)return{type:"new",arrow:"",abs:""};const n=e>0?"up":e<0?"down":"flat",s=e>0?"▲":e<0?"▼":"—";return{type:n,arrow:s,abs:Math.abs(e).toFixed(1)}}function Ct(t,e){return K((Z.value[t.key]||{})[e[0]],e[2],e[3])}function z(){const t={};return c.app!==""&&(t.app_id=c.app),c.region!==""&&(t.region=c.region),c.product!==""&&(t.product_id=parseInt(String(c.product))),nt(t),t}function at(){const t={};return c.product!==""&&(t.product_id=parseInt(String(c.product))),nt(t),t}function nt(t){c.channel!==""&&(t.channel_id=c.channel==="__none__"?"":c.channel)}async function A(t,e){try{return{code:0,data:await D(t,e)??{}}}catch{return null}}async function Dt(){const t=await A("getstatssummary",z());X.value=t&&t.code===0&&t.data?t.data:{};const e=await A("getstatssummary",at());tt.value=e&&e.code===0&&e.data?e.data:{}}async function At(){const t=T(new Date),e=new Date;e.setDate(e.getDate()-1);const n=T(e),s=z();s.start_day=t,s.end_day=t;const i=z();i.start_day=n,i.end_day=n;const h=await A("getstatssummary",s);J.value=h&&h.code===0&&h.data?h.data:{};const v=await A("getstatssummary",i);et.value=v&&v.code===0&&v.data?v.data:{};const I=new Date,$t=("0"+(I.getMonth()+1)).slice(-2),Rt=("0"+I.getDate()).slice(-2);st.value=$t+"-"+Rt+" 实时"}async function ot(t){let e;if(t.key==="device")e=at();else{const v=gt(V[t.key]);e=z(),e.start_day=v.start,e.end_day=v.end}const n=await A("getstatssummary",e),s=n&&n.code===0&&n.data?n.data:{};if(Z.value={...Z.value,[t.key]:s},t.key==="device")return;const i=await A("getstatstrend",e),h=i&&i.code===0?i.data||[]:[];Bt(t,h)}function St(t,e){V[t]=e;const n=g.find(s=>s.key===t);n&&ot(n)}function lt(){Dt(),At(),d.value.forEach(t=>ot(t))}const rt={},$={};function Mt(t,e){e&&(rt[t]=e)}function Bt(t,e){const n=window.Chart,s=rt[t.key];if(!n||!s)return;const i=e.map(v=>Et(v.stat_day)),h=t.lines.map(v=>({label:v[1],data:e.map(I=>Number(I[v[0]])||0),borderColor:v[2],backgroundColor:v[2]+"22",tension:.35,fill:!0,pointRadius:0,borderWidth:2}));if($[t.key]){$[t.key].data.labels=i,$[t.key].data.datasets=h,$[t.key].update();return}$[t.key]=new n(s,{type:"line",data:{labels:i,datasets:h},options:{responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{boxWidth:10,padding:12,font:{size:11}}}},scales:{x:{ticks:{maxTicksLimit:8,font:{size:10},color:"#94a3b8"},grid:{display:!1}},y:{beginAtZero:!0,ticks:{precision:0,maxTicksLimit:5,font:{size:10},color:"#94a3b8"},grid:{color:"#f1f5f9"}}},interaction:{mode:"index",intersect:!1}}})}async function Nt(){if(M.value)try{const e=(await D("getmyapps",{}))?.apps??[],n=[...new Set(e.map(s=>s.app_name||s.name).filter(Boolean))];C.value=n.map(s=>({value:s,label:s}))}catch{C.value=[]}else if(F.value)C.value=j.value.map(t=>({value:t,label:t}));else try{const t=await x("apps/list",{}),e=Array.isArray(t)?t:[],n=[...new Set(e.map(s=>s.app_name||s.name||"").filter(Boolean))];C.value=n.map(s=>({value:s,label:s}))}catch{C.value=[]}try{const t=await D("getproducts",{});let e=t&&t.products?t.products:[];F.value&&B.value.length&&(e=e.filter(n=>B.value.includes(n.id))),W.value=e.map(n=>({value:n.id,label:(n.devicename||"产品#"+n.id)+" (#"+n.id+")"}))}catch{W.value=[]}try{const t=await D("getchannels",{status:-1}),e=t&&t.channels?t.channels:[];Y.value=e.map(n=>({value:n.id,label:(n.name||"渠道商")+" ("+n.id+")"}))}catch{Y.value=[]}}function Lt(){return new Promise(t=>{if(window.Chart)return t();const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js",e.onload=()=>t(),e.onerror=()=>t(),document.head.appendChild(e)})}return vt(async()=>{await Lt(),await Nt(),lt()}),(t,e)=>{const n=se;return o(),l("div",null,[Q(n),a("div",ae,[a("div",ne,[!M.value||C.value.length?(o(),l("div",oe,[e[5]||(e[5]=a("label",{class:"label py-1"},[a("span",{class:"label-text text-xs text-slate-500"},"应用")],-1)),H(a("select",{"onUpdate:modelValue":e[0]||(e[0]=s=>c.app=s),class:"select select-bordered select-sm w-40"},[e[4]||(e[4]=a("option",{value:""},"全部应用",-1)),(o(!0),l(k,null,E(C.value,s=>(o(),l("option",{key:s.value,value:s.value},r(s.label),9,le))),128))],512),[[P,c.app]])])):f("",!0),M.value?f("",!0):(o(),l("div",re,[e[7]||(e[7]=a("label",{class:"label py-1"},[a("span",{class:"label-text text-xs text-slate-500"},"区域")],-1)),H(a("select",{"onUpdate:modelValue":e[1]||(e[1]=s=>c.region=s),class:"select select-bordered select-sm w-32"},[e[6]||(e[6]=a("option",{value:""},"全部区域",-1)),(o(!0),l(k,null,E(bt.value,s=>(o(),l("option",{key:s.value,value:s.value},r(s.label),9,ie))),128))],512),[[P,c.region]])])),a("div",ce,[e[9]||(e[9]=a("label",{class:"label py-1"},[a("span",{class:"label-text text-xs text-slate-500"},"产品")],-1)),H(a("select",{"onUpdate:modelValue":e[2]||(e[2]=s=>c.product=s),class:"select select-bordered select-sm w-48"},[e[8]||(e[8]=a("option",{value:""},"全部产品",-1)),(o(!0),l(k,null,E(W.value,s=>(o(),l("option",{key:s.value,value:s.value},r(s.label),9,ue))),128))],512),[[P,c.product]])]),pt(y).isDealer?f("",!0):(o(),l("div",de,[e[12]||(e[12]=a("label",{class:"label py-1"},[a("span",{class:"label-text text-xs text-slate-500"},"渠道商")],-1)),H(a("select",{"onUpdate:modelValue":e[3]||(e[3]=s=>c.channel=s),class:"select select-bordered select-sm w-48"},[e[10]||(e[10]=a("option",{value:""},"全部渠道商",-1)),e[11]||(e[11]=a("option",{value:"__none__"},"未分配渠道",-1)),(o(!0),l(k,null,E(Y.value,s=>(o(),l("option",{key:s.value,value:s.value},r(s.label),9,_e))),128))],512),[[P,c.channel]])])),a("button",{class:"btn btn-primary btn-sm text-white",onClick:lt},"查询"),e[13]||(e[13]=a("span",{class:"text-xs text-slate-400 ml-auto self-center"},"顶部为全量总览;各版面右上角可单独选时间周期",-1))])]),e[18]||(e[18]=a("div",{class:"sec-title muted"},[a("span",{class:"bar",style:{background:"#cbd5e1"}}),a("h2",null,"累计数据"),a("span",{class:"sub"},"全量累计 · 随筛选条件变化")],-1)),a("div",ve,[(o(!0),l(k,null,E(p.value,s=>(o(),l("div",{key:s[0],class:"cum-card"},[a("span",{class:"ico",style:U({background:N(s[0])[1]})},r(N(s[0])[0]),5),a("div",pe,[a("div",me,r(s[1]),1),a("div",fe,r(Ft(s)),1)])]))),128))]),a("div",ye,[a("div",be,[e[14]||(e[14]=a("span",{class:"bar",style:{background:"linear-gradient(180deg,#0EA5E9,#22D3EE)"}},null,-1)),e[15]||(e[15]=a("h2",null,"今日数据",-1)),a("span",ge,r(st.value),1),e[16]||(e[16]=a("span",{class:"sub"},"今日 0 点至现在 · 含较昨日同比(设备类无日期维度,仅见累计)",-1))]),a("div",he,[(o(!0),l(k,null,E(O.value,s=>(o(),l("div",{key:s[0],class:"today-card"},[a("span",{class:"accent",style:U({background:N(s[0])[2]})},null,4),a("div",ke,[a("span",Ee,r(s[1]),1),a("span",{class:"ico",style:U({background:N(s[0])[1]})},r(N(s[0])[0]),5)]),a("div",we,r(xt(s)),1),a("div",Fe,[L(s).type==="new"?(o(),l("span",xe,"新")):L(s).type!=="none"?(o(),l("span",{key:1,class:G(["delta",L(s).type])},r(L(s).arrow)+" "+r(L(s).abs)+"%",3)):f("",!0),e[17]||(e[17]=a("span",null,"较昨日",-1))])]))),128))])]),e[19]||(e[19]=a("div",{class:"sec-title"},[a("span",{class:"bar",style:{background:"linear-gradient(180deg,#10B981,#22D3EE)"}}),a("h2",null,"趋势分析"),a("span",{class:"sub"},"各版面右上角可独立选择时间周期")],-1)),a("div",Ce,[(o(!0),l(k,null,E(d.value,s=>(o(),l("div",{key:s.key,class:"panel"},[a("div",De,[a("span",{class:"panel-dot",style:U({background:s.tint})},[(o(),l("svg",{width:"17",height:"17",fill:"none",viewBox:"0 0 24 24",stroke:s.color},[a("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:s.icon},null,8,Se)],8,Ae))],4),a("span",Me,r(s.title),1),s.key==="device"?(o(),l("span",Be,"当前累计 · 无日期维度")):(o(),l("div",Ne,[(o(),l(k,null,E(yt,i=>a("button",{key:i[0],class:G(["tbtn",{"tbtn-on":i[0]===V[s.key]}]),onClick:h=>St(s.key,Number(i[0]))},r(i[1]),11,Le)),64))]))]),a("div",$e,[a("div",Re,[(o(!0),l(k,null,E(s.stats,i=>(o(),l("div",{key:i[0],class:"stat-box"},[a("div",Oe,r(i[1]),1),a("div",Ve,r(Ct(s,i)),1)]))),128))]),s.key!=="device"?(o(),l("div",Te,[a("canvas",{ref_for:!0,ref:i=>Mt(s.key,i)},null,512)])):f("",!0)])]))),128))])])}}}),Ge=mt(ze,[["__scopeId","data-v-449e8f97"]]);export{Ge as default};