diff --git a/package.json b/package.json index 7d8eed07..71bbe0a8 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "dayjs": "^1.11.11", "echarts": "~5.5.0", "file-saver": "^2.0.5", + "grid-layout-plus": "^1.0.5", "intl-tel-input": "^23.8.1", "js-base64": "^3.7.7", "js-cookie": "^3.0.5", @@ -41,7 +42,6 @@ "vue-i18n": "^9.13.1", "vue-router": "^4.4.0", "vue3-smooth-dnd": "^0.0.6", - "vuedraggable": "^4.1.0", "xlsx": "~0.18.5" }, "devDependencies": { diff --git a/src/api/tool/iperf.ts b/src/api/tool/iperf.ts new file mode 100644 index 00000000..5b5e146c --- /dev/null +++ b/src/api/tool/iperf.ts @@ -0,0 +1,20 @@ +import { request } from '@/plugins/http-fetch'; + +// iperf 版本信息 +export function iperfV(data: Record) { + return request({ + url: '/tool/iperf/v', + method: 'get', + params: data, + }); +} + +// iperf 软件安装 +export function iperfI(data: Record) { + return request({ + url: '/tool/iperf/i', + method: 'post', + data: data, + timeout: 60_000, + }); +} diff --git a/src/api/tool/neFile.ts b/src/api/tool/neFile.ts index 34cf0624..236a33c2 100644 --- a/src/api/tool/neFile.ts +++ b/src/api/tool/neFile.ts @@ -1,7 +1,7 @@ import { request } from '@/plugins/http-fetch'; /** - * 查询文件列表列表 + * 查询网元端文件列表 * @param query 查询参数 * @returns object */ @@ -14,7 +14,7 @@ export function listNeFiles(query: Record) { } /** - * 从网元端获取文件 + * 从网元到本地获取文件 * @param query 查询参数 * @returns object */ @@ -27,3 +27,24 @@ export function getNeFile(query: Record) { timeout: 180_000, }); } + +// 从网元到本地获取目录压缩为ZIP +export function getNeDirZip(data: Record) { + return request({ + url: '/ne/action/pullDirZip', + method: 'get', + params: data, + responseType: 'blob', + timeout: 60_000, + }); +} + +// 查看网元端文件内容 +export function getNeViewFile(data: Record) { + return request({ + url: '/ne/action/viewFile', + method: 'get', + params: data, + timeout: 60_000, + }); +} diff --git a/src/api/tool/ping.ts b/src/api/tool/ping.ts new file mode 100644 index 00000000..b897604e --- /dev/null +++ b/src/api/tool/ping.ts @@ -0,0 +1,10 @@ +import { request } from '@/plugins/http-fetch'; + +// ping 网元端版本信息 +export function pingV(data: Record) { + return request({ + url: '/tool/ping/v', + method: 'get', + params: data, + }); +} diff --git a/src/api/trace/pcap.ts b/src/api/trace/pcap.ts index b65e6d91..da3a4cd7 100644 --- a/src/api/trace/pcap.ts +++ b/src/api/trace/pcap.ts @@ -20,17 +20,6 @@ export function dumpStop(data: Record) { }); } -// 网元抓包PACP 下载 -export function dumpDownload(data: Record) { - return request({ - url: '/trace/tcpdump/download', - method: 'get', - params: data, - responseType: 'blob', - timeout: 60_000, - }); -} - // UPF标准版内部抓包 export function traceUPF(data: Record) { return request({ diff --git a/src/components/TerminalSSHView/index.vue b/src/components/TerminalSSHView/index.vue index 33af459b..c5e7d73f 100644 --- a/src/components/TerminalSSHView/index.vue +++ b/src/components/TerminalSSHView/index.vue @@ -13,6 +13,11 @@ const props = defineProps({ type: String, required: true, }, + /**ws连接地址,必传 如/ws/view */ + url: { + type: String, + required: true, + }, /**网元类型,必传 */ neType: { type: String, @@ -33,6 +38,11 @@ const props = defineProps({ type: Number, default: 40, }, + /**ws发送requestId前缀 如ssh_id */ + prefix: { + type: String, + default: 'ssh', + }, }); /**终端输入DOM节点实例对象 */ @@ -148,13 +158,18 @@ function wsMessage(res: Record) { if (parts.length > 0) { let text = parts[parts.length - 1]; // 找到最后输出标记 - const lestIndex = text.lastIndexOf('\u001b[?2004h\u001b]0;'); + let lestIndex = text.lastIndexOf('\u001b[?2004h\u001b]0;'); if (lestIndex !== -1) { text = text.substring(0, lestIndex); } - if (text === '' || text === '\r\n' || text.startsWith("^C\r\n") ) { + if (text === '' || text === '\r\n' || text.startsWith('^C\r\n')) { return; } + // 是否还有最后输出标记 + lestIndex = text.lastIndexOf('\u001b[?2004h'); + if (lestIndex !== -1) { + text = text.substring(0, lestIndex); + } // console.log({ parts, text }); terminal.value.write(text); return; @@ -168,7 +183,7 @@ onMounted(() => { if (props.neType && props.neId) { // 建立链接 const options: OptionsType = { - url: '/ws/view', + url: props.url, params: { neType: props.neType, neId: props.neId, @@ -185,7 +200,7 @@ onMounted(() => { }); onBeforeUnmount(() => { - ws.close(); + if (ws.state() === WebSocket.OPEN) ws.close(); }); // 给组件设置属性 ref="xxxTerminal" @@ -200,7 +215,7 @@ defineExpose({ /**发送命令 */ send: (type: string, data: Record) => { ws.send({ - requestId: `ssh_${props.id}`, + requestId: `${props.prefix}_${props.id}`, type, data, }); @@ -208,7 +223,7 @@ defineExpose({ /**模拟按下 Ctrl+C */ ctrlC: () => { ws.send({ - requestId: `ssh_${props.id}`, + requestId: `${props.prefix}_${props.id}`, type: 'ctrl-c', }); }, diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index c4ed59a6..aad058da 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -685,11 +685,12 @@ export default { addrPlease: "Please fill in the host IP address correctly", port: "Port", portPlease: "Please fill in the host port number correctly", - user: "Login User", - userPlease: "Please fill in the host login user correctly", + user: "User", + userPlease: "Please fill in the host user correctly", + database: "DataBase", authMode: "Auth Mode", password: "Password", - passwordPlease: "Please fill in the host login password correctly", + passwordPlease: "Please fill in the host password correctly", privateKey: "Private Key", privateKeyPlease: "Please fill in the private key characters correctly ~/.ssh/id_rsa", passPhrase: "Private Key Cipher", @@ -1110,8 +1111,8 @@ export default { fileUPFTip: 'UPF internal packet capture and analysis packet', textStart: "Start", textStop: "Stop", - textLog: "Log", - textLogMsg: "Log Info", + textLog: "LogFile", + textLogMsg: "LogFile Info", textDown: "Download", downTip: "Are you sure you want to download the {title} capture data file?", downOk: "{title} file download complete", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 77cd7b64..3f878c47 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -686,10 +686,11 @@ export default { port: "端口", portPlease: "请正确填写主机端口号", user: "用户名", - userPlease: "请正确填写主机登录用户", + userPlease: "请正确填写主机用户", + database: "数据库", authMode: "认证模式", password: "密码", - passwordPlease: "请正确填写主机登录密码", + passwordPlease: "请正确填写主机密码", privateKey: "私钥", privateKeyPlease: "请正确填写私钥字符内容 ~/.ssh/id_rsa", passPhrase: "私钥密码", @@ -1110,8 +1111,8 @@ export default { fileUPFTip: 'UPF内部抓包分析包', textStart: "开始", textStop: "停止", - textLog: "日志", - textLogMsg: "日志信息", + textLog: "日志文件", + textLogMsg: "日志文件信息", textDown: "下载", downTip: "确认要下载 {title} 抓包数据文件吗?", downOk: "{title} 文件下载完成", diff --git a/src/plugins/http-fetch.ts b/src/plugins/http-fetch.ts index e1205c68..df9da37b 100644 --- a/src/plugins/http-fetch.ts +++ b/src/plugins/http-fetch.ts @@ -187,7 +187,6 @@ function beforeRequest(options: OptionsType): OptionsType | Promise { const separator = options.url.includes('?') ? '&' : '?'; // 请求加密 if (options.crypto) { - debugger; const data = encryptAES(JSON.stringify(paramStr), APP_DATA_API_KEY); options.url += `${separator}data=${encodeURIComponent(data)}`; } else { diff --git a/src/utils/parse-utils.ts b/src/utils/parse-utils.ts index 568e8b18..e091aa8e 100644 --- a/src/utils/parse-utils.ts +++ b/src/utils/parse-utils.ts @@ -173,13 +173,13 @@ export function parseSizeFromKbs(sizeByte: number, timeInterval: number): any { /** * 字节数转换单位 * @param bits 字节Bit大小 64009540 = 512.08 MB - * @returns xx B/ KB / MB / GB / TB + * @returns xx B / KB / MB / GB / TB / PB / EB / ZB / YB */ export function parseSizeFromBits(bits: number | string): string { bits = Number(bits) || 0; if (bits <= 0) return '0 B'; bits = bits * 8; - const units = ['B', 'KB', 'MB', 'GB', 'TB']; + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const unitIndex = Math.floor(Math.log2(bits) / 10); const value = (bits / Math.pow(1000, unitIndex)).toFixed(2); const unti = units[unitIndex]; diff --git a/src/views/configManage/softwareManage/index.vue b/src/views/configManage/softwareManage/index.vue index 0ec309e4..d9867444 100644 --- a/src/views/configManage/softwareManage/index.vue +++ b/src/views/configManage/softwareManage/index.vue @@ -425,8 +425,6 @@ function fnGetList(pageNum?: number) { (queryParams.pageNum - 1) * tablePagination.pageSize && queryParams.pageNum !== 1 ) { - debugger; - tableState.loading = false; fnGetList(queryParams.pageNum - 1); } diff --git a/src/views/dashboard/overview/hooks/useWS.ts b/src/views/dashboard/overview/hooks/useWS.ts index 9afb6959..33936ada 100644 --- a/src/views/dashboard/overview/hooks/useWS.ts +++ b/src/views/dashboard/overview/hooks/useWS.ts @@ -44,7 +44,7 @@ export default function useWS() { // 普通信息 switch (requestId) { // AMF_UE会话事件 - case 'amf_1010_001': + case 'amf_1010': if (Array.isArray(data.rows)) { eventListParse('amf_ue', data); } @@ -85,7 +85,7 @@ export default function useWS() { } break; // AMF_UE会话事件 - case '1010_001': + case '1010': if (data.data) { queue.add(() => eventItemParseAndPush('amf_ue', data.data)); } @@ -128,7 +128,7 @@ export default function useWS() { function userActivitySend() { // AMF_UE会话事件 ws.send({ - requestId: 'amf_1010_001', + requestId: 'amf_1010', type: 'amf_ue', data: { neType: 'AMF', @@ -175,11 +175,11 @@ export default function useWS() { /**订阅通道组 * * 指标UPF (GroupID:12_neId) - * AMF_UE会话事件(GroupID:1010_neId) + * AMF_UE会话事件(GroupID:1010) * MME_UE会话事件(GroupID:1011_neId) * IMS_CDR会话事件(GroupID:1005_neId) */ - subGroupID: '12_001,1010_001,1011_001,1005_001', + subGroupID: '12_001,1010,1011_001,1005_001', }, onmessage: wsMessage, onerror: (ev: any) => { diff --git a/src/views/logManage/neFile/components/ViewDrawer.vue b/src/views/logManage/neFile/components/ViewDrawer.vue index 1c096b89..f2718379 100644 --- a/src/views/logManage/neFile/components/ViewDrawer.vue +++ b/src/views/logManage/neFile/components/ViewDrawer.vue @@ -1,5 +1,5 @@ @@ -122,9 +123,11 @@ function fnReload() { diff --git a/src/views/logManage/neFile/index.vue b/src/views/logManage/neFile/index.vue index 8c9aa4b5..6158223b 100644 --- a/src/views/logManage/neFile/index.vue +++ b/src/views/logManage/neFile/index.vue @@ -204,11 +204,13 @@ function fnDirCD(dir: string, index?: number) { /**网元类型选择对应修改 */ function fnNeChange(keys: any, _: any) { + if (!Array.isArray(keys)) return; + const neType = keys[0]; + const neId = keys[1]; // 不是同类型时需要重新加载 - if (Array.isArray(keys) && queryParams.neType !== keys[0]) { - const neType = keys[0]; + if (queryParams.neType !== neType || queryParams.neId !== neId) { queryParams.neType = neType; - queryParams.neId = keys[1]; + queryParams.neId = neId; if (neType === 'IMS') { nePathArr.value = ['/var/log/ims']; queryParams.search = ''; diff --git a/src/views/ne/neInfo/components/EditModal.vue b/src/views/ne/neInfo/components/EditModal.vue index d7f55748..b28b5142 100644 --- a/src/views/ne/neInfo/components/EditModal.vue +++ b/src/views/ne/neInfo/components/EditModal.vue @@ -40,7 +40,7 @@ let dict: { * 测试主机连接 */ function fnHostTest(row: Record) { - if (modalState.confirmLoading || !row.addr) return; + if (modalState.confirmLoading || !row.addr || !row.port) return; modalState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); testNeHost(row) @@ -124,8 +124,8 @@ let modalState: ModalStateType = reactive({ addr: '', port: 22, user: 'omcuser', - authMode: '0', - password: 'a9tU53r', + authMode: '2', + password: '', privateKey: '', passPhrase: '', remark: '', @@ -283,11 +283,11 @@ function fnModalCancel() { /**表单修改网元类型 */ function fnNeTypeChange(v: any) { - const hostsLen = modalState.from.hosts.length; // 网元默认只含22和4100 - if (hostsLen === 3 && v !== 'UPF') { + if (modalState.from.hosts.length === 3) { modalState.from.hosts.pop(); } + const hostsLen = modalState.from.hosts.length; // UPF标准版本可支持5002 if (hostsLen === 2 && v === 'UPF') { modalState.from.hosts.push({ @@ -295,11 +295,27 @@ function fnNeTypeChange(v: any) { hostType: 'telnet', groupId: '1', title: 'Telnet_NE_5002', - addr: '', + addr: modalState.from.ip, port: 5002, - user: 'user', + user: 'admin', authMode: '0', - password: 'user', + password: 'admin', + remark: '', + }); + } + // UDM可支持6379 + if (hostsLen === 2 && v === 'UDM') { + modalState.from.hosts.push({ + hostId: undefined, + hostType: 'redis', + groupId: '1', + title: 'REDIS_NE_6379', + addr: modalState.from.ip, + port: 6379, + user: 'udmdb', + authMode: '0', + password: 'helloearth', + dbName: '0', remark: '', }); } @@ -626,8 +642,13 @@ onMounted(() => { (s:any) => !(s.hostType === 'telnet' && modalState.from.neType === 'OMC') )" :key="host.title" - :header="`${host.hostType.toUpperCase()} ${host.port}`" > + @@ -654,7 +675,22 @@ onMounted(() => { - + + + + + + { v-model:value="host.authMode" default-value="0" :options="dict.neHostAuthMode" - :disabled="host.hostType === 'telnet'" > @@ -692,7 +727,6 @@ onMounted(() => { > - + + + + + { /> + { if (res.code === RESULT_CODE_SUCCESS) { message.success(t('common.msgSuccess', { msg: t('common.export') }), 3); @@ -555,6 +555,9 @@ function fnLoadData() { fnQueryReset(); }, timerS * 1000); } else { + modalState.loadDataLoading = false; + tableState.loading = false; // 表格loading + fnQueryReset(); message.error({ content: t('common.getInfoFail'), duration: 3, diff --git a/src/views/neUser/sub/index.vue b/src/views/neUser/sub/index.vue index afed05ef..43c4d54a 100644 --- a/src/views/neUser/sub/index.vue +++ b/src/views/neUser/sub/index.vue @@ -878,7 +878,7 @@ function fnExportList(type: string) { if (!neId) return; const key = 'exportSub'; message.loading({ content: t('common.loading'), key }); - exportUDMSub({ ...queryParams, ...{ type } }).then(res => { + exportUDMSub(Object.assign({ type: type }, queryParams)).then(res => { if (res.code === RESULT_CODE_SUCCESS) { message.success({ content: t('common.msgSuccess', { msg: t('common.export') }), @@ -920,6 +920,9 @@ function fnLoadData() { fnQueryReset(); }, timerS * 1000); } else { + modalState.loadDataLoading = false; + tableState.loading = false; // 表格loading + fnQueryReset(); message.error({ content: t('common.getInfoFail'), duration: 3, diff --git a/src/views/perfManage/kpiKeyTarget/index.vue b/src/views/perfManage/kpiKeyTarget/index.vue index 1775bf62..57616248 100644 --- a/src/views/perfManage/kpiKeyTarget/index.vue +++ b/src/views/perfManage/kpiKeyTarget/index.vue @@ -1,44 +1,175 @@ diff --git a/src/views/system/log/login/index.vue b/src/views/system/log/login/index.vue index aaf15eee..b64e33f7 100644 --- a/src/views/system/log/login/index.vue +++ b/src/views/system/log/login/index.vue @@ -193,7 +193,6 @@ function fnTableSelectedRows( _: (string | number)[], rows: Record[] ) { - //debugger tableState.selectedRowKeys = rows.map(item => item.loginId); // 针对单个登录账号解锁 if (rows.length === 1) { diff --git a/src/views/system/quick-start/components/NeInfoConfig.vue b/src/views/system/quick-start/components/NeInfoConfig.vue index 3a169df5..3e7c9453 100644 --- a/src/views/system/quick-start/components/NeInfoConfig.vue +++ b/src/views/system/quick-start/components/NeInfoConfig.vue @@ -139,7 +139,7 @@ let tableColumns: any = [ * 测试主机连接 */ function fnHostTest(row: Record) { - if (tabState.confirmLoading || !row.addr) return; + if (tabState.confirmLoading || !row.addr || !row.port) return; tabState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); testNeHost(row) @@ -187,19 +187,19 @@ function fnHostAuthorized(row: Record) { * 表单修改网元类型 */ function fnNeTypeChange(v: any, data: any) { - const hostsLen = data.hosts.length; // 网元默认只含22和4100 - if (hostsLen === 3 && v !== 'UPF') { - data.hosts.pop(); + if (modalState.from.hosts.length === 3) { + modalState.from.hosts.pop(); } + const hostsLen = modalState.from.hosts.length; // UPF标准版本可支持5002 if (hostsLen === 2 && v === 'UPF') { - data.hosts.push({ + modalState.from.hosts.push({ hostId: undefined, hostType: 'telnet', groupId: '1', title: 'Telnet_NE_5002', - addr: '', + addr: modalState.from.ip, port: 5002, user: 'admin', authMode: '0', @@ -207,6 +207,22 @@ function fnNeTypeChange(v: any, data: any) { remark: '', }); } + // UDM可支持6379 + if (hostsLen === 2 && v === 'UDM') { + modalState.from.hosts.push({ + hostId: undefined, + hostType: 'redis', + groupId: '1', + title: 'REDIS_NE_6379', + addr: modalState.from.ip, + port: 6379, + user: 'udmdb', + authMode: '0', + password: 'helloearth', + dbName: '0', + remark: '', + }); + } } //打开新增或修改界面 diff --git a/src/views/system/setting/components/change-home-index.vue b/src/views/system/setting/components/change-home-index.vue index a260c947..e96f039b 100644 --- a/src/views/system/setting/components/change-home-index.vue +++ b/src/views/system/setting/components/change-home-index.vue @@ -1,14 +1,11 @@ diff --git a/src/views/tool/ping/index.vue b/src/views/tool/ping/index.vue index a4987aa7..182601a7 100644 --- a/src/views/tool/ping/index.vue +++ b/src/views/tool/ping/index.vue @@ -1,17 +1,17 @@ diff --git a/src/views/traceManage/pcap/file.vue b/src/views/traceManage/pcap/file.vue index 02e25a82..260ad502 100644 --- a/src/views/traceManage/pcap/file.vue +++ b/src/views/traceManage/pcap/file.vue @@ -7,6 +7,7 @@ import { Modal, message } from 'ant-design-vue/lib'; import { parseDateToStr } from '@/utils/date-utils'; import { getNeFile, listNeFiles } from '@/api/tool/neFile'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; +import ViewDrawer from '@/views/logManage/neFile/components/ViewDrawer.vue'; import useNeInfoStore from '@/store/modules/neinfo'; import useTabsStore from '@/store/modules/tabs'; import useI18n from '@/hooks/useI18n'; @@ -218,16 +219,18 @@ function fnDirCD(dir: string, index?: number) { /**网元类型选择对应修改 */ function fnNeChange(keys: any, _: any) { + if (!Array.isArray(keys)) return; + const neType = keys[0]; + const neId = keys[1]; // 不是同类型时需要重新加载 - if (Array.isArray(keys) && queryParams.neType !== keys[0]) { - const neType = keys[0]; + if (queryParams.neType !== neType || queryParams.neId !== neId) { queryParams.neType = neType; - queryParams.neId = keys[1]; + queryParams.neId = neId; if (neType === 'UPF' && tmp.value) { nePathArr.value = ['/tmp']; - queryParams.search = `${neType}_${keys[1]}`; + queryParams.search = `${neType}_${neId}`; } else { - nePathArr.value = [`/tmp/omc/tcpdump/${neType.toLowerCase()}/${keys[1]}`]; + nePathArr.value = [`/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}`]; queryParams.search = ''; } fnGetList(1); @@ -270,6 +273,25 @@ function fnGetList(pageNum?: number) { }); } +/**抽屉状态 */ +const viewDrawerState = reactive({ + visible: false, + /**文件路径 /var/log/amf.log */ + filePath: '', + /**网元类型 */ + neType: '', + /**网元ID */ + neId: '', +}); + +/**打开抽屉查看 */ +function fnDrawerOpen(row: Record) { + viewDrawerState.filePath = [...nePathArr.value, row.fileName].join('/'); + viewDrawerState.neType = neTypeSelect.value[0]; + viewDrawerState.neId = neTypeSelect.value[1]; + viewDrawerState.visible = !viewDrawerState.visible; +} + onMounted(() => { // 获取网元网元列表 neInfoStore.fnNelist().then(res => { @@ -375,6 +397,16 @@ onMounted(() => { diff --git a/src/views/traceManage/pcap/index.vue b/src/views/traceManage/pcap/index.vue index e0bca8bf..8ca2fb90 100644 --- a/src/views/traceManage/pcap/index.vue +++ b/src/views/traceManage/pcap/index.vue @@ -4,9 +4,9 @@ import { useRoute, useRouter } from 'vue-router'; import { message, Modal } from 'ant-design-vue/lib'; import { ColumnsType } from 'ant-design-vue/lib/table'; import { PageContainer } from 'antdv-pro-layout'; -import { dumpStart, dumpStop, dumpDownload, traceUPF } from '@/api/trace/pcap'; +import { dumpStart, dumpStop, traceUPF } from '@/api/trace/pcap'; import { listAllNeInfo } from '@/api/ne/neInfo'; -import { getNeFile } from '@/api/tool/neFile'; +import { getNeDirZip, getNeFile, getNeViewFile } from '@/api/tool/neFile'; import saveAs from 'file-saver'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import useI18n from '@/hooks/useI18n'; @@ -31,7 +31,7 @@ type ModalStateType = { /**任务编号 */ taskCode: string; /**任务日志,upf标准版为空字符串 */ - logMsg: string; + taskFiles: string[]; /**提交表单参数 */ data: { neType: string; @@ -65,7 +65,14 @@ type ModalStateType = { /**详情框是否显示 */ visibleByView: boolean; /**详情框内容 */ - logMsg: string; + viewFrom: { + neType: string; + neId: string; + path: string; + action: string; + files: string[]; + content: string; + }; }; /**对话框对象信息状态 */ @@ -106,7 +113,14 @@ let modalState: ModalStateType = reactive({ }, ], visibleByView: false, - logMsg: '', + viewFrom: { + neType: '', + neId: '', + path: '', + action: '', + files: [], + content: '', + }, }); /**表格状态类型 */ @@ -194,7 +208,7 @@ function fnGetList() { cmdStart: start, cmdStop: stop, taskCode: '', - logMsg: '', + taskFiles: [], data: { neType: item.neType, neId: item.neId, @@ -218,7 +232,7 @@ function fnSelectCmd(id: any, option: any) { modalState.from[id].cmdStop = option.stop; // 重置任务 modalState.from[id].taskCode = ''; - modalState.from[id].logMsg = ''; + modalState.from[id].taskFiles = []; } /** @@ -341,7 +355,7 @@ function fnRecordStop(row?: Record) { if (res.status === 'fulfilled') { const resV = res.value; fromArr[idx].loading = false; - fromArr[idx].logMsg = ''; + fromArr[idx].taskFiles = []; if (fromArr[idx].cmdStop) { fromArr[idx].taskCode = ''; } @@ -350,7 +364,7 @@ function fnRecordStop(row?: Record) { if (fromArr[idx].cmdStop) { fromArr[idx].taskCode = resV.data; } else { - fromArr[idx].logMsg = resV.msg; + fromArr[idx].taskFiles = resV.data; } message.success({ content: t('views.traceManage.pcap.stopOk', { title }), @@ -422,10 +436,15 @@ function fnDownPCAP(row?: Record) { ) ); } else { + const { neType, neId } = from.data; + const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${taskCode}`; reqArr.push( - dumpDownload( - Object.assign({ taskCode: taskCode, delTemp: true }, from.data) - ) + getNeDirZip({ + neType, + neId, + path, + delTemp: true, + }) ); } } @@ -497,8 +516,42 @@ function fnBatchOper(key: string) { function fnModalVisibleByVive(id: string | number) { const from = modalState.from[id]; if (!from) return; + const { neType, neId } = from.data; + const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${ + from.taskCode + }`; + const files = from.taskFiles.filter(f => f.endsWith('log')); + modalState.viewFrom.neType = neType; + modalState.viewFrom.neId = neId; + modalState.viewFrom.path = path; + modalState.viewFrom.files = [...files]; + fnViveTab(files[0]); modalState.visibleByView = true; - modalState.logMsg = from.logMsg; +} + +/**对话框tab查看 */ +function fnViveTab(action: any) { + console.log('fnViveTab', action); + if (modalState.viewFrom.action === action) return; + modalState.viewFrom.action = action; + modalState.viewFrom.content = ''; + const { neType, neId, path } = modalState.viewFrom; + getNeViewFile({ + neId, + neType, + path, + fileName: action, + }).then(res => { + if (res.code === RESULT_CODE_SUCCESS) { + modalState.viewFrom.content = res.data; + } else { + modalState.viewFrom.content = ''; + message.warning({ + content: `${res.msg}`, + duration: 3, + }); + } + }); } /** @@ -507,7 +560,8 @@ function fnModalVisibleByVive(id: string | number) { */ function fnModalCancel() { modalState.visibleByView = false; - modalState.logMsg = ''; + modalState.viewFrom.action = ''; + modalState.viewFrom.files = []; } /**跳转文件数据页面 */ @@ -651,7 +705,7 @@ onMounted(() => { placement="topRight" v-if=" !modalState.from[record.id].loading && - !!modalState.from[record.id].logMsg + modalState.from[record.id].taskFiles.length > 0 " > diff --git a/src/views/traceManage/wireshark/index.vue b/src/views/traceManage/wireshark/index.vue index cada1bef..4bd0e6fb 100644 --- a/src/views/traceManage/wireshark/index.vue +++ b/src/views/traceManage/wireshark/index.vue @@ -18,6 +18,7 @@ import { packetStart, packetStop, packetFilter, + packetKeep, } from '@/api/trace/packet'; const ws = new WS(); const { t } = useI18n(); @@ -29,6 +30,8 @@ type StateType = { devices: { id: string; label: string; children: any[] }[]; /**初始化 */ initialized: boolean; + /**保活调度器 */ + keepTimer: any; /**任务 */ task: { taskNo: string; @@ -64,6 +67,7 @@ type StateType = { const state = reactive({ devices: [], initialized: false, + keepTimer: null, task: { taskNo: 'laYlTbq', device: '192.168.5.58', @@ -274,6 +278,9 @@ function wsMessage(res: Record) { // 建联时发送请求 if (!requestId && data.clientId) { state.initialized = true; + state.keepTimer = setInterval(() => { + packetKeep(state.task.taskNo, 120); + }, 90 * 1000); return; } @@ -320,7 +327,9 @@ onMounted(() => { }); onBeforeUnmount(() => { - ws.close(); + clearInterval(state.keepTimer); + state.keepTimer = null; + if (ws.state() === WebSocket.OPEN) ws.close(); });