iot-ui-vue/src/views/device/Product/Detail/MetadataMap/index.vue

225 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class='metadata-map'>
<div class='left'>
<j-input-search
style='width: 350px;margin-bottom:24px;'
placeholder='搜索平台属性名称'
@search='search'
/>
<j-table
:columns="columns"
:data-source="dataSource"
:pagination='false'
:rowSelection='{
selectedRowKeys: selectedKeys,
hideSelectAll: true,
columnWidth: 0
}'
rowKey='id'
>
<template #bodyCell="{ column, text, record }">
<template v-if='column.dataIndex === "name"'>
<span class='metadata-title'>{{ text }} ({{ record.id }})</span>
</template>
<template v-if='column.dataIndex === "plugin"'>
<j-select
v-model:value='record.plugin'
style='width: 100%'
@change='(id) => pluginChange(record, id)'
>
<j-select-option
v-for='(item, index) in pluginOptions'
:key='index + "_" + item.id'
:value='item.value'
:disabled='selectedPluginKeys.includes(item.id)'
>{{ item.label }} ({{ item.id }})</j-select-option>
</j-select>
</template>
</template>
</j-table>
</div>
<div class='right'>
<div class='title'>
功能说明
</div>
<p>
该功能用于将插件中的
<b>物模型属性标识</b>
<b>平台物模型属性标识</b>进行映射,当两方属性标识不一致时可在当前页面直接修改映射管理系统将以映射后的物模型属性进行数据处理
</p>
<p>
未完成映射的属性标识目标属性列数据为空代表该属性值来源以在平台配置的来源为准
</p>
<p>
数据条背景亮起代表<b>标识一致</b><b>已完成映射</b>的属性
</p>
<div class='title'>
功能图示
</div>
<div>
<img :src='getImage("/device/matadataMap.png")' />
</div>
</div>
</div>
</template>
<script setup lang='ts' name='MetadataMap'>
import { storeToRefs } from 'pinia'
import { useProductStore } from '@/store/product';
import { detail as queryPluginAccessDetail } from '@/api/link/accessConfig'
import { getPluginData, getProductByPluginId } from '@/api/link/plugin'
import { getImage, onlyMessage } from '@/utils/comm'
import { getMetadateMapById, metadateMapById } from '@/api/device/instance'
const productStore = useProductStore();
const { current: productDetail } = storeToRefs(productStore)
const dataSource = ref([])
const pluginOptions = ref<any[]>([])
const tableFilter = (value: string, record: any) => {
console.log(value, record)
return true
}
const columns = [
{
title: '序号',
dataIndex: 'index',
width: 120
},
{
title: '平台属性',
dataIndex: 'name',
},
{
title: '目标属性',
dataIndex: 'plugin',
filters: [
{ text: '置顶已映射数据', value: 'already' },
{ text: '置顶未映射数据', value: 'not' },
],
onFilter: tableFilter
}
]
const selectedKeys = computed(() => {
return dataSource.value.filter(item => !!item?.plugin).map(item => item.id)
})
const selectedPluginKeys = computed(() => {
return dataSource.value.filter(item => !!item?.plugin).map(item => item.plugin)
})
const getMetadataMapData = () => {
return new Promise(resolve => {
getMetadateMapById(productDetail.value?.id).then(res => {
if (res.success) {
resolve(res.result?.filter(item => item.customMapping)?.map(item => {
return {
id: item.metadataId,
pluginId: item.originalId
}
}) || [])
}
})
})
}
const getDefaultMetadata = async () => {
const metadata = JSON.parse(productDetail.value?.metadata || '{}')
const properties = metadata.properties
const pluginMedata = await getPluginMetadata()
const pluginProperties = pluginMedata?.properties || []
const metadataMap = await getMetadataMapData()
pluginOptions.value = pluginProperties.map(item => ({...item, label: item.name, value: item.id}))
const concatProperties = [ ...pluginProperties.map(item => ({ id: item.id, pluginId: item.id})), ...metadataMap]
dataSource.value = properties?.map((item: any, index: number) => {
const _m = concatProperties.find(p => p.id === item.id)
return {
index: index + 1,
id: item.id, // 产品物模型id
name: item.name,
type: item.valueType?.type,
plugin: _m?.pluginId, // 插件物模型id
}
})
}
const getPluginMetadata = (): Promise<{ properties: any[]}> => {
return new Promise(resolve => {
queryPluginAccessDetail(productDetail.value?.accessId!).then(async res => {
if (res.success) {
const _channelId = (res.result as any)!.channelId
const pluginRes = await getPluginData('product', _channelId, productDetail.value?.id).catch(() => ({ success: false, result: {}}))
const resp = await getProductByPluginId(_channelId).catch(() => ({ success: false, result: []}))
if (resp.success) {
const _item = (resp.result as any[])?.find((item: any) => item.id === (pluginRes?.result as any)?.externalId)
resolve(_item ? _item.metadata : { properties: [] })
}
}
resolve({ properties: [] })
})
})
}
const pluginChange = async (value: any, id: string) => {
const res = await metadateMapById(productDetail.value?.id, [{
metadataType: 'property',
metadataId: value.id,
originalId: id
}])
if (res.success) {
onlyMessage('操作成功')
}
}
getDefaultMetadata()
</script>
<style scoped lang='less'>
.metadata-map {
position: relative;
min-height: 100%;
.left {
margin-right: 424px;
}
.right {
position: absolute;
border: 1px solid rgba(0, 0, 0, 0.08);
height: 100%;
width: 400px;
top: 0;
right: 0;
padding: 16px;
.title {
margin-bottom: 16px;
color: rgba(#000, .85);
font-weight: bold;
p {
initial-letter: 28px;
color: #666666;
}
}
}
.metadata-title {
color: #666666;
}
:deep(.ant-table-selection-column) {
padding: 0;
label {
display: none;
}
}
}
</style>