feat: 信令分析
This commit is contained in:
@@ -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',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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')"
|
||||
|
||||
Reference in New Issue
Block a user