|
@@ -0,0 +1,218 @@
|
|
|
+<template>
|
|
|
+ <div class="layout-padding">
|
|
|
+ <div class="layout-padding-auto layout-padding-view">
|
|
|
+ <el-row shadow="hover" class="ml10">
|
|
|
+ <el-form :inline="true" :model="state.queryForm" @keyup.enter="query" ref="queryRef">
|
|
|
+ <el-form-item label="客户端ID" prop="appName">
|
|
|
+ <el-input placeholder="请输入客户端ID" clearable v-model="state.queryForm.clientID" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="时间" prop="appName">
|
|
|
+ <el-date-picker value-format="YYYY-MM-DD HH:mm:ss" style="width: 300px;" v-model="timeRange"
|
|
|
+ type="datetimerange" start-placeholder="开始时间" end-placeholder="截止时间" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button @click="query" class="ml10" icon="search" type="primary">
|
|
|
+ 查询
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-table ref="tableRef" :data="state.dataList" row-key="path" style="width: 100%" v-loading="state.loading"
|
|
|
+ border :cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle?.headerCellStyle">
|
|
|
+ <el-table-column label="客户端ID" prop="clientID" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">{{ row.clientID }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="IP" prop="updateTime" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">{{ getIp(row.deviceInfo || '{}') }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="设备信息" prop="deviceInfo" show-overflow-tooltip>
|
|
|
+ <template #header>
|
|
|
+ <div class="header-wrapper">
|
|
|
+ <span>设备信息</span>
|
|
|
+ <el-popover placement="top" trigger="hover" content="点击查看具体设备信息" :width="200">
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="header-icon">
|
|
|
+ <QuestionFilled />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div @click="showJsonData(row.deviceInfo)">
|
|
|
+ {{ row.deviceInfo }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="请求头" prop="headInfo" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">{{ row.headInfo }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="创建时间" prop="createTime" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">{{ row.createTime }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="更新时间" prop="updateTime" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">{{ row.updateTime }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="数据" prop="total">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <!-- <el-tag title="点击查看">共{{ row.total }}条</el-tag> -->
|
|
|
+ <el-button title="点击查看" type="primary" link @click="handleDetail(row.clientID)">共{{ row.total }}条</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination" />
|
|
|
+ </div>
|
|
|
+ <dataListModal ref="dataListRef" />
|
|
|
+ <JsonDataDialog ref="jsonDataDialogRef" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" name="marketingApps" setup>
|
|
|
+import { pageList } from '/@/api/marketing/data';
|
|
|
+import { BasicTableProps, useTable } from '/@/hooks/table';
|
|
|
+import { useI18n } from 'vue-i18n';
|
|
|
+import { ref } from 'vue'
|
|
|
+import { formatDate } from '/@/utils/formatTime';
|
|
|
+
|
|
|
+const dataListModal = defineAsyncComponent(() => import('./dataListModal.vue'));
|
|
|
+const dataListRef = ref();
|
|
|
+const handleDetail = (clientID: string) => {
|
|
|
+ dataListRef.value.openDialog(clientID);
|
|
|
+}
|
|
|
+
|
|
|
+// 添加JSON数据弹窗组件
|
|
|
+const JsonDataDialog = defineAsyncComponent(() => import('./JsonDataDialog.vue'))
|
|
|
+const jsonDataDialogRef = ref()
|
|
|
+// 添加展示JSON数据的方法
|
|
|
+const showJsonData = (data: any) => {
|
|
|
+ jsonDataDialogRef.value.openDialog(data)
|
|
|
+}
|
|
|
+
|
|
|
+const { t } = useI18n();
|
|
|
+// 定义变量内容
|
|
|
+const tableRef = ref();
|
|
|
+const EditDialogRef = ref();
|
|
|
+const statisticalDialogRef = ref();
|
|
|
+const queryRef = ref();
|
|
|
+const state: BasicTableProps = reactive<BasicTableProps>({
|
|
|
+ pageList: pageList,
|
|
|
+ createdIsNeed: false,
|
|
|
+ queryForm: {
|
|
|
+ clientID: '',
|
|
|
+ startTime: '',
|
|
|
+ endTime: ''
|
|
|
+ },
|
|
|
+ pagination: {
|
|
|
+ current: 1,
|
|
|
+ size: 10,
|
|
|
+ total: 0,
|
|
|
+ pageSizes: [5, 10, 20, 50, 100]
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const getIp = (jsonString: string) => {
|
|
|
+ const ipv4Match = jsonString.match(/"ipv4"\s*:\s*"([^"]+)"/);
|
|
|
+ return ipv4Match ? ipv4Match[1] : null;
|
|
|
+}
|
|
|
+
|
|
|
+const timeRange = computed({
|
|
|
+ get() {
|
|
|
+ return [state.queryForm.startTime, state.queryForm.endTime]
|
|
|
+ },
|
|
|
+ set(val) {
|
|
|
+ if (val?.length) {
|
|
|
+ // state.queryForm.startTime = formatDate(new Date(val[0]), 'YYYY-mm-dd HH:mm:ss');
|
|
|
+ // state.queryForm.endTime = formatDate(new Date(val[1]), 'YYYY-mm-dd HH:mm:ss');
|
|
|
+ state.queryForm.startTime = val[0];
|
|
|
+ state.queryForm.endTime = val[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
|
|
+
|
|
|
+// 搜索事件
|
|
|
+const query = (refresh: boolean = false) => {
|
|
|
+ state.dataList = [];
|
|
|
+ state.queryForm.domainType = state.queryForm.domainSelected == 0 ? '' : state.queryForm.domainSelected;
|
|
|
+ getDataList(refresh);
|
|
|
+};
|
|
|
+
|
|
|
+// 清空搜索条件
|
|
|
+const resetQuery = () => {
|
|
|
+ queryRef.value.resetFields();
|
|
|
+ state.queryForm.clientID = '';
|
|
|
+ state.queryForm.startTime = '';
|
|
|
+ state.queryForm.endTime = '';
|
|
|
+ state.dataList = [];
|
|
|
+ getDataList();
|
|
|
+};
|
|
|
+
|
|
|
+// 打开统计弹窗
|
|
|
+const onOpenStatistical = (row: any) => {
|
|
|
+ statisticalDialogRef.value.openDialog(row, true);
|
|
|
+};
|
|
|
+
|
|
|
+// 格式化数据展示
|
|
|
+const formatNum = (value: string | number = 0) => {
|
|
|
+ let num = Number(value);
|
|
|
+ if (num > 0 && num < 1) {
|
|
|
+ return (num * 100).toFixed(2) + '%';
|
|
|
+
|
|
|
+ } else if (num >= 1 && num < 10000) {
|
|
|
+ return num;
|
|
|
+ }
|
|
|
+ return '--'
|
|
|
+}
|
|
|
+
|
|
|
+const statusFormatter = (row: any, column: any, cellValue: any, index: any) => {
|
|
|
+ return cellValue || '--';
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ query();
|
|
|
+})
|
|
|
+
|
|
|
+</script>
|
|
|
+<style scoped lang="scss">
|
|
|
+:deep(.el-link__inner) {
|
|
|
+ display: inline-block;
|
|
|
+ width: 100%;
|
|
|
+ justify-content: start;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-link.is-underline:hover:after) {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+.table-tabs {
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.header-wrapper {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.device-info-cell {
|
|
|
+ cursor: pointer;
|
|
|
+ color: #409eff;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.header-icon {
|
|
|
+ margin-left: 5px;
|
|
|
+ color: #999;
|
|
|
+ font-size: 14px;
|
|
|
+ cursor: help;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|