929 lines
34 KiB
Vue
929 lines
34 KiB
Vue
<template>
|
|
<j-spin :spinning="spinning">
|
|
<pro-search
|
|
:columns="columns"
|
|
target="search-point"
|
|
@search="handleSearch"
|
|
/>
|
|
<FullPage>
|
|
<j-scrollbar height="680">
|
|
<j-pro-table
|
|
ref="tableRef"
|
|
model="CARD"
|
|
:columns="columns"
|
|
:gridColumn="2"
|
|
:gridColumns="[1, 2]"
|
|
:request="queryPoint"
|
|
:defaultParams="defaultParams"
|
|
:rowSelection="
|
|
isCheck
|
|
? {
|
|
selectedRowKeys: _selectedRowKeys,
|
|
onSelectNone: () => (_selectedRowKeys = []),
|
|
}
|
|
: false
|
|
"
|
|
:params="params"
|
|
>
|
|
<template #headerTitle>
|
|
<j-space>
|
|
<PermissionButton
|
|
v-if="
|
|
[
|
|
'MODBUS_TCP',
|
|
'COLLECTOR_GATEWAY',
|
|
'snap7',
|
|
'iec104',
|
|
].includes(data?.provider)
|
|
"
|
|
type="primary"
|
|
@click="handleAdd"
|
|
hasPermission="DataCollect/Collector:add"
|
|
>
|
|
<template #icon
|
|
><AIcon type="PlusOutlined"
|
|
/></template>
|
|
新增点位
|
|
</PermissionButton>
|
|
<PermissionButton
|
|
v-if="
|
|
data?.provider === 'OPC_UA' ||
|
|
data?.provider === 'BACNetIp'
|
|
"
|
|
type="primary"
|
|
@click="handleScan"
|
|
hasPermission="DataCollect/Collector:add"
|
|
>
|
|
<template #icon
|
|
><AIcon type="PlusOutlined"
|
|
/></template>
|
|
扫描
|
|
</PermissionButton>
|
|
<PermissionButton
|
|
v-if="data?.id && data.id !== '*'"
|
|
type="primary"
|
|
@click="handleImport"
|
|
hasPermission="DataCollect/Collector:add"
|
|
>
|
|
批量导入
|
|
</PermissionButton>
|
|
<PermissionButton
|
|
v-if="data?.id && data.id !== '*'"
|
|
type="primary"
|
|
@click="handleExport"
|
|
hasPermission="DataCollect/Collector:add"
|
|
>
|
|
数据导出
|
|
</PermissionButton>
|
|
<BatchDropdown
|
|
v-if="data?.id && data.id !== '*'"
|
|
ref="batchRef"
|
|
v-model:isCheck="isCheck"
|
|
:actions="batchActions"
|
|
@change="onCheckChange"
|
|
/>
|
|
</j-space>
|
|
<div v-if="isCheck" style="margin-top: 15px">
|
|
<j-checkbox
|
|
v-model:checked="checkAll"
|
|
@change="onCheckAllChange"
|
|
>全选</j-checkbox
|
|
>
|
|
</div>
|
|
</template>
|
|
<template #card="slotProps">
|
|
<PointCardBox
|
|
:showStatus="true"
|
|
:value="slotProps"
|
|
@click="handleClick"
|
|
:active="_selectedRowKeys.includes(slotProps.id)"
|
|
class="card-box"
|
|
:status="slotProps?.runningState?.value"
|
|
:statusText="slotProps?.runningState?.text"
|
|
:statusNames="
|
|
Object.fromEntries(colorMap.entries())
|
|
"
|
|
>
|
|
<template #title>
|
|
<slot name="title">
|
|
<Ellipsis style="width: calc(100% - 10px)">
|
|
<div class="card-box-title">
|
|
{{ slotProps.name }}
|
|
</div>
|
|
</Ellipsis>
|
|
</slot>
|
|
</template>
|
|
<template #action>
|
|
<div class="card-box-action">
|
|
<PermissionButton
|
|
type="text"
|
|
:tooltip="{
|
|
title: '删除',
|
|
}"
|
|
hasPermission="DataCollect/Collector:delete"
|
|
:popConfirm="{
|
|
title: `确认删除?`,
|
|
onConfirm: () =>
|
|
handleDelete(slotProps.id),
|
|
}"
|
|
>
|
|
<a
|
|
style="
|
|
font-size: 20px;
|
|
margin-top: -10px;
|
|
"
|
|
><AIcon type="DeleteOutlined"
|
|
/></a>
|
|
</PermissionButton>
|
|
|
|
<PermissionButton
|
|
type="text"
|
|
@click="handleEdit(slotProps)"
|
|
hasPermission="DataCollect/Collector:update"
|
|
>
|
|
<a style="font-size: 20px"
|
|
><AIcon type="FormOutlined"
|
|
/></a>
|
|
</PermissionButton>
|
|
</div>
|
|
</template>
|
|
<template #img>
|
|
<img :src="ImageMap.get(slotProps.provider)" />
|
|
</template>
|
|
<template #content>
|
|
<div class="card-box-content">
|
|
<div class="card-box-content-left">
|
|
<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"
|
|
>
|
|
{{
|
|
getParseData(slotProps)
|
|
}}
|
|
</j-ellipsis>
|
|
</div>
|
|
<div
|
|
class="ard-box-content-left-1-title"
|
|
v-else
|
|
>
|
|
<j-ellipsis
|
|
style="max-width: 150px"
|
|
>
|
|
{{
|
|
getReadParseData(
|
|
slotProps,
|
|
)
|
|
}}
|
|
</j-ellipsis>
|
|
</div>
|
|
<a
|
|
v-if="
|
|
getAccessModes(
|
|
slotProps,
|
|
).includes('write')
|
|
"
|
|
@click.stop="
|
|
clickEdit(slotProps)
|
|
"
|
|
><AIcon type="EditOutlined"
|
|
/></a>
|
|
<a
|
|
v-if="
|
|
getAccessModes(
|
|
slotProps,
|
|
).includes('read')
|
|
"
|
|
@click.stop="
|
|
clickRead(slotProps)
|
|
"
|
|
><AIcon type="RedoOutlined"
|
|
/></a>
|
|
</div>
|
|
<div
|
|
v-if="
|
|
propertyValue.has(slotProps.id)
|
|
"
|
|
class="card-box-content-right-2"
|
|
>
|
|
<Ellipsis>
|
|
{{
|
|
propertyValue.get(
|
|
slotProps.id,
|
|
)?.hex || ''
|
|
}}
|
|
</Ellipsis>
|
|
<p>
|
|
{{
|
|
dayjs(
|
|
propertyValue.get(
|
|
slotProps.id,
|
|
)?.timestamp,
|
|
).format(
|
|
'YYYY-MM-DD HH:mm:ss',
|
|
)
|
|
}}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-box-content-right">
|
|
<Ellipsis
|
|
style="
|
|
width: calc(100% - 10px);
|
|
margin-bottom: 10px;
|
|
"
|
|
>
|
|
<div
|
|
v-if="getRight1(slotProps)"
|
|
class="card-box-content-right-1"
|
|
>
|
|
<span>
|
|
{{ getQuantity(slotProps) }}
|
|
</span>
|
|
<span>
|
|
{{ getAddress(slotProps) }}
|
|
</span>
|
|
<span>
|
|
{{
|
|
getScaleFactor(
|
|
slotProps,
|
|
)
|
|
}}
|
|
</span>
|
|
</div>
|
|
</Ellipsis>
|
|
<Ellipsis
|
|
style="
|
|
width: calc(100% - 10px);
|
|
margin-bottom: 10px;
|
|
"
|
|
>
|
|
<div
|
|
class="card-box-content-right-2"
|
|
>
|
|
<span>{{
|
|
getText(slotProps)
|
|
}}</span>
|
|
<span
|
|
v-if="
|
|
getInterval(slotProps)
|
|
"
|
|
>{{
|
|
getInterval(slotProps)
|
|
}}</span
|
|
>
|
|
</div>
|
|
</Ellipsis>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</PointCardBox>
|
|
</template>
|
|
</j-pro-table>
|
|
</j-scrollbar>
|
|
</FullPage>
|
|
|
|
<SaveModBus
|
|
v-if="visible.saveModBus"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<SaveOPCUA
|
|
v-if="visible.saveOPCUA"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<WritePoint
|
|
v-if="visible.writePoint"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<BatchUpdate
|
|
v-if="visible.batchUpdate"
|
|
:data="current"
|
|
:provider="data.provider"
|
|
@change="saveChange"
|
|
/>
|
|
<SaveS7 v-if="visible.saveS7" :data="current" @change="saveChange" />
|
|
<SaveIEC104
|
|
v-if="visible.saveIEC104"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<SaveBACNet
|
|
v-if="visible.saveBACNet"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<Scan v-if="visible.scan" :data="current" @change="saveChange" />
|
|
<ScanBacnet
|
|
v-if="visible.scanBacnet"
|
|
:data="current"
|
|
@change="saveChange"
|
|
/>
|
|
<Import
|
|
v-if="visible.import"
|
|
:data="current"
|
|
@close-import="closeImport"
|
|
/>
|
|
</j-spin>
|
|
</template>
|
|
<script lang="ts" setup name="PointPage">
|
|
import { getImage } from '@/utils/comm';
|
|
import {
|
|
queryPoint,
|
|
batchDeletePoint,
|
|
removePoint,
|
|
readPoint,
|
|
getProviders,
|
|
getStates,
|
|
exportPoint,
|
|
} from '@/api/data-collect/collector';
|
|
import { onlyMessage } from '@/utils/comm';
|
|
import PointCardBox from './components/PointCardBox/index.vue';
|
|
import WritePoint from './components/WritePoint/index.vue';
|
|
import BatchUpdate from './components/BatchUpdate/index.vue';
|
|
import SaveModBus from './Save/SaveModBus.vue';
|
|
import SaveOPCUA from './Save/SaveOPCUA.vue';
|
|
import Scan from './Scan/index.vue';
|
|
import ScanBacnet from './ScanBacnet/index.vue';
|
|
import SaveBACNet from './Save/SaveBACNet.vue';
|
|
import { colorMap } from '../data';
|
|
import { cloneDeep, isBoolean, isNumber, throttle } from 'lodash-es';
|
|
import { getWebSocket } from '@/utils/websocket';
|
|
import { map } from 'rxjs/operators';
|
|
import dayjs from 'dayjs';
|
|
import SaveS7 from './Save/SaveS7.vue';
|
|
import SaveIEC104 from './Save/SaveIEC104.vue';
|
|
import Import from './components/Import/index.vue';
|
|
import { downloadFileByUrl } from '@/utils/utils';
|
|
import BatchDropdown from '@/components/BatchDropdown/index.vue';
|
|
const props = defineProps({
|
|
data: {
|
|
type: Object,
|
|
default: {},
|
|
},
|
|
});
|
|
|
|
const tableRef = ref<Record<string, any>>({});
|
|
const params = ref<Record<string, any>>({});
|
|
const opcImage = getImage('/DataCollect/device-opcua.png');
|
|
const modbusImage = getImage('/DataCollect/device-modbus.png');
|
|
const s7Image = getImage('/DataCollect/s7.png');
|
|
const gatewayImage = getImage('/DataCollect/gateway.png');
|
|
const iecImage = getImage('/DataCollect/IEC104.png');
|
|
const ImageMap = new Map();
|
|
ImageMap.set('OPC_UA', opcImage);
|
|
ImageMap.set('MODBUS_TCP', modbusImage);
|
|
ImageMap.set('snap7', s7Image);
|
|
ImageMap.set('iec104', iecImage);
|
|
ImageMap.set('COLLECTOR_GATEWAY', gatewayImage);
|
|
|
|
const visible = reactive({
|
|
saveModBus: false,
|
|
saveOPCUA: false,
|
|
writePoint: false,
|
|
batchUpdate: false,
|
|
scan: false,
|
|
saveS7: false,
|
|
import: false,
|
|
saveIEC104: false,
|
|
scanBacnet: false,
|
|
saveBACNet: false,
|
|
});
|
|
const current: any = ref({});
|
|
const accessModesOption = ref();
|
|
const _selectedRowKeys = ref<string[]>([]);
|
|
const checkAll = ref(false);
|
|
const spinning = ref(false);
|
|
const ReadIdMap = new Map();
|
|
const isCheck = ref(false);
|
|
const batchRef = ref();
|
|
const defaultParams = ref({
|
|
sorts: [{ name: 'id', order: 'desc' }],
|
|
terms: [
|
|
{
|
|
terms: [
|
|
{
|
|
column: 'collectorId',
|
|
termType: 'eq',
|
|
value: !props.data?.id
|
|
? 'undefined'
|
|
: props.data.id === '*'
|
|
? undefined
|
|
: props.data.id,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
});
|
|
|
|
const accessModesMODBUS_TCP = [
|
|
{
|
|
label: '读',
|
|
value: 'read',
|
|
},
|
|
{
|
|
label: '写',
|
|
value: 'write',
|
|
},
|
|
];
|
|
|
|
const columns = [
|
|
{
|
|
title: '点位名称',
|
|
dataIndex: 'name',
|
|
key: 'name',
|
|
search: {
|
|
type: 'string',
|
|
},
|
|
},
|
|
{
|
|
title: '通讯协议',
|
|
dataIndex: 'provider',
|
|
key: 'provider',
|
|
search: {
|
|
type: 'select',
|
|
options: async () => {
|
|
const resp: any = await getProviders();
|
|
if (resp.success) {
|
|
return resp.result.map((item: any) => ({
|
|
label: item.name,
|
|
value: item.id,
|
|
}));
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: '访问类型',
|
|
dataIndex: 'accessModes$in$any',
|
|
key: 'accessModes$in$any',
|
|
search: {
|
|
type: 'select',
|
|
options: accessModesOption,
|
|
},
|
|
},
|
|
{
|
|
title: '运行状态',
|
|
dataIndex: 'runningState',
|
|
key: 'runningState',
|
|
search: {
|
|
type: 'select',
|
|
options: async () => {
|
|
const resq: any = await getStates();
|
|
if (resq.status === 200) {
|
|
return resq.result.map((item: any) => ({
|
|
label: item.text,
|
|
value: item.value,
|
|
}));
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: '说明',
|
|
dataIndex: 'description',
|
|
key: 'description',
|
|
search: {
|
|
type: 'string',
|
|
},
|
|
},
|
|
];
|
|
|
|
const subRef = ref();
|
|
const propertyValue = ref(new Map());
|
|
const batchActions = ref<any>([]);
|
|
const handleAdd = () => {
|
|
if (props.data?.provider === 'snap7') {
|
|
visible.saveS7 = true;
|
|
current.value = {
|
|
collectorId: props.data?.id,
|
|
provider: props.data?.provider,
|
|
deviceType: props.data?.configuration.type,
|
|
};
|
|
} else if (props.data?.provider === 'iec104') {
|
|
visible.saveIEC104 = true;
|
|
current.value = {
|
|
collectorId: props.data?.id,
|
|
provider: props.data?.provider,
|
|
};
|
|
} else {
|
|
visible.saveModBus = true;
|
|
current.value = {
|
|
collectorId: props.data?.id,
|
|
provider: props.data?.provider || 'MODBUS_TCP',
|
|
};
|
|
}
|
|
};
|
|
const handleEdit = (data: any) => {
|
|
if (data?.provider === 'OPC_UA') {
|
|
visible.saveOPCUA = true;
|
|
} else if (data?.provider === 'snap7') {
|
|
visible.saveS7 = true;
|
|
} else if (data?.provider === 'iec104') {
|
|
visible.saveIEC104 = true;
|
|
} else if (data?.provider === 'BACNetIp') {
|
|
visible.saveBACNet = true;
|
|
} else {
|
|
visible.saveModBus = true;
|
|
}
|
|
current.value = cloneDeep({
|
|
...data,
|
|
deviceType:
|
|
props.data?.configuration?.type ||
|
|
props.data?.configuration?.valueType,
|
|
});
|
|
};
|
|
|
|
const handleDelete = (id: string | undefined = undefined) => {
|
|
spinning.value = true;
|
|
const response = !id
|
|
? batchDeletePoint(_selectedRowKeys.value).catch(() => {})
|
|
: removePoint(id as string).catch(() => {});
|
|
response.then((res) => {
|
|
if (res?.status === 200) {
|
|
cancelSelect();
|
|
tableRef.value?.reload();
|
|
onlyMessage('操作成功', 'success');
|
|
}
|
|
spinning.value = false;
|
|
});
|
|
return response;
|
|
};
|
|
|
|
const onCheckChange = () => {
|
|
_selectedRowKeys.value = [];
|
|
checkAll.value = false;
|
|
};
|
|
|
|
const handleBatchDelete = () => {
|
|
if (!_selectedRowKeys.value.length) {
|
|
onlyMessage('至少选择一条数据', 'error');
|
|
return
|
|
}
|
|
handleDelete();
|
|
};
|
|
|
|
const handleBatchUpdate = () => {
|
|
if (!_selectedRowKeys.value.length) {
|
|
onlyMessage('至少选择一条数据', 'error');
|
|
return
|
|
}
|
|
const dataSet = new Set(_selectedRowKeys.value);
|
|
const dataMap = new Map();
|
|
tableRef?.value?._dataSource.forEach((i: any) => {
|
|
dataSet.has(i.id) && dataMap.set(i.id, i);
|
|
});
|
|
current.value = [...dataMap.values()];
|
|
visible.batchUpdate = true;
|
|
};
|
|
|
|
const handleScan = () => {
|
|
if (props.data?.provider === 'OPC_UA') {
|
|
visible.scan = true;
|
|
} else if (props.data?.provider === 'BACNetIp') {
|
|
visible.scanBacnet = true;
|
|
}
|
|
current.value = cloneDeep(props.data);
|
|
};
|
|
const handleImport = () => {
|
|
visible.import = true;
|
|
current.value = cloneDeep(props.data);
|
|
};
|
|
const handleExport = async () => {
|
|
const params =
|
|
props?.data?.provider === 'COLLECTOR_GATEWAY'
|
|
? props?.data?.configuration?.collectorProvider
|
|
: props?.data?.provider;
|
|
const res: any = await exportPoint(props.data.collectorId, params);
|
|
if (res) {
|
|
const blob = new Blob([res], { type: 'xlsx' });
|
|
const url = URL.createObjectURL(blob);
|
|
downloadFileByUrl(url, `${props?.data?.channelName}点位数据`, 'xlsx');
|
|
}
|
|
};
|
|
const clickEdit = async (data: object) => {
|
|
visible.writePoint = true;
|
|
current.value = cloneDeep(data);
|
|
};
|
|
|
|
// ReadIdMap
|
|
const clickRead = async (data: any) => {
|
|
const res: any = await readPoint(data?.collectorId, [data?.id]);
|
|
if (res.status === 200) {
|
|
const readData: any = res.result[0];
|
|
const _data = ReadIdMap.get(data?.id);
|
|
ReadIdMap.set(data?.id, { ..._data, ...readData });
|
|
console.log('====', ReadIdMap.get(data.id));
|
|
cancelSelect();
|
|
tableRef.value?.reload();
|
|
onlyMessage('操作成功', 'success');
|
|
}
|
|
};
|
|
|
|
const getQuantity = (item: Partial<Record<string, any>>) => {
|
|
const { quantity } = item.configuration?.parameter || '';
|
|
return !!quantity ? quantity + '(寄存器数量)' : '';
|
|
};
|
|
const getAddress = (item: Partial<Record<string, any>>) => {
|
|
const { address } = item.configuration?.parameter || '';
|
|
return !!address || address === 0 ? address + '(地址)' : '';
|
|
};
|
|
const getScaleFactor = (item: Partial<Record<string, any>>) => {
|
|
const { scaleFactor } = item.configuration?.codec?.configuration || '';
|
|
return !!scaleFactor ? scaleFactor + '(缩放因子)' : '';
|
|
};
|
|
const getRight1 = (item: Partial<Record<string, any>>) => {
|
|
return !!getQuantity(item) || getAddress(item) || getScaleFactor(item);
|
|
};
|
|
const getText = (item: Partial<Record<string, any>>) => {
|
|
return (item?.accessModes || []).map((i: any) => i?.text).join(',');
|
|
};
|
|
const getInterval = (item: Partial<Record<string, any>>) => {
|
|
const { interval } = item.configuration || '';
|
|
return !!interval ? '采集频率' + interval + 'ms' : '';
|
|
};
|
|
|
|
const getAccessModes = (item: Partial<Record<string, any>>) => {
|
|
return item?.accessModes?.map((i: any) => i?.value);
|
|
};
|
|
|
|
const getParseData = (item: any) => {
|
|
const { parseData, dataType } = propertyValue.value.get(item.id);
|
|
const data = isNumber(parseData) ? parseData || 0 : parseData;
|
|
const _data = `${data}(${dataType}) `;
|
|
return _data;
|
|
};
|
|
const getReadParseData = (item: any) => {
|
|
let _data = '--';
|
|
if (ReadIdMap.has(item.id)) {
|
|
const { parseData, dataType } = ReadIdMap.get(item.id);
|
|
if (isBoolean(parseData)) {
|
|
_data = `${parseData}(${dataType || '-'}) `;
|
|
} else {
|
|
_data = !!parseData ? `${parseData}(${dataType || '-'}) ` : '--';
|
|
}
|
|
}
|
|
return _data;
|
|
};
|
|
|
|
const saveChange = (value: object) => {
|
|
for (let key in visible) {
|
|
visible[key] = false;
|
|
}
|
|
current.value = {};
|
|
if (value) {
|
|
tableRef.value?.reload();
|
|
onlyMessage('操作成功', 'success');
|
|
}
|
|
};
|
|
|
|
const cancelSelect = () => {
|
|
_selectedRowKeys.value = [];
|
|
};
|
|
|
|
const handleClick = (dt: any) => {
|
|
if (!isCheck.value) {
|
|
return;
|
|
}
|
|
if (_selectedRowKeys.value.includes(dt.id)) {
|
|
const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id);
|
|
_selectedRowKeys.value.splice(_index, 1);
|
|
checkAll.value = false;
|
|
} else {
|
|
_selectedRowKeys.value = [..._selectedRowKeys.value, dt.id];
|
|
if (
|
|
_selectedRowKeys.value.length === tableRef.value?._dataSource.length
|
|
) {
|
|
checkAll.value = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleSubscribeValue = throttle((payload: any) => {
|
|
propertyValue.value.set(payload.pointId, payload);
|
|
});
|
|
|
|
const subscribeProperty = (value: any) => {
|
|
const list = value.map((item: any) => item.id);
|
|
const id = `collector-${props.data?.channelId || 'channel'}-${
|
|
props.data?.id || (props.data && props.data.id === '*')
|
|
? 'point'
|
|
: props.data?.id
|
|
}-data-${list.join('-')}`;
|
|
const topic = `/collector/${props.data?.channelId || '*'}/${
|
|
props.data?.id || (props.data && props.data.id === '*')
|
|
? '*'
|
|
: props.data?.id
|
|
}/data`;
|
|
subRef.value = getWebSocket(id, topic, {
|
|
pointId: list.join(','),
|
|
})
|
|
?.pipe(map((res: any) => res.payload))
|
|
.subscribe((payload: any) => {
|
|
//防止刷新过快
|
|
handleSubscribeValue(payload);
|
|
});
|
|
};
|
|
|
|
const onCheckAllChange = (e: any) => {
|
|
if (e.target.checked) {
|
|
_selectedRowKeys.value = [
|
|
...tableRef.value?._dataSource.map((i: any) => i.id),
|
|
];
|
|
} else {
|
|
cancelSelect();
|
|
checkAll.value = false;
|
|
}
|
|
};
|
|
|
|
const closeImport = () => {
|
|
visible.import = false;
|
|
tableRef.value.reload();
|
|
};
|
|
|
|
watch(
|
|
() => tableRef?.value?._dataSource,
|
|
(value) => {
|
|
subRef.value?.unsubscribe();
|
|
if (value.length !== 0) {
|
|
setTimeout(() => {
|
|
subscribeProperty(value);
|
|
value.forEach((item: any) => {
|
|
item?.accessModes?.forEach((i: any) => {
|
|
if (i?.value === 'read') {
|
|
ReadIdMap.set(item.id, item);
|
|
}
|
|
});
|
|
});
|
|
}, 100);
|
|
}
|
|
cancelSelect();
|
|
checkAll.value = false;
|
|
},
|
|
);
|
|
watch(
|
|
() => _selectedRowKeys.value,
|
|
(value) => {
|
|
if (value.length === 0) {
|
|
checkAll.value = false;
|
|
}
|
|
},
|
|
);
|
|
|
|
watch(
|
|
() => props.data,
|
|
(value) => {
|
|
if (!!value) {
|
|
accessModesOption.value =
|
|
value?.provider === 'MODBUS_TCP'
|
|
? accessModesMODBUS_TCP
|
|
: accessModesMODBUS_TCP.concat({
|
|
label: '订阅',
|
|
value: 'subscribe',
|
|
});
|
|
defaultParams.value.terms[0].terms[0].value = !value.id
|
|
? 'undefined'
|
|
: value.id === '*'
|
|
? undefined
|
|
: value.id;
|
|
tableRef?.value?.reload && tableRef?.value?.reload();
|
|
// cancelSelect();
|
|
checkAll.value = false;
|
|
batchRef.value?.reload();
|
|
batchActions.value =
|
|
props?.data?.provider === 'OPC_UA' ||
|
|
props?.data?.provider === 'BACNetIp'
|
|
? [
|
|
{
|
|
key: 'update',
|
|
text: '批量编辑',
|
|
permission: 'DataCollect/Collector:update',
|
|
icon: 'FormOutlined',
|
|
selected: {
|
|
onClick: handleBatchUpdate,
|
|
},
|
|
},
|
|
{
|
|
key: 'delete',
|
|
text: '批量删除',
|
|
danger: true,
|
|
permission: 'DataCollect/Collector:delete',
|
|
icon: 'DeleteOutlined',
|
|
selected: {
|
|
popConfirm: {
|
|
title: '确认删除?',
|
|
onConfirm: handleBatchDelete,
|
|
},
|
|
},
|
|
},
|
|
]
|
|
: [
|
|
{
|
|
key: 'delete',
|
|
text: '批量删除',
|
|
danger: true,
|
|
permission: 'DataCollect/Collector:delete',
|
|
icon: 'DeleteOutlined',
|
|
selected: {
|
|
popConfirm: {
|
|
title: '确认删除?',
|
|
onConfirm: handleBatchDelete,
|
|
},
|
|
},
|
|
},
|
|
];
|
|
}
|
|
},
|
|
{ immediate: true, deep: true },
|
|
);
|
|
|
|
onUnmounted(() => {
|
|
subRef.value?.unsubscribe();
|
|
});
|
|
|
|
/**
|
|
* 搜索
|
|
* @param params
|
|
*/
|
|
const handleSearch = (e: any) => {
|
|
params.value = e;
|
|
};
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.card-box {
|
|
// min-width: 480px;
|
|
a {
|
|
color: #474747;
|
|
z-index: 1;
|
|
}
|
|
a:hover {
|
|
color: #315efb;
|
|
z-index: 1;
|
|
}
|
|
.card-box-title {
|
|
font-size: 18px;
|
|
color: #474747;
|
|
}
|
|
.card-box-action {
|
|
width: 90px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: -10px;
|
|
}
|
|
.card-box-content {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
.card-box-content-left {
|
|
max-width: 220px;
|
|
border-right: 1px solid #e0e4e8;
|
|
height: 68px;
|
|
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;
|
|
}
|
|
}
|
|
a {
|
|
margin-left: 10px;
|
|
}
|
|
}
|
|
.card-box-content-right {
|
|
flex: 0.8;
|
|
margin-left: 20px;
|
|
.card-box-content-right-1 {
|
|
span {
|
|
margin: 0 5px 0 0;
|
|
}
|
|
}
|
|
.card-box-content-right-2 {
|
|
span {
|
|
margin: 0 5px 0 0;
|
|
padding: 3px 12px;
|
|
background: #f3f3f3;
|
|
color: #616161;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|