index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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="updateTime" show-overflow-tooltip>
  55. <template #default="{ row }">{{ row.updateTime }}</template>
  56. </el-table-column>
  57. <el-table-column label="数据" prop="total">
  58. <template #default="{ row }">
  59. <!-- <el-tag title="点击查看">共{{ row.total }}条</el-tag> -->
  60. <el-button title="点击查看" type="primary" link @click="handleDetail(row.clientID)">共{{ row.total }}条</el-button>
  61. </template>
  62. </el-table-column>
  63. </el-table>
  64. <pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination" />
  65. </div>
  66. <dataListModal ref="dataListRef" />
  67. <JsonDataDialog ref="jsonDataDialogRef" />
  68. </div>
  69. </template>
  70. <script lang="ts" name="marketingApps" setup>
  71. import { pageList } from '/@/api/marketing/data';
  72. import { BasicTableProps, useTable } from '/@/hooks/table';
  73. import { useI18n } from 'vue-i18n';
  74. import { ref } from 'vue'
  75. import { formatDate } from '/@/utils/formatTime';
  76. const dataListModal = defineAsyncComponent(() => import('./dataListModal.vue'));
  77. const dataListRef = ref();
  78. const handleDetail = (clientID: string) => {
  79. dataListRef.value.openDialog(clientID);
  80. }
  81. // 添加JSON数据弹窗组件
  82. const JsonDataDialog = defineAsyncComponent(() => import('./JsonDataDialog.vue'))
  83. const jsonDataDialogRef = ref()
  84. // 添加展示JSON数据的方法
  85. const showJsonData = (data: any) => {
  86. jsonDataDialogRef.value.openDialog(data)
  87. }
  88. const { t } = useI18n();
  89. // 定义变量内容
  90. const tableRef = ref();
  91. const EditDialogRef = ref();
  92. const statisticalDialogRef = ref();
  93. const queryRef = ref();
  94. const state: BasicTableProps = reactive<BasicTableProps>({
  95. pageList: pageList,
  96. createdIsNeed: false,
  97. queryForm: {
  98. clientID: '',
  99. startTime: '',
  100. endTime: ''
  101. },
  102. pagination: {
  103. current: 1,
  104. size: 10,
  105. total: 0,
  106. pageSizes: [5, 10, 20, 50, 100]
  107. },
  108. });
  109. const getIp = (jsonString: string) => {
  110. const ipv4Match = jsonString.match(/"ipv4"\s*:\s*"([^"]+)"/);
  111. return ipv4Match ? ipv4Match[1] : null;
  112. }
  113. const getDeviceName = (jsonString: string) => {
  114. const nameMatch = jsonString.match(/"name"\s*:\s*"([^"]+)"/);
  115. const systemNameMatch = jsonString.match(/"systemName"\s*:\s*"([^"]+)"/);
  116. const name = nameMatch ? nameMatch[1] : 'unKnown';
  117. const systemName = systemNameMatch ? systemNameMatch[1] : 'unKnown';
  118. return `设备名称:${name}; 系统名称:${systemName}`
  119. }
  120. const timeRange = computed({
  121. get() {
  122. return [state.queryForm.startTime, state.queryForm.endTime]
  123. },
  124. set(val) {
  125. if (val?.length) {
  126. // state.queryForm.startTime = formatDate(new Date(val[0]), 'YYYY-mm-dd HH:mm:ss');
  127. // state.queryForm.endTime = formatDate(new Date(val[1]), 'YYYY-mm-dd HH:mm:ss');
  128. state.queryForm.startTime = val[0];
  129. state.queryForm.endTime = val[1];
  130. }
  131. }
  132. })
  133. const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
  134. // 搜索事件
  135. const query = (refresh: boolean = false) => {
  136. state.dataList = [];
  137. state.queryForm.domainType = state.queryForm.domainSelected == 0 ? '' : state.queryForm.domainSelected;
  138. getDataList(refresh);
  139. };
  140. // 清空搜索条件
  141. const resetQuery = () => {
  142. queryRef.value.resetFields();
  143. state.queryForm.clientID = '';
  144. state.queryForm.startTime = '';
  145. state.queryForm.endTime = '';
  146. state.dataList = [];
  147. getDataList();
  148. };
  149. // 打开统计弹窗
  150. const onOpenStatistical = (row: any) => {
  151. statisticalDialogRef.value.openDialog(row, true);
  152. };
  153. // 格式化数据展示
  154. const formatNum = (value: string | number = 0) => {
  155. let num = Number(value);
  156. if (num > 0 && num < 1) {
  157. return (num * 100).toFixed(2) + '%';
  158. } else if (num >= 1 && num < 10000) {
  159. return num;
  160. }
  161. return '--'
  162. }
  163. const statusFormatter = (row: any, column: any, cellValue: any, index: any) => {
  164. return cellValue || '--';
  165. }
  166. onMounted(() => {
  167. query();
  168. })
  169. </script>
  170. <style scoped lang="scss">
  171. :deep(.el-link__inner) {
  172. display: inline-block;
  173. width: 100%;
  174. justify-content: start;
  175. }
  176. :deep(.el-link.is-underline:hover:after) {
  177. display: none;
  178. }
  179. .table-tabs {
  180. margin-bottom: 10px;
  181. }
  182. .header-wrapper {
  183. display: inline-flex;
  184. align-items: center;
  185. }
  186. .device-info-cell {
  187. cursor: pointer;
  188. color: #409eff;
  189. &:hover {
  190. text-decoration: underline;
  191. }
  192. }
  193. .header-icon {
  194. margin-left: 5px;
  195. color: #999;
  196. font-size: 14px;
  197. cursor: help;
  198. &:hover {
  199. color: #409eff;
  200. }
  201. }
  202. </style>