fix: 修改bug

This commit is contained in:
100011797 2023-07-05 18:29:24 +08:00
parent 6651e75930
commit be0aeb9a0a
8 changed files with 557 additions and 380 deletions

View File

@ -35,10 +35,11 @@
<div class='info-body'> <div class='info-body'>
<img <img
:src=" :src="
iconMap.get( bindUser?.avatar ||
bindUser?.applicationProvider, iconMap.get(
) || getImage('/apply/internal-standalone.png') bindUser?.applicationProvider,
" ) || getImage('/apply/internal-standalone.png')
"
/> />
<p>账号{{ bindUser?.result?.userId || '-' }}</p> <p>账号{{ bindUser?.result?.userId || '-' }}</p>
<p>用户名{{ bindUser?.result?.name || '-' }}</p> <p>用户名{{ bindUser?.result?.name || '-' }}</p>
@ -62,7 +63,7 @@
:src="getImage('/bind/Vector.png')" :src="getImage('/bind/Vector.png')"
/> />
<img <img
:src='iconMap.get(bindUser?.applicationProvider)' :src='bindUser?.avatar || iconMap.get(bindUser?.applicationProvider)'
/> />
</div> </div>
<div class='desc'> <div class='desc'>

View File

@ -128,10 +128,13 @@ onMounted(() => {
} }
.content-item-right { .content-item-right {
button:hover { :deep(button) {
background-color: @primary-color; &:hover {
color: #fff; background-color: @primary-color;
color: #fff;
}
} }
} }
} }
} }

View File

@ -0,0 +1,81 @@
<template>
<ResizeObserver @resize="onResize">
<div class="tag-box" ref="box">
<div v-for="(item, i) in value" :key="item.id" ref="tags">
<div v-if="i != _index" class="tag">
{{ item.name }}
</div>
<div
v-else
class="tag-ellipsis"
:style="
i === _index
? {
width: `${offWidth}px`,
}
: {}
"
>
{{ item.name }}
</div>
</div>
</div>
</ResizeObserver>
</template>
<script lang="ts" setup>
import { default as ResizeObserver } from 'ant-design-vue/lib/vc-resize-observer';
const props = defineProps({
value: {
type: Array,
default: () => [],
},
});
const tags = ref<any>([]);
const box = ref<any>(null);
const _index = ref<number>(-1);
const offWidth = ref<number>(0);
const onResize = ({ width }: { width: number }) => {
let total = 0;
for (let i = 0; i < tags.value.length; i++) {
const item = tags.value[i];
total += item?.scrollWidth || 0;
const val = item?.offsetWidth - (total - width);
if (total >= width) {
_index.value = i;
offWidth.value = val;
break;
}
}
};
</script>
<style lang="less" scoped>
.tag-box {
margin-top: 15px;
display: flex;
width: 100%;
overflow: hidden;
.tag {
background-color: #f7f8fa;
border-radius: 32px;
margin-right: 8px;
padding: 0 14px;
color: #333333;
white-space: nowrap;
}
.tag-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-color: #f7f8fa;
border-radius: 32px;
margin-right: 8px;
padding: 0 14px;
color: #333333;
}
}
</style>

View File

