update: 采集器 右侧卡片新增websocket

This commit is contained in:
jackhoo_98 2023-03-13 14:00:49 +08:00
parent 08ca907b99
commit 0d749d6867
6 changed files with 127 additions and 57 deletions

View File

@ -25,7 +25,7 @@
"event-source-polyfill": "^1.0.31",
"global": "^4.4.0",
"jetlinks-store": "^0.0.3",
"jetlinks-ui-components": "^1.0.4",
"jetlinks-ui-components": "^1.0.5",
"js-cookie": "^3.0.1",
"less": "^4.1.3",
"less-loader": "^11.1.0",

View File

@ -3,7 +3,7 @@
<j-table
:dataSource="modelRef.dataSource"
:columns="FormTableColumns"
:scroll="{ x: 1100, y: 500 }"
:scroll="{ x: 1100, y: 550 }"
>
<template #bodyCell="{ column: { dataIndex }, record, index }">
<template v-if="dataIndex === 'name'">
@ -151,14 +151,14 @@
</template>
<template v-if="dataIndex === 'action'">
<a-tooltip title="删除">
<a-popconfirm
<j-tooltip title="删除">
<j-popconfirm
title="确认删除"
@confirm="clickDelete(record.id)"
>
<AIcon type="DeleteOutlined" />
</a-popconfirm>
</a-tooltip>
<a><AIcon type="DeleteOutlined" /></a>
</j-popconfirm>
</j-tooltip>
</template>
</template>
</j-table>

View File

@ -5,21 +5,15 @@
<j-checkbox v-model:checked="isSelected">隐藏已有节点</j-checkbox>
</div>
<j-spin :spinning="spinning">
<a-tree
v-model:checkedKeys="checkedKeys"
:tree-data="treeData"
default-expand-all
checkable
@check="onCheck"
:height="600"
>
<!-- <a-tree
:load-data="onLoadData"
:tree-data="treeData"
v-model:checkedKeys="checkedKeys"
checkable
@check="onCheck"
> -->
:height="650"
>
<template #title="{ name, key }">
<span
:class="[

View File

@ -71,7 +71,6 @@ const handleOk = async () => {
accessModes: item.accessModes?.value || [],
};
});
console.log(1112, props.data, data, list);
const resp = await savePointBatch([...list]);
if (resp.status === 200) {
emit('change', true);

View File

@ -98,18 +98,14 @@
</template>
<template #action>
<div class="card-box-action">
<a>
<j-popconfirm
title="确定删除?"
@confirm="handlDelete(slotProps.id)"
>
<AIcon type="DeleteOutlined" />
<a><AIcon type="DeleteOutlined" /></a>
</j-popconfirm>
</a>
<a
><AIcon
@click="handlEdit(slotProps)"
type="FormOutlined"
<a @click="handlEdit(slotProps)"
><AIcon type="FormOutlined"
/></a>
</div>
</template>
@ -125,16 +121,31 @@
<template #content>
<div class="card-box-content">
<div class="card-box-content-left">
<span>--</span>
<div class="card-box-content-left-1">
<div
class="ard-box-content-left-1-title"
v-if="propertyValue.has(slotProps.id)"
>
<j-ellipsis style="max-width: 150px">
{{
propertyValue.get(slotProps.id)
?.parseData[0] || 0
}}({{
propertyValue.get(slotProps.id)
?.dataType
}})
</j-ellipsis>
</div>
<span v-else>--</span>
<a
v-if="
getAccessModes(slotProps).includes(
'write',
)
"
><AIcon
@click.stop="clickEdit(slotProps)"
type="EditOutlined"
><AIcon type="EditOutlined"
/></a>
<a
v-if="
@ -142,11 +153,31 @@
'read',
)
"
><AIcon
@click.stop="clickRedo(slotProps)"
type="RedoOutlined"
><AIcon type="RedoOutlined"
/></a>
</div>
<div
v-if="propertyValue.has(slotProps.id)"
class="card-box-content-right-2"
>
<p>
{{
propertyValue.get(slotProps.id)
?.hex || ''
}}
</p>
<p>
{{
moment(
propertyValue.get(slotProps.id)
?.timestamp,
).format('YYYY-MM-DD HH:mm:ss')
}}
</p>
</div>
</div>
<div class="card-box-content-right">
<div
v-if="getRight1(slotProps)"
@ -207,6 +238,9 @@ import SaveOPCUA from './Save/SaveOPCUA.vue';
import Scan from './Scan/index.vue';
import { colorMap, getState } from '../data.ts';
import { cloneDeep } from 'lodash-es';
import { getWebSocket } from '@/utils/websocket';
import { map } from 'rxjs/operators';
import moment from 'moment';
const props = defineProps({
data: {
@ -215,7 +249,6 @@ const props = defineProps({
},
});
const menuStory = useMenuStore();
const tableRef = ref<Record<string, any>>({});
const params = ref<Record<string, any>>({});
const opcImage = getImage('/DataCollect/device-opcua.png');
@ -242,7 +275,6 @@ const defaultParams = ref({
{
column: 'collectorId',
value: collectorId.value,
// value: '1610517928766550016', //
},
],
},
@ -332,6 +364,9 @@ const columns = [
},
];
const subRef = ref();
const propertyValue = ref(new Map());
const handlAdd = () => {
visible.saveModBus = true;
current.value = {
@ -431,6 +466,7 @@ const cancelSelect = () => {
};
const handleClick = (dt: any) => {
if (props.data?.provider !== 'OPC_UA') return;
if (_selectedRowKeys.value.includes(dt.id)) {
const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id);
_selectedRowKeys.value.splice(_index, 1);
@ -439,6 +475,32 @@ const handleClick = (dt: any) => {
}
};
const subscribeProperty = (value: any) => {
const list = value.map((item: any) => item.id);
const id = `collector-${props.data?.channelId || 'channel'}-${
props.data?.id || 'point'
}-data-${list.join('-')}`;
const topic = `/collector/${props.data?.channelId || '*'}/${
props.data?.id || '*'
}/data`;
subRef.value = getWebSocket(id, topic, {
pointId: list.join(','),
})
?.pipe(map((res) => res.payload))
.subscribe((payload: any) => {
propertyValue.value.set(payload.pointId, payload);
});
};
watch(
() => tableRef?.value?._dataSource,
(value) => {
if (value.length !== 0) {
subscribeProperty(value);
}
},
);
watch(
() => props.data,
(value) => {
@ -451,13 +513,19 @@ watch(
value: 'subscribe',
});
defaultParams.value.terms[0].terms[0].value = value.id;
// defaultParams.value.terms[0].terms[0].value = '1610517928766550016'; //
tableRef?.value?.reload && tableRef?.value?.reload();
cancelSelect();
}
},
{ immediate: true, deep: true },
);
onUnmounted(() => {
if (subRef.value) {
subRef.value?.unsubscribe();
}
});
/**
* 搜索
* @param params
@ -492,12 +560,22 @@ const handleSearch = (e: any) => {
margin-top: 10px;
display: flex;
.card-box-content-left {
flex: 0.2;
// flex: 0.2;
max-width: 220px;
border-right: 1px solid #e0e4e8;
height: 68px;
padding-right: 20px;
padding-right: 10px;
.card-box-content-left-1 {
display: flex;
justify-content: flex-start;
.card-box-content-left-1-title {
color: #000;
font-size: 20px;
opacity: 0.85;
}
}
// justify-content: space-between;
a {
margin-left: 10px;
}

View File

@ -174,7 +174,6 @@ export const FormTableColumns = [
title: '操作',
key: 'action',
dataIndex: 'action',
fixed: 'right',
width: 80,
},