fix: 运维管理 设备接入网关修复部分bug

This commit is contained in:
jackhoo_98 2023-03-16 15:59:01 +08:00
parent 62592b6e83
commit 05045768d2
10 changed files with 599 additions and 580 deletions

View File

@ -1,6 +1,7 @@
<template>
<j-spin :spinning="spinning">
<pro-search :columns="columns" target="search" @search="handleSearch" />
<j-scrollbar height="680">
<j-pro-table
ref="tableRef"
model="CARD"
@ -24,7 +25,9 @@
@click="handlAdd"
hasPermission="DataCollect/Collector:add"
>
<template #icon><AIcon type="PlusOutlined" /></template>
<template #icon
><AIcon type="PlusOutlined"
/></template>
新增点位
</PermissionButton>
@ -34,7 +37,9 @@
@click="handlScan"
hasPermission="DataCollect/Collector:add"
>
<template #icon><AIcon type="PlusOutlined" /></template>
<template #icon
><AIcon type="PlusOutlined"
/></template>
扫描
</PermissionButton>
<j-dropdown v-if="data?.provider === 'OPC_UA'">
@ -129,33 +134,39 @@
<div class="card-box-content-left-1">
<div
class="ard-box-content-left-1-title"
v-if="propertyValue.has(slotProps.id)"
v-if="
propertyValue.has(slotProps.id)
"
>
<j-ellipsis
style="max-width: 150px"
>
<j-ellipsis style="max-width: 150px">
{{
propertyValue.get(slotProps.id)
?.parseData[0] || 0
propertyValue.get(
slotProps.id,
)?.parseData[0] || 0
}}({{
propertyValue.get(slotProps.id)
?.dataType
propertyValue.get(
slotProps.id,
)?.dataType
}})
</j-ellipsis>
</div>
<span v-else>--</span>
<a
v-if="
getAccessModes(slotProps).includes(
'write',
)
getAccessModes(
slotProps,
).includes('write')
"
@click.stop="clickEdit(slotProps)"
><AIcon type="EditOutlined"
/></a>
<a
v-if="
getAccessModes(slotProps).includes(
'read',
)
getAccessModes(
slotProps,
).includes('read')
"
@click.stop="clickRedo(slotProps)"
><AIcon type="RedoOutlined"
@ -174,8 +185,9 @@
<p>
{{
moment(
propertyValue.get(slotProps.id)
?.timestamp,
propertyValue.get(
slotProps.id,
)?.timestamp,
).format('YYYY-MM-DD HH:mm:ss')
}}
</p>
@ -187,13 +199,19 @@
v-if="getRight1(slotProps)"
class="card-box-content-right-1"
>
<span>{{ getQuantity(slotProps) }}</span>
<span>{{
getQuantity(slotProps)
}}</span>
<span>{{ getAddress(slotProps) }}</span>
<span>{{ getScaleFactor(slotProps) }}</span>
<span>{{
getScaleFactor(slotProps)
}}</span>
</div>
<div class="card-box-content-right-2">
<span>{{ getText(slotProps) }}</span>
<span>{{ getInterval(slotProps) }}</span>
<span>{{
getInterval(slotProps)
}}</span>
</div>
</div>
</div>
@ -201,6 +219,7 @@
</PointCardBox>
</template>
</j-pro-table>
</j-scrollbar>
<SaveModBus
v-if="visible.saveModBus"
:data="current"

View File

