225 lines
6.2 KiB
Vue
225 lines
6.2 KiB
Vue
<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> |