fix: 修改bug
This commit is contained in:
parent
6ff2f9ebad
commit
683d3e20e8
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
|
@ -580,9 +580,9 @@ export const getDeviceNumber = (data?:any) => server.post<number>('/device-insta
|
|||
*/
|
||||
export const importDeviceByPlugin = (productId: string, data: any[]) => server.post(`/device/instance/plugin/${productId}/import`, data)
|
||||
|
||||
export const metadateMapById = (type: 'device' | 'product', productId: string, data: any[]) => server.patch(`/device/metadata/mapping/${type}/${productId}`, data)
|
||||
export const metadataMapById = (type: 'device' | 'product', productId: string, data: any[]) => server.patch(`/device/metadata/mapping/${type}/${productId}`, data)
|
||||
|
||||
export const getMetadateMapById = (type: 'device' | 'product', productId: string) => server.get(`/device/metadata/mapping/${type}/${productId}`)
|
||||
export const getMetadataMapById = (type: 'device' | 'product', productId: string) => server.get(`/device/metadata/mapping/${type}/${productId}`)
|
||||
|
||||
export const getInkingDevices = (data: string[]) => server.post('/plugin/mapping/device/_all', data)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<j-modal
|
||||
title="图片编辑"
|
||||
:title="title"
|
||||
visible
|
||||
:width="400"
|
||||
@cancel="cancel"
|
||||
|
@ -29,6 +29,10 @@ import { fileUpload } from '@/api/comm';
|
|||
const props = defineProps({
|
||||
img: {
|
||||
type: String
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '图片编辑'
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ const beforeUpload = (file: UploadProps['fileList'][number]) => {
|
|||
const isSize = file.size / 1024 / 1024 < maxSize;
|
||||
if (!isSize) {
|
||||
message.error(`图片大小必须小于${maxSize}M`);
|
||||
return false
|
||||
}
|
||||
|
||||
getBase64(file, (base64Url) => {
|
||||
|
|
|
@ -133,6 +133,7 @@ const beforeUpload = (file: UploadProps['fileList'][number]) => {
|
|||
const isSize = file.size / 1024 / 1024 < maxSize;
|
||||
if (!isSize) {
|
||||
message.error(`图片大小必须小于${maxSize}M`);
|
||||
return false
|
||||
}
|
||||
|
||||
getBase64(file, (base64Url) => {
|
||||
|
|
|
@ -1,240 +1,291 @@
|
|||
<template>
|
||||
<div class='metadata-map'>
|
||||
<div class='left'>
|
||||
<j-input-search
|
||||
style='width: 350px;margin-bottom:24px;'
|
||||
placeholder='搜索平台属性名称'
|
||||
allowClear
|
||||
@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, index }">
|
||||
<template v-if='column.dataIndex === "name"'>
|
||||
<span class='metadata-title'>
|
||||
<j-ellipsis>
|
||||
{{ text }} ({{ record.id }})
|
||||
</j-ellipsis>
|
||||
</span>
|
||||
</template>
|
||||
<template v-if='column.dataIndex === "plugin"'>
|
||||
<j-select
|
||||
v-model:value='record.plugin'
|
||||
style='width: 100%'
|
||||
allowClear
|
||||
@change='(id) => pluginChange(record, id)'
|
||||
<div class="metadata-map">
|
||||
<div class="left">
|
||||
<j-input-search
|
||||
style="width: 350px; margin-bottom: 24px"
|
||||
placeholder="搜索平台属性名称"
|
||||
allowClear
|
||||
@search="search"
|
||||
/>
|
||||
<j-table
|
||||
:columns="columns"
|
||||
:data-source="dataSource"
|
||||
:pagination="false"
|
||||
:rowSelection="{
|
||||
selectedRowKeys: selectedKeys,
|
||||
hideSelectAll: true,
|
||||
columnWidth: 0,
|
||||
}"
|
||||
rowKey="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>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.dataIndex === 'original'">
|
||||
<span>
|
||||
目标属性<j-tooltip title="协议包中物模型下的属性">
|
||||
<AIcon
|
||||
style="margin-left: 10px"
|
||||
type="QuestionCircleOutlined"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, text, record }">
|
||||
<template v-if="column.dataIndex === 'name'">
|
||||
<span class="metadata-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="请选择"
|
||||
>
|
||||
<j-select-option
|
||||
v-for="(item, index) in targetOptions"
|
||||
:key="index + '_' + item.id"
|
||||
:value="item.value"
|
||||
:disabled="
|
||||
selectedOriginalKeys.includes(item.id)
|
||||
"
|
||||
>{{ item.label }} ({{
|
||||
item.id
|
||||
}})</j-select-option
|
||||
>
|
||||
</j-select>
|
||||
</template>
|
||||
</template>
|
||||
</j-table>
|
||||
</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.jpg')" />
|
||||
</div>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='MetadataMap'>
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { detail as queryPluginAccessDetail } from '@/api/link/accessConfig'
|
||||
// import { getPluginData, getProductByPluginId } from '@/api/link/plugin'
|
||||
import { getImage, onlyMessage } from '@/utils/comm'
|
||||
import { getMetadateMapById, metadateMapById, getProtocolMetadata } from '@/api/device/instance'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getImage, onlyMessage } from '@/utils/comm';
|
||||
import {
|
||||
getMetadataMapById,
|
||||
metadataMapById,
|
||||
getProtocolMetadata,
|
||||
} from '@/api/device/instance';
|
||||
import { useInstanceStore } from '@/store/instance';
|
||||
|
||||
const deviceStore = useInstanceStore()
|
||||
const { current: deviceDetail } = storeToRefs(deviceStore)
|
||||
const dataSourceCache = ref([])
|
||||
const dataSource = ref([])
|
||||
const pluginOptions = ref<any[]>([])
|
||||
const deviceStore = useInstanceStore();
|
||||
const { current: deviceDetail } = storeToRefs(deviceStore);
|
||||
const dataSourceCache = ref([]);
|
||||
const dataSource = ref([]);
|
||||
const targetOptions = ref<any[]>([]);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '平台属性',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '目标属性',
|
||||
dataIndex: 'plugin',
|
||||
width: 250,
|
||||
sorter: {
|
||||
compare: (a, b) => (a.plugin?.length || 0) - (b.plugin?.length || 0)
|
||||
}
|
||||
}
|
||||
]
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '平台属性',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '目标属性',
|
||||
dataIndex: 'original',
|
||||
width: 250,
|
||||
sorter: {
|
||||
compare: (a, b) =>
|
||||
(a.original?.length || 0) - (b.original?.length || 0),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const selectedKeys = computed(() => {
|
||||
return dataSource.value?.filter((item: any) => !!item?.plugin).map((i: any) => i.id) || []
|
||||
})
|
||||
return (
|
||||
dataSource.value
|
||||
?.filter((item: any) => !!item?.original)
|
||||
.map((i: any) => i.id) || []
|
||||
);
|
||||
});
|
||||
|
||||
const selectedPluginKeys = computed(() => {
|
||||
return dataSource.value?.filter((item: any) => !!item?.plugin).map((i: any) => i.plugin) || []
|
||||
})
|
||||
const selectedOriginalKeys = computed(() => {
|
||||
return (
|
||||
dataSource.value
|
||||
?.filter((item: any) => !!item?.original)
|
||||
.map((i: any) => i.original) || []
|
||||
);
|
||||
});
|
||||
|
||||
const metadata = computed(() => {
|
||||
return JSON.parse(deviceDetail.value?.metadata || '{}')
|
||||
})
|
||||
return JSON.parse(deviceDetail.value?.metadata || '{}');
|
||||
});
|
||||
|
||||
const _id = deviceDetail.value?.id
|
||||
const _id = deviceDetail.value?.id;
|
||||
|
||||
const getMetadataMapData = () => {
|
||||
return new Promise(resolve => {
|
||||
getMetadateMapById('device', _id).then((res: any) => {
|
||||
if (res.success) {
|
||||
resolve(res.result?.filter((i: any) => i.customMapping)?.map((item: any) => {
|
||||
return {
|
||||
id: item.metadataId,
|
||||
pluginId: item.originalId
|
||||
}
|
||||
}) || [])
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
getMetadataMapById('device', _id).then((res: any) => {
|
||||
if (res.success) {
|
||||
resolve(
|
||||
res.result
|
||||
?.filter((i: any) => i.customMapping)
|
||||
?.map((item: any) => {
|
||||
return {
|
||||
id: item.metadataId,
|
||||
originalId: 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
|
||||
}
|
||||
}
|
||||
if (value) {
|
||||
dataSource.value = dataSourceCache.value.filter((item: any) => {
|
||||
return !!item.name?.includes(value);
|
||||
});
|
||||
} else {
|
||||
dataSource.value = dataSourceCache.value;
|
||||
}
|
||||
};
|
||||
|
||||
const getDefaultMetadata = async () => {
|
||||
const properties = metadata.value?.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 properties = metadata.value?.properties;
|
||||
const _metadata = await getMetadata();
|
||||
const _properties = _metadata?.properties || [];
|
||||
const metadataMap: any = await getMetadataMapData();
|
||||
|
||||
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
|
||||
targetOptions.value = _properties.map((item) => ({
|
||||
...item,
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
|
||||
const concatProperties = [...metadataMap];
|
||||
const arr = concatProperties.map((item) => item.id);
|
||||
const _arr = concatProperties.map((item) => item.originalId);
|
||||
|
||||
_properties.map((item) => {
|
||||
// 添加默认映射,但是该选项还没被其他属性映射
|
||||
if (!arr.includes(item.id) && !_arr.includes(item.id)) {
|
||||
concatProperties.push({ id: item.id, originalId: item.id });
|
||||
}
|
||||
});
|
||||
|
||||
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,
|
||||
original: _m?.originalId, // 协议包物模型id
|
||||
};
|
||||
}) || [];
|
||||
dataSourceCache.value = dataSource.value;
|
||||
};
|
||||
|
||||
const getMetadata = (): Promise<{ properties: any[] }> => {
|
||||
return new Promise((resolve) => {
|
||||
const transport = deviceDetail.value?.transport;
|
||||
getProtocolMetadata(deviceDetail.value?.protocol || '', transport).then(
|
||||
(res: any) => {
|
||||
if (res.success) {
|
||||
resolve(JSON.parse(res?.result || '{}'));
|
||||
}
|
||||
resolve({ properties: [] });
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const onChange = async (value: any, id: string) => {
|
||||
const res = await metadataMapById('device', _id, [
|
||||
{
|
||||
metadataType: 'property',
|
||||
metadataId: value.id,
|
||||
originalId: id || null,
|
||||
},
|
||||
]);
|
||||
if (res.success) {
|
||||
onlyMessage('操作成功');
|
||||
}
|
||||
}) || []
|
||||
dataSourceCache.value = dataSource.value
|
||||
}
|
||||
|
||||
const getPluginMetadata = (): Promise<{ properties: any[]}> => {
|
||||
return new Promise(resolve => {
|
||||
const transport = deviceDetail.value?.transport
|
||||
getProtocolMetadata(deviceDetail.value?.protocol || '', transport).then((res: any) => {
|
||||
if(res.success){
|
||||
resolve(JSON.parse(res?.result || '{}'))
|
||||
}
|
||||
resolve({ properties: [] })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const pluginChange = async (value: any, id: string) => {
|
||||
const res = await metadateMapById('device', _id, [{
|
||||
metadataType: 'property',
|
||||
metadataId: value.id,
|
||||
originalId: id || null
|
||||
}])
|
||||
if (res.success) {
|
||||
onlyMessage('操作成功')
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultMetadata()
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getDefaultMetadata();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
.metadata-map {
|
||||
// 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);
|
||||
// position: relative;
|
||||
min-height: 100%;
|
||||
min-width: 410px;
|
||||
width: 33.33333%;
|
||||
// top: 0;
|
||||
// right: 0;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
|
||||
.title {
|
||||
margin-bottom: 16px;
|
||||
color: rgba(#000, .85);
|
||||
font-weight: bold;
|
||||
.left {
|
||||
// margin-right: 44px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
p {
|
||||
initial-letter: 28px;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.metadata-title {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
:deep(.ant-table-selection-column) {
|
||||
padding: 0;
|
||||
label {
|
||||
display: none;
|
||||
:deep(.ant-table-selection-column) {
|
||||
padding: 0;
|
||||
label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -18,6 +18,18 @@
|
|||
}'
|
||||
rowKey='id'
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.dataIndex === 'plugin'">
|
||||
<span>
|
||||
目标属性<j-tooltip title="插件中物模型下的属性">
|
||||
<AIcon
|
||||
style="margin-left: 10px"
|
||||
type="QuestionCircleOutlined"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, text, record, index }">
|
||||
<template v-if='column.dataIndex === "name"'>
|
||||
<span class='metadata-title'>
|
||||
|
@ -77,7 +89,7 @@ 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'
|
||||
import { getMetadataMapById, metadataMapById } from '@/api/device/instance'
|
||||
|
||||
const productStore = useProductStore();
|
||||
const { current: productDetail } = storeToRefs(productStore)
|
||||
|
@ -86,7 +98,6 @@ const dataSource = ref([])
|
|||
const pluginOptions = ref<any[]>([])
|
||||
|
||||
const tableFilter = (value: string, record: any) => {
|
||||
console.log(value, record)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -118,7 +129,7 @@ const selectedPluginKeys = computed(() => {
|
|||
|
||||
const getMetadataMapData = () => {
|
||||
return new Promise(resolve => {
|
||||
getMetadateMapById('product', productDetail.value?.id).then(res => {
|
||||
getMetadataMapById('product', productDetail.value?.id).then(res => {
|
||||
if (res.success) {
|
||||
resolve(res.result?.filter(item => item.customMapping)?.map(item => {
|
||||
return {
|
||||
|
@ -144,12 +155,23 @@ const search = (value: string) => {
|
|||
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()
|
||||
const pluginMetadata = await getPluginMetadata()
|
||||
const pluginProperties = pluginMetadata?.properties || []
|
||||
const metadataMap: any = 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]
|
||||
// const concatProperties = [ ...pluginProperties.map(item => ({ id: item.id, pluginId: item.id})), ...metadataMap]
|
||||
const concatProperties = [...metadataMap];
|
||||
const arr = concatProperties.map((item) => item.id);
|
||||
const _arr = concatProperties.map((item) => item.pluginId);
|
||||
|
||||
pluginProperties.map((item) => {
|
||||
// 添加默认映射,但是该选项还没被其他属性映射
|
||||
if (!arr.includes(item.id) && !_arr.includes(item.id)) {
|
||||
concatProperties.push({ id: item.id, pluginId: item.id });
|
||||
}
|
||||
});
|
||||
|
||||
dataSource.value = properties?.map((item: any, index: number) => {
|
||||
const _m = concatProperties.find(p => p.id === item.id)
|
||||
return {
|
||||
|
@ -182,7 +204,7 @@ const getPluginMetadata = (): Promise<{ properties: any[]}> => {
|
|||
}
|
||||
|
||||
const pluginChange = async (value: any, id: string) => {
|
||||
const res = await metadateMapById('product', productDetail.value?.id, [{
|
||||
const res = await metadataMapById('product', productDetail.value?.id, [{
|
||||
metadataType: 'property',
|
||||
metadataId: value.id,
|
||||
originalId: id
|
||||
|
@ -192,7 +214,9 @@ const pluginChange = async (value: any, id: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
getDefaultMetadata()
|
||||
onMounted(() => {
|
||||
getDefaultMetadata()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
:img="cropperImg"
|
||||
@cancel="cropperVisible = false"
|
||||
@ok="saveImage"
|
||||
title="更换图片"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
@ -133,6 +134,7 @@ const beforeUpload = (file: UploadProps['fileList'][number]) => {
|
|||
const isSize = file.size / 1024 / 1024 < maxSize;
|
||||
if (!isSize) {
|
||||
message.error(`图片大小必须小于${maxSize}M`);
|
||||
return false
|
||||
}
|
||||
|
||||
getBase64(file, (base64Url) => {
|
||||
|
@ -166,7 +168,7 @@ const saveImage = (url: string) => {
|
|||
.upload-image-warp {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
|
||||
|
||||
.upload-image-border {
|
||||
position: relative;
|
||||
|
|
|
@ -1357,7 +1357,7 @@
|
|||
@click="
|
||||
clickAddItem(
|
||||
form.data.sso.orgIdList,
|
||||
'Role',
|
||||
'Department',
|
||||
)
|
||||
"
|
||||
class="add-item"
|
||||
|
@ -1709,9 +1709,12 @@ function getOrgIdList() {
|
|||
function clickAddItem(data: string[], target: string) {
|
||||
const tab: any = window.open(`${origin}/#/system/${target}?save=true`);
|
||||
tab.onTabSaveSuccess = (value: string) => {
|
||||
data.push(value);
|
||||
if (target === 'Role') getRoleIdList();
|
||||
else getOrgIdList();
|
||||
if (target === 'Role') {
|
||||
getRoleIdList();
|
||||
} else {
|
||||
getOrgIdList()
|
||||
}
|
||||
data.push(value)
|
||||
};
|
||||
}
|
||||
// 保存
|
||||
|
|
|
@ -1,110 +1,125 @@
|
|||
<template>
|
||||
<div class="child-item" :class="{ border: !isLast }">
|
||||
<div class="child-item-left">
|
||||
<div style="color: #333333">
|
||||
{{ data?.name }}
|
||||
<j-spin :spinning="spinning">
|
||||
<div class="child-item" :class="{ border: !isLast }">
|
||||
<div class="child-item-left">
|
||||
<div style="color: #333333">
|
||||
{{ data?.name }}
|
||||
</div>
|
||||
<div>
|
||||
<j-tooltip :title="!action ? '暂无权限,请联系管理员' : ''">
|
||||
<j-switch
|
||||
:disabled="!action"
|
||||
@change="onSwitchChange"
|
||||
:checked="checked"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<j-tooltip :title="!action ? '暂无权限,请联系管理员' : ''">
|
||||
<j-switch
|
||||
:disabled="!action"
|
||||
@change="onSwitchChange"
|
||||
:checked="checked"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="child-item-right" :class="{ disabled: !checked }">
|
||||
<MCarousel :data="data?.channels">
|
||||
<template #card="slotProps">
|
||||
<div class="box-item">
|
||||
<j-dropdown>
|
||||
<div class="box-item-img">
|
||||
<img
|
||||
style="width: 100%"
|
||||
:src="
|
||||
iconMap.get(slotProps?.channelProvider)
|
||||
<div class="child-item-right" :class="{ disabled: !checked }">
|
||||
<MCarousel :data="data?.channels">
|
||||
<template #card="slotProps">
|
||||
<div class="box-item">
|
||||
<j-dropdown>
|
||||
<div class="box-item-img">
|
||||
<img
|
||||
style="width: 100%"
|
||||
:src="
|
||||
iconMap.get(
|
||||
slotProps?.channelProvider,
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<template
|
||||
#overlay
|
||||
v-if="
|
||||
slotProps?.channelProvider !==
|
||||
'inside-mail'
|
||||
"
|
||||
/>
|
||||
>
|
||||
<j-menu mode="">
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onView(slotProps)"
|
||||
type="link"
|
||||
:hasPermission="true"
|
||||
>
|
||||
查看
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onEdit(slotProps)"
|
||||
type="link"
|
||||
:hasPermission="[
|
||||
'system/NoticeRule:update',
|
||||
]"
|
||||
>
|
||||
编辑
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onDelete(slotProps.id)"
|
||||
danger
|
||||
type="link"
|
||||
:hasPermission="[
|
||||
'system/NoticeRule:delete',
|
||||
]"
|
||||
>
|
||||
删除
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
<div class="box-item-text">
|
||||
{{ slotProps?.name }}
|
||||
</div>
|
||||
<template
|
||||
#overlay
|
||||
v-if="
|
||||
slotProps?.channelProvider !== 'inside-mail'
|
||||
"
|
||||
>
|
||||
<j-menu mode="">
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onView(slotProps)"
|
||||
type="link"
|
||||
:hasPermission="true"
|
||||
>
|
||||
查看
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onEdit(slotProps)"
|
||||
type="link"
|
||||
:hasPermission="[
|
||||
'system/NoticeRule:update',
|
||||
]"
|
||||
>
|
||||
编辑
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="onDelete(slotProps.id)"
|
||||
danger
|
||||
type="link"
|
||||
:hasPermission="[
|
||||
'system/NoticeRule:delete',
|
||||
]"
|
||||
>
|
||||
删除
|
||||
</PermissionButton>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
<div class="box-item-text">
|
||||
{{ slotProps?.name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MCarousel>
|
||||
</template>
|
||||
</MCarousel>
|
||||
|
||||
<div class="box-item-add">
|
||||
<div class="box-item-img">
|
||||
<j-tooltip :title="!add ? '暂无权限,请联系管理员' : ''">
|
||||
<j-button :disabled="!add" type="text" @click="onAdd">
|
||||
<AIcon
|
||||
style="font-size: 20px"
|
||||
type="PlusOutlined"
|
||||
/>
|
||||
<div class="box-item-add">
|
||||
<div class="box-item-img">
|
||||
<j-tooltip
|
||||
:title="!add ? '暂无权限,请联系管理员' : ''"
|
||||
>
|
||||
<j-button
|
||||
:disabled="!add"
|
||||
type="text"
|
||||
@click="onAdd"
|
||||
>
|
||||
<AIcon
|
||||
style="font-size: 20px"
|
||||
type="PlusOutlined"
|
||||
/>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
<div class="box-item-text"></div>
|
||||
</div>
|
||||
|
||||
<div class="child-item-right-auth">
|
||||
<j-tooltip :title="!update ? '暂无权限,请联系管理员' : ''">
|
||||
<j-button
|
||||
:disabled="!update"
|
||||
type="text"
|
||||
@click="onAuth"
|
||||
>
|
||||
<div
|
||||
class="child-item-right-auth-btn"
|
||||
:class="{ active: auth.length }"
|
||||
>
|
||||
<AIcon type="UserOutlined" />
|
||||
<span>权限控制</span>
|
||||
</div>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
<div class="box-item-text"></div>
|
||||
</div>
|
||||
|
||||
<div class="child-item-right-auth">
|
||||
<j-tooltip :title="!update ? '暂无权限,请联系管理员' : ''">
|
||||
<j-button :disabled="!update" type="text" @click="onAuth">
|
||||
<div
|
||||
class="child-item-right-auth-btn"
|
||||
:class="{ active: auth.length }"
|
||||
>
|
||||
<AIcon type="UserOutlined" />
|
||||
<span>权限控制</span>
|
||||
</div>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</j-spin>
|
||||
<Save
|
||||
:data="current"
|
||||
v-if="visible"
|
||||
|
@ -156,8 +171,8 @@ const props = defineProps({
|
|||
},
|
||||
provider: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['refresh']);
|
||||
|
@ -170,6 +185,7 @@ const current = ref<any>({});
|
|||
const checked = ref<boolean>(false);
|
||||
const auth = ref<string[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const spinning = ref<boolean>(false);
|
||||
|
||||
const permission = usePermissionStore();
|
||||
const user = useUserInfo();
|
||||
|
@ -220,16 +236,24 @@ const onAuthSave = (_data: string[]) => {
|
|||
role: {
|
||||
idList: _data || [],
|
||||
},
|
||||
permissions: props.provider === 'alarm' ? [{ id: 'alarm-config', actions: ['query'] }] : [],
|
||||
permissions:
|
||||
props.provider === 'alarm'
|
||||
? [{ id: 'alarm-config', actions: ['query'] }]
|
||||
: [],
|
||||
},
|
||||
};
|
||||
editChannelConfig(props.data.id, obj).then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!', 'success');
|
||||
authVisible.value = false;
|
||||
emits('refresh');
|
||||
}
|
||||
});
|
||||
spinning.value = true;
|
||||
editChannelConfig(props.data.id, obj)
|
||||
.then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!', 'success');
|
||||
authVisible.value = false;
|
||||
emits('refresh');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
spinning.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onAction = (e: boolean) => {
|
||||
|
@ -242,16 +266,35 @@ const onAction = (e: boolean) => {
|
|||
(item: any) => item.channelProvider === 'inside-mail',
|
||||
)
|
||||
) {
|
||||
actionChannelConfig(props.data.id, 'enable').then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!');
|
||||
emits('refresh');
|
||||
}
|
||||
});
|
||||
spinning.value = true;
|
||||
actionChannelConfig(props.data.id, 'enable')
|
||||
.then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!');
|
||||
emits('refresh');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
spinning.value = false;
|
||||
});
|
||||
} else {
|
||||
const obj = {
|
||||
...props.data,
|
||||
state: 'enabled',
|
||||
grant:
|
||||
!props.data.grant?.role && props.provider === 'alarm'
|
||||
? {
|
||||
role: {
|
||||
idList: [],
|
||||
},
|
||||
permissions: [
|
||||
{
|
||||
id: 'alarm-config',
|
||||
actions: ['query'],
|
||||
},
|
||||
],
|
||||
}
|
||||
: props.data.grant,
|
||||
channels: [
|
||||
{
|
||||
name: '站内信',
|
||||
|
@ -260,12 +303,17 @@ const onAction = (e: boolean) => {
|
|||
},
|
||||
],
|
||||
};
|
||||
saveChannelConfig([obj]).then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!', 'success');
|
||||
emits('refresh');
|
||||
}
|
||||
});
|
||||
spinning.value = true;
|
||||
saveChannelConfig([obj])
|
||||
.then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!', 'success');
|
||||
emits('refresh');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
spinning.value = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
actionChannelConfig(props.data.id, 'disable').then((resp) => {
|
||||
|
|
Loading…
Reference in New Issue