feat: 故障管理-业务终端状态

master
李小林 6 months ago
parent a74f864c61
commit 568c8e8b30
  1. 13
      src/api/fault/index.ts
  2. 3
      src/layout/components/NavBar/components/NavbarRight.vue
  3. 7
      src/views/family/operate/fault-management/components/Diagnosis.vue
  4. 876
      src/views/family/operate/fault-management/components/ServiceEndpointStatus.vue
  5. 7
      src/views/family/operate/fault-management/index.vue

@ -31,3 +31,16 @@ export function basicInfoDiagnosis(
},
});
}
export function faultServiceStatus(
devId?: number,
remote?: string
): AxiosPromise<any> {
return request({
url: "/api/fault/v1/basic_info/service_status",
method: "GET",
params: {
devId,
remote,
},
});
}

@ -88,9 +88,6 @@ function logout() {
const skipPersonal = () => {
router.push(`/resources/personal-center`);
};
onMounted(()=>{
console.log(avatarUrl.value);
})
</script>
<style lang="scss" scoped>
.setting-item {

@ -47,7 +47,12 @@
class-name="my-content"
width="150px"
>
<div class="my-content">修复建议 : {{ result.errorDesc }}</div>
<div class="my-content">
修复建议 :
<span style="color: red; font-size: 10px">{{
result.errorDesc
}}</span>
</div>
</el-descriptions-item>
</el-descriptions>
</div>

@ -0,0 +1,876 @@
<template>
<div class="app-container">
<el-tabs type="border-card" class="demo-tabs" v-loading="loading">
<el-tab-pane>
<template #label>
<div style="display: flex; align-items: center">
<el-icon size="15"> <Grid /> </el-icon>&nbsp;<span
style="font-weight: 500; font-size: 14px; line-height: 16px"
>业务状态</span
>
</div>
</template>
<el-scrollbar height="380">
<el-descriptions direction="vertical" border :column="6">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('VoipInfoQueryGPON')"
>VOIP详细信息
</el-button>
</template>
<el-descriptions-item
label="PVC/VLAN配置"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ voip["PVC"] }}
</el-descriptions-item>
<el-descriptions-item
label=" 连接类型"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ connectTypeEnum(voip["ConnectType"]) }}
</el-descriptions-item>
<el-descriptions-item
label=" 连接状态"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>{{ connectStatusEnum(voip["ConnectStatus"]) }}
</el-descriptions-item>
<el-descriptions-item
label=" voip服务器"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ voip["VoipServer"] }}
</el-descriptions-item>
<el-descriptions-item
label="备用服务器"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ voip["StandbyServer"] }}
</el-descriptions-item>
<el-descriptions-item
label="注册状态"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ getEnrollmentStatus(voip["LineValue"]) }}
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="voip['state'] != '2' && voip['state'] != undefined"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ voip["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions direction="vertical" border :column="4">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('IptvQueryGPON')"
>IPTV详细信息
</el-button>
</template>
<el-descriptions-item
label="PVC/VLAN配置"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ iptv["PVC"] }}
</el-descriptions-item>
<el-descriptions-item
label=" 连接类型"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ connectTypeEnum(iptv["ConnectType"]) }}
</el-descriptions-item>
<el-descriptions-item
label=" 连接状态"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>{{ connectStatusEnum(iptv["ConnectStatus"]) }}
</el-descriptions-item>
<el-descriptions-item
label=" 绑定lan 口"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ bindingLan(iptv["BIND_LAN"]) }}
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="iptv['state'] != '2' && iptv['state'] != undefined"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ iptv["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions direction="vertical" border :column="11">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('WLanInfoQuery')"
>WLAN详细信息
</el-button>
</template>
<el-descriptions-item
label="SSID名称"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="240px"
>
<div v-if="wlan['SSID'] != undefined">
<div
:style="
index != wlan['SSID'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['SSID'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label=" 连接设备数"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['DeviceCount'] != undefined">
<div
:style="
index != wlan['DeviceCount'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['DeviceCount'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="功率级别"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['Signal'] != undefined">
<div
:style="
index != wlan['Signal'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['Signal'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="隐藏/广播"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['SSIDHide'] != undefined">
<div
:style="
index != wlan['SSIDHide'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['SSIDHide'].split(':')"
:key="index"
>
{{ SSSIdHide(item) }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="加密方式"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['WPAEncryptionModes'] != undefined">
<div
:style="
index != wlan['WPAEncryptionModes'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['WPAEncryptionModes'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label=" WPS关键字"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['KeyWord'] != undefined">
<div
:style="
index != wlan['KeyWord'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['KeyWord'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="信道"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['ChannelsInUse'] != undefined">
<div
:style="
index != wlan['ChannelsInUse'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['ChannelsInUse'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="当前功率(dBm)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="180px"
>
<div v-if="wlan['PowerValue'] != undefined">
<div
:style="
index != wlan['PowerValue'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['PowerValue'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="SSID连接"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['Status'] != undefined">
<div
:style="
index != wlan['Status'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['Status'].split(':')"
:key="index"
>
{{ SSSIdStatus(item) }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="802.11工作模式"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="180px"
>
<div v-if="wlan['Standard'] != undefined">
<div
:style="
index != wlan['Standard'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan['Standard'].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label="设备IP"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-if="wlan['AssociatedDeviceIPAddress'] != undefined">
<div
:style="
index !=
wlan['AssociatedDeviceIPAddress'].split(':').length - 1
? 'border-bottom: var(--el-descriptions-table-border)'
: ''
"
v-for="(item, index) in wlan[
'AssociatedDeviceIPAddress'
].split(':')"
:key="index"
>
{{ item }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="wlan['state'] != '2' && wlan['state'] != undefined"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ wlan["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane>
<template #label>
<div style="display: flex; align-items: center">
<el-icon size="15"> <Grid /> </el-icon>&nbsp;<span
style="font-weight: 500; font-size: 14px; line-height: 16px"
>终端状态</span
>
</div>
</template>
<el-scrollbar height="380">
<el-descriptions direction="vertical" border :column="5">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('LinkInfoQueryGPON')"
>设备链路详细信息
</el-button>
</template>
<el-descriptions-item
label="PON口的发射光功率(单位是:dBm)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ link["TXPower"] }}
</el-descriptions-item>
<el-descriptions-item
label="PON口的接收光功率(单位是:dBm)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ link["RXPower"] }}
</el-descriptions-item>
<el-descriptions-item
label="光模块的工作温度,单位是(C)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>{{ link["TransceiverTemperature"] }}
</el-descriptions-item>
<el-descriptions-item
label="光模块的供电电压(单位:V)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ link["SupplyVottage"] }}
</el-descriptions-item>
<el-descriptions-item
label="光发送机的偏置电流(单位:mA)"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ link["BiasCurrent"] }}
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="link['state'] != '2' && link['state'] != undefined"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ link["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions direction="vertical" border :column="9">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('DigitalhomeQueryGPON')"
>宽带上网详细信息
</el-button>
</template>
<el-descriptions-item
label="PVC/VLAN配置"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ broadband["PVC"] }}
</el-descriptions-item>
<el-descriptions-item
label="连接类型"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ connectTypeEnum(broadband["ConnectType"]) }}
</el-descriptions-item>
<el-descriptions-item
label="绑定端口"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="180px"
>{{ getLanPort(broadband["LanInterface"]) }}
</el-descriptions-item>
<el-descriptions-item
label="连接状态"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ connectStatusEnum(broadband["ConnectStatus"]) }}
</el-descriptions-item>
<el-descriptions-item
label="DNS"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="180px"
>
{{ broadband["DNSServer"] }}
</el-descriptions-item>
<el-descriptions-item
label="PPPOE帐号"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ broadband["Username"] }}
</el-descriptions-item>
<el-descriptions-item
label="密码"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ broadband["Password"] }}
</el-descriptions-item>
<el-descriptions-item
label="IP地址"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ broadband["Ipaddress"] }}
</el-descriptions-item>
<el-descriptions-item
label="拨号失败错误"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ broadband["Errors"] }}
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="
broadband['state'] != '2' && broadband['state'] != undefined
"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ broadband["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions direction="vertical" border :column="1">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('LanInfoQuery')"
>LAN侧详细信息
</el-button>
</template>
<el-descriptions-item
label-class-name="my-label-none"
class-name="my-content"
>
<div class="any-table">
<el-table :data="lanData">
<el-table-column label="名称" align="center" prop="name" />
<el-table-column label="状态" align="center" prop="status" />
</el-table>
</div>
</el-descriptions-item>
<el-descriptions-item
label-align="center"
align="left"
label-class-name="my-label-none"
class-name="my-content"
width="150px"
v-if="lan['state'] != '2' && lan['state'] != undefined"
>
<div style="color: red; padding: 0 8px; font-size: 10px">
错误信息{{ lan["result"] }}
</div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions direction="vertical" border :column="3">
<template #title>
<el-button
type="primary"
link
:icon="Grid"
:disabled="prop.devId === 0"
@click="getServiceDetailInfo('LanInfoQuery')"
>DHCP地址池信息
</el-button>
</template>
<el-descriptions-item
label="最小地址"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ lan["MinAddress"] }}
</el-descriptions-item>
<el-descriptions-item
label="最大地址"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ lan["MaxAddress"] }}
</el-descriptions-item>
<el-descriptions-item
label="保留地址"
label-align="center"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>{{ lan["ReservedAddresses"] }}
</el-descriptions-item>
</el-descriptions>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
import { Grid } from "@element-plus/icons-vue";
import { faultServiceStatus } from "@/api/fault";
import { Action } from "element-plus";
interface LanInfo {
name?: string;
status?: string;
}
const prop = defineProps<{
devId: number;
}>();
const loading = ref<boolean>(false);
const voip = ref<any>({});
const iptv = ref<any>({});
const wlan = ref<any>({});
const link = ref<any>({});
const broadband = ref<any>({});
const lan = ref<any>({});
// eslint-disable-next-line vue/return-in-computed-property
const lanData = computed(() => {
let tableData: LanInfo[] = [];
let lanConfig = lan.value["LanConfig"];
if (lanConfig) {
let lanArr: string[] = lanConfig.split("@");
lanArr.forEach((obj) => {
if (obj.length > 0) {
let arr = obj.split("#");
let lanInfo: LanInfo = {
name: arr[0],
status: arr[3],
};
tableData.push(lanInfo);
}
});
}
return tableData;
});
function getEnrollmentStatus(str?: string) {
if (str) {
const match = str.match(/#([^#]*)#/);
if (match) {
return match[1];
}
}
}
function connectStatusEnum(str?: string) {
switch (str) {
case "Connected":
return "已连接";
case "Connecting":
return "正在连接";
case "Disconnected":
return "未连接";
}
}
function connectTypeEnum(str?: string) {
switch (str) {
case "IP_Routed":
return "路由";
case "PPPoE_Bridged":
return "桥接";
default:
return str;
}
}
function getLanPort(str?: string) {
if (str) {
return str.length > 0 ? "LAN1 LAN3 LAN4" : "";
} else {
return "";
}
}
function SSSIdStatus(str?: string) {
if (str) {
switch (str) {
case "0":
return "禁用";
case "1":
return "在线";
case "2":
return "离线";
default:
return "离线";
}
}
}
function SSSIdHide(str?: string) {
if (str) {
switch (str) {
case "1":
return "隐藏";
default:
return "广播";
}
}
}
function bindingLan(str?: string) {
if (str) {
if (str.length > 0) {
return "LAN2";
}
}
}
const getServiceDetailInfo = (remote: string) => {
loading.value = true;
faultServiceStatus(prop.devId, remote)
.then(({ data }) => {
switch (remote) {
case "VoipInfoQueryGPON":
voip.value = data;
break;
case "IptvQueryGPON":
iptv.value = data;
break;
case "WLanInfoQuery":
wlan.value = data;
break;
case "LinkInfoQueryGPON":
link.value = data;
break;
case "DigitalhomeQueryGPON":
broadband.value = data;
break;
case "LanInfoQuery":
lan.value = data;
break;
}
})
.finally(() => {
loading.value = false;
});
};
</script>
<style scoped>
:deep(.el-descriptions__header) {
margin-bottom: 5px;
}
:deep(.my-content) {
height: 32px;
}
:deep(.my-label-none) {
display: none;
}
:deep(
.el-descriptions__body
.el-descriptions__table.is-bordered
.el-descriptions__cell
) {
padding: 8px 0;
}
</style>

@ -107,7 +107,9 @@
<div v-show="currentTab === 0">
<basic-info-query ref="basicInfoQueryRef" />
</div>
<div v-show="currentTab === 1">业务终端状态</div>
<div v-show="currentTab === 1">
<service-endpoint-status :dev-id="currentFaultQueryVO.devId" />
</div>
<div v-show="currentTab === 2">故障诊断应用</div>
<div v-show="currentTab === 3">高级查询</div>
<div v-show="currentTab === 4">健康库</div>
@ -122,6 +124,7 @@ import BasicInfoQuery from "@/views/family/operate/fault-management/components/b
import { FaultQuery, FaultQueryVO } from "@/api/fault/types";
import { faultQueryList } from "@/api/fault";
import { Close } from "@element-plus/icons-vue";
import ServiceEndpointStatus from "@/views/family/operate/fault-management/components/ServiceEndpointStatus.vue";
defineOptions({
name: "FaultManagement",
@ -153,8 +156,10 @@ const getData = () => {
loading.value = false;
});
};
const currentFaultQueryVO = ref<FaultQueryVO>(<FaultQueryVO>{ devId: 0 });
const loadBasicInfo = (vo: FaultQueryVO) => {
flag.value = false;
currentFaultQueryVO.value = vo;
basicInfoQueryRef.value.getBasicInfo(vo);
};
</script>

Loading…
Cancel
Save