|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<div class="dialog">
|
|
|
<el-dialog
|
|
|
- :title="'统计'"
|
|
|
+ :title="t('marketingApps.statistical')"
|
|
|
width="80%"
|
|
|
v-model="visible"
|
|
|
:destroy-on-close="true"
|
|
@@ -9,68 +9,68 @@
|
|
|
:before-close="done=>handleClose(done)"
|
|
|
draggable>
|
|
|
<div class="dialog-body">
|
|
|
-
|
|
|
- <div class="statistics-table-wrapper">
|
|
|
- <el-row v-show="showSearch">
|
|
|
- <el-form :inline="true" :model="state.queryForm" @keyup.enter="withCollapsedChildren(getDataList)" ref="queryRef">
|
|
|
- <el-form-item :label="'时间范围'" prop="timeRange">
|
|
|
- <el-select v-model="state.queryForm.timeRange" @change="handleTimeChange()">
|
|
|
- <el-option :value="TimeRange.ALL" :label="'全部'">全部</el-option>
|
|
|
- <el-option :value="TimeRange.TWENTY_FOUR_HOURS" :label="'24小时'">24小时</el-option>
|
|
|
- <el-option :value="TimeRange.FIFTEEN_MINUTES" :label="'15分钟'">15分钟</el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- </el-row>
|
|
|
- <el-table class="statistics-table" :data="state.dataList" row-key="ip" @sort-change="withCollapsedChildren(sortChangeHandle)" style="width: 100%"
|
|
|
- v-loading="state.loading" border :cell-style="tableStyle.cellStyle"
|
|
|
- :header-cell-style="tableStyle.headerCellStyle"
|
|
|
- :expand-row-keys="expandedRowKeys"
|
|
|
- @expand-change="handleExpandChange"
|
|
|
- >
|
|
|
- <!-- <el-table-column align="center" type="selection" width="40" /> -->
|
|
|
- <el-table-column show-overflow-tooltip type="expand">
|
|
|
- <template #default="{ row }">
|
|
|
- <div class="child-table-container">
|
|
|
- <el-table :data="row.childTableData" v-loading="row.childTableData.childLoading" border :cell-style="tableStyle.cellStyle"
|
|
|
- :header-cell-style="tableStyle.headerCellStyle">
|
|
|
- <!-- <el-table-column :label="t('apps.ip')" prop="ip" show-overflow-tooltip></el-table-column> -->
|
|
|
- <el-table-column :label="t('apps.fingerprint')" prop="fingerprint" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.device')" prop="device" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.firstAccessTime')" prop="firstAccessTime" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.lastAccessTime')" prop="lastAccessTime" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.lastVisitedPage')" prop="lastVisitedPage" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.accessVolume')" prop="accessVolume" show-overflow-tooltip></el-table-column>
|
|
|
- </el-table>
|
|
|
- <div class="pagination-container" @click.stop>
|
|
|
- <pagination v-bind="row.childPagination"
|
|
|
- :current-page="row.childPagination.page"
|
|
|
- :page-size="row.childPagination.size"
|
|
|
- :total="row.childPagination.total"
|
|
|
- :key="`pagination-${row.ip}-${row.childPagination.page}`"
|
|
|
- @size-change="size => handlePageSizeChange(row, size)"
|
|
|
- @current-change="page => handlePageChange(row, page)" />
|
|
|
+ <div class="statistics-table-wrapper">
|
|
|
+ <el-row v-show="showSearch">
|
|
|
+ <el-form :inline="true" :model="state.queryForm" @keyup.enter="withCollapsedChildren(getDataList)" ref="queryRef">
|
|
|
+ <el-form-item :label="t('marketingApps.timeRange')" prop="timeRange">
|
|
|
+ <el-select v-model="state.queryForm.timeRange" @change="handleTimeChange()">
|
|
|
+ <el-option v-for="item in timeRangeOptions" :value="item.value" :label="item.label">{{ item.label }}</el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-row>
|
|
|
+ <el-table class="statistics-table" :data="state.dataList" row-key="ip" @sort-change="withCollapsedChildren(sortChangeHandle)" style="width: 100%"
|
|
|
+ v-loading="state.loading" border :cell-style="tableStyle.cellStyle"
|
|
|
+ :header-cell-style="tableStyle.headerCellStyle"
|
|
|
+ :expand-row-keys="expandedRowKeys"
|
|
|
+ @expand-change="handleExpandChange"
|
|
|
+ >
|
|
|
+ <!-- <el-table-column align="center" type="selection" width="40" /> -->
|
|
|
+ <el-table-column show-overflow-tooltip type="expand">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="child-table-container">
|
|
|
+ <el-table :data="row.childTableData" v-loading="row.childTableData.childLoading" border :cell-style="tableStyle.cellStyle"
|
|
|
+ :header-cell-style="tableStyle.headerCellStyle">
|
|
|
+ <!-- <el-table-column :label="t('marketingApps.ip')" prop="ip" show-overflow-tooltip></el-table-column> -->
|
|
|
+ <el-table-column :label="t('marketingApps.fingerprint')" prop="fingerprint" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.device')" prop="device" show-overflow-tooltip>
|
|
|
+ <template>
|
|
|
+ {{ row.osType + " " + row.osVersion }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.firstAccessTime')" prop="firstTime" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.lastAccessTime')" prop="lastTime" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.lastVisitedPage')" prop="url" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.accessVolume')" prop="count" show-overflow-tooltip></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="pagination-container" @click.stop>
|
|
|
+ <pagination v-bind="row.childPagination"
|
|
|
+ :current-page="row.childPagination.page"
|
|
|
+ :page-size="row.childPagination.size"
|
|
|
+ :total="row.childPagination.total"
|
|
|
+ :key="`pagination-${row.ip}-${row.childPagination.page}`"
|
|
|
+ @size-change="size => handlePageSizeChange(row, size)"
|
|
|
+ @current-change="page => handlePageChange(row, page)" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column :label="t('apps.firstAccessTime')" prop="firstAccessTime" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.lastAccessTime')" prop="lastAccessTime" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.accessSource')" prop="accessSource" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.lastVisitedPage')" prop="lastVisitedPage" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.IP')" prop="IP" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.area')" prop="area" show-overflow-tooltip></el-table-column>
|
|
|
- <el-table-column :label="t('apps.accessVolume')" prop="accessVolume" show-overflow-tooltip></el-table-column>
|
|
|
- </el-table>
|
|
|
-
|
|
|
- <pagination
|
|
|
- @current-change="page => withCollapsedChildren(currentChangeHandle, page)"
|
|
|
- @size-change="size => withCollapsedChildren(sizeChangeHandle, size)"
|
|
|
- v-bind="state.pagination">
|
|
|
- </pagination>
|
|
|
- <br>
|
|
|
- </div>
|
|
|
-
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.firstAccessTime')" prop="firstTime" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.lastAccessTime')" prop="lastTime" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.accessSource')" prop="utmSource" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.lastVisitedPage')" prop="url" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.IP')" prop="ip" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.area')" prop="region" show-overflow-tooltip></el-table-column>
|
|
|
+ <el-table-column :label="t('marketingApps.accessVolume')" prop="count" show-overflow-tooltip></el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <pagination
|
|
|
+ @current-change="page => withCollapsedChildren(currentChangeHandle, page)"
|
|
|
+ @size-change="size => withCollapsedChildren(sizeChangeHandle, size)"
|
|
|
+ v-bind="state.pagination">
|
|
|
+ </pagination>
|
|
|
+ <br>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
</div>
|
|
@@ -79,13 +79,14 @@
|
|
|
<script setup lang="ts">
|
|
|
import { ref, reactive, watchEffect } from 'vue';
|
|
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
|
|
-import { pageList, detailList } from '/@/api/marketing/statistics';
|
|
|
+import { getStatPage, getStatSecondPage } from '/@/api/marketing/apps';
|
|
|
+import { fetchItemList } from '/@/api/admin/dict';
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
|
|
enum TimeRange {
|
|
|
- ALL = 0,
|
|
|
- TWENTY_FOUR_HOURS = 1,
|
|
|
- FIFTEEN_MINUTES = 2,
|
|
|
+ ALL = "0",
|
|
|
+ TWENTY_FOUR_HOURS = "1",
|
|
|
+ FIFTEEN_MINUTES = "2",
|
|
|
}
|
|
|
|
|
|
const visible = ref(false);
|
|
@@ -103,7 +104,7 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|
|
timeRange: TimeRange.ALL,
|
|
|
appId: '',
|
|
|
},
|
|
|
- pageList: pageList,
|
|
|
+ pageList: getStatPage,
|
|
|
dataListLoading: true,
|
|
|
pagination: {
|
|
|
current: 1,
|
|
@@ -112,15 +113,25 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|
|
pageSizes: [5, 10, 20, 50, 100]
|
|
|
},
|
|
|
});
|
|
|
+const timeRangeOptions = ref([]) as any;
|
|
|
|
|
|
const { getDataList, currentChangeHandle, sortChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
|
|
|
|
|
+// 获取时间范围列表
|
|
|
+const getTimeRangeList = async () => {
|
|
|
+ const { data } = await fetchItemList({
|
|
|
+ dictType: 'timeRange'
|
|
|
+ });
|
|
|
+ timeRangeOptions.value = data?.records || [];
|
|
|
+ timeRangeOptions.value.length && (state.queryForm.timeRange = timeRangeOptions.value[0].value);
|
|
|
+}
|
|
|
+
|
|
|
// 打开弹窗
|
|
|
const openDialog = async (_row: any) => {
|
|
|
+ await getTimeRangeList();
|
|
|
visible.value = true;
|
|
|
- getDataList();
|
|
|
- state.queryForm.timeRange = TimeRange.ALL;
|
|
|
state.queryForm.appId = _row.id;
|
|
|
+ getDataList();
|
|
|
};
|
|
|
|
|
|
const handleClose = (done) => {
|
|
@@ -134,13 +145,16 @@ const handleClose = (done) => {
|
|
|
// withCollapsedChildren(getDataList);
|
|
|
// };
|
|
|
|
|
|
+// 时间范围下拉框选中事件
|
|
|
const handleTimeChange = () => {
|
|
|
withCollapsedChildren(getDataList);
|
|
|
+ // 如果是15分钟,则每分钟刷新一次数据
|
|
|
if(state.queryForm.timeRange === TimeRange.FIFTEEN_MINUTES) {
|
|
|
setIntervalTime.value = setInterval(() => {
|
|
|
getDataList();
|
|
|
- }, 4000);
|
|
|
+ }, 60*1000);
|
|
|
}else{
|
|
|
+ // 清除定时器
|
|
|
clearInterval(setIntervalTime.value);
|
|
|
}
|
|
|
}
|
|
@@ -169,7 +183,7 @@ watchEffect(() => {
|
|
|
const loadChildData = async (parentRow) => {
|
|
|
parentRow.childLoading = true;
|
|
|
try {
|
|
|
- const res = await detailList({
|
|
|
+ const res = await getStatSecondPage({
|
|
|
ip: parentRow.ip,
|
|
|
current: parentRow.childPagination.page,
|
|
|
size: parentRow.childPagination.size
|
|
@@ -185,7 +199,7 @@ const loadChildData = async (parentRow) => {
|
|
|
/**
|
|
|
* 关闭所有二级表格,后执行对应函数
|
|
|
* @param callback 执行函数
|
|
|
- * @param args 执行函数(参数)
|
|
|
+ * @param args 执行函数的参数
|
|
|
*/
|
|
|
const withCollapsedChildren = (callback: Function, ...args: any[]) => {
|
|
|
expandedRowKeys.value = [];
|