index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <div class="layout-padding">
  3. <div class="layout-padding-auto layout-padding-view">
  4. <el-row shadow="hover" class="ml10">
  5. <el-form :inline="true" :model="state.queryForm" @keyup.enter="query" ref="queryRef">
  6. <el-form-item label="客户端ID" prop="appName">
  7. <el-input placeholder="请输入客户端ID" clearable v-model="state.queryForm.clientID" />
  8. </el-form-item>
  9. <el-form-item label="时间" prop="appName">
  10. <el-date-picker value-format="YYYY-MM-DD HH:mm:ss" style="width: 300px;" v-model="timeRange"
  11. type="datetimerange" start-placeholder="开始时间" end-placeholder="截止时间" />
  12. </el-form-item>
  13. <el-form-item>
  14. <el-button @click="query" class="ml10" icon="search" type="primary">
  15. 查询
  16. </el-button>
  17. <el-button @click="resetQuery" icon="Refresh">重置</el-button>
  18. </el-form-item>
  19. </el-form>
  20. </el-row>
  21. <el-table ref="tableRef" :data="state.dataList" row-key="path" style="width: 100%" v-loading="state.loading"
  22. border :cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle?.headerCellStyle">
  23. <el-table-column label="客户端ID" prop="clientID" show-overflow-tooltip>
  24. <template #default="{ row }">{{ row.clientID }}</template>
  25. </el-table-column>
  26. <el-table-column label="IP" prop="updateTime" show-overflow-tooltip>
  27. <template #default="{ row }">{{ getIp(row.deviceInfo || '{}') }}</template>
  28. </el-table-column>
  29. <el-table-column label="设备信息" min-width="150" prop="deviceInfo" show-overflow-tooltip>
  30. <template #header>
  31. <div class="header-wrapper">
  32. <span>设备信息</span>
  33. <el-popover placement="top" trigger="hover" content="点击查看具体设备信息" :width="200">
  34. <template #reference>
  35. <el-icon class="header-icon">
  36. <QuestionFilled />
  37. </el-icon>
  38. </template>
  39. </el-popover>
  40. </div>
  41. </template>
  42. <template #default="{ row }">
  43. <div @click="showJsonData(row.deviceInfo)">
  44. {{ getDeviceName(row.deviceInfo) }}
  45. </div>
  46. </template>
  47. </el-table-column>
  48. <el-table-column label="请求头" prop="headInfo" show-overflow-tooltip>
  49. <template #default="{ row }">{{ row.headInfo }}</template>
  50. </el-table-column>
  51. <!-- <el-table-column label="创建时间" prop="createTime" show-overflow-tooltip>
  52. <template #default="{ row }">{{ row.createTime }}</template>
  53. </el-table-column> -->
  54. <el-table-column label="最后推送时间" prop="latestPushTime" show-overflow-tooltip>
  55. <template #default="{ row }">{{ row.latestPushTime }}</template>
  56. </el-table-column>
  57. <el-table-column label="更新时间" prop="updateTime" show-overflow-tooltip>
  58. <template #default="{ row }">{{ row.updateTime }}</template>
  59. </el-table-column>
  60. <el-table-column label="数据" prop="total">
  61. <template #default="{ row }">
  62. <!-- <el-tag title="点击查看">共{{ row.total }}条</el-tag> -->
  63. <el-button title="点击查看" type="primary" link @click="handleDetail(row.clientID)">共{{ row.total }}条</el-button>
  64. </template>
  65. </el-table-column>
  66. </el-table>
  67. <pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination" />
  68. </div>
  69. <dataListModal ref="dataListRef" />
  70. <JsonDataDialog ref="jsonDataDialogRef" />
  71. </div>
  72. </template>
  73. <script lang="ts" name="marketingApps" setup>
  74. import { pageList } from '/@/api/marketing/data';
  75. import { BasicTableProps, useTable } from '/@/hooks/table';
  76. import { useI18n } from 'vue-i18n';
  77. import { ref } from 'vue'
  78. import { formatDate } from '/@/utils/formatTime';
  79. const dataListModal = defineAsyncComponent(() => import('./dataListModal.vue'));
  80. const dataListRef = ref();
  81. const route = useRoute();
  82. const handleDetail = (clientID: string) => {
  83. dataListRef.value.openDialog(clientID);
  84. }
  85. // 添加JSON数据弹窗组件
  86. const JsonDataDialog = defineAsyncComponent(() => import('./JsonDataDialog.vue'))
  87. const jsonDataDialogRef = ref()
  88. // 添加展示JSON数据的方法
  89. const showJsonData = (data: any) => {
  90. jsonDataDialogRef.value.openDialog(data)
  91. }
  92. const { t } = useI18n();
  93. // 定义变量内容
  94. const tableRef = ref();
  95. const EditDialogRef = ref();
  96. const statisticalDialogRef = ref();
  97. const queryRef = ref();
  98. const state: BasicTableProps = reactive<BasicTableProps>({
  99. pageList: pageList,
  100. createdIsNeed: false,
  101. queryForm: {
  102. clientID: '',
  103. startTime: '',
  104. endTime: ''
  105. },
  106. pagination: {
  107. current: 1,
  108. size: 10,
  109. total: 0,
  110. pageSizes: [5, 10, 20, 50, 100]
  111. },
  112. });
  113. const getIp = (jsonString: string) => {
  114. const ipv4Match = jsonString.match(/"ipv4"\s*:\s*"([^"]+)"/);
  115. return ipv4Match ? ipv4Match[1] : null;
  116. }
  117. const getDeviceName = (jsonString: string) => {
  118. if(!jsonString) return '';
  119. const nameMatch = jsonString.match(/"name"\s*:\s*"([^"]+)"/);
  120. const systemNameMatch = jsonString.match(/"systemName"\s*:\s*"([^"]+)"/);
  121. const name = nameMatch ? nameMatch[1] : 'unKnown';
  122. const systemName = systemNameMatch ? systemNameMatch[1] : 'unKnown';
  123. return `设备名称:${name}; 系统名称:${systemName}`
  124. }
  125. const timeRange = computed({
  126. get() {
  127. return [state.queryForm.startTime, state.queryForm.endTime]
  128. },
  129. set(val) {
  130. if (val?.length) {
  131. // state.queryForm.startTime = formatDate(new Date(val[0]), 'YYYY-mm-dd HH:mm:ss');
  132. // state.queryForm.endTime = formatDate(new Date(val[1]), 'YYYY-mm-dd HH:mm:ss');
  133. state.queryForm.startTime = val[0];
  134. state.queryForm.endTime = val[1];
  135. }
  136. }
  137. })
  138. const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
  139. // 搜索事件
  140. const query = (refresh: boolean = false) => {
  141. state.dataList = [];
  142. state.queryForm.domainType = state.queryForm.domainSelected == 0 ? '' : state.queryForm.domainSelected;
  143. getDataList(refresh);
  144. };
  145. // 清空搜索条件
  146. const resetQuery = () => {
  147. queryRef.value.resetFields();
  148. state.queryForm.clientID = '';
  149. state.queryForm.startTime = '';
  150. state.queryForm.endTime = '';
  151. state.dataList = [];
  152. getDataList();
  153. };
  154. // 打开统计弹窗
  155. const onOpenStatistical = (row: any) => {
  156. statisticalDialogRef.value.openDialog(row, true);
  157. };
  158. // 格式化数据展示
  159. const formatNum = (value: string | number = 0) => {
  160. let num = Number(value);
  161. if (num > 0 && num < 1) {
  162. return (num * 100).toFixed(2) + '%';
  163. } else if (num >= 1 && num < 10000) {
  164. return num;
  165. }
  166. return '--'
  167. }
  168. const statusFormatter = (row: any, column: any, cellValue: any, index: any) => {
  169. return cellValue || '--';
  170. }
  171. onMounted(() => {
  172. query();
  173. if(route.query.clientID) {
  174. setTimeout(() => {
  175. dataListRef.value.openDialog(route.query.clientID);
  176. }, 500);
  177. // dataListRef.value.openDialog(route.query.clientID);
  178. }
  179. // console.log(route.query.clientID);
  180. })
  181. </script>
  182. <style scoped lang="scss">
  183. :deep(.el-link__inner) {
  184. display: inline-block;
  185. width: 100%;
  186. justify-content: start;
  187. }
  188. :deep(.el-link.is-underline:hover:after) {
  189. display: none;
  190. }
  191. .table-tabs {
  192. margin-bottom: 10px;
  193. }
  194. .header-wrapper {
  195. display: inline-flex;
  196. align-items: center;
  197. }
  198. .device-info-cell {
  199. cursor: pointer;
  200. color: #409eff;
  201. &:hover {
  202. text-decoration: underline;
  203. }
  204. }
  205. .header-icon {
  206. margin-left: 5px;
  207. color: #999;
  208. font-size: 14px;
  209. cursor: help;
  210. &:hover {
  211. color: #409eff;
  212. }
  213. }
  214. </style>