feat: 信令分析

This commit is contained in:
TsMask
2023-09-25 15:04:45 +08:00
parent 3525d7567e
commit 21a4ad986d
3 changed files with 101 additions and 57 deletions

View File

@@ -54,21 +54,15 @@ export async function listTraceData(query: Record<string, any>) {
return result;
}
// 网元抓包pcap文件下载
export function tcpdumpPcapDownload(data: Record<string, string>) {
/**
* 信令数据解析HTML
* @param id 任务ID
* @returns
*/
export function getTraceRawInfo(id: Record<string, string>) {
return request({
url: '/traceManagement/v1/tcpdumpPcapDownload',
method: 'post',
data: data,
responseType: 'blob',
});
}
// 网元抓包生成pcap
export function tcpdumpNeUPFTask(data: Record<string, string>) {
return request({
url: '/traceManagement/v1/tcpdumpNeUPFTask',
method: 'post',
data: data,
url: `/traceManagement/v1/decMessage/${id}`,
method: 'get',
responseType: 'text',
});
}

View File

@@ -11,7 +11,7 @@ import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { downloadNeBackup } from '@/api/configManage/backupManage';
import { saveAs } from 'file-saver';
import useI18n from '@/hooks/useI18n';
import { listTraceData } from '@/api/trace/analysis';
import { getTraceRawInfo, listTraceData } from '@/api/trace/analysis';
const { t } = useI18n();
const route = useRoute();
@@ -151,34 +151,6 @@ function fnTableSize({ key }: MenuInfo) {
tableState.size = key as SizeType;
}
/**信息文件下载 */
function fnDownloadFile(row: Record<string, any>) {
Modal.confirm({
title: '提示',
content: `确认下载记录编号为 【${row.id}】 的数据项文件?`,
onOk() {
const key = 'downloadNeBackup';
message.loading({ content: t('common.loading'), key });
downloadNeBackup(toRaw(row)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: `已完成下载`,
key,
duration: 2,
});
saveAs(res.data, `user_${Date.now()}.xlsx`);
} else {
message.error({
content: `${res.msg}`,
key,
duration: 2,
});
}
});
},
});
}
/**查询备份信息列表 */
function fnGetList() {
if (tableState.loading) return;
@@ -209,6 +181,7 @@ let modalState: ModalStateType = reactive({
title: '信令信息',
from: {
rawData: '',
rawDataHTML: '',
},
});
@@ -221,7 +194,28 @@ function fnModalVisible(row: Record<string, any>) {
const hexString = parseBase64Data(row.rawMsg);
const rawData = convertToReadableFormat(hexString);
modalState.from.rawData = rawData;
modalState.title = `任务 ${row.taskId} 信令信息`;
// RAW解析HTML
getTraceRawInfo(row.id).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
const htmlString = res.msg;
// 删除所有 <a> 标签
const withoutATags = htmlString.replace(/<a\b[^>]*>(.*?)<\/a>/gi, '');
// 删除所有 <script> 标签
const withoutScriptTags = withoutATags.replace(
/<script\b[^>]*>([\s\S]*?)<\/script>/gi,
''
);
// 默认全展开
const withoutHiddenElements = withoutScriptTags.replace(
/style="display:none"/gi,
'style="background:#ffffff"'
);
modalState.from.rawDataHTML = withoutHiddenElements;
} else {
modalState.from.rawDataHTML = '无信息';
}
});
modalState.title = `任务 ${row.imsi}`;
modalState.visible = true;
}
@@ -255,7 +249,7 @@ function convertToReadableFormat(hexString: string) {
let result = '';
let asciiResult = '';
let arr = [];
let row = 0;
let row = 100;
for (let i = 0; i < hexString.length; i += 2) {
const hexChars = hexString.substring(i, i + 2);
const decimal = parseInt(hexChars, 16);
@@ -289,6 +283,20 @@ function convertToReadableFormat(hexString: string) {
return arr;
}
/**信息文件下载 */
function fnDownloadFile() {
Modal.confirm({
title: '提示',
content: `确认下载信令详情HTML文件?`,
onOk() {
const blob = new Blob([modalState.from.rawDataHTML], {
type: 'text/plain',
});
saveAs(blob, `${modalState.title}_${Date.now()}.html`);
},
});
}
onMounted(() => {
// 获取列表数据
fnGetList();
@@ -409,18 +417,38 @@ onMounted(() => {
<!-- 新增框或修改框 -->
<a-modal
width="1200px"
width="800px"
:title="modalState.title"
:visible="modalState.visible"
@cancel="fnModalVisibleClose"
>
<h4>信令数据</h4>
<div v-for="v in modalState.from.rawData" :key="v.row">
<div>{{ v.code }}</div>
<div>{{ v.asciiText }}</div>
</div>
<div class="raw-title">信令数据</div>
<a-row
class="raw"
:gutter="16"
v-for="v in modalState.from.rawData"
:key="v.row"
>
<a-col class="num" :span="2">{{ v.row }}</a-col>
<a-col class="code" :span="12">{{ v.code }}</a-col>
<a-col class="txt" :span="10">{{ v.asciiText }}</a-col>
</a-row>
<a-divider />
<h4>信令信息</h4>
<div class="raw-title">
信令详情
<a-button
type="dashed"
size="small"
@click.prevent="fnDownloadFile"
v-if="modalState.from.rawDataHTML !== '无信息'"
>
<template #icon>
<DownloadOutlined />
</template>
下载HTML
</a-button>
</div>
<div class="raw-html" v-html="modalState.from.rawDataHTML"></div>
</a-modal>
</PageContainer>
</template>
@@ -429,4 +457,26 @@ onMounted(() => {
.table :deep(.ant-pagination) {
padding: 0 24px;
}
.raw {
&-title {
color: #000000d9;
font-size: 24px;
line-height: 1.8;
}
.num {
background-color: #e5e5e5;
}
.code {
background-color: #e7e6ff;
}
.txt {
background-color: #ffe3e5;
}
&-html {
max-height: 300px;
overflow-y: scroll;
}
}
</style>

View File

@@ -307,11 +307,11 @@ onMounted(() => {
v-model:value="modalState.from.upfStart"
allow-clear
placeholder="upf pacp 命令"
style="width: 80%"
style="width: 75%"
/>
<a-button
type="primary"
style="width: 20%"
style="width: 25%"
:disabled="modalState.confirmLoading"
:loading="modalState.confirmLoading"
@click.prevent="fnUPF('start')"
@@ -330,11 +330,11 @@ onMounted(() => {
v-model:value="modalState.from.upfStop"
allow-clear
placeholder="upf pacp 命令"
style="width: 80%"
style="width: 75%"
/>
<a-button
type="primary"
style="width: 20%"
style="width: 25%"
:disabled="modalState.confirmLoading"
:loading="modalState.confirmLoading"
@click.prevent="fnUPF('stop')"