Browse Source

完成用户类登录统计-登录数据-今日非网登录数据接口;

zhaowenkang/feature-20260206140254-后台AI复盘二期
songjie 1 month ago
parent
commit
4e25a3cbca
  1. 23
      src/api/platformData.js
  2. 133
      src/views/PlatformData/UserLoginStats.vue

23
src/api/platformData.js

@ -132,6 +132,29 @@ export function getUserLoginChannelMember(params) {
}) })
} }
// 获取非网登录数据(渠道分布)
export function getUserLoginChannelNoMember(params) {
const formData = new FormData();
formData.append('token', localStorage.getItem('token'));
if (params) {
if (params.region) formData.append('region', params.region);
if (params.start_time) formData.append('start_time', params.start_time);
if (params.end_time) formData.append('end_time', params.end_time);
}
return request({
url: 'http://7a1b8c9e.r40.cpolar.top/admin/user/active/ChannelNonMember',
method: 'post',
headers: {
'token': localStorage.getItem('token'),
'client': 'ios',
'version': '1',
'Content-Type': 'multipart/form-data'
},
data: formData
})
}
// 获取用户登录趋势数据 // 获取用户登录趋势数据
export function getUserLoginTrend(params) { export function getUserLoginTrend(params) {
const formData = new FormData(); const formData = new FormData();

133
src/views/PlatformData/UserLoginStats.vue

@ -18,7 +18,7 @@
</div> </div>
<!-- 登录数据 Tab --> <!-- 登录数据 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-bar">
<div class="search-label">地区</div> <div class="search-label">地区</div>
@ -100,10 +100,10 @@
<div class="detail-section"> <div class="detail-section">
<div class="section-title"><el-icon><DataLine /></el-icon> {{ statsTitle }}</div> <div class="section-title"><el-icon><DataLine /></el-icon> {{ statsTitle }}</div>
<el-table :data="loginTableData1" style="width: 100%" :header-cell-style="headerCellStyle"> <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> </el-table>
</div> </div>
@ -111,27 +111,27 @@
<div class="detail-section"> <div class="detail-section">
<div class="section-title"><el-icon><Trophy /></el-icon> {{ statsTitle }}</div> <div class="section-title"><el-icon><Trophy /></el-icon> {{ statsTitle }}</div>
<el-table :data="loginTableData2" style="width: 100%" :header-cell-style="headerCellStyle"> <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> </el-table>
</div> </div>
<!-- 表格3: 非网登录数据 --> <!-- 表格3: 非网登录数据 -->
<div class="detail-section"> <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 :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> </el-table>
</div> </div>
</div> </div>
<!-- 各地区登录数据 Tab --> <!-- 各地区登录数据 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-bar">
<div class="search-label">地区查询</div> <div class="search-label">地区查询</div>
@ -223,7 +223,7 @@
import { ref, onMounted, nextTick, watch } from 'vue'; import { ref, onMounted, nextTick, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import * as echarts from 'echarts'; 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 route = useRoute();
const router = useRouter(); const router = useRouter();
@ -233,6 +233,8 @@ const dateRange = ref('');
const selectedRegion = ref(''); const selectedRegion = ref('');
const searchRegion = ref(''); const searchRegion = ref('');
const dateRangeRegion = ref(''); const dateRangeRegion = ref('');
const loading = ref(false);
const loadingRegion = ref(false);
const chartTrendRef = ref(null); const chartTrendRef = ref(null);
let chartTrendInstance = 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 = () => { const handleSearch = () => {
// URL // URL
const query = { ...route.query }; const query = { ...route.query };
@ -487,10 +539,7 @@ const handleSearch = () => {
router.replace({ query }); router.replace({ query });
fetchTrendData();
fetchLoginData();
fetchLoginChannelData();
fetchLoginChannelMemberData();
fetchAllLoginData();
}; };
const handleReset = () => { const handleReset = () => {
@ -504,10 +553,22 @@ const handleReset = () => {
delete query.region; delete query.region;
router.replace({ query }); 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 () => { const fetchRegionActiveData = async () => {
@ -695,8 +756,7 @@ const handleSearchRegion = () => {
router.replace({ query }); router.replace({ query });
fetchRegionActiveData();
fetchRegionHistogramData();
fetchAllRegionData();
}; };
const handleResetRegion = () => { const handleResetRegion = () => {
@ -710,8 +770,7 @@ const handleResetRegion = () => {
delete query.r_region; delete query.r_region;
router.replace({ query }); router.replace({ query });
fetchRegionActiveData();
fetchRegionHistogramData();
fetchAllRegionData();
}; };
// Tab 1 // Tab 1
@ -719,13 +778,7 @@ const loginTableData1 = ref([]);
const loginTableData2 = 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 // Tab 2 regionalTableData1, 2, 3 fetchRegionActiveData
const headerCellStyle = { const headerCellStyle = {
@ -741,11 +794,9 @@ const initCharts = () => {
if (activeTab.value === 'loginData') { if (activeTab.value === 'loginData') {
// fetchTrendData -> updateTrendChart // fetchTrendData -> updateTrendChart
// fetchTrendData // fetchTrendData
fetchTrendData();
fetchLoginData();
fetchAllLoginData();
} else if (activeTab.value === 'regionalData') { } else if (activeTab.value === 'regionalData') {
fetchRegionActiveData();
fetchRegionHistogramData();
fetchAllRegionData();
// //
if (chartRegionBarRef.value) { if (chartRegionBarRef.value) {
const chart = echarts.init(chartRegionBarRef.value); const chart = echarts.init(chartRegionBarRef.value);
@ -858,9 +909,7 @@ watch(activeTab, (newVal) => {
onMounted(() => { onMounted(() => {
if (activeTab.value === 'loginData') { if (activeTab.value === 'loginData') {
fetchLoginData();
fetchLoginChannelData();
fetchLoginChannelMemberData();
fetchAllLoginData();
} }
initCharts(); initCharts();
}); });

Loading…
Cancel
Save