PageSourceSearch

https://kooai.top/assets/ChannelAnalytics-axwdVcqw.js

js kooai.top collected 2026-10-02 02:09:55 UTC 13,625 bytes, 1 lines download raw bytes

1import{D as ve}from"./DailyTrendChart-BL8NpSnZ.js";import{ac as S}from"./index-CvxDUdwh.js";import{_ as me}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{a4 as F,a8 as pe,a7 as be,b7 as fe,be as ye,m as _e,a as ge,aW as Ce}from"./icons-B5R-B_eA.js";import{o as we,x as k,y as G,z as n,L as t,H as o,u as h,G as A,B as s,C as u,I as H,N as he,O as Ve,K as Ne,b as p,D as m,c as C}from"./vendor-CGUashZo.js";import"./vue-DF2iH-iO.js";const K={partner:"合作商",web:"网页",browser_extension:"浏览器插件",miniprogram:"小程序",other:"其他"};function ke(b={}){const c=b.leading_channel;return[{label:"新增用户",value:Number(b.new_users||0),note:"统计期内完成注册"},{label:"已归因用户",value:Number(b.attributed_users||0),note:"注册时命中有效渠道码"},{label:"直接 / 未知",value:Number(b.direct_users||0),note:"未携带有效渠道码"},{label:"第一来源",value:(c==null?void 0:c.name)||"-",note:c?`带来 ${Number(c.new_users||0)} 位新用户`:"暂无渠道归因"}]}function xe(b,c){const f=String(c||"").trim().toLowerCase();if(!f)return"";const x=new URL(b);return x.searchParams.set("channel",f),x.toString()}function W(b){return K[b]||K.other}const ze={class:"page channel-analytics-page"},Te={class:"page-header"},Se={class:"heading-actions"},Ue={class:"period-line"},$e={class:"metric-grid"},Le={class:"metric-icon"},Ae={class:"section-heading"},Be={class:"channel-name-cell"},De={class:"detail-grid"},Ie={class:"section-heading"},Pe={class:"row-actions"},Re={class:"channel-form"},qe={class:"span-2"},Ee={class:"dialog-actions"},Me={__name:"ChannelAnalytics",setup(b){const c=p(30),f=p(null),x=p([]),w=p(!1),U=p(!1),v=p(""),y=p(""),V=p(!1),g=p(""),i=p(R()),Y=[{label:"近 7 天",value:7},{label:"近 30 天",value:30}],j=[{label:"合作商",value:"partner"},{label:"网页",value:"web"},{label:"浏览器插件",value:"browser_extension"},{label:"小程序",value:"miniprogram"},{label:"其他",value:"other"}],J=[ye,_e,ge,Ce],Q=C(()=>{var a;return ke((a=f.value)==null?void 0:a.summary).map((e,d)=>({...e,icon:J[d]}))}),I=C(()=>{var a;return((a=f.value)==null?void 0:a.channels)||[]}),P=C(()=>{var a;return((a=f.value)==null?void 0:a.daily)||[]}),B=C(()=>{const a=new Map;for(const e of P.value){const d=String((e==null?void 0:e.date)||"");d&&a.set(d,(a.get(d)||0)+Number((e==null?void 0:e.new_users)||0))}return[...a.entries()].sort((e,d)=>e[0].localeCompare(d[0])).map(([e,d])=>({date:e,calls:d}))}),X=C(()=>{var a;return((a=B.value.at(-1))==null?void 0:a.calls)??null}),Z=C(()=>B.value.slice(-7).reduce((a,e)=>a+Number(e.calls||0),0)),ee=C(()=>{var a;return((a=f.value)==null?void 0:a.features)||[]}),le=C(()=>{var e;const a=(e=f.value)==null?void 0:e.period;return a?`${a.start} 至 ${a.end}`:""});function R(){return{code:"",name:"",type:"other",attribution_days:30,partner_name:"",contact:"",note:""}}async function z(){w.value=!0,v.value="";try{const[a,e]=await Promise.all([S.channelAnalytics(c.value),S.acquisitionChannels()]);f.value=a,x.value=Array.isArray(e==null?void 0:e.items)?e.items:[]}catch(a){v.value=a.message||"渠道统计加载失败"}finally{w.value=!1}}function q(){g.value="",i.value=R(),v.value="",y.value="",V.value=!0}function ae(a){g.value=a.id,i.value={code:a.code,name:a.name||"",type:a.type||"other",attribution_days:Number(a.attribution_days||30),partner_name:a.partner_name||"",contact:a.contact||"",note:a.note||""},v.value="",y.value="",V.value=!0}async function ne(){if(!U.value){U.value=!0,v.value="",y.value="";try{const a={...i.value,code:String(i.value.code||"").trim().toLowerCase(),name:String(i.value.name||"").trim()};g.value?await S.updateAcquisitionChannel({...a,id:g.value}):await S.createAcquisitionChannel(a),V.value=!1,await z(),y.value=g.value?"渠道设置已保存。":"渠道已创建,可以开始使用渠道链接。"}catch(a){v.value=a.message||"渠道保存失败"}finally{U.value=!1}}}async function te(a){v.value="",y.value="";try{await S.setAcquisitionChannelStatus({id:a.id,enabled:!a.enabled}),await z(),y.value=a.enabled?`已停用渠道:${a.name}`:`已启用渠道:${a.name}`}catch(e){v.value=e.message||"渠道状态更新失败"}}async function oe(a){const e=typeof window>"u"?"https://koo.ai":window.location.origin,d=xe(`${e}/register`,a.code);try{await navigator.clipboard.writeText(d),y.value=`已复制 ${a.name}
1 的注册渠道链接。`,v.value=""}catch{v.value=`复制失败,请手动使用:${d}`}}function N(a){return Number(a||0).toLocaleString("zh-CN")}function se(a){return`${Number(a||0).toFixed(1)}%`}function ue(a){if(!a)return"-";const e=new Date(a);return Number.isNaN(e.getTime())?String(a):e.toLocaleString("zh-CN",{hour12:!1})}function E(a){return a.channel_name||"直接访问 / 未知来源"}return we(z),(a,e)=>{const d=m("SelectButton"),_=m("Button"),M=m("Message"),D=m("Tag"),T=m("Card"),r=m("Column"),$=m("DataTable"),L=m("InputText"),re=m("Select"),ie=m("InputNumber"),de=m("Textarea"),ce=m("Dialog");return k(),G("section",ze,[n("header",Te,[e[11]||(e[11]=n("div",null,[n("p",{class:"eyebrow"},"Acquisition"),n("h1",null,"新增用户来源"),n("p",null,"用唯一渠道码识别注册来源,查看哪个合作商、网页、插件或小程序带来的新用户最多。")],-1)),n("div",Se,[t(d,{modelValue:c.value,"onUpdate:modelValue":e[0]||(e[0]=l=>c.value=l),options:Y,"option-label":"label","option-value":"value",onChange:z},null,8,["modelValue"]),t(_,{rounded:"",onClick:q},{default:o(()=>[t(h(F),{size:17}),e[10]||(e[10]=n("span",null,"创建渠道",-1))]),_:1}),t(_,{severity:"secondary",outlined:"",rounded:"","aria-label":"刷新",loading:w.value,onClick:z},{default:o(()=>[t(h(pe),{size:18})]),_:1},8,["loading"])])]),v.value?(k(),A(M,{key:0,severity:"error",closable:!1},{default:o(()=>[s(u(v.value),1)]),_:1})):H("",!0),y.value?(k(),A(M,{key:1,severity:"success",closable:!1},{default:o(()=>[s(u(y.value),1)]),_:1})):H("",!0),n("div",Ue,[t(D,{severity:"secondary",rounded:""},{default:o(()=>[s(u(le.value||`近 ${c.value} 天`),1)]),_:1}),e[12]||(e[12]=n("span",null,"注册成功时冻结来源;历史账号不会倒推渠道。",-1))]),n("section",$e,[t(ve,{rows:B.value,title:"按天新增用户",subtitle:"每根柱子为当日新增注册用户数",today:X.value,last7:Z.value,unit:"人"},null,8,["rows","today","last7"]),(k(!0),G(he,null,Ve(Q.value,l=>(k(),A(T,{key:l.label,class:"metric-card"},{content:o(()=>[n("span",Le,[(k(),A(Ne(l.icon),{size:18}))]),n("span",null,u(l.label),1),n("strong",null,u(typeof l.value=="number"?N(l.value):l.value),1),n("small",null,u(l.note),1)]),_:2},1024))),128))]),t(T,{class:"table-section"},{content:o(()=>[n("div",Ae,[e[13]||(e[13]=n("div",null,[n("h2",null,"渠道新增用户排行"),n("p",null,"按统计期内完成注册的用户数排序,渠道访问次数只作为辅助判断。")],-1)),t(D,{severity:"info",rounded:""},{default:o(()=>[s(u(I.value.length)+" 个渠道",1)]),_:1})]),t($,{value:I.value,size:"small","striped-rows":"","show-gridlines":"",loading:w.value,class:"prime-data-table","sort-field":"new_users","sort-order":-1},{empty:o(()=>[...e[14]||(e[14]=[s("暂无渠道,请先创建一个唯一渠道码。",-1)])]),default:o(()=>[t(r,{field:"name",header:"渠道"},{body:o(({data:l})=>[n("div",Be,[n("strong",null,u(l.name),1),n("code",null,u(l.code),1)])]),_:1}),t(r,{field:"type",header:"类型"},{body:o(({data:l})=>[s(u(h(W)(l.type)),1)]),_:1}),t(r,{field:"new_users",header:"新增用户",sortable:""},{body:o(({data:l})=>[n("strong",null,u(N(l.new_users)),1)]),_:1}),t(r,{field:"share_pct",header:"新增占比",sortable:""},{body:o(({data:l})=>[s(u(se(l.share_pct)),1)]),_:1}),t(r,{field:"touches",header:"渠道访问",sortable:""},{body:o(({data:l})=>[s(u(N(l.touches)),1)]),_:1}),t(r,{field:"last_touch_at",header:"最近访问"},{body:o(({data:l})=>[s(u(ue(l.last_touch_at)),1)]),_:1}),t(r,{field:"enabled",header:"状态"},{body:o(({data:l})=>[t(D,{severity:l.enabled?"success":"secondary",rounded:""},{default:o(()=>[s(u(l.enabled?"启用":"停用"),1)]),_:2},1032,["severity"])]),_:1})]),_:1},8,["value","loading"])]),_:1}),n("div",De,[t(T,{class:"table-section"},{content:o(()=>[e[16]||(e[16]=n("div",{class:"section-heading"},[n("div",null,[n("h2",null,"每日来源明细"),n("p",null,"按注册日期拆分渠道来源。")])],-1)),t($,{value:P.value,size:"small","striped-rows":"",loading:w.value,class:"prime-data-table"},{empty:o(()=>[...e[15]||(e[15]=[s("统计期内暂无新增用户。",-1)])]),default:o(()=>[t(r,{field:"date",header:"日期"}),t(r,{header:"来源"},{body:o(({data:l})=>[s(u(E(l)),1)]),_:1}),t(r,{field:"new_users",header:"新增用户",sortable:""},{body:o(({data:l})=>[s(u(N(l.new_users)),1)]),_:1})]),_:1},8,["value","loading"])]),_:1}),t(T,{class:"table-section"},{content:o(()=>[e[18]||(e[18]=n("div",{class:"section-heading"},[n("div",null,[n("h2",null,"来源用户常用功能"),n("p",null,"注册来源与登录后的功能访问关联。")])],-1)),t($,{value:ee.value,size:"small","striped-rows":"",loading:w.value,class:"prime-data-table"},{empty:o(()=>[...e[17]||(e[17]=[s("暂无来源用户的功能使用记录。",-1)])]),default:o(()=>[t(r,{header:"来源"},{body:o(({data:l})=>[s(u(E(l)),1)]),_:1}),t(r,{field:"module_label",header:"功能"}),t(r,{field:"users",header:"用户数",sortable:""},{body:o(({data:l})=>[s(u(N(l.users)),1)]),_:1}),t(r,{field:"page_views",header:"访问量",sortable:""},{body:o(({data:l})=>[s(u(N(l.page_views)),1)]),_:1})]),_:1},8,["value","loading"])]),_:1})]),t(T,{class:"table-section channel-management"},{content:o(()=>[n("div",Ie,[e[20]||(e[20]=n("div",null,[n("h2",null,"渠道管理"),n("p",null,[s("渠道码创建后保持唯一。把 "),n("code",null,"?channel=渠道码"),s(" 加到任意站内链接即可记录来源。")])],-1)),t(_,{size:"small",rounded:"",onClick:q},{default:o(()=>[t(h(F),{size:16}),e[19]||(e[19]=n("span",null,"创建渠道",-1))]),_:1})]),t($,{value:x.value,size:"small","striped-rows":"","show-gridlines":"",loading:w.value,class:"prime-data-table"},{empty:o(()=>[...e[22]||(e[22]=[s("暂无渠道。",-1)])]),default:o(()=>[t(r,{field:"name",header:"渠道名称"}),t(r,{field:"code",header:"唯一渠道码"},{body:o(({data:l})=>[n("code",null,u(l.code),1)]),_:1}),t(r,{field:"type",header:"类型"},{body:o(({data:l})=>[s(u(h(W)(l.type)),1)]),_:1}),t(r,{field:"partner_name",header:"合作方"},{body:o(({data:l})=>[s(u(l.partner_name||"-"),1)]),_:1}),t(r,{field:"attribution_days",header:"Cookie 有效期"},{body:o(({data:l})=>[s(u(l.attribution_days)+" 天",1)]),_:1}),t(r,{header:"使用"},{body:o(({data:l})=>[t(_,{severity:"secondary",text:"",size:"small",onClick:O=>oe(l)},{default:o(()=>[t(h(be),{size:15}),e[21]||(e[21]=n("span",null,"复制链接",-1))]),_:1},8,["onClick"])]),_:1}),t(r,{header:"操作"},{body:o(({data:l})=>[n("div",Pe,[t(_,{severity:"secondary",text:"",rounded:"","aria-label":"编辑渠道",onClick:O=>ae(l)},{default:o(()=>[t(h(fe),{size:16})]),_:1},8,["onClick"]),t(_,{severity:l.enabled?"danger":"success",text:"",size:"small",onClick:O=>te(l)},{default:o(()=>[s(u(l.enabled?"停用":"启用"),1)]),_:2}
1,1032,["severity","onClick"])])]),_:1})]),_:1},8,["value","loading"])]),_:1}),t(ce,{visible:V.value,"onUpdate:visible":e[9]||(e[9]=l=>V.value=l),modal:"",header:g.value?"编辑渠道":"创建渠道",class:"channel-dialog",style:{width:"min(680px, 94vw)"}},{footer:o(()=>[n("div",Ee,[t(_,{severity:"secondary",text:"",onClick:e[8]||(e[8]=l=>V.value=!1)},{default:o(()=>[...e[31]||(e[31]=[s("取消",-1)])]),_:1}),t(_,{loading:U.value,onClick:ne},{default:o(()=>[s(u(g.value?"保存设置":"创建渠道"),1)]),_:1},8,["loading"])])]),default:o(()=>[n("div",Re,[n("label",null,[e[23]||(e[23]=n("span",null,"唯一渠道码",-1)),t(L,{modelValue:i.value.code,"onUpdate:modelValue":e[1]||(e[1]=l=>i.value.code=l),class:"full",disabled:!!g.value,placeholder:"例如 partner_a、chrome_plugin"},null,8,["modelValue","disabled"]),e[24]||(e[24]=n("small",null,"2-64 位小写字母、数字、下划线或短横线;创建后不可修改。",-1))]),n("label",null,[e[25]||(e[25]=n("span",null,"渠道名称",-1)),t(L,{modelValue:i.value.name,"onUpdate:modelValue":e[2]||(e[2]=l=>i.value.name=l),class:"full",placeholder:"例如 合作商 A、Chrome 插件"},null,8,["modelValue"])]),n("label",null,[e[26]||(e[26]=n("span",null,"渠道类型",-1)),t(re,{modelValue:i.value.type,"onUpdate:modelValue":e[3]||(e[3]=l=>i.value.type=l),options:j,"option-label":"label","option-value":"value",fluid:""},null,8,["modelValue"])]),n("label",null,[e[27]||(e[27]=n("span",null,"Cookie 有效期",-1)),t(ie,{modelValue:i.value.attribution_days,"onUpdate:modelValue":e[4]||(e[4]=l=>i.value.attribution_days=l),min:1,max:365,suffix:" 天",fluid:""},null,8,["modelValue"])]),n("label",null,[e[28]||(e[28]=n("span",null,"合作方(可选)",-1)),t(L,{modelValue:i.value.partner_name,"onUpdate:modelValue":e[5]||(e[5]=l=>i.value.partner_name=l),class:"full",placeholder:"合作公司或负责人"},null,8,["modelValue"])]),n("label",null,[e[29]||(e[29]=n("span",null,"联系方式(可选)",-1)),t(L,{modelValue:i.value.contact,"onUpdate:modelValue":e[6]||(e[6]=l=>i.value.contact=l),class:"full",placeholder:"微信、电话或邮箱"},null,8,["modelValue"])]),n("label",qe,[e[30]||(e[30]=n("span",null,"备注(可选)",-1)),t(de,{modelValue:i.value.note,"onUpdate:modelValue":e[7]||(e[7]=l=>i.value.note=l),rows:"3",class:"full",placeholder:"记录渠道用途,不影响归因逻辑"},null,8,["modelValue"])])])]),_:1},8,["visible","header"])])}}},Ye=me(Me,[["__scopeId","data-v-7ccb0528"]]);export{Ye as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.