jcloud/dashboard/src2/components/marketplace/MarketplaceAppAnalytics.vue
2025-04-12 17:39:38 +08:00

212 lines
5.2 KiB
Vue

<template>
<div v-if="$resources.analytics.data">
<div class="col-span-2 mb-5 rounded-md border">
<div class="grid grid-cols-2 lg:grid-cols-5">
<div class="border-b border-r p-5 lg:border-b-0">
<div class="text-base text-gray-700">总安装量</div>
<div class="mt-2 flex items-start justify-between">
<div>
<div class="leading-4">
<span class="text-base text-gray-900">
{{ installAnalytics.total_installs }}
</span>
</div>
</div>
</div>
</div>
<div class="border-b border-r p-5 lg:border-b-0">
<div class="text-base text-gray-700">激活站点</div>
<div class="mt-2 flex items-start justify-between">
<div>
<div class="leading-4">
<span class="text-base text-gray-900">
{{ installAnalytics.installs_active_sites }}
</span>
</div>
</div>
</div>
</div>
<div class="border-b border-r p-5 lg:border-b-0">
<div class="text-base text-gray-700">激活站点分组</div>
<div class="mt-2 flex items-start justify-between">
<div>
<div class="leading-4">
<span class="text-base text-gray-900">
{{ installAnalytics.installs_active_benches }}
</span>
</div>
</div>
</div>
</div>
<div class="border-b border-r p-5 lg:border-b-0">
<div class="text-base text-gray-700">每周安装量</div>
<div class="mt-2 flex items-start justify-between">
<div>
<div class="leading-4">
<span class="text-base text-gray-900">
{{ installAnalytics.installs_last_week }}
</span>
</div>
</div>
</div>
</div>
<div class="border-b border-r p-5 lg:border-b-0">
<div class="text-base text-gray-700">总收入</div>
<div class="mt-2 flex items-start justify-between">
<div>
<div class="leading-4">
<span class="text-base text-gray-900">
{{ $format.userCurrency(totalEarnings) }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div
v-if="$resources.plausible_analytics.data"
class="grid grid-cols-1 gap-5 lg:grid-cols-2"
>
<LineChart
title="页面浏览量"
type="time"
key="Page Views"
:data="
mapChartAnalytics(
this.$resources.plausible_analytics.data?.pageviews || []
)
"
unit="views"
:chartTheme="[$theme.colors.purple[500]]"
:loading="$resources.plausible_analytics.loading"
:error="$resources.plausible_analytics.error"
/>
<LineChart
title="独立访客"
type="time"
key="Unique Visitors"
:data="
mapChartAnalytics(
this.$resources.plausible_analytics.data?.visitors || []
)
"
unit="visitors"
:chartTheme="[$theme.colors.green[500]]"
:loading="$resources.plausible_analytics.loading"
:error="$resources.plausible_analytics.error"
/>
</div>
<LineChart
v-if="$resources.plausible_analytics.data"
class="mt-5"
title="每周安装量"
type="time"
key="Weekly Installs"
:data="
mapChartAnalytics(
this.$resources.plausible_analytics.data?.weekly_installs || []
)
"
unit="installs"
:chartTheme="[$theme.colors.yellow[500]]"
:loading="$resources.plausible_analytics.loading"
:error="$resources.plausible_analytics.error"
/>
</div>
</template>
<script>
import { DateTime } from 'luxon';
import LineChart from '@/components/charts/LineChart.vue';
export default {
name: 'MarketplaceAppAnalytics',
props: {
app: String
},
components: {
LineChart
},
methods: {
formatDate(data) {
return data.map(d => d.date);
},
getChartOptions(yFormatter) {
return {
axisOptions: {
xIsSeries: true,
shortenYAxisNumbers: 1
},
lineOptions: {
hideDots: true,
regionFill: true
},
tooltipOptions: {
formatTooltipX: d => {
return DateTime.fromISO(d).toLocaleString(DateTime.DATE_MED);
},
formatTooltipY: yFormatter
}
};
},
mapChartAnalytics(data) {
if (!data) return;
return {
datasets: [data.map(d => [+new Date(d.date), d.value])]
};
}
},
resources: {
analytics() {
return {
url: 'jcloud.api.marketplace.analytics',
auto: true,
params: {
name: this.app
}
};
},
plausible_analytics() {
return {
url: 'jcloud.api.analytics.plausible_analytics',
auto: true,
params: {
name: this.app
}
};
}
},
computed: {
installAnalytics() {
if (
!this.$resources.analytics.loading &&
this.$resources.analytics.data
) {
return this.$resources.analytics.data;
}
return {};
},
totalEarnings() {
if (!this.installAnalytics.total_payout.cny_amount) return 0;
if (this.$team.pg.currency === 'CNY') {
return (
this.installAnalytics.total_payout.cny_amount +
this.installAnalytics.total_payout.usd_amount * 82
);
} else {
return (
this.installAnalytics.total_payout.cny_amount / 82 +
this.installAnalytics.total_payout.usd_amount
);
}
}
}
};
</script>