@ -48,7 +48,7 @@ const checkedChange = (id: string) => {
overflow: hidden;
background: url('/public/images/access.png') no-repeat;
background-size: 100% 100%;
min-height: 105px;
height: 120px;
.title {
width: calc(100% - 88px);
@ -94,7 +94,6 @@ const checkedChange = (id: string) => {
position: relative;
color: #2f54eb;
border-color: #2f54eb;
.checked-icon {
display: block;
}

View File

@ -108,6 +108,7 @@
</j-row> </j-form
></j-col>
<j-col :span="8">
<j-scrollbar height="500">
<div class="doc">
<h1>操作指引</h1>
<div>
@ -152,6 +153,7 @@
1.在IOT端启用设备时若CTWing平台没有与之对应的设备则将在CTWing端自动创建新设备
</div>
</div>
</j-scrollbar>
</j-col>
</j-row>
</div>
@ -179,8 +181,12 @@
新增
</PermissionButton>
</div>
<div class="card-item">
<j-row :gutter="[24, 24]" v-if="procotolList.length > 0">
<j-scrollbar height="500">
<j-row
:gutter="[24, 24]"
v-if="procotolList.length > 0"
style="margin-right: 10px"
>
<j-col
:span="8"
v-for="item in procotolList"
@ -195,7 +201,7 @@
</j-col>
</j-row>
<j-empty v-else description="暂无数据" />
</div>
</j-scrollbar>
</div>
</div>
<div v-if="current === 2" class="card-last">
@ -362,26 +368,24 @@ const formData = ref<Form>({
const current = ref(0);
const stepCurrent = ref(0);
const steps = ref(['接入配置', '消息协议', '完成']);
const procotolList = ref([]);
const procotolList: any = ref([]);
const allProcotolList = ref([]);
const procotolCurrent = ref('');
const procotolCurrent: any = ref('');
const procotolChange = (id: string) => {
procotolCurrent.value = id;
};
const procotolSearch = (value: string) => {
if (value) {
const list = allProcotolList.value.filter((i) => {
return (
procotolList.value = value
? allProcotolList.value.filter(
(i: any) =>
i.name &&
i.name.toLocaleLowerCase().includes(value.toLocaleLowerCase())
);
});
procotolList.value = list;
} else {
procotolList.value = allProcotolList.value;
}
i.name
.toLocaleLowerCase()
.includes(value.toLocaleLowerCase()),
)
: allProcotolList.value;
};
const saveData = async () => {
@ -411,7 +415,7 @@ const saveData = async () => {
};
const queryProcotolList = async (id: string, params = {}) => {
const resp = await getProtocolList(ProtocolMapping.get(id), {
const resp: any = await getProtocolList(ProtocolMapping.get(id), {
...params,
'sorts[0].name': 'createTime',
'sorts[0].order': 'desc',
@ -424,10 +428,10 @@ const queryProcotolList = async (id: string, params = {}) => {
const addProcotol = () => {
const url = menuStory.menus['link/Protocol']?.path;
const tab = window.open(
const tab: any = window.open(
`${window.location.origin + window.location.pathname}#${url}?save=true`,
);
tab.onTabSaveSuccess = (value) => {
tab.onTabSaveSuccess = (value: any) => {
if (value.success) {
procotolCurrent.value = value.result?.id;
queryProcotolList(props.provider?.id);
@ -486,12 +490,7 @@ watch(
}
.steps-box {
min-height: 400px;
.card-item {
padding-right: 5px;
max-height: 480px;
overflow-y: auto;
overflow-x: hidden;
}
.card-last {
padding-right: 5px;
overflow-y: auto;

View File

@ -29,23 +29,17 @@
},
]"
>
<div class="form-label">
<template #label>
接口地址
<span
class="form-label-required"
>*</span
<j-tooltip
title="同步物联网平台设备数据到OneNet"
>
<j-tooltip>
<template #title>
<p>
同步物联网平台设备数据到OneNet
</p>
</template>
<AIcon
type="QuestionCircleOutlined"
style="margin-left: 2px"
/>
</j-tooltip>
</div>
</template>
<j-input
disabled
v-model:value="
@ -95,23 +89,17 @@
},
]"
>
<div class="form-label">
<template #label>
通知Token
<span
class="form-label-required"
>*</span
<j-tooltip
title="接收OneNet推送的Token地址"
>
<j-tooltip>
<template #title>
<p>
接收OneNet推送的Token地址
</p>
</template>
<AIcon
type="QuestionCircleOutlined"
style="margin-left: 2px"
/>
</j-tooltip>
</div>
</template>
<j-input
v-model:value="
formState.validateToken
@ -131,20 +119,17 @@
},
]"
>
<div class="form-label">
<template #label>
aesKey
<j-tooltip>
<template #title>
<p>
OneNet
端生成的消息加密key
</p>
</template>
<j-tooltip
title="OneNet端生成的消息加密key"
>
<AIcon
type="QuestionCircleOutlined"
style="margin-left: 2px"
/>
</j-tooltip>
</div>
</template>
<j-input
v-model:value="formState.aesKey"
placeholder="请输入aesKey"
@ -171,6 +156,7 @@
</j-row> </j-form
></j-col>
<j-col :span="8">
<j-scrollbar height="500">
<div class="doc">
<h1>操作指引</h1>
<div>
@ -251,6 +237,7 @@
1.在IOT端启用设备时若OneNet平台没有与之对应的设备则将在OneNet端自动创建新设备
</div>
</div>
</j-scrollbar>
</j-col>
</j-row>
</div>
@ -278,8 +265,12 @@
新增
</PermissionButton>
</div>
<div class="card-item">
<j-row :gutter="[24, 24]" v-if="procotolList.length > 0">
<j-scrollbar height="500">
<j-row
:gutter="[24, 24]"
v-if="procotolList.length > 0"
style="margin-right: 10px"
>
<j-col
:span="8"
v-for="item in procotolList"
@ -294,7 +285,7 @@
</j-col>
</j-row>
<j-empty v-else description="暂无数据" />
</div>
</j-scrollbar>
</div>
</div>
<div v-if="current === 2" class="card-last">
@ -463,26 +454,24 @@ const formData = ref<Form>({
const current = ref(0);
const stepCurrent = ref(0);
const steps = ref(['接入配置', '消息协议', '完成']);
const procotolList = ref([]);
const procotolList: any = ref([]);
const allProcotolList = ref([]);
const procotolCurrent = ref('');
const procotolCurrent: any = ref('');
const procotolChange = (id: string) => {
procotolCurrent.value = id;
};
const procotolSearch = (value: string) => {
if (value) {
const list = allProcotolList.value.filter((i) => {
return (
procotolList.value = value
? allProcotolList.value.filter(
(i: any) =>
i.name &&
i.name.toLocaleLowerCase().includes(value.toLocaleLowerCase())
);
});
procotolList.value = list;
} else {
procotolList.value = allProcotolList.value;
}
i.name
.toLocaleLowerCase()
.includes(value.toLocaleLowerCase()),
)
: allProcotolList.value;
};
const saveData = async () => {
@ -513,7 +502,7 @@ const saveData = async () => {
};
const queryProcotolList = async (id: string, params = {}) => {
const resp = await getProtocolList(ProtocolMapping.get(id), {
const resp: any = await getProtocolList(ProtocolMapping.get(id), {
...params,
'sorts[0].name': 'createTime',
'sorts[0].order': 'desc',
@ -526,10 +515,10 @@ const queryProcotolList = async (id: string, params = {}) => {
const addProcotol = () => {
const url = menuStory.menus['link/Protocol']?.path;
const tab = window.open(
const tab: any = window.open(
`${window.location.origin + window.location.pathname}#${url}?save=true`,
);
tab.onTabSaveSuccess = (value) => {
tab.onTabSaveSuccess = (value: any) => {
if (value.success) {
procotolCurrent.value = value.result?.id;
queryProcotolList(props.provider?.id);
@ -587,12 +576,6 @@ watch(
}
.steps-box {
min-height: 400px;
.card-item {
padding-right: 5px;
max-height: 480px;
overflow-y: auto;
overflow-x: hidden;
}
.card-last {
padding-right: 5px;
overflow-y: auto;

View File

@ -29,14 +29,18 @@
新增
</PermissionButton>
</div>
<div class="card-item">
<j-row :gutter="[24, 24]" v-if="networkList.length > 0">
<j-scrollbar height="500">
<j-row
:gutter="[24, 24]"
v-if="networkList.length > 0"
style="margin-right: 10px"
>
<j-col
:span="8"
v-for="item in networkList"
:key="item.id"
>
<access-card
<AccessCard
@checkedChange="checkedChange"
:checked="networkCurrent"
:data="{
@ -96,11 +100,11 @@
</j-tooltip>
</div>
</template>
</access-card>
</AccessCard>
</j-col>
</j-row>
<j-empty v-else description="暂无数据" />
</div>
</j-scrollbar>
</div>
</div>
<div
@ -250,9 +254,9 @@ const formRef = ref<FormInstance>();
const current = ref(0);
const stepCurrent = ref(0);
const steps = ref(['网络组件', '完成']);
const networkCurrent = ref('');
const networkList = ref([]);
const allNetworkList = ref([]);
const networkCurrent: any = ref('');
const networkList: any = ref([]);
const allNetworkList: any = ref([]);
const onFinish = async (values: any) => {
const providerId = props.provider.id;
@ -288,15 +292,15 @@ const queryNetworkList = async (id: string, include: string, data = {}) => {
};
const networkSearch = (value: string) => {
if (value) {
networkList.value = allNetworkList.value.filter(
networkList.value = value
? allNetworkList.value.filter(
(i: any) =>
i.name &&
i.name.toLocaleLowerCase().includes(value.toLocaleLowerCase()),
);
} else {
networkList.value = allNetworkList.value;
}
i.name
.toLocaleLowerCase()
.includes(value.toLocaleLowerCase()),
)
: allNetworkList.value;
};
const saveData = async () => {
@ -306,12 +310,12 @@ const saveData = async () => {
const addNetwork = () => {
const url = menuStory.menus['link/Type/Detail']?.path;
const tab = window.open(
const tab: any = window.open(
`${window.location.origin + window.location.pathname}#${url}?type=${
NetworkTypeMapping.get(props.provider?.id) || ''
}`,
);
tab.onTabSaveSuccess = (value) => {
tab.onTabSaveSuccess = (value: any) => {
if (value.success) {
networkCurrent.value = value.result.id;
queryNetworkList(props.provider?.id, networkCurrent.value || '');
@ -364,12 +368,6 @@ watch(
}
.steps-box {
min-height: 400px;
.card-item {
padding-right: 5px;
max-height: 480px;
overflow-y: auto;
overflow-x: hidden;
}
.card-last {
padding-right: 5px;
overflow-y: auto;
@ -405,9 +403,6 @@ watch(
}
.config-right {
padding: 20px;
// color: rgba(0, 0, 0, 0.8);
// background: rgba(0, 0, 0, 0.04);
.config-right-item {
margin-bottom: 10px;

View File

@ -71,24 +71,17 @@
},
]"
>
<div>
<template #label>
集群
<span style="color: red; margin: 0 4px 0 -2px"
>*</span
<j-tooltip
title="共享配置:集群下所有节点共用同一配置,独立配置:集群下不同节点使用不同配置"
>
<j-tooltip>
<template #title>
<p>
共享配置:集群下所有节点共用同一配置
</p>
<p>
独立配置:集群下不同节点使用不同配置
</p>
</template>
<AIcon type="QuestionCircleOutlined" />
<AIcon
type="QuestionCircleOutlined"
style="margin-left: 2px"
/>
</j-tooltip>
</div>
</template>
<j-radio-group
v-model:value="formState.shareCluster"
>
@ -218,20 +211,26 @@
:header="`#${index + 1}.节点`"
>
<template #extra>
<AIcon type="DeleteOutlined" />
<AIcon
@click="removeCluster(cluster)"
type="DeleteOutlined"
/>
</template>
<j-row :gutter="[24, 24]">
<j-col :span="8">
<j-form-item
label="节点名称"
:name="[
'cluster',
index,
'clusterNodeId',
]"
:rules="{
required: true,
message:
'请选择节点名称',
}"
>
<div class="form-label">
节点名称
</div>
<j-select
v-model:value="
cluster.clusterNodeId
@ -527,22 +526,22 @@ import { getResourcesCurrent, getClusters } from '@/api/link/accessConfig';
import { update, save } from '@/api/link/accessConfig';
interface Form2 {
clusterNodeId: string;
port: string;
host: string;
publicPort: string;
publicHost: string;
clusterNodeId: string | undefined;
port: string | undefined;
host: string | undefined;
publicPort: string | undefined;
publicHost: string | undefined;
id: number;
}
interface FormState {
domain: string;
sipId: string;
domain: string | undefined;
sipId: string | undefined;
shareCluster: boolean;
hostPort: {
port: string;
host: string;
publicPort: string;
publicHost: string;
port: string | undefined;
host: string | undefined;
publicPort: string | undefined;
publicHost: string | undefined;
};
}
@ -576,14 +575,14 @@ const formData = ref({
description: '',
});
let formState = ref<FormState>({
domain: '',
sipId: '',
domain: undefined,
sipId: undefined,
shareCluster: true,
hostPort: {
port: '',
port: undefined,
host: '0.0.0.0',
publicPort: '',
publicHost: '',
publicPort: undefined,
publicHost: undefined,
},
});
@ -610,11 +609,11 @@ const removeCluster = (item: Form2) => {
const addCluster = () => {
const id = Date.now();
dynamicValidateForm.cluster.push({
clusterNodeId: '',
port: '',
host: '',
publicPort: '',
publicHost: '',
clusterNodeId: undefined,
port: undefined,
host: undefined,
publicPort: undefined,
publicHost: undefined,
id,
});
activeKey.value = [...activeKey.value, id.toString()];
@ -665,16 +664,7 @@ const saveData = () => {
id === ':id' ? await save(params) : await update({ ...params, id });
if (resp.status === 200) {
message.success('操作成功!');
// if (params.get('save')) {
// if ((window as any).onTabSaveSuccess) {
// if (resp.result) {
// (window as any).onTabSaveSuccess(resp.result);
// setTimeout(() => window.close(), 300);
// }
// }
// } else {
history.back();
// }
}
});
};
@ -709,14 +699,14 @@ onMounted(() => {
getResourcesCurrent().then((resp) => {
if (resp.status === 200) {
sipListConst = resp.result;
sipListOption.value = sipListConst.map((i) => ({
sipListOption.value = sipListConst.map((i: any) => ({
value: i.host,
label: i.host,
}));
sipList.value = sipListConst
.find((i) => i.host === '0.0.0.0')
?.portList.map((i) => {
.find((i: any) => i.host === '0.0.0.0')
?.portList.map((i: any) => {
return {
value: JSON.stringify({
host: '0.0.0.0',
@ -728,9 +718,9 @@ onMounted(() => {
}
});
getClusters().then((resp) => {
getClusters().then((resp: any) => {
if (resp.status === 200) {
const list = resp.result.map((i) => ({
const list = resp.result.map((i: any) => ({
value: i.id,
label: i.name,
}));

View File

@ -25,8 +25,12 @@
新增
</PermissionButton>
</div>
<div class="card-item">
<j-row :gutter="[24, 24]" v-if="networkList.length > 0">
<j-scrollbar height="480">
<j-row
:gutter="[24, 24]"
v-if="networkList.length > 0"
style="margin-right: 10px"
>
<j-col
:span="8"
v-for="item in networkList"
@ -88,7 +92,7 @@
</j-col>
</j-row>
<j-empty v-else description="暂无数据" />
</div>
</j-scrollbar>
</div>
<div class="steps-box" v-else-if="current === 1">
<div class="alert">
@ -111,8 +115,12 @@
新增
</PermissionButton>
</div>
<div class="card-item">
<j-row :gutter="[24, 24]" v-if="procotolList.length > 0">
<j-scrollbar height="480">
<j-row
:gutter="[24, 24]"
v-if="procotolList.length > 0"
style="margin-right: 10px"
>
<j-col
:span="8"
v-for="item in procotolList"
@ -127,7 +135,7 @@
</j-col>
</j-row>
<j-empty v-else description="暂无数据" />
</div>
</j-scrollbar>
</div>
<div class="steps-box" v-else>
<div
@ -169,6 +177,7 @@
</j-form>
</j-col>
<j-col :span="12">
<j-scrollbar height="600">
<div class="config-right">
<div class="config-right-item">
<div class="config-right-item-title">
@ -188,7 +197,9 @@
<div class="config-right-item-context">
{{
procotolList.find(
(i) => i.id === procotolCurrent,
(i: any) =>
i.id ===
procotolCurrent,
).name
}}
</div>
@ -196,7 +207,9 @@
class="config-right-item-context"
v-if="config.document"
>
<Markdown :source="config.document" />
<Markdown
:source="config.document"
/>
</div>
</div>
<div
@ -233,10 +246,13 @@
: 'URL信息'
}}
</div>
<j-scrollbar height="200">
<j-table
:pagination="false"
:rowKey="generateUUID()"
:datj-source="config.routes || []"
:data-source="
config.routes || []
"
bordered
:columns="
config.id === 'MQTT'
@ -246,7 +262,11 @@
:scroll="{ y: 300 }"
>
<template
#bodyCell="{ column, text, record }"
#bodyCell="{
column,
text,
record,
}"
>
<template
v-if="
@ -258,8 +278,10 @@
</template>
</template>
</j-table>
</j-scrollbar>
</div>
</div>
</j-scrollbar>
</j-col>
</j-row>
</div>
@ -444,6 +466,8 @@ const getNetworkCurrentData = () =>
const getColor = (i: any) => (i.health === -1 ? 'red' : 'green');
const getStream = (record: any) => {
console.log(222, record);
let stream = '';
if (record.upstream && record.downstream) stream = '上行、下行';
else if (record.upstream) stream = '上行';
@ -493,19 +517,16 @@ const saveData = () => {
protocol: procotolCurrent.value,
channel: 'network', //
channelId: networkCurrent.value,
};
const resp =
id === ':id'
? await save(params)
: await update({
...params,
id,
provider: props.provider.id,
transport:
props.provider?.id === 'child-device'
? 'Gateway'
: ProtocolMapping.get(props.provider.id),
});
};
const resp =
id === ':id'
? await save(params)
: await update({ ...params, id });
if (resp.status === 200) {
message.success('操作成功!');
history.back();
@ -549,7 +570,6 @@ const next = async () => {
rowSpan: 0,
};
const list = config.value?.routes || [];
const arr = list.filter(
(res: any) => res.group === record.group,
);
@ -558,7 +578,6 @@ const next = async () => {
rowIndex === 0 ||
list[rowIndex - 1].group !== record.group;
isRowIndex && (obj.rowSpan = arr.length);
return obj;
},
};
@ -629,12 +648,6 @@ watch(
}
.steps-box {
min-height: 400px;
.card-item {
padding-right: 5px;
max-height: 480px;
overflow-y: auto;
overflow-x: hidden;
}
.card-last {
padding-right: 5px;
overflow-y: auto;

View File

@ -6,7 +6,6 @@
target="search"
@search="handleSearch"
/>
<j-pro-table
ref="tableRef"
model="CARD"
@ -353,6 +352,12 @@ const handleSearch = (e: any) => {
};
</script>
<style lang="less" scoped>
.table {
max-height: 700px;
overflow-y: auto;
overflow-x: hidden;
}
.tableCardDisabled {
width: 100%;
background: url('/images/access-config-diaabled.png') no-repeat;

View File

@ -135,11 +135,17 @@ const changeType = (value: Array<string>) => {
const onSubmit = async () => {
const data: any = await formRef.value?.validate();
loading.value = true;
const response = !id
const response: any = !id
? await save(data).catch(() => {})
: await update({ ...props.data, ...data }).catch(() => {});
if (response?.status === 200) {
emit('change', response?.status === 200);
if ((window as any).onTabSaveSuccess) {
if (response.result?.id) {
(window as any).onTabSaveSuccess(response);
setTimeout(() => window.close(), 300);
}
}
}
loading.value = false;
};

View File

@ -36,6 +36,7 @@
show-search
:filter-option="filterOption"
@change="changeType"
:disabled="!!NetworkType"
/>
</j-form-item>
</j-col>
@ -981,6 +982,7 @@ import {
resourcesCurrent,
supports,
certificates,
start,
} from '@/api/link/type';
import {
FormStates,
@ -1146,13 +1148,21 @@ const saveData = async () => {
: { ...formData.value, ...formRef2Data };
loading.value = true;
const resp =
const resp: any =
id === ':id'
? await save(params).catch(() => {})
: await update({ ...params, id }).catch(() => {});
if (resp?.status === 200) {
message.success('操作成功!');
history.back();
if ((window as any).onTabSaveSuccess) {
if (resp.result?.id) {
start(resp.result?.id).then(() => {
(window as any).onTabSaveSuccess(resp);
setTimeout(() => window.close(), 300);
});
}
}
}
loading.value = false;
};