|
|
|
@ -18,7 +18,7 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 登录数据 Tab --> |
|
|
|
<div v-show="activeTab === 'loginData'" class="tab-content"> |
|
|
|
<div v-show="activeTab === 'loginData'" class="tab-content" v-loading="loading"> |
|
|
|
<!-- 搜索栏 --> |
|
|
|
<div class="search-bar"> |
|
|
|
<div class="search-label">地区</div> |
|
|
|
@ -100,10 +100,10 @@ |
|
|
|
<div class="detail-section"> |
|
|
|
<div class="section-title"><el-icon><DataLine /></el-icon> {{ statsTitle }}登录数据</div> |
|
|
|
<el-table :data="loginTableData1" style="width: 100%" :header-cell-style="headerCellStyle"> |
|
|
|
<el-table-column prop="channel" label="来源渠道" /> |
|
|
|
<el-table-column prop="total" :label="statsTitle + '登录总数'" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
|
|
|
<el-table-column prop="percent" label="占比" /> |
|
|
|
<el-table-column prop="channel" label="来源渠道" align="center" /> |
|
|
|
<el-table-column prop="total" :label="statsTitle + '登录总数'" align="center" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" align="center" /> |
|
|
|
<el-table-column prop="percent" label="占比" align="center" /> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
|
|
|
|
@ -111,27 +111,27 @@ |
|
|
|
<div class="detail-section"> |
|
|
|
<div class="section-title"><el-icon><Trophy /></el-icon> {{ statsTitle }}会员登录数据</div> |
|
|
|
<el-table :data="loginTableData2" style="width: 100%" :header-cell-style="headerCellStyle"> |
|
|
|
<el-table-column prop="channel" label="来源渠道" /> |
|
|
|
<el-table-column prop="total" :label="statsTitle + '登录会员数'" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
|
|
|
<el-table-column prop="rate" label="会员登录率" /> |
|
|
|
<el-table-column prop="channel" label="来源渠道" align="center" /> |
|
|
|
<el-table-column prop="total" :label="statsTitle + '登录会员数'" align="center" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" align="center" /> |
|
|
|
<el-table-column prop="rate" label="会员登录率" align="center" /> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 表格3: 非网登录数据 --> |
|
|
|
<div class="detail-section"> |
|
|
|
<div class="section-title"><el-icon><User /></el-icon> 非网登录数据</div> |
|
|
|
<div class="section-title"><el-icon><User /></el-icon> {{ statsTitle }}非网登录数据</div> |
|
|
|
<el-table :data="loginTableData3" style="width: 100%" :header-cell-style="headerCellStyle"> |
|
|
|
<el-table-column prop="channel" label="来源渠道" /> |
|
|
|
<el-table-column prop="total" label="今日登录会员数" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
|
|
|
<el-table-column prop="rate" label="非网登录率" /> |
|
|
|
<el-table-column prop="channel" label="来源渠道" align="center" /> |
|
|
|
<el-table-column prop="total" :label="statsTitle + '登录非网数'" align="center" /> |
|
|
|
<el-table-column prop="dailyNew" label="较昨日新增" align="center" /> |
|
|
|
<el-table-column prop="rate" label="非网登录率" align="center" /> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 各地区登录数据 Tab --> |
|
|
|
<div v-show="activeTab === 'regionalData'" class="tab-content"> |
|
|
|
<div v-show="activeTab === 'regionalData'" class="tab-content" v-loading="loadingRegion"> |
|
|
|
<!-- 搜索栏 --> |
|
|
|
<div class="search-bar"> |
|
|
|
<div class="search-label">地区查询</div> |
|
|
|
@ -223,7 +223,7 @@ |
|
|
|
import { ref, onMounted, nextTick, watch } from 'vue'; |
|
|
|
import { useRoute, useRouter } from 'vue-router'; |
|
|
|
import * as echarts from 'echarts'; |
|
|
|
import { getUserLoginList, getUserLoginTrend, getRegionActiveData, getRegionActiveDataHistogram, getUserLoginChannel, getUserLoginChannelMember } from '../../api/platformData'; |
|
|
|
import { getUserLoginList, getUserLoginTrend, getRegionActiveData, getRegionActiveDataHistogram, getUserLoginChannel, getUserLoginChannelMember, getUserLoginChannelNoMember } from '../../api/platformData'; |
|
|
|
|
|
|
|
const route = useRoute(); |
|
|
|
const router = useRouter(); |
|
|
|
@ -233,6 +233,8 @@ const dateRange = ref(''); |
|
|
|
const selectedRegion = ref(''); |
|
|
|
const searchRegion = ref(''); |
|
|
|
const dateRangeRegion = ref(''); |
|
|
|
const loading = ref(false); |
|
|
|
const loadingRegion = ref(false); |
|
|
|
|
|
|
|
const chartTrendRef = ref(null); |
|
|
|
let chartTrendInstance = null; |
|
|
|
@ -467,6 +469,56 @@ const fetchLoginChannelMemberData = async () => { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const fetchLoginChannelNoMemberData = async () => { |
|
|
|
let params = {}; |
|
|
|
if (dateRange.value && dateRange.value.length === 2) { |
|
|
|
params.start_time = formatDate(dateRange.value[0]); |
|
|
|
params.end_time = formatDate(dateRange.value[1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (selectedRegion.value && selectedRegion.value !== 'all') { |
|
|
|
params.region = selectedRegion.value; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
const res = await getUserLoginChannelNoMember(params); |
|
|
|
console.log("获取非网登录渠道数据响应:", res); |
|
|
|
|
|
|
|
// 兼容处理拦截器 |
|
|
|
const data = res.list ? res : (res.data && res.data.list ? res.data : null); |
|
|
|
|
|
|
|
if (data && data.list) { |
|
|
|
loginTableData3.value = data.list.map(item => ({ |
|
|
|
channel: item.source, |
|
|
|
total: item.today_count, |
|
|
|
dailyNew: item.growth_value, |
|
|
|
rate: item.ratio + '%' |
|
|
|
})); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
console.error('获取非网登录渠道数据失败:', e); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 统一获取登录数据 Tab 的所有数据 |
|
|
|
const fetchAllLoginData = async () => { |
|
|
|
loading.value = true; |
|
|
|
try { |
|
|
|
// 使用 Promise.all 并行请求所有接口 |
|
|
|
await Promise.all([ |
|
|
|
fetchTrendData(), |
|
|
|
fetchLoginData(), |
|
|
|
fetchLoginChannelData(), |
|
|
|
fetchLoginChannelMemberData(), |
|
|
|
fetchLoginChannelNoMemberData() |
|
|
|
]); |
|
|
|
} catch (error) { |
|
|
|
console.error('获取登录数据失败:', error); |
|
|
|
} finally { |
|
|
|
loading.value = false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const handleSearch = () => { |
|
|
|
// 更新 URL 参数 |
|
|
|
const query = { ...route.query }; |
|
|
|
@ -487,10 +539,7 @@ const handleSearch = () => { |
|
|
|
|
|
|
|
router.replace({ query }); |
|
|
|
|
|
|
|
fetchTrendData(); |
|
|
|
fetchLoginData(); |
|
|
|
fetchLoginChannelData(); |
|
|
|
fetchLoginChannelMemberData(); |
|
|
|
fetchAllLoginData(); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleReset = () => { |
|
|
|
@ -504,10 +553,22 @@ const handleReset = () => { |
|
|
|
delete query.region; |
|
|
|
router.replace({ query }); |
|
|
|
|
|
|
|
fetchTrendData(); |
|
|
|
fetchLoginData(); |
|
|
|
fetchLoginChannelData(); |
|
|
|
fetchLoginChannelMemberData(); |
|
|
|
fetchAllLoginData(); |
|
|
|
}; |
|
|
|
|
|
|
|
// 统一获取地区数据 Tab 的所有数据 |
|
|
|
const fetchAllRegionData = async () => { |
|
|
|
loadingRegion.value = true; |
|
|
|
try { |
|
|
|
await Promise.all([ |
|
|
|
fetchRegionActiveData(), |
|
|
|
fetchRegionHistogramData() |
|
|
|
]); |
|
|
|
} catch (error) { |
|
|
|
console.error('获取地区数据失败:', error); |
|
|
|
} finally { |
|
|
|
loadingRegion.value = false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const fetchRegionActiveData = async () => { |
|
|
|
@ -695,8 +756,7 @@ const handleSearchRegion = () => { |
|
|
|
|
|
|
|
router.replace({ query }); |
|
|
|
|
|
|
|
fetchRegionActiveData(); |
|
|
|
fetchRegionHistogramData(); |
|
|
|
fetchAllRegionData(); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleResetRegion = () => { |
|
|
|
@ -710,8 +770,7 @@ const handleResetRegion = () => { |
|
|
|
delete query.r_region; |
|
|
|
router.replace({ query }); |
|
|
|
|
|
|
|
fetchRegionActiveData(); |
|
|
|
fetchRegionHistogramData(); |
|
|
|
fetchAllRegionData(); |
|
|
|
}; |
|
|
|
|
|
|
|
// Tab 1 数据 |
|
|
|
@ -719,13 +778,7 @@ const loginTableData1 = ref([]); |
|
|
|
|
|
|
|
const loginTableData2 = ref([]); |
|
|
|
|
|
|
|
const loginTableData3 = [ |
|
|
|
{ channel: 'App Store', total: '1,245', dailyNew: '', rate: '38%' }, |
|
|
|
{ channel: 'Play Store', total: '987', dailyNew: '', rate: '30%' }, |
|
|
|
{ channel: 'H5', total: '543', dailyNew: '', rate: '17%' }, |
|
|
|
{ channel: 'APK', total: '321', dailyNew: '', rate: '10%' }, |
|
|
|
{ channel: '总计', total: '3,096', dailyNew: '', rate: '100%' }, |
|
|
|
]; |
|
|
|
const loginTableData3 = ref([]); |
|
|
|
|
|
|
|
// Tab 2 数据:regionalTableData1, 2, 3 已改为响应式变量并在 fetchRegionActiveData 中更新 |
|
|
|
const headerCellStyle = { |
|
|
|
@ -741,11 +794,9 @@ const initCharts = () => { |
|
|
|
if (activeTab.value === 'loginData') { |
|
|
|
// 趋势图已经在 fetchTrendData -> updateTrendChart 中初始化和更新 |
|
|
|
// 这里只需要处理初始无数据时的状态,或者等待 fetchTrendData 调用 |
|
|
|
fetchTrendData(); |
|
|
|
fetchLoginData(); |
|
|
|
fetchAllLoginData(); |
|
|
|
} else if (activeTab.value === 'regionalData') { |
|
|
|
fetchRegionActiveData(); |
|
|
|
fetchRegionHistogramData(); |
|
|
|
fetchAllRegionData(); |
|
|
|
// 柱状图 |
|
|
|
if (chartRegionBarRef.value) { |
|
|
|
const chart = echarts.init(chartRegionBarRef.value); |
|
|
|
@ -858,9 +909,7 @@ watch(activeTab, (newVal) => { |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
if (activeTab.value === 'loginData') { |
|
|
|
fetchLoginData(); |
|
|
|
fetchLoginChannelData(); |
|
|
|
fetchLoginChannelMemberData(); |
|
|
|
fetchAllLoginData(); |
|
|
|
} |
|
|
|
initCharts(); |
|
|
|
}); |
|
|
|
|