@ -16,25 +16,12 @@
</div> </div>
<div class="person-header-item-info-right"> <div class="person-header-item-info-right">
<div class="person-header-item-info-right-top"> <div class="person-header-item-info-right-top">
Hi, {{ user.userInfos?.name }} <j-ellipsis>
Hi, {{ user.userInfos?.name }}
</j-ellipsis>
</div> </div>
<div class="person-header-item-info-right-info"> <div class="person-header-item-info-right-info">
<!-- <div class="tag-box"> <RoleShow :value="user.userInfos?.roleList || []" />
<div
v-for="i in user.userInfos?.orgList || []"
:key="i?.id"
class="tag"
>{{ i?.name }}</div
>
</div> -->
<div class="tag-box">
<div
v-for="i in user.userInfos?.roleList || []"
:key="i?.id"
class="tag"
><j-ellipsis>{{ i?.name }}</j-ellipsis></div
>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -105,6 +92,7 @@ import {
USER_CENTER_MENU_CODE, USER_CENTER_MENU_CODE,
} from '@/utils/consts'; } from '@/utils/consts';
import { usePermissionStore } from '@/store/permission'; import { usePermissionStore } from '@/store/permission';
import RoleShow from './components/RoleShow/index.vue';
const imageTypes = reactive([ const imageTypes = reactive([
'image/jpeg', 'image/jpeg',
@ -204,6 +192,7 @@ onUnmounted(() => {
height: 100%; height: 100%;
.person-header-item-info { .person-header-item-info {
display: flex; display: flex;
width: calc(100% - 380px);
.person-header-item-info-left { .person-header-item-info-left {
margin-right: 30px; margin-right: 30px;
} }
@ -211,25 +200,16 @@ onUnmounted(() => {
.person-header-item-info-right { .person-header-item-info-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: calc(100% - 126px);
.person-header-item-info-right-top { .person-header-item-info-right-top {
display: flex; display: flex;
font-size: 26px; font-size: 26px;
color: #1d2129; color: #1d2129;
font-weight: 500; font-weight: 500;
width: 100%;
} }
.person-header-item-info-right-info { .person-header-item-info-right-info {
.tag-box { width: 100%;
margin-top: 15px;
display: flex;
.tag {
background-color: #F7F8FA;
border-radius: 32px;
margin-right: 8px;
padding: 0 14px;
color: #333333;
}
}
} }
} }
} }

View File

@ -7,94 +7,103 @@
allowClear allowClear
@search="search" @search="search"
/> />
<j-table <div class="box">
:columns="columns" <j-scrollbar height="100%">
:data-source="dataSource" <j-table
:pagination="false" :columns="columns"
:rowSelection="{ :data-source="dataSource"
selectedRowKeys: selectedKeys, :pagination="false"
hideSelectAll: true, :rowSelection="{
columnWidth: 0, selectedRowKeys: selectedKeys,
}" hideSelectAll: true,
rowKey="id" columnWidth: 0,
> }"
<template #headerCell="{ column }"> rowKey="id"
<template v-if="column.dataIndex === 'original'"> :customRow="customRow"
<div >
style=" <template #headerCell="{ column }">
width: 100%; <template v-if="column.dataIndex === 'original'">
display: flex; <div
justify-content: space-between; style="
align-items: center; width: 100%;
" display: flex;
> justify-content: space-between;
<span> align-items: center;
目标属性<j-tooltip "
title="协议包中物模型下的属性"
> >
<AIcon <span>
style="margin-left: 10px" 目标属性<j-tooltip
type="QuestionCircleOutlined" title="协议包中物模型下的属性"
/>
</j-tooltip>
</span>
<j-tag
v-if="filterValue !== undefined"
color="#87d068"
closable
@close="onClose"
><AIcon type="ArrowUpOutlined" /><span>{{
filterValue ? '已映射' : '未映射'
}}</span></j-tag
>
<j-dropdown v-else>
<AIcon type="FilterOutlined" />
<template #overlay>
<j-menu @click="onFilter">
<j-menu-item :key="true"
>置顶已映射数据</j-menu-item
> >
<j-menu-item :key="false" <AIcon
>置顶未映射数据</j-menu-item style="margin-left: 10px"
> type="QuestionCircleOutlined"
</j-menu> />
</template> </j-tooltip>
</j-dropdown> </span>
</div> <j-tag
</template> v-if="filterValue !== undefined"
</template> color="#87d068"
<template #bodyCell="{ column, text, record }"> closable
<template v-if="column.dataIndex === 'name'"> @close="onClose"
<span class="metadata-title"> ><AIcon
<j-ellipsis> type="ArrowUpOutlined"
{{ text }} ({{ record.id }}) /><span>{{
</j-ellipsis> filterValue ? '已映射' : '未映射'
</span> }}</span></j-tag
</template> >
<template v-if="column.dataIndex === 'original'"> <j-dropdown v-else>
<j-select <AIcon type="FilterOutlined" />
v-model:value="record.original" <template #overlay>
style="width: 100%" <j-menu @click="onFilter">
allowClear <j-menu-item :key="true"
@change="(id) => onChange(record, id)" >置顶已映射数据</j-menu-item
placeholder="请选择" >
> <j-menu-item :key="false"
<j-select-option >置顶未映射数据</j-menu-item
v-for="(item, index) in targetOptions" >
:key="index + '_' + item.id" </j-menu>
:value="item.value" </template>
:disabled=" </j-dropdown>
selectedOriginalKeys.includes(item.id) </div>
" </template>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'name'">
<span class="metadata-title" ref="title">
<j-ellipsis>
{{ text }} ({{ record.id }})
</j-ellipsis>
</span>
</template>
<template v-if="column.dataIndex === 'original'">
<j-select
v-model:value="record.original"
style="width: 100%"
allowClear
@change="(id) => onChange(record, id)"
placeholder="请选择"
> >
{{ item.label }} ({{ <j-select-option
item.id v-for="(item, index) in targetOptions"
}})</j-select-option :key="index + '_' + item.id"
> :value="item.value"
</j-select> :disabled="
</template> selectedOriginalKeys.includes(
</template> item.id,
</j-table> )
"
>
{{ item.label }} ({{
item.id
}})</j-select-option
>
</j-select>
</template>
</template>
</j-table>
</j-scrollbar>
</div>
</div> </div>
<div class="right"> <div class="right">
<j-scrollbar> <j-scrollbar>
@ -140,6 +149,8 @@ const targetOptions = ref<any[]>([]);
const filterValue = ref<boolean | undefined>(undefined); const filterValue = ref<boolean | undefined>(undefined);
const originalData = ref([]); const originalData = ref([]);
const _value = ref<any>(undefined);
const columns = [ const columns = [
{ {
title: '序号', title: '序号',
@ -198,13 +209,22 @@ const getMetadataMapData = () => {
}); });
}; };
const customRow = (record: any) => {
return {
id: record.id,
class: _value.value === record.name ? 'metadata-search-row' : '',
};
};
const search = (value: string) => { const search = (value: string) => {
if (value) { if (value) {
dataSource.value = dataSourceCache.value.filter((item: any) => { const _item: any = dataSourceCache.value.find((item: any) => {
return !!item.name?.includes(value); return value === item.name;
}); });
_value.value = _item.name;
document.getElementById(_item?.id)?.scrollIntoView(); //
} else { } else {
dataSource.value = dataSourceCache.value; _value.value = undefined;
} }
}; };
@ -276,7 +296,7 @@ const onChange = async (value: any, id: string) => {
}; };
const onFilter = ({ key }: any) => { const onFilter = ({ key }: any) => {
originalData.value = dataSource.value originalData.value = dataSource.value;
const _dataSource = cloneDeep(dataSource.value).sort((a: any, b: any) => { const _dataSource = cloneDeep(dataSource.value).sort((a: any, b: any) => {
if (!key) { if (!key) {
return (a.original ? 1 : -1) - (b.original ? 1 : -1); return (a.original ? 1 : -1) - (b.original ? 1 : -1);
@ -301,14 +321,24 @@ onMounted(() => {
<style scoped lang='less'> <style scoped lang='less'>
.metadata-map { .metadata-map {
// position: relative;
min-height: 100%; min-height: 100%;
display: flex; display: flex;
gap: 24px; gap: 24px;
.left { .left {
// margin-right: 44px;
flex: 1; flex: 1;
height: 100%;
.box {
height: calc(100vh - 388px);
overflow: hidden;
:deep(.metadata-search-row) {
td {
background: #ffff80 !important;
}
}
}
} }
.right { .right {

View File

@ -1,137 +1,152 @@
<template> <template>
<div class='metadata-map'> <div class="metadata-map">
<div class='left'> <div class="left">
<j-input-search <j-input-search
style='width: 350px;margin-bottom:24px;' style="width: 350px; margin-bottom: 24px"
placeholder='搜索平台属性名称' placeholder="搜索平台属性名称"
allowClear allowClear
@search='search' @search="search"
/> />
<j-table <div class="box">
:columns="columns" <j-scrollbar height="100%">
:data-source="dataSource" <j-table
:pagination='false' :columns="columns"
:rowSelection='{ :data-source="dataSource"
selectedRowKeys: selectedKeys, :pagination="false"
hideSelectAll: true, :rowSelection="{
columnWidth: 0 selectedRowKeys: selectedKeys,
}' hideSelectAll: true,
rowKey='id' columnWidth: 0,
> }"
<template #headerCell="{ column }"> rowKey="id"
<template v-if="column.dataIndex === 'plugin'"> :customRow="customRow"
<div >
style=" <template #headerCell="{ column }">
width: 100%; <template v-if="column.dataIndex === 'plugin'">
display: flex; <div
justify-content: space-between; style="
align-items: center; width: 100%;
" display: flex;
> justify-content: space-between;
<span> align-items: center;
目标属性<j-tooltip title="插件中物模型下的属性"> "
<AIcon >
style="margin-left: 10px" <span>
type="QuestionCircleOutlined" 目标属性<j-tooltip
/> title="插件中物模型下的属性"
</j-tooltip> >
</span> <AIcon
<j-tag style="margin-left: 10px"
v-if="filterValue !== undefined" type="QuestionCircleOutlined"
color="#87d068" />
closable </j-tooltip>
@close="onClose" </span>
><AIcon type="ArrowUpOutlined" /><span>{{ <j-tag
filterValue ? '已映射' : '未映射' v-if="filterValue !== undefined"
}}</span></j-tag color="#87d068"
> closable
<j-dropdown v-else> @close="onClose"
<AIcon type="FilterOutlined" /> ><AIcon
<template #overlay> type="ArrowUpOutlined"
<j-menu @click="onFilter"> /><span>{{
<j-menu-item :key="true" filterValue ? '已映射' : '未映射'
>置顶已映射数据</j-menu-item }}</span></j-tag
> >
<j-menu-item :key="false" <j-dropdown v-else>
>置顶未映射数据</j-menu-item <AIcon type="FilterOutlined" />
> <template #overlay>
</j-menu> <j-menu @click="onFilter">
</template> <j-menu-item :key="true"
</j-dropdown> >置顶已映射数据</j-menu-item
</div> >
</template> <j-menu-item :key="false"
</template> >置顶未映射数据</j-menu-item
<template #bodyCell="{ column, text, record }"> >
<template v-if='column.dataIndex === "name"'> </j-menu>
<span class='metadata-title'> </template>
<j-ellipsis> </j-dropdown>
{{ text }} ({{ record.id }}) </div>
</j-ellipsis> </template>
</span> </template>
</template> <template #bodyCell="{ column, text, record }">
<template v-if='column.dataIndex === "plugin"'> <template v-if="column.dataIndex === 'name'">
<j-select <span class="metadata-title">
v-model:value='record.plugin' <j-ellipsis>
style='width: 100%' {{ text }} ({{ record.id }})
allowClear </j-ellipsis>
@change='(id) => pluginChange(record, id)' </span>
> </template>
<j-select-option <template v-if="column.dataIndex === 'plugin'">
v-for='(item, index) in pluginOptions' <j-select
:key='index + "_" + item.id' v-model:value="record.plugin"
:value='item.value' style="width: 100%"
:disabled='selectedPluginKeys.includes(item.id)' allowClear
><j-tooltip :title="selectedPluginKeys.includes(item.id) ? '该属性已绑定平台属性' : ''"> @change="(id) => pluginChange(record, id)"
{{ item.label }} ({{ >
item.id <j-select-option
}}) v-for="(item, index) in pluginOptions"
</j-tooltip></j-select-option> :key="index + '_' + item.id"
</j-select> :value="item.value"
</template> :disabled="
</template> selectedPluginKeys.includes(item.id)
</j-table> "
><j-tooltip
:title="
selectedPluginKeys.includes(
item.id,
)
? '该属性已绑定平台属性'
: ''
"
>
{{ item.label }} ({{ item.id }})
</j-tooltip></j-select-option
>
</j-select>
</template>
</template>
</j-table>
</j-scrollbar>
</div>
</div>
<div class="right">
<j-scrollbar>
<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>
</j-scrollbar>
</div>
</div> </div>
<div class='right'>
<j-scrollbar>
<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>
</j-scrollbar>
</div>
</div>
</template> </template>
<script setup lang='ts' name='MetadataMap'> <script setup lang='ts' name='MetadataMap'>
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia';
import { useProductStore } from '@/store/product'; import { useProductStore } from '@/store/product';
import { detail as queryPluginAccessDetail } from '@/api/link/accessConfig' import { detail as queryPluginAccessDetail } from '@/api/link/accessConfig';
import { getPluginData, getProductByPluginId } from '@/api/link/plugin' import { getPluginData, getProductByPluginId } from '@/api/link/plugin';
import { getImage, onlyMessage } from '@/utils/comm' import { getImage, onlyMessage } from '@/utils/comm';
import { getMetadataMapById, metadataMapById } from '@/api/device/instance' import { getMetadataMapById, metadataMapById } from '@/api/device/instance';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
const productStore = useProductStore(); const productStore = useProductStore();
const { current: productDetail } = storeToRefs(productStore) const { current: productDetail } = storeToRefs(productStore);
const dataSourceCache = ref([]) const dataSourceCache = ref([]);
const dataSource = ref([]) const dataSource = ref([]);
const pluginOptions = ref<any[]>([]) const pluginOptions = ref<any[]>([]);
const filterValue = ref<boolean | undefined>(undefined); const filterValue = ref<boolean | undefined>(undefined);
const originalData = ref([]); const originalData = ref([]);
@ -141,66 +156,103 @@ const originalData = ref([]);
// } // }
const columns = [ const columns = [
{ {
title: '序号', title: '序号',
dataIndex: 'index', dataIndex: 'index',
width: 100 width: 100,
}, },
{ {
title: '平台属性', title: '平台属性',
dataIndex: 'name', dataIndex: 'name',
}, },
{ {
title: '目标属性', title: '目标属性',
dataIndex: 'plugin', dataIndex: 'plugin',
width: 250, width: 250,
// sorter: tableFilter // sorter: tableFilter
} },
] ];
const _value = ref<any>(undefined);
const selectedKeys = computed(() => { const selectedKeys = computed(() => {
return dataSource.value?.filter(item => !!item?.plugin).map(item => item.id) || [] return (
}) dataSource.value
?.filter((item) => !!item?.plugin)
.map((item) => item.id) || []
);
});
const selectedPluginKeys = computed(() => { const selectedPluginKeys = computed(() => {
return dataSource.value?.filter(item => !!item?.plugin).map(item => item.plugin) || [] return (
}) dataSource.value
?.filter((item) => !!item?.plugin)
.map((item) => item.plugin) || []
);
});
const getMetadataMapData = () => { const getMetadataMapData = () => {
return new Promise(resolve => { return new Promise((resolve) => {
getMetadataMapById('product', productDetail.value?.id).then(res => { getMetadataMapById('product', productDetail.value?.id).then((res) => {
if (res.success) { if (res.success) {
resolve(res.result?.filter(item => item.customMapping)?.map(item => { resolve(
return { res.result
id: item.metadataId, ?.filter((item) => item.customMapping)
pluginId: item.originalId ?.map((item) => {
} return {
}) || []) id: item.metadataId,
} pluginId: item.originalId,
}) };
}) }) || [],
} );
}
});
});
};
// const search = (value: string) => {
// if (value) {
// dataSource.value = dataSourceCache.value.filter((item: any) => {
// return !!item.name?.includes(value)
// })
// } else {
// dataSource.value = dataSourceCache.value
// }
// }
const customRow = (record: any) => {
return {
id: record.id,
class: _value.value === record.name ? 'metadata-search-row' : '',
};
};
const search = (value: string) => { const search = (value: string) => {
if (value) { if (value) {
dataSource.value = dataSourceCache.value.filter((item: any) => { const _item: any = dataSourceCache.value.find((item: any) => {
return !!item.name?.includes(value) return value === item.name;
}) });
} else { _value.value = _item.name;
dataSource.value = dataSourceCache.value document.getElementById(_item?.id)?.scrollIntoView(); //
} } else {
} _value.value = undefined;
}
};
const getDefaultMetadata = async () => { const getDefaultMetadata = async () => {
const metadata = JSON.parse(productDetail.value?.metadata || '{}') const metadata = JSON.parse(productDetail.value?.metadata || '{}');
const properties = metadata.properties const properties = metadata.properties;
const pluginMetadata = await getPluginMetadata() const pluginMetadata = await getPluginMetadata();
const pluginProperties = pluginMetadata?.properties || [] const pluginProperties = pluginMetadata?.properties || [];
const metadataMap: any = await getMetadataMapData() const metadataMap: any = await getMetadataMapData();
pluginOptions.value = pluginProperties.map(item => ({...item, label: item.name, value: item.id})) pluginOptions.value = pluginProperties.map((item) => ({
...item,
label: item.name,
value: item.id,
}));
// const concatProperties = [ ...pluginProperties.map(item => ({ id: item.id, pluginId: item.id})), ...metadataMap] // const concatProperties = [ ...pluginProperties.map(item => ({ id: item.id, pluginId: item.id})), ...metadataMap]
const concatProperties = [...metadataMap]; const concatProperties = [...metadataMap];
const arr = concatProperties.map((item) => item.id); const arr = concatProperties.map((item) => item.id);
const _arr = concatProperties.map((item) => item.pluginId); const _arr = concatProperties.map((item) => item.pluginId);
@ -211,50 +263,65 @@ const getDefaultMetadata = async () => {
} }
}); });
dataSource.value = properties?.map((item: any, index: number) => { dataSource.value =
const _m = concatProperties.find(p => p.id === item.id) properties?.map((item: any, index: number) => {
return { const _m = concatProperties.find((p) => p.id === item.id);
index: index + 1, return {
id: item.id, // id index: index + 1,
name: item.name, id: item.id, // id
type: item.valueType?.type, name: item.name,
plugin: _m?.pluginId, // id type: item.valueType?.type,
} plugin: _m?.pluginId, // id
}) || [] };
dataSourceCache.value = dataSource.value }) || [];
} dataSourceCache.value = dataSource.value;
};
const getPluginMetadata = (): Promise<{ properties: any[]}> => { const getPluginMetadata = (): Promise<{ properties: any[] }> => {
return new Promise(resolve => { return new Promise((resolve) => {
queryPluginAccessDetail(productDetail.value?.accessId!).then(async res => { queryPluginAccessDetail(productDetail.value?.accessId!).then(
if (res.success) { async (res) => {
const _channelId = (res.result as any)!.channelId if (res.success) {
const pluginRes = await getPluginData('product', productDetail.value?.accessId || '', productDetail.value?.id).catch(() => ({ success: false, result: {}})) const _channelId = (res.result as any)!.channelId;
const resp = await getProductByPluginId(_channelId).catch(() => ({ success: false, result: []})) const pluginRes = await getPluginData(
if (resp.success) { 'product',
const _item = (resp.result as any[])?.find((item: any) => item.id === (pluginRes?.result as any)?.externalId) productDetail.value?.accessId || '',
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(_item ? _item.metadata : { properties: [] });
} }
} }
resolve({ properties: [] }) resolve({ properties: [] });
}) },
}) );
} });
};
const pluginChange = async (value: any, id: string) => { const pluginChange = async (value: any, id: string) => {
const res = await metadataMapById('product', productDetail.value?.id, [{ const res = await metadataMapById('product', productDetail.value?.id, [
metadataType: 'property', {
metadataId: value.id, metadataType: 'property',
originalId: id metadataId: value.id,
}]) originalId: id,
if (res.success) { },
onlyMessage('操作成功') ]);
} if (res.success) {
} onlyMessage('操作成功');
}
};
const onFilter = ({ key }: any) => { const onFilter = ({ key }: any) => {
originalData.value = dataSource.value originalData.value = dataSource.value;
const _dataSource = cloneDeep(dataSource.value).sort((a: any, b: any) => { const _dataSource = cloneDeep(dataSource.value).sort((a: any, b: any) => {
if (!key) { if (!key) {
return (a.plugin ? 1 : -1) - (b.plugin ? 1 : -1); return (a.plugin ? 1 : -1) - (b.plugin ? 1 : -1);
@ -273,54 +340,64 @@ const onClose = () => {
}; };
onMounted(() => { onMounted(() => {
getDefaultMetadata() getDefaultMetadata();
}) });
</script> </script>
<style scoped lang='less'> <style scoped lang='less'>
.metadata-map { .metadata-map {
// position: relative; // position: relative;
min-height: 100%;
display: flex;
gap: 24px;
.left {
// margin-right: 44px;
flex: 1;
}
.right {
// position: absolute;
border: 1px solid rgba(0, 0, 0, 0.08);
min-height: 100%; min-height: 100%;
min-width: 410px; display: flex;
width: 33.33333%; gap: 24px;
// top: 0;
// right: 0;
padding: 16px;
.title { .left {
margin-bottom: 16px; // margin-right: 44px;
color: rgba(#000, .85); flex: 1;
font-weight: bold;
p { .box {
initial-letter: 28px; height: calc(100vh - 392px);
overflow: hidden;
:deep(.metadata-search-row) {
td {
background: #ffff80 !important;
}
}
}
}
.right {
// position: absolute;
border: 1px solid rgba(0, 0, 0, 0.08);
min-height: 100%;
min-width: 410px;
width: 33.33333%;
// top: 0;
// right: 0;
padding: 16px;
.title {
margin-bottom: 16px;
color: rgba(#000, 0.85);
font-weight: bold;
p {
initial-letter: 28px;
color: #666666;
}
}
}
.metadata-title {
color: #666666; color: #666666;
}
} }
}
.metadata-title { :deep(.ant-table-selection-column) {
color: #666666; padding: 0;
} label {
display: none;
:deep(.ant-table-selection-column) { }
padding: 0;
label {
display: none;
} }
}
} }
</style> </style>

View File

@ -429,7 +429,12 @@ const formRules = ref({
'configuration.host': [{ required: true, message: '请输入服务器地址', trigger: 'blur' }], 'configuration.host': [{ required: true, message: '请输入服务器地址', trigger: 'blur' }],
'configuration.sender': [ 'configuration.sender': [
{ required: true, message: '请输入发件人', trigger: 'blur' }, { required: true, message: '请输入发件人', trigger: 'blur' },
{ max: 64, message: '最多可输入64个字符' }, // { max: 64, message: '64' },
{
pattern:
/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
message: '请输入正确的邮箱',
},
], ],
'configuration.username': [ 'configuration.username': [
{ required: true, message: '请输入用户名', trigger: 'blur' }, { required: true, message: '请输入用户名', trigger: 'blur' },

View File

@ -71,7 +71,7 @@ const props = defineProps({
}, },
gridColumn: { gridColumn: {
type: Number, type: Number,
default: 2 default: 3
} }
}); });