@koishi-ce/plugin-analytics 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/echarts-B6DtxUFq.js +19 -0
- package/dist/index.js +1 -1
- package/lib/index.mjs +1 -1
- package/package.json +4 -3
- package/src/index.test.ts +24 -2
- package/src/index.ts +4 -1
- package/dist/echarts-BMfAiWrm.js +0 -19
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{icons as e,root as t,store as n,useI18n as r}from"@koishi-ce/client";import{Fragment as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createSlots as u,createTextVNode as d,createVNode as f,defineAsyncComponent as p,defineComponent as m,h,openBlock as g,provide as ee,ref as _,renderSlot as v,resolveComponent as y,toDisplayString as b,unref as x,withCtx as S}from"vue";var C=p(()=>import(`./echarts-BMfAiWrm.js`)),w=_(`send`);function T({title:e,fields:r=[],showTab:i,options:a}){return m({render:()=>{if(!r.every(e=>n[e]))return null;let o=a(n,w.value);if(!o)return;let s=e=>t.$i18n.t(e);return h(y(`k-card`),{class:`frameless analytic-chart`},{header:()=>[h(`span`,{class:`left`},[typeof e==`function`?e():e]),...i?[h(`span`,{class:`right`},[h(`span`,{class:`tab-item`+(w.value===`send`?` active`:``),onClick:()=>w.value=`send`},[s(`analytics.stats.send`)]),h(`span`,{class:`tab-item`+(w.value===`receive`?` active`:``),onClick:()=>w.value=`receive`},[s(`analytics.stats.receive`)])])]:[]],default:()=>h(C,{option:o,autoresize:!0})})}})}var E={item(e){return{trigger:`item`,formatter:e}},axis(e){return{trigger:`axis`,axisPointer:{type:`cross`},formatter:e}}},D=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.bot.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(!t)return;let r=Object.entries(t.messageByBot).map(([e,t])=>({name:e,children:Object.entries(t).map(([e,t])=>({name:t.name||e,value:t[n]}))}));if(r.reduce((e,{children:t})=>e+t.reduce((e,{value:t})=>e+t,0),0))return{tooltip:E.item(({data:t})=>e.$i18n.t(t.children?`analytics.bot.tipPlatform`:`analytics.bot.tipAccount`,[t.name,+t.value.toFixed(1)])),series:[{type:`sunburst`,data:r,radius:[`0`,`65%`],nodeClick:!1,emphasis:{focus:`ancestor`},levels:[{},{label:{rotate:`tangential`}},{label:{position:`outside`,padding:3,silent:!1}}]}]}}})})},O=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.command.title`),fields:[`analytics`],options({analytics:t}){if(!t)return;let n=Object.entries(t.commandRate).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({name:e,value:t}));if(n.length)return{tooltip:E.item(({data:t})=>{let n=[t.name];return n.push(e.$i18n.t(`analytics.command.tip`,[+t.value.toFixed(1)])),n.join(`<br>`)}),series:[{type:`pie`,data:n,radius:[`35%`,`65%`],minShowLabelAngle:3}]}}})})},k=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.history.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(!t||!t.messageByDate.length)return;let r=t.messageByDate.slice(1),i=e.$i18n.i18n.global.locale.value;return{tooltip:E.axis(([t])=>{if(!t)return``;let{name:n,value:r}=t,i=new Date(n).getDay(),a=e.$i18n.t(`analytics.history.weekdays`).split(` `)[i];return e.$i18n.t(`analytics.history.tip`,[n,a,r])}),xAxis:{type:`category`,data:r.map((e,t)=>new Date(Date.now()-(t+1)*864e5).toLocaleDateString(i)).reverse()},yAxis:{type:`value`},series:{type:`line`,smooth:!0,data:r.map(e=>e[n]).reverse()}}}})})},A=e=>`${(e-.5).toFixed()}:00-${(e+.5).toFixed()}:00`,j=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.hour.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(t&&!t.messageByHour.every(e=>!e[n]))return{tooltip:E.axis(([r])=>{if(!r)return``;let[i=0]=r.data,{dataIndex:a}=r,o=t.messageByHour[a];return[`${A(i)}`,e.$i18n.t(`analytics.hour.tip`,[+(o?.[n]||0).toFixed(1)])].join(`<br>`)}),xAxis:{type:`value`,min:0,max:24,minInterval:1,maxInterval:4,axisLabel:{formatter:e=>`${e}:00`},axisPointer:{label:{formatter:({value:e})=>A(e)}}},yAxis:{type:`value`},series:[{data:t.messageByHour.map((e,t)=>[t+.5,e[n]||0]),type:`bar`,stack:`1`}]}}})})},M=e=>{e.plugin(k),e.plugin(j),e.plugin(D),e.plugin(O)},N={class:`content`},P={class:`title`},F={class:`value`},I={class:`left`},L={class:`right`},R=m({__name:`numeric`,props:{title:{},icon:{}},setup(e){return(t,n)=>{let r=y(`k-icon`),i=y(`k-card`);return g(),o(i,{class:`k-analytic-number`},u({default:S(()=>[f(r,{name:e.icon},null,8,[`name`]),l(`div`,N,[l(`p`,P,b(e.title),1),l(`p`,F,[v(t.$slots,`default`,{},()=>[n[0]||=d(`-`,-1)])])])]),_:2},[t.$slots[`footer-left`]?{name:`footer`,fn:S(()=>[l(`span`,I,[v(t.$slots,`footer-left`)]),l(`span`,L,[v(t.$slots,`footer-right`,{},()=>[n[1]||=d(`-`,-1)])])]),key:`0`}:void 0]),1024)}}}),z={key:0,class:`card-grid numeric-grid`},B=m({__name:`index`,setup(e){let{t}=r();ee(`component:analytic-number`,R);let i=a(()=>{let e=n.analytics.dauHistory.slice(1),t=n.analytics.dauHistory.length-1;return t?e.reduce((e,t)=>e+t,0)/Math.min(e.length,t):0});return(e,r)=>{let a=y(`k-slot-item`),o=y(`k-slot`);return x(n).analytics?(g(),c(`div`,z,[f(o,{name:`analytic-number`},{default:S(()=>[f(a,null,{default:S(()=>[f(R,{icon:`analytic:user`,title:x(t)(`analytics.numbers.users`)},{default:S(()=>[d(b(x(n).analytics.userCount),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.newUsers`)),1)]),"footer-right":S(()=>[d(b(x(n).analytics.userIncrement),1)]),_:1},8,[`title`]),f(R,{icon:`analytic:guild`,title:x(t)(`analytics.numbers.guilds`)},{default:S(()=>[d(b(x(n).analytics.guildCount),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.newGuilds`)),1)]),"footer-right":S(()=>[d(b(x(n).analytics.guildIncrement),1)]),_:1},8,[`title`]),f(R,{icon:`analytic:heart`,title:x(t)(`analytics.numbers.dauToday`)},{default:S(()=>[d(b(x(n).analytics.dauHistory[0]),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.dauRecent`)),1)]),"footer-right":S(()=>[d(b(+i.value.toFixed(1)),1)]),_:1},8,[`title`])]),_:1})]),_:1})])):s(`v-if`,!0)}}}),V=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},H=V(B,[[`__scopeId`,`data-v-bc1c77bd`]]),U={class:`card-grid chart-grid`},W=m({__name:`home`,setup(e){return(e,t)=>{let n=y(`k-slot`);return g(),c(i,null,[f(H),l(`div`,U,[f(n,{name:`analytic-chart`})])],64)}}}),G={analytics:{hour:{title:`Nachrichten pro Stunde`,tip:`Tagesdurchschnitt Nachrichten: {0}`},bot:{title:`Nachrichtenanteil pro Plattform`,tipPlatform:`Plattform: {0}<br>Tagesdurchschnitt: {1}`,tipAccount:`Spitzname: {0}<br>Tagesdurchschnitt: {1}`},command:{title:`Befehlsaufruf-Häufigkeit`,tip:`Tagesdurchschnitt Aufrufe: {0}`},history:{title:`Nachrichtenverlauf`,weekdays:`So Mo Di Mi Do Fr Sa`,tip:`{0} {1}<br>Nachrichten: {2}`},stats:{send:`Gesendet`,receive:`Empfangen`},numbers:{users:`Benutzer`,newUsers:`Neue Benutzer gestern`,guilds:`Gruppen`,newGuilds:`Neue Gruppen gestern`,dauToday:`DAU heute`,dauRecent:`DAU zuletzt`}}},te={analytics:{hour:{title:`Messages per Hour`,tip:`Daily average messages: {0}`},bot:{title:`Message Share by Platform`,tipPlatform:`Platform: {0}<br>Daily average messages: {1}`,tipAccount:`Nickname: {0}<br>Daily average messages: {1}`},command:{title:`Command Invocation Frequency`,tip:`Daily average invocations: {0}`},history:{title:`Message History`,weekdays:`Sun Mon Tue Wed Thu Fri Sat`,tip:`{0} {1}<br>Messages: {2}`},stats:{send:`Sent`,receive:`Received`},numbers:{users:`Users`,newUsers:`New users yesterday`,guilds:`Groups`,newGuilds:`New groups yesterday`,dauToday:`DAU today`,dauRecent:`Recent DAU`}}},K={analytics:{hour:{title:`Messages par heure`,tip:`Moyenne quotidienne de messages : {0}`},bot:{title:`Répartition des messages par plateforme`,tipPlatform:`Plateforme : {0}<br>Moyenne quotidienne : {1}`,tipAccount:`Pseudo : {0}<br>Moyenne quotidienne : {1}`},command:{title:`Fréquence d'appel des commandes`,tip:`Appels quotidiens moyens : {0}`},history:{title:`Historique des messages`,weekdays:`dim. lun. mar. mer. jeu. ven. sam.`,tip:`{0} {1}<br>Messages : {2}`},stats:{send:`Envoyés`,receive:`Reçus`},numbers:{users:`Utilisateurs`,newUsers:`Nouveaux utilisateurs hier`,guilds:`Groupes`,newGuilds:`Nouveaux groupes hier`,dauToday:`DAU du jour`,dauRecent:`DAU récent`}}},q={analytics:{hour:{title:`毎時間のメッセージ数`,tip:`日平均メッセージ数:{0}`},bot:{title:`プラットフォーム別メッセージ割合`,tipPlatform:`プラットフォーム:{0}<br>日平均メッセージ数:{1}`,tipAccount:`ニックネーム:{0}<br>日平均メッセージ数:{1}`},command:{title:`コマンド実行頻度`,tip:`日平均実行回数:{0}`},history:{title:`履歴メッセージ数`,weekdays:`日 月 火 水 木 金 土`,tip:`{0} {1}曜日<br>メッセージ数:{2}`},stats:{send:`送信`,receive:`受信`},numbers:{users:`ユーザー数`,newUsers:`昨日の新規ユーザー`,guilds:`グループ数`,newGuilds:`昨日の新規グループ`,dauToday:`本日の DAU`,dauRecent:`最近の DAU`}}},J={analytics:{hour:{title:`Сообщений по часам`,tip:`В среднем сообщений в день: {0}`},bot:{title:`Доля сообщений по платформам`,tipPlatform:`Платформа: {0}<br>В среднем сообщений в день: {1}`,tipAccount:`Ник: {0}<br>В среднем сообщений в день: {1}`},command:{title:`Частота вызова команд`,tip:`В среднем вызовов в день: {0}`},history:{title:`История сообщений`,weekdays:`Вс Пн Вт Ср Чт Пт Сб`,tip:`{0} {1}<br>Сообщений: {2}`},stats:{send:`Отправлено`,receive:`Получено`},numbers:{users:`Пользователи`,newUsers:`Новые пользователи за вчера`,guilds:`Группы`,newGuilds:`Новые группы за вчера`,dauToday:`DAU сегодня`,dauRecent:`DAU за последнее время`}}},Y={analytics:{hour:{title:`每小时消息数量`,tip:`日均消息数量:{0}`},bot:{title:`各平台消息占比`,tipPlatform:`平台:{0}<br>日均消息数量:{1}`,tipAccount:`昵称:{0}<br>日均消息数量:{1}`},command:{title:`指令调用频率`,tip:`日均调用:{0}`},history:{title:`历史消息数量`,weekdays:`日 一 二 三 四 五 六`,tip:`{0} 星期{1}<br>消息数量:{2}`},stats:{send:`发送`,receive:`接收`},numbers:{users:`用户数量`,newUsers:`昨日新增用户`,guilds:`群组数量`,newGuilds:`昨日新增群组`,dauToday:`今日 DAU`,dauRecent:`近期 DAU`}}},X={analytics:{hour:{title:`每小時訊息數量`,tip:`日均訊息數量:{0}`},bot:{title:`各平台訊息佔比`,tipPlatform:`平台:{0}<br>日均訊息數量:{1}`,tipAccount:`暱稱:{0}<br>日均訊息數量:{1}`},command:{title:`指令呼叫頻率`,tip:`日均呼叫:{0}`},history:{title:`歷史訊息數量`,weekdays:`日 一 二 三 四 五 六`,tip:`{0} 星期{1}<br>訊息數量:{2}`},stats:{send:`傳送`,receive:`接收`},numbers:{users:`使用者數量`,newUsers:`昨日新增使用者`,guilds:`群組數量`,newGuilds:`昨日新增群組`,dauToday:`今日 DAU`,dauRecent:`近期 DAU`}}},Z={},Q={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 640 512`};function ne(e,t){return g(),c(`svg`,Q,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M274.7 304H173.3c-95.73 0-173.3 77.6-173.3 173.3C0 496.5 15.52 512 34.66 512H413.3C432.5 512 448 496.5 448 477.3C448 381.6 370.4 304 274.7 304zM413.3 480H34.66C33.2 480 32 478.8 32 477.3C32 399.4 95.4 336 173.3 336H274.7C352.6 336 416 399.4 416 477.3C416 478.8 414.8 480 413.3 480zM224 256c70.7 0 128-57.31 128-128S294.7 0 224 0C153.3 0 96 57.31 96 128S153.3 256 224 256zM224 32c52.94 0 96 43.06 96 96c0 52.93-43.06 96-96 96S128 180.9 128 128C128 75.06 171.1 32 224 32zM375.1 241C392.9 250.8 412.3 256 432 256C493.8 256 544 205.8 544 144S493.8 32 432 32c-12.83 0-25.39 2.156-37.34 6.391c-8.328 2.953-12.69 12.09-9.734 20.42c2.953 8.344 12.12 12.66 20.42 9.734C413.9 65.53 422.8 64 432 64C476.1 64 512 99.89 512 144S476.1 224 432 224c-14.08 0-27.91-3.703-39.98-10.69c-7.656-4.453-17.44-1.828-21.86 5.828C365.7 226.8 368.3 236.6 375.1 241zM490.7 320H448c-8.844 0-16 7.156-16 16S439.2 352 448 352h42.67C555.4 352 608 404.6 608 469.3C608 475.2 603.2 480 597.3 480H496c-8.844 0-16 7.156-16 16s7.156 16 16 16h101.3C620.9 512 640 492.9 640 469.3C640 386.1 573 320 490.7 320z`},null,-1)]])}var re=V(Z,[[`render`,ne]]),ie={},ae={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 512 512`};function oe(e,t){return g(),c(`svg`,ae,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M255.1 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 0 232.4 0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84.02L255.1 96zM255.1 141.3L221.4 106.6C196.1 81.31 160 69.77 124.7 75.66C71.21 84.58 31.1 130.9 31.1 185.1V190.9C31.1 223.6 45.55 254.7 69.42 277L250.1 445.7C251.7 447.2 253.8 448 255.1 448C258.2 448 260.3 447.2 261.9 445.7L442.6 277C466.4 254.7 480 223.6 480 190.9V185.1C480 130.9 440.8 84.58 387.3 75.66C351.1 69.77 315.9 81.31 290.6 106.6L255.1 141.3z`},null,-1)]])}var $=V(ie,[[`render`,oe]]),se={},ce={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 512 512`};function le(e,t){return g(),c(`svg`,ce,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C172.2 512 97.87 471.8 51.19 409.6C45.88 402.5 47.31 392.5 54.37 387.2C61.44 381.9 71.47 383.3 76.78 390.4C117.7 444.8 182.7 480 256 480C379.7 480 480 379.7 480 256C480 132.3 379.7 32 256 32C166.7 32 89.51 84.3 53.55 160H144C152.8 160 160 167.2 160 176C160 184.8 152.8 192 144 192H16C7.164 192 0 184.8 0 176V48C0 39.16 7.164 32 16 32C24.84 32 32 39.16 32 48V131.1C75.66 53.29 159.6 0 256 0zM256 128C264.8 128 272 135.2 272 144V249.4L347.3 324.7C353.6 330.9 353.6 341.1 347.3 347.3C341.1 353.6 330.9 353.6 324.7 347.3L244.7 267.3C241.7 264.3 239.1 260.2 239.1 256V144C239.1 135.2 247.2 128 255.1 128H256z`},null,-1)]])}var ue=V(se,[[`render`,le]]),de={},fe={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 448 512`};function pe(e,t){return g(),c(`svg`,fe,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M224 256c70.7 0 128-57.31 128-128s-57.3-128-128-128C153.3 0 96 57.31 96 128S153.3 256 224 256zM224 32c52.94 0 96 43.06 96 96c0 52.93-43.06 96-96 96S128 180.9 128 128C128 75.06 171.1 32 224 32zM274.7 304H173.3C77.61 304 0 381.6 0 477.3c0 19.14 15.52 34.67 34.66 34.67h378.7C432.5 512 448 496.5 448 477.3C448 381.6 370.4 304 274.7 304zM413.3 480H34.66C33.2 480 32 478.8 32 477.3C32 399.4 95.4 336 173.3 336h101.3C352.6 336 416 399.4 416 477.3C416 478.8 414.8 480 413.3 480z`},null,-1)]])}var me=V(de,[[`render`,pe]]);e.register(`analytic:guild`,re),e.register(`analytic:heart`,$),e.register(`analytic:history`,ue),e.register(`analytic:user`,me);var he=e=>{e.$i18n.extend(`de-DE`,G),e.$i18n.extend(`en-US`,te),e.$i18n.extend(`fr-FR`,K),e.$i18n.extend(`ja-JP`,q),e.$i18n.extend(`ru-RU`,J),e.$i18n.extend(`zh-CN`,Y),e.$i18n.extend(`zh-TW`,X),e.plugin(M),e.slot({type:`home`,component:W,order:0})};export{he as default};
|
|
1
|
+
import{icons as e,root as t,store as n,useI18n as r}from"@koishi-ce/client";import{Fragment as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createSlots as u,createTextVNode as d,createVNode as f,defineAsyncComponent as p,defineComponent as m,h,openBlock as g,provide as ee,ref as _,renderSlot as v,resolveComponent as y,toDisplayString as b,unref as x,withCtx as S}from"vue";var C=p(()=>import(`./echarts-B6DtxUFq.js`)),w=_(`send`);function T({title:e,fields:r=[],showTab:i,options:a}){return m({render:()=>{if(!r.every(e=>n[e]))return null;let o=a(n,w.value);if(!o)return;let s=e=>t.$i18n.t(e);return h(y(`k-card`),{class:`frameless analytic-chart`},{header:()=>[h(`span`,{class:`left`},[typeof e==`function`?e():e]),...i?[h(`span`,{class:`right`},[h(`span`,{class:`tab-item`+(w.value===`send`?` active`:``),onClick:()=>w.value=`send`},[s(`analytics.stats.send`)]),h(`span`,{class:`tab-item`+(w.value===`receive`?` active`:``),onClick:()=>w.value=`receive`},[s(`analytics.stats.receive`)])])]:[]],default:()=>h(C,{option:o,autoresize:!0})})}})}var E={item(e){return{trigger:`item`,formatter:e}},axis(e){return{trigger:`axis`,axisPointer:{type:`cross`},formatter:e}}},D=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.bot.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(!t)return;let r=Object.entries(t.messageByBot).map(([e,t])=>({name:e,children:Object.entries(t).map(([e,t])=>({name:t.name||e,value:t[n]}))}));if(r.reduce((e,{children:t})=>e+t.reduce((e,{value:t})=>e+t,0),0))return{tooltip:E.item(({data:t})=>e.$i18n.t(t.children?`analytics.bot.tipPlatform`:`analytics.bot.tipAccount`,[t.name,+t.value.toFixed(1)])),series:[{type:`sunburst`,data:r,radius:[`0`,`65%`],nodeClick:!1,emphasis:{focus:`ancestor`},levels:[{},{label:{rotate:`tangential`}},{label:{position:`outside`,padding:3,silent:!1}}]}]}}})})},O=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.command.title`),fields:[`analytics`],options({analytics:t}){if(!t)return;let n=Object.entries(t.commandRate).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({name:e,value:t}));if(n.length)return{tooltip:E.item(({data:t})=>{let n=[t.name];return n.push(e.$i18n.t(`analytics.command.tip`,[+t.value.toFixed(1)])),n.join(`<br>`)}),series:[{type:`pie`,data:n,radius:[`35%`,`65%`],minShowLabelAngle:3}]}}})})},k=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.history.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(!t||!t.messageByDate.length)return;let r=t.messageByDate.slice(1),i=e.$i18n.i18n.global.locale.value;return{tooltip:E.axis(([t])=>{if(!t)return``;let{name:n,value:r}=t,i=new Date(n).getDay(),a=e.$i18n.t(`analytics.history.weekdays`).split(` `)[i];return e.$i18n.t(`analytics.history.tip`,[n,a,r])}),xAxis:{type:`category`,data:r.map((e,t)=>new Date(Date.now()-(t+1)*864e5).toLocaleDateString(i)).reverse()},yAxis:{type:`value`},series:{type:`line`,smooth:!0,data:r.map(e=>e[n]).reverse()}}}})})},A=e=>`${(e-.5).toFixed()}:00-${(e+.5).toFixed()}:00`,j=e=>{e.slot({type:`analytic-chart`,component:T({title:()=>e.$i18n.t(`analytics.hour.title`),fields:[`analytics`],showTab:!0,options({analytics:t},n){if(t&&!t.messageByHour.every(e=>!e[n]))return{tooltip:E.axis(([r])=>{if(!r)return``;let[i=0]=r.data,{dataIndex:a}=r,o=t.messageByHour[a];return[`${A(i)}`,e.$i18n.t(`analytics.hour.tip`,[+(o?.[n]||0).toFixed(1)])].join(`<br>`)}),xAxis:{type:`value`,min:0,max:24,minInterval:1,maxInterval:4,axisLabel:{formatter:e=>`${e}:00`},axisPointer:{label:{formatter:({value:e})=>A(e)}}},yAxis:{type:`value`},series:[{data:t.messageByHour.map((e,t)=>[t+.5,e[n]||0]),type:`bar`,stack:`1`}]}}})})},M=e=>{e.plugin(k),e.plugin(j),e.plugin(D),e.plugin(O)},N={class:`content`},P={class:`title`},F={class:`value`},I={class:`left`},L={class:`right`},R=m({__name:`numeric`,props:{title:{},icon:{}},setup(e){return(t,n)=>{let r=y(`k-icon`),i=y(`k-card`);return g(),o(i,{class:`k-analytic-number`},u({default:S(()=>[f(r,{name:e.icon},null,8,[`name`]),l(`div`,N,[l(`p`,P,b(e.title),1),l(`p`,F,[v(t.$slots,`default`,{},()=>[n[0]||=d(`-`,-1)])])])]),_:2},[t.$slots[`footer-left`]?{name:`footer`,fn:S(()=>[l(`span`,I,[v(t.$slots,`footer-left`)]),l(`span`,L,[v(t.$slots,`footer-right`,{},()=>[n[1]||=d(`-`,-1)])])]),key:`0`}:void 0]),1024)}}}),z={key:0,class:`card-grid numeric-grid`},B=m({__name:`index`,setup(e){let{t}=r();ee(`component:analytic-number`,R);let i=a(()=>{let e=n.analytics.dauHistory.slice(1),t=n.analytics.dauHistory.length-1;return t?e.reduce((e,t)=>e+t,0)/Math.min(e.length,t):0});return(e,r)=>{let a=y(`k-slot-item`),o=y(`k-slot`);return x(n).analytics?(g(),c(`div`,z,[f(o,{name:`analytic-number`},{default:S(()=>[f(a,null,{default:S(()=>[f(R,{icon:`analytic:user`,title:x(t)(`analytics.numbers.users`)},{default:S(()=>[d(b(x(n).analytics.userCount),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.newUsers`)),1)]),"footer-right":S(()=>[d(b(x(n).analytics.userIncrement),1)]),_:1},8,[`title`]),f(R,{icon:`analytic:guild`,title:x(t)(`analytics.numbers.guilds`)},{default:S(()=>[d(b(x(n).analytics.guildCount),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.newGuilds`)),1)]),"footer-right":S(()=>[d(b(x(n).analytics.guildIncrement),1)]),_:1},8,[`title`]),f(R,{icon:`analytic:heart`,title:x(t)(`analytics.numbers.dauToday`)},{default:S(()=>[d(b(x(n).analytics.dauHistory[0]),1)]),"footer-left":S(()=>[d(b(x(t)(`analytics.numbers.dauRecent`)),1)]),"footer-right":S(()=>[d(b(+i.value.toFixed(1)),1)]),_:1},8,[`title`])]),_:1})]),_:1})])):s(`v-if`,!0)}}}),V=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},H=V(B,[[`__scopeId`,`data-v-bc1c77bd`]]),U={class:`card-grid chart-grid`},W=m({__name:`home`,setup(e){return(e,t)=>{let n=y(`k-slot`);return g(),c(i,null,[f(H),l(`div`,U,[f(n,{name:`analytic-chart`})])],64)}}}),G={analytics:{hour:{title:`Nachrichten pro Stunde`,tip:`Tagesdurchschnitt Nachrichten: {0}`},bot:{title:`Nachrichtenanteil pro Plattform`,tipPlatform:`Plattform: {0}<br>Tagesdurchschnitt: {1}`,tipAccount:`Spitzname: {0}<br>Tagesdurchschnitt: {1}`},command:{title:`Befehlsaufruf-Häufigkeit`,tip:`Tagesdurchschnitt Aufrufe: {0}`},history:{title:`Nachrichtenverlauf`,weekdays:`So Mo Di Mi Do Fr Sa`,tip:`{0} {1}<br>Nachrichten: {2}`},stats:{send:`Gesendet`,receive:`Empfangen`},numbers:{users:`Benutzer`,newUsers:`Neue Benutzer gestern`,guilds:`Gruppen`,newGuilds:`Neue Gruppen gestern`,dauToday:`DAU heute`,dauRecent:`DAU zuletzt`}}},te={analytics:{hour:{title:`Messages per Hour`,tip:`Daily average messages: {0}`},bot:{title:`Message Share by Platform`,tipPlatform:`Platform: {0}<br>Daily average messages: {1}`,tipAccount:`Nickname: {0}<br>Daily average messages: {1}`},command:{title:`Command Invocation Frequency`,tip:`Daily average invocations: {0}`},history:{title:`Message History`,weekdays:`Sun Mon Tue Wed Thu Fri Sat`,tip:`{0} {1}<br>Messages: {2}`},stats:{send:`Sent`,receive:`Received`},numbers:{users:`Users`,newUsers:`New users yesterday`,guilds:`Groups`,newGuilds:`New groups yesterday`,dauToday:`DAU today`,dauRecent:`Recent DAU`}}},K={analytics:{hour:{title:`Messages par heure`,tip:`Moyenne quotidienne de messages : {0}`},bot:{title:`Répartition des messages par plateforme`,tipPlatform:`Plateforme : {0}<br>Moyenne quotidienne : {1}`,tipAccount:`Pseudo : {0}<br>Moyenne quotidienne : {1}`},command:{title:`Fréquence d'appel des commandes`,tip:`Appels quotidiens moyens : {0}`},history:{title:`Historique des messages`,weekdays:`dim. lun. mar. mer. jeu. ven. sam.`,tip:`{0} {1}<br>Messages : {2}`},stats:{send:`Envoyés`,receive:`Reçus`},numbers:{users:`Utilisateurs`,newUsers:`Nouveaux utilisateurs hier`,guilds:`Groupes`,newGuilds:`Nouveaux groupes hier`,dauToday:`DAU du jour`,dauRecent:`DAU récent`}}},q={analytics:{hour:{title:`毎時間のメッセージ数`,tip:`日平均メッセージ数:{0}`},bot:{title:`プラットフォーム別メッセージ割合`,tipPlatform:`プラットフォーム:{0}<br>日平均メッセージ数:{1}`,tipAccount:`ニックネーム:{0}<br>日平均メッセージ数:{1}`},command:{title:`コマンド実行頻度`,tip:`日平均実行回数:{0}`},history:{title:`履歴メッセージ数`,weekdays:`日 月 火 水 木 金 土`,tip:`{0} {1}曜日<br>メッセージ数:{2}`},stats:{send:`送信`,receive:`受信`},numbers:{users:`ユーザー数`,newUsers:`昨日の新規ユーザー`,guilds:`グループ数`,newGuilds:`昨日の新規グループ`,dauToday:`本日の DAU`,dauRecent:`最近の DAU`}}},J={analytics:{hour:{title:`Сообщений по часам`,tip:`В среднем сообщений в день: {0}`},bot:{title:`Доля сообщений по платформам`,tipPlatform:`Платформа: {0}<br>В среднем сообщений в день: {1}`,tipAccount:`Ник: {0}<br>В среднем сообщений в день: {1}`},command:{title:`Частота вызова команд`,tip:`В среднем вызовов в день: {0}`},history:{title:`История сообщений`,weekdays:`Вс Пн Вт Ср Чт Пт Сб`,tip:`{0} {1}<br>Сообщений: {2}`},stats:{send:`Отправлено`,receive:`Получено`},numbers:{users:`Пользователи`,newUsers:`Новые пользователи за вчера`,guilds:`Группы`,newGuilds:`Новые группы за вчера`,dauToday:`DAU сегодня`,dauRecent:`DAU за последнее время`}}},Y={analytics:{hour:{title:`每小时消息数量`,tip:`日均消息数量:{0}`},bot:{title:`各平台消息占比`,tipPlatform:`平台:{0}<br>日均消息数量:{1}`,tipAccount:`昵称:{0}<br>日均消息数量:{1}`},command:{title:`指令调用频率`,tip:`日均调用:{0}`},history:{title:`历史消息数量`,weekdays:`日 一 二 三 四 五 六`,tip:`{0} 星期{1}<br>消息数量:{2}`},stats:{send:`发送`,receive:`接收`},numbers:{users:`用户数量`,newUsers:`昨日新增用户`,guilds:`群组数量`,newGuilds:`昨日新增群组`,dauToday:`今日 DAU`,dauRecent:`近期 DAU`}}},X={analytics:{hour:{title:`每小時訊息數量`,tip:`日均訊息數量:{0}`},bot:{title:`各平台訊息佔比`,tipPlatform:`平台:{0}<br>日均訊息數量:{1}`,tipAccount:`暱稱:{0}<br>日均訊息數量:{1}`},command:{title:`指令呼叫頻率`,tip:`日均呼叫:{0}`},history:{title:`歷史訊息數量`,weekdays:`日 一 二 三 四 五 六`,tip:`{0} 星期{1}<br>訊息數量:{2}`},stats:{send:`傳送`,receive:`接收`},numbers:{users:`使用者數量`,newUsers:`昨日新增使用者`,guilds:`群組數量`,newGuilds:`昨日新增群組`,dauToday:`今日 DAU`,dauRecent:`近期 DAU`}}},Z={},Q={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 640 512`};function ne(e,t){return g(),c(`svg`,Q,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M274.7 304H173.3c-95.73 0-173.3 77.6-173.3 173.3C0 496.5 15.52 512 34.66 512H413.3C432.5 512 448 496.5 448 477.3C448 381.6 370.4 304 274.7 304zM413.3 480H34.66C33.2 480 32 478.8 32 477.3C32 399.4 95.4 336 173.3 336H274.7C352.6 336 416 399.4 416 477.3C416 478.8 414.8 480 413.3 480zM224 256c70.7 0 128-57.31 128-128S294.7 0 224 0C153.3 0 96 57.31 96 128S153.3 256 224 256zM224 32c52.94 0 96 43.06 96 96c0 52.93-43.06 96-96 96S128 180.9 128 128C128 75.06 171.1 32 224 32zM375.1 241C392.9 250.8 412.3 256 432 256C493.8 256 544 205.8 544 144S493.8 32 432 32c-12.83 0-25.39 2.156-37.34 6.391c-8.328 2.953-12.69 12.09-9.734 20.42c2.953 8.344 12.12 12.66 20.42 9.734C413.9 65.53 422.8 64 432 64C476.1 64 512 99.89 512 144S476.1 224 432 224c-14.08 0-27.91-3.703-39.98-10.69c-7.656-4.453-17.44-1.828-21.86 5.828C365.7 226.8 368.3 236.6 375.1 241zM490.7 320H448c-8.844 0-16 7.156-16 16S439.2 352 448 352h42.67C555.4 352 608 404.6 608 469.3C608 475.2 603.2 480 597.3 480H496c-8.844 0-16 7.156-16 16s7.156 16 16 16h101.3C620.9 512 640 492.9 640 469.3C640 386.1 573 320 490.7 320z`},null,-1)]])}var re=V(Z,[[`render`,ne]]),ie={},ae={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 512 512`};function oe(e,t){return g(),c(`svg`,ae,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M255.1 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 0 232.4 0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84.02L255.1 96zM255.1 141.3L221.4 106.6C196.1 81.31 160 69.77 124.7 75.66C71.21 84.58 31.1 130.9 31.1 185.1V190.9C31.1 223.6 45.55 254.7 69.42 277L250.1 445.7C251.7 447.2 253.8 448 255.1 448C258.2 448 260.3 447.2 261.9 445.7L442.6 277C466.4 254.7 480 223.6 480 190.9V185.1C480 130.9 440.8 84.58 387.3 75.66C351.1 69.77 315.9 81.31 290.6 106.6L255.1 141.3z`},null,-1)]])}var $=V(ie,[[`render`,oe]]),se={},ce={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 512 512`};function le(e,t){return g(),c(`svg`,ce,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512C172.2 512 97.87 471.8 51.19 409.6C45.88 402.5 47.31 392.5 54.37 387.2C61.44 381.9 71.47 383.3 76.78 390.4C117.7 444.8 182.7 480 256 480C379.7 480 480 379.7 480 256C480 132.3 379.7 32 256 32C166.7 32 89.51 84.3 53.55 160H144C152.8 160 160 167.2 160 176C160 184.8 152.8 192 144 192H16C7.164 192 0 184.8 0 176V48C0 39.16 7.164 32 16 32C24.84 32 32 39.16 32 48V131.1C75.66 53.29 159.6 0 256 0zM256 128C264.8 128 272 135.2 272 144V249.4L347.3 324.7C353.6 330.9 353.6 341.1 347.3 347.3C341.1 353.6 330.9 353.6 324.7 347.3L244.7 267.3C241.7 264.3 239.1 260.2 239.1 256V144C239.1 135.2 247.2 128 255.1 128H256z`},null,-1)]])}var ue=V(se,[[`render`,le]]),de={},fe={class:`k-icon`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 448 512`};function pe(e,t){return g(),c(`svg`,fe,[...t[0]||=[l(`path`,{fill:`currentColor`,d:`M224 256c70.7 0 128-57.31 128-128s-57.3-128-128-128C153.3 0 96 57.31 96 128S153.3 256 224 256zM224 32c52.94 0 96 43.06 96 96c0 52.93-43.06 96-96 96S128 180.9 128 128C128 75.06 171.1 32 224 32zM274.7 304H173.3C77.61 304 0 381.6 0 477.3c0 19.14 15.52 34.67 34.66 34.67h378.7C432.5 512 448 496.5 448 477.3C448 381.6 370.4 304 274.7 304zM413.3 480H34.66C33.2 480 32 478.8 32 477.3C32 399.4 95.4 336 173.3 336h101.3C352.6 336 416 399.4 416 477.3C416 478.8 414.8 480 413.3 480z`},null,-1)]])}var me=V(de,[[`render`,pe]]);e.register(`analytic:guild`,re),e.register(`analytic:heart`,$),e.register(`analytic:history`,ue),e.register(`analytic:user`,me);var he=e=>{e.$i18n.extend(`de-DE`,G),e.$i18n.extend(`en-US`,te),e.$i18n.extend(`fr-FR`,K),e.$i18n.extend(`ja-JP`,q),e.$i18n.extend(`ru-RU`,J),e.$i18n.extend(`zh-CN`,Y),e.$i18n.extend(`zh-TW`,X),e.plugin(M),e.slot({type:`home`,component:W,order:0})};export{he as default};
|
package/lib/index.mjs
CHANGED
|
@@ -121,7 +121,7 @@ var Analytics = class extends DataService {
|
|
|
121
121
|
}
|
|
122
122
|
createIndex(session) {
|
|
123
123
|
return {
|
|
124
|
-
selfId: session.selfId,
|
|
124
|
+
selfId: session.selfId ?? "",
|
|
125
125
|
platform: session.platform,
|
|
126
126
|
date: Time.getDateNumber(),
|
|
127
127
|
hour: (/* @__PURE__ */ new Date()).getHours()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koishi-ce/plugin-analytics",
|
|
3
3
|
"description": "Show statistics for Koishi application",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.mjs",
|
|
7
7
|
"typings": "lib/index.d.ts",
|
|
@@ -54,9 +54,10 @@
|
|
|
54
54
|
"@koishi-ce/koishi": "^1.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@koishi-ce/
|
|
57
|
+
"@koishi-ce/plugin-database-memory": "^1.1.0",
|
|
58
|
+
"@koishi-ce/client": "^1.1.1",
|
|
58
59
|
"echarts": "^6.1.0",
|
|
59
|
-
"@koishi-ce/koishi": "^1.0.
|
|
60
|
+
"@koishi-ce/koishi": "^1.0.11",
|
|
60
61
|
"vite": "^8.2.2",
|
|
61
62
|
"vue-echarts": "^8.1.0"
|
|
62
63
|
},
|
package/src/index.test.ts
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
} from "bun:test";
|
|
12
12
|
import { Console, type Entry } from "@koishi-ce/console";
|
|
13
13
|
import { App, type Plugin, Time } from "@koishi-ce/koishi";
|
|
14
|
+
import memory from "@koishi-ce/plugin-database-memory";
|
|
14
15
|
import mock from "@koishi-ce/plugin-mock";
|
|
15
|
-
import memory from "@koishijs/plugin-database-memory";
|
|
16
16
|
import analytics from "./index.ts";
|
|
17
17
|
|
|
18
18
|
// Analytics 类仅默认导出,实例类型经构造器派生(namespace 侧的 Payload 等随实例可用)
|
|
@@ -31,7 +31,7 @@ class FakeConsole extends Console {
|
|
|
31
31
|
const app = new App();
|
|
32
32
|
|
|
33
33
|
// 同 admin:CJS 实现配 ESM 声明,nodenext 互操作视图多包一层 default,类型层穿透取真实类
|
|
34
|
-
app.plugin(memory
|
|
34
|
+
app.plugin(memory);
|
|
35
35
|
// Console 基类的 static inject 是 cordis 3 旧形态,与 Plugin.Constructor 期待类型不兼容,仅做类型层转型
|
|
36
36
|
app.plugin(
|
|
37
37
|
FakeConsole as unknown as Plugin.Constructor<App>,
|
|
@@ -144,6 +144,28 @@ describe("analytics 统计服务", () => {
|
|
|
144
144
|
expect(rows[0]?.count).toBe(1);
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
it("无 selfId 的会话按空串落库不丢统计", async () => {
|
|
148
|
+
// upstream: koishijs/koishi#1501——selfId 是联合主键的非空列,
|
|
149
|
+
// 裸传 undefined 会令整批 upsert 因约束失败而丢失统计
|
|
150
|
+
app.emit("send", { platform: "sandbox:web" } as never);
|
|
151
|
+
await service().upload(true);
|
|
152
|
+
const today = Time.getDateNumber();
|
|
153
|
+
const rows = await app.database.get(
|
|
154
|
+
"analytics.message",
|
|
155
|
+
{
|
|
156
|
+
date: today,
|
|
157
|
+
platform: "sandbox:web",
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
// upsert 回调形式在同键行上不合并(既有行为,SUM 语义不受
|
|
161
|
+
// 影响),断言存在空串键的行即可
|
|
162
|
+
expect(
|
|
163
|
+
rows.some(
|
|
164
|
+
(row) => row.selfId === "" && row.count >= 1,
|
|
165
|
+
),
|
|
166
|
+
).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
|
|
147
169
|
it("非强制上传在间隔超时后触发(statsInternal=0)", async () => {
|
|
148
170
|
// statsInternal 为 0:任意时间流逝都满足间隔条件,走 forced=false 路径
|
|
149
171
|
await new Promise((resolve) => setTimeout(resolve, 5));
|
package/src/index.ts
CHANGED
|
@@ -209,7 +209,10 @@ class Analytics extends DataService<Analytics.Payload> {
|
|
|
209
209
|
session: Session<any, any, any>,
|
|
210
210
|
): Analytics.Index {
|
|
211
211
|
return {
|
|
212
|
-
selfId
|
|
212
|
+
// selfId 为联合主键之一且列非空,沙盒等无 selfId 的会话落
|
|
213
|
+
// 空串行,避免整批 upsert 因非空约束失败丢统计
|
|
214
|
+
// upstream: koishijs/koishi#1501
|
|
215
|
+
selfId: session.selfId ?? "",
|
|
213
216
|
platform: session.platform,
|
|
214
217
|
date: Time.getDateNumber(),
|
|
215
218
|
hour: new Date().getHours(),
|