|
@@ -1,7 +1,9 @@
|
|
|
<template>
|
|
|
- <div class="mt-2 el-card p-4">
|
|
|
- <Title left-line
|
|
|
- :title="selectedVersionLocal === '' ? t('versionDistribution.allVersion') : selectedVersionLocal + t('versionDistribution.version')">
|
|
|
+ <div class="mt-2 el-card p-4">
|
|
|
+ <Title
|
|
|
+ left-line
|
|
|
+ :title="selectedVersionLocal === '' ? t('versionDistribution.allVersion') : selectedVersionLocal + t('versionDistribution.version')"
|
|
|
+ >
|
|
|
<template #default>
|
|
|
<el-popover class="box-item" placement="right" trigger="hover" width="300">
|
|
|
<template #reference>
|
|
@@ -15,20 +17,23 @@
|
|
|
<p><span>趋势图展示累计用户排名Top10版本的变化趋势</span></p>
|
|
|
<p><span class="highlight">新增用户:</span><span>第一次启动应用的用户(以设备为判断标准)</span></p>
|
|
|
<p>
|
|
|
- <span
|
|
|
- class="highlight">活跃用户:</span><span>启动过应用的用户(去重),启动过一次的用户即视为活跃用户,包括新用户与老用户</span>
|
|
|
+ <span class="highlight">活跃用户:</span><span>启动过应用的用户(去重),启动过一次的用户即视为活跃用户,包括新用户与老用户</span>
|
|
|
</p>
|
|
|
<p>
|
|
|
- <span
|
|
|
- class="highlight">启动次数:</span><span>打开应用视为启动。完全退出或后台运行超过30s后再次进入应用,视为一次新启动。开发过程中可以通过setSessionContinueMills来自定义两次启动的间隔,默认30s</span>
|
|
|
+ <span class="highlight">启动次数:</span
|
|
|
+ ><span
|
|
|
+ >打开应用视为启动。完全退出或后台运行超过30s后再次进入应用,视为一次新启动。开发过程中可以通过setSessionContinueMills来自定义两次启动的间隔,默认30s</span
|
|
|
+ >
|
|
|
</p>
|
|
|
<p>
|
|
|
- <span
|
|
|
- class="highlight">版本累计用户(%):</span><span>截止到现在,该版本的累计用户(占累计用户全体的比例);若该版本的用户升级到其他版本,则累计用户会减少</span>
|
|
|
+ <span class="highlight">版本累计用户(%):</span
|
|
|
+ ><span>截止到现在,该版本的累计用户(占累计用户全体的比例);若该版本的用户升级到其他版本,则累计用户会减少</span>
|
|
|
</p>
|
|
|
<p><span class="highlight">升级用户:</span><span>从其他版本升级到该版本的用户(以设备为判断标准)</span></p>
|
|
|
<p>
|
|
|
- <span>如果当日用户先启动老版本然后升级到新版本,分版本查看数据时,此用户在新老版本都会被算为活跃用户(按总体查看数据时不受影响)</span>
|
|
|
+ <span
|
|
|
+ >如果当日用户先启动老版本然后升级到新版本,分版本查看数据时,此用户在新老版本都会被算为活跃用户(按总体查看数据时不受影响)</span
|
|
|
+ >
|
|
|
</p>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -36,24 +41,26 @@
|
|
|
</el-popover>
|
|
|
</template>
|
|
|
</Title>
|
|
|
- <div class=" p-10">
|
|
|
+ <div class="p-10">
|
|
|
<div class="flex items-center justify-between mb-2 mt-3">
|
|
|
<div class="flex items-center">
|
|
|
- <el-select v-if="selectedVersionLocal !== ''" v-model="selectedVersionLocal" class="w-[140px] ml-2"
|
|
|
- style="width: 140px" placeholder="全部频道">
|
|
|
- <el-option v-for="item in channelOptions" :key="item.value" :label="item.label"
|
|
|
- :value="item.value" />
|
|
|
+ <el-select
|
|
|
+ v-if="selectedVersionLocal !== ''"
|
|
|
+ v-model="selectedVersionLocal"
|
|
|
+ class="w-[140px] ml-2"
|
|
|
+ style="width: 140px"
|
|
|
+ placeholder="全部频道"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in channelOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
</el-select>
|
|
|
- <el-select v-model="industryCompare" class="!w-[120px] ml-2" clearable
|
|
|
- @change="handleCompareChange">
|
|
|
+ <el-select v-model="industryCompare" class="!w-[120px] ml-2" clearable @change="handleCompareChange">
|
|
|
<el-option label="版本对比" value="version" />
|
|
|
<el-option v-if="selectedVersionLocal !== ''" label="渠道对比" value="channel" />
|
|
|
<el-option v-if="selectedVersionLocal !== ''" label="时段对比" value="time" />
|
|
|
</el-select>
|
|
|
|
|
|
<!-- 版本对比和渠道对比使用popover -->
|
|
|
- <el-popover v-if="industryCompare !== 'time' && industryCompare" placement="bottom" trigger="click"
|
|
|
- width="400">
|
|
|
+ <el-popover v-if="industryCompare !== 'time' && industryCompare" placement="bottom" trigger="click" width="400">
|
|
|
<template #reference>
|
|
|
<el-button class="ml-2">{{ t('versionDistribution.version') }}</el-button>
|
|
|
</template>
|
|
@@ -61,12 +68,16 @@
|
|
|
<div class="p-3">
|
|
|
<div class="mb-3">
|
|
|
<label class="text-sm font-medium mb-2 block">{{ getCompareTitle() }}</label>
|
|
|
- <el-input v-model="searchKeyword" :placeholder="`请搜索${getCompareTypeText()}`"
|
|
|
- clearable @input="filterCompareOptions" size="small" />
|
|
|
+ <el-input
|
|
|
+ v-model="searchKeyword"
|
|
|
+ :placeholder="`请搜索${getCompareTypeText()}`"
|
|
|
+ clearable
|
|
|
+ @input="filterCompareOptions"
|
|
|
+ size="small"
|
|
|
+ />
|
|
|
</div>
|
|
|
<div class="max-h-60 overflow-y-auto">
|
|
|
- <el-checkbox-group v-model="selectedCompareItems"
|
|
|
- @change="handleCompareItemsChange">
|
|
|
+ <el-checkbox-group v-model="selectedCompareItems" @change="handleCompareItemsChange">
|
|
|
<div v-for="item in filteredCompareOptions" :key="item" class="mb-2">
|
|
|
<el-checkbox :label="item" size="small">{{ item }}</el-checkbox>
|
|
|
</div>
|
|
@@ -77,19 +88,32 @@
|
|
|
</el-popover>
|
|
|
|
|
|
<!-- 时段对比使用日期选择 -->
|
|
|
- <el-popover v-if="industryCompare === 'time'" placement="bottom" trigger="click" width="300"
|
|
|
- :visible="timeCompareVisible" :hide-after="0" :persistent="true">
|
|
|
+ <el-popover
|
|
|
+ v-if="industryCompare === 'time'"
|
|
|
+ placement="bottom"
|
|
|
+ trigger="click"
|
|
|
+ width="300"
|
|
|
+ :visible="timeCompareVisible"
|
|
|
+ :hide-after="0"
|
|
|
+ :persistent="true"
|
|
|
+ >
|
|
|
<template #reference>
|
|
|
- <el-button class="ml-2"
|
|
|
- @click="timeCompareVisible = !timeCompareVisible">{{ t('versionDistribution.version') }}</el-button>
|
|
|
+ <el-button class="ml-2" @click="timeCompareVisible = !timeCompareVisible">{{ t('versionDistribution.version') }}</el-button>
|
|
|
</template>
|
|
|
<template #default>
|
|
|
<div class="p-3">
|
|
|
<div class="mb-3">
|
|
|
<label class="text-sm font-medium mb-2 block">选择对比时段</label>
|
|
|
- <el-date-picker v-model="timeCompareRange" type="date" format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD" :disabled-date="disableAfterToday"
|
|
|
- @change="handleTimeCompareChange" style="width: 100%" :clearable="false" />
|
|
|
+ <el-date-picker
|
|
|
+ v-model="timeCompareRange"
|
|
|
+ type="date"
|
|
|
+ format="YYYY-MM-DD"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ :disabled-date="disableAfterToday"
|
|
|
+ @change="handleTimeCompareChange"
|
|
|
+ style="width: 100%"
|
|
|
+ :clearable="false"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -108,7 +132,7 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="relative">
|
|
|
+ <div class="relative ml-[-50px]">
|
|
|
<div ref="lineChartRef" style="width: 100%; height: 320px"></div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -118,13 +142,12 @@
|
|
|
<div class="flex items-center justify-between mb-2">
|
|
|
<div class="flex">
|
|
|
<div v-if="selectedVersionLocal == ''" class="flex items-center">
|
|
|
- <el-radio-group v-model="timeGranularity">
|
|
|
- <el-radio-button label="hour">今日</el-radio-button>
|
|
|
- <el-radio-button label="day">作日 </el-radio-button>
|
|
|
+ <el-radio-group v-model="queryDate">
|
|
|
+ <el-radio-button :label="0">今日</el-radio-button>
|
|
|
+ <el-radio-button :label="1">作日 </el-radio-button>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
- <div class="text-base font-medium cursor-pointer select-none ml-3 items-center flex text-[#167AF0]"
|
|
|
- @click="showDetail = !showDetail">
|
|
|
+ <div class="text-base font-medium cursor-pointer select-none ml-3 items-center flex text-[#167AF0]" @click="showDetail = !showDetail">
|
|
|
{{ showDetail ? '收起明细数据' : '展开明细数据' }}
|
|
|
<el-icon class="ml-2">
|
|
|
<ArrowDown v-if="showDetail" />
|
|
@@ -137,14 +160,32 @@
|
|
|
<el-button>导出</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-table v-if="showDetail" :data="pagedTableRows" border>
|
|
|
+ <el-table v-if="showDetail && queryDate === 1" :data="tableData" border>
|
|
|
<el-table-column prop="date" label="日期" align="center" min-width="140" />
|
|
|
- <el-table-column prop="hyyh" label="启动次数" align="center" min-width="140" />
|
|
|
- <el-table-column prop="ratio" label="启动次数(占比)" align="center" min-width="220"> </el-table-column>
|
|
|
+ <el-table-column prop="newUser" label="新增用户" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="activeUser" label="活跃用户" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="launch" label="启动次数" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="upgradeUser" label="升级用户" align="center" min-width="140" />
|
|
|
+ </el-table>
|
|
|
+ <el-table v-else-if="showDetail && queryDate === 0" :data="tableData" border>
|
|
|
+ <el-table-column prop="version" label="版本" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="newUser" label="截至至今版本累计用户(%)" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="totalUser" label="累计用户" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="newUser" label="新增用户" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="activeUser" label="活跃用户" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="launch" label="启动次数" align="center" min-width="140" />
|
|
|
+ <el-table-column prop="upgradeUser" label="升级用户" align="center" min-width="140" />
|
|
|
</el-table>
|
|
|
<div v-if="showDetail" class="flex justify-end mt-2">
|
|
|
- <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" background
|
|
|
- layout="total, prev, pager, next, sizes" :total="tableRows.length" :page-sizes="[5, 10, 20]" />
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="pagination.current"
|
|
|
+ v-model:page-size="pagination.size"
|
|
|
+ @change="getDataDetail"
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next, sizes"
|
|
|
+ :total="pagination.total"
|
|
|
+ :page-sizes="[5, 10, 20]"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -166,9 +207,9 @@ import { getTrend as getLaunchTrend } from '/@/api/count/activations';
|
|
|
|
|
|
import { getTrendUpgrade, getTrendDetailAll, getTrendDetailOne, getTrendDetailSource, getTrendSource } from '/@/api/count/version';
|
|
|
|
|
|
-
|
|
|
const { t } = useI18n();
|
|
|
|
|
|
+
|
|
|
interface ChannelOption {
|
|
|
label: string;
|
|
|
value: string;
|
|
@@ -186,12 +227,14 @@ const props = defineProps<{
|
|
|
selectedVersion?: string;
|
|
|
channelOptions: ChannelOption[];
|
|
|
showAllVersions?: boolean;
|
|
|
- formData?: {
|
|
|
+ formData: {
|
|
|
time?: string[];
|
|
|
version?: string;
|
|
|
};
|
|
|
}>();
|
|
|
|
|
|
+const queryDate = ref(0);
|
|
|
+
|
|
|
const emit = defineEmits<{
|
|
|
(e: 'update:selectedVersion', v: string): void;
|
|
|
}>();
|
|
@@ -204,11 +247,14 @@ watch(
|
|
|
}
|
|
|
);
|
|
|
watch(selectedVersionLocal, (v) => emit('update:selectedVersion', v));
|
|
|
-watch(() => props.formData, (v) => {
|
|
|
- formData.value.fromDate = v?.time && v.time[0] ? v.time[0] : '';
|
|
|
- formData.value.toDate = v?.time && v.time[1] ? v.time[1] : '';
|
|
|
-
|
|
|
-})
|
|
|
+watch(
|
|
|
+ () => props.formData,
|
|
|
+ (v) => {
|
|
|
+ formData.value.fromDate = v?.time && v.time[0] ? v.time[0] : '';
|
|
|
+ formData.value.toDate = v?.time && v.time[1] ? v.time[1] : '';
|
|
|
+ formData.value.version = v?.version ? [v?.version] : [];
|
|
|
+ }
|
|
|
+);
|
|
|
|
|
|
// 版本、渠道和时段对比相关状态
|
|
|
const industryCompare = ref('');
|
|
@@ -251,8 +297,14 @@ const formData = ref({
|
|
|
channel: [] as string[],
|
|
|
fromDate: '',
|
|
|
toDate: '',
|
|
|
- timeUnit: "day",
|
|
|
+ timeUnit: 'day',
|
|
|
+});
|
|
|
+const pagination = ref({
|
|
|
+ current: 1, //当前页数
|
|
|
+ total: 0, // 数据总数
|
|
|
+ size: 5, // 每页显示条数
|
|
|
});
|
|
|
+const tableData = ref([]);
|
|
|
|
|
|
const getData = async (type: string) => {
|
|
|
//上方图表
|
|
@@ -270,14 +322,12 @@ const getData = async (type: string) => {
|
|
|
toDate: props.formData?.time?.[1] || '',
|
|
|
};
|
|
|
console.log(formData.value);
|
|
|
-
|
|
|
|
|
|
// 根据选择的类型调用不同的API
|
|
|
if (timeGranularity.value === 'addUser') {
|
|
|
res = await getAddUserTrend({ ...formData.value });
|
|
|
}
|
|
|
console.log(formData.value);
|
|
|
-
|
|
|
|
|
|
// 根据选择的类型调用不同的API
|
|
|
if (timeGranularity.value === 'addUser') {
|
|
@@ -297,8 +347,58 @@ const getData = async (type: string) => {
|
|
|
initChartData(data);
|
|
|
};
|
|
|
|
|
|
+// 为对比项添加数据到图表
|
|
|
+const addCompareData = async (item: string) => {
|
|
|
+ const compareFormData = {
|
|
|
+ ...formData.value,
|
|
|
+ version: industryCompare.value === 'version' ? [item] : formData.value.version,
|
|
|
+ channel: industryCompare.value === 'channel' ? [item] : formData.value.channel,
|
|
|
+ };
|
|
|
+
|
|
|
+ let res;
|
|
|
+ let data;
|
|
|
+
|
|
|
+ // 根据选择的类型调用不同的API
|
|
|
+ if (timeGranularity.value === 'addUser') {
|
|
|
+ res = await getAddUserTrend(compareFormData);
|
|
|
+ data = res?.data || [];
|
|
|
+ } else if (timeGranularity.value === 'activeUser') {
|
|
|
+ res = await getActiveUserTrend(compareFormData);
|
|
|
+ data = res?.data || [];
|
|
|
+ } else if (timeGranularity.value === 'launchUser') {
|
|
|
+ res = await getLaunchTrend(compareFormData);
|
|
|
+ data = res?.data || [];
|
|
|
+ } else if (timeGranularity.value === 'upgradeUser') {
|
|
|
+ res = await getTrendUpgrade(compareFormData);
|
|
|
+ data = res?.data || [];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将新数据添加到图表中
|
|
|
+ if (data && data.items && data.items.length > 0) {
|
|
|
+ const newItem = data.items[0];
|
|
|
+ const randomColorIndex = Math.floor(Math.random() * colorSchemes.length);
|
|
|
+
|
|
|
+ const chartItem = {
|
|
|
+ name: getName(newItem, 0, data),
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ data: newItem.data,
|
|
|
+ itemStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ lineStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ lineChartData.value.items.push(chartItem);
|
|
|
+ initLineChart();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const initChartData = async (data: any) => {
|
|
|
if (!industryCompare.value) {
|
|
|
+ // 非对比模式:显示主数据
|
|
|
masterData.value = data;
|
|
|
lineChartData.value.items = data.items.map((item: any, index: number) => {
|
|
|
const randomColorIndex = Math.floor(Math.random() * colorSchemes.length);
|
|
@@ -317,31 +417,44 @@ const initChartData = async (data: any) => {
|
|
|
});
|
|
|
chartTimes.value = [];
|
|
|
} else {
|
|
|
- lineChartData.value.items.push(
|
|
|
- data.items.map((item: any, index: number) => {
|
|
|
- const randomColorIndex = Math.floor(Math.random() * colorSchemes.length);
|
|
|
- return {
|
|
|
- name: getName(item, index, data),
|
|
|
- type: 'line',
|
|
|
- smooth: true,
|
|
|
- data: item.data,
|
|
|
- itemStyle: {
|
|
|
- color: colorSchemes[randomColorIndex].color,
|
|
|
- },
|
|
|
- lineStyle: {
|
|
|
- color: colorSchemes[randomColorIndex].color,
|
|
|
- },
|
|
|
- };
|
|
|
- })[0]
|
|
|
- );
|
|
|
+ // 对比模式:将新数据添加到现有图表中
|
|
|
+ if (data && data.items && data.items.length > 0) {
|
|
|
+ const newItem = data.items[0];
|
|
|
+ const randomColorIndex = Math.floor(Math.random() * colorSchemes.length);
|
|
|
+
|
|
|
+ const chartItem = {
|
|
|
+ name: getName(newItem, 0, data),
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ data: newItem.data,
|
|
|
+ itemStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ lineStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ lineChartData.value.items.push(chartItem);
|
|
|
+ }
|
|
|
+
|
|
|
if (industryCompare.value == 'time') {
|
|
|
chartTimes.value.push(data.dates);
|
|
|
- lineChartData.value.items[0].name = formData.value.fromDate + ' ~ ' + formData.value.toDate;
|
|
|
+ if (lineChartData.value.items.length > 0) {
|
|
|
+ lineChartData.value.items[0].name = formData.value.fromDate + ' ~ ' + formData.value.toDate;
|
|
|
+ }
|
|
|
} else {
|
|
|
chartTimes.value = [];
|
|
|
}
|
|
|
}
|
|
|
- lineChartData.value.dates = masterData.value.dates;
|
|
|
+
|
|
|
+ // 确保日期数据正确设置
|
|
|
+ if (masterData.value.dates && masterData.value.dates.length > 0) {
|
|
|
+ lineChartData.value.dates = masterData.value.dates;
|
|
|
+ } else if (data && data.dates) {
|
|
|
+ lineChartData.value.dates = data.dates;
|
|
|
+ }
|
|
|
+
|
|
|
initLineChart();
|
|
|
};
|
|
|
|
|
@@ -364,6 +477,29 @@ function formatNumber(value: number | string): string {
|
|
|
const num = typeof value === 'number' ? value : Number(value || 0);
|
|
|
return num.toLocaleString('zh-CN');
|
|
|
}
|
|
|
+const getDataDetail = async () => {
|
|
|
+ if (props.formData.version === '') {
|
|
|
+ const res = await getTrendDetailAll({
|
|
|
+ ...formData.value,
|
|
|
+ ...pagination.value,
|
|
|
+ });
|
|
|
+ const dataDetail = res?.data || [];
|
|
|
+ pagination.value.current = dataDetail.current; //当前页码
|
|
|
+ pagination.value.total = dataDetail.total; //总条数
|
|
|
+ pagination.value.size = dataDetail.size; //每页条数
|
|
|
+ tableData.value = dataDetail.records;
|
|
|
+ } else {
|
|
|
+ const res = await getTrendDetailOne({
|
|
|
+ ...formData.value,
|
|
|
+ ...pagination.value,
|
|
|
+ });
|
|
|
+ const dataDetail = res?.data || [];
|
|
|
+ pagination.value.current = dataDetail.current; //当前页码
|
|
|
+ pagination.value.total = dataDetail.total; //总条数
|
|
|
+ pagination.value.size = dataDetail.size; //每页条数
|
|
|
+ tableData.value = dataDetail.records;
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
const formatterTips = (params: any) => {
|
|
|
if (!params || !params.length) return '';
|
|
@@ -422,7 +558,7 @@ function initLineChart(): void {
|
|
|
type: 'scroll', // 支持图例滚动
|
|
|
},
|
|
|
grid: {
|
|
|
- left: 40,
|
|
|
+ left: 100,
|
|
|
right: 20,
|
|
|
top: 20, // 为图例留出空间
|
|
|
bottom: 60,
|
|
@@ -451,37 +587,28 @@ onMounted(() => {
|
|
|
});
|
|
|
|
|
|
watch(timeGranularity, () => {
|
|
|
- getData('');
|
|
|
+ getData('clearAll');
|
|
|
+});
|
|
|
+watch(queryDate, () => {
|
|
|
+ getDataDetail();
|
|
|
});
|
|
|
-
|
|
|
watch(selectedVersionLocal, () => {
|
|
|
industryCompare.value = '';
|
|
|
getData('');
|
|
|
});
|
|
|
|
|
|
// 监听showAllVersions变化,重新初始化对比选项
|
|
|
-watch(() => props.showAllVersions, () => {
|
|
|
- if (industryCompare.value === 'version') {
|
|
|
- initCompareOptions();
|
|
|
+watch(
|
|
|
+ () => props.showAllVersions,
|
|
|
+ () => {
|
|
|
+ if (industryCompare.value === 'version') {
|
|
|
+ initCompareOptions();
|
|
|
+ }
|
|
|
}
|
|
|
-});
|
|
|
-
|
|
|
-const tableRows = ref<TableRow[]>(
|
|
|
- Array.from({ length: 42 }).map((_, idx) => ({
|
|
|
- date: `2025-08-${String(11).padStart(2, '0')}`,
|
|
|
- newUsers: 727,
|
|
|
- hyyh: '115',
|
|
|
- ratio: '97.45%',
|
|
|
- }))
|
|
|
);
|
|
|
|
|
|
-const currentPage = ref(1);
|
|
|
-const pageSize = ref(5);
|
|
|
-const pagedTableRows = computed(() => {
|
|
|
- const startIndex = (currentPage.value - 1) * pageSize.value;
|
|
|
|
|
|
- return tableRows.value.slice(startIndex, startIndex + pageSize.value);
|
|
|
-});
|
|
|
+
|
|
|
|
|
|
// 版本和渠道对比相关函数
|
|
|
function handleCompareChange(value: string) {
|
|
@@ -494,7 +621,29 @@ function clearCompare() {
|
|
|
selectedCompareItems.value = [];
|
|
|
timeCompareRange.value = '';
|
|
|
industryCompare.value = '';
|
|
|
- getData('clearAll');
|
|
|
+
|
|
|
+ // 重置图表数据到主数据
|
|
|
+ if (masterData.value && masterData.value.items) {
|
|
|
+ lineChartData.value.items = masterData.value.items.map((item: any, index: number) => {
|
|
|
+ const randomColorIndex = Math.floor(Math.random() * colorSchemes.length);
|
|
|
+ return {
|
|
|
+ name: item.name,
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ data: item.data,
|
|
|
+ itemStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ lineStyle: {
|
|
|
+ color: colorSchemes[randomColorIndex].color,
|
|
|
+ },
|
|
|
+ };
|
|
|
+ });
|
|
|
+ lineChartData.value.dates = masterData.value.dates;
|
|
|
+ initLineChart();
|
|
|
+ } else {
|
|
|
+ getData('clearAll');
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function getCompareTitle(): string {
|
|
@@ -523,7 +672,7 @@ function filterCompareOptions() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function handleCompareItemsChange(items: string[]) {
|
|
|
+async function handleCompareItemsChange(items: string[]) {
|
|
|
selectedCompareItems.value = items;
|
|
|
|
|
|
// 对比当前值和之前的值
|
|
@@ -563,16 +712,21 @@ function handleCompareItemsChange(items: string[]) {
|
|
|
// 从后往前删除,避免索引变化影响
|
|
|
removedItemIndices
|
|
|
.sort((a, b) => b - a)
|
|
|
- .forEach(index => {
|
|
|
- // 清理对应的图表数据
|
|
|
- // 这里可以根据实际需要清理图表数据
|
|
|
+ .forEach((index) => {
|
|
|
+ // 删除对应的图表数据项(索引+1是因为第一个是主数据)
|
|
|
+ if (lineChartData.value.items.length > index + 1) {
|
|
|
+ lineChartData.value.items.splice(index + 1, 1);
|
|
|
+ }
|
|
|
});
|
|
|
+ initLineChart();
|
|
|
}
|
|
|
|
|
|
// 根据是否有新增项来决定是否重新获取数据
|
|
|
if (addedItems.length > 0) {
|
|
|
- // 触发数据重新获取
|
|
|
- getData('');
|
|
|
+ // 为每个新增项获取数据并添加到图表
|
|
|
+ for (const item of addedItems) {
|
|
|
+ await addCompareData(item);
|
|
|
+ }
|
|
|
} else if (removedItemIndices.length > 0) {
|
|
|
// 如果只是移除了项,则重新初始化图表
|
|
|
initLineChart();
|
|
@@ -603,7 +757,7 @@ function handleTimeCompareChange(value: string) {
|
|
|
timeCompareRange.value = value;
|
|
|
formData.value.toDate = timeCompareRange.value;
|
|
|
formData.value.fromDate = dayjs(timeCompareRange.value).subtract(7, 'day').format('YYYY-MM-DD');
|
|
|
- formData.value.channel = props.channelOptions?.map(item => item.value) || [];
|
|
|
+ formData.value.channel = props.channelOptions?.map((item) => item.value) || [];
|
|
|
formData.value.version = selectedVersionLocal.value ? [selectedVersionLocal.value] : [];
|
|
|
|
|
|
getData('');
|