fix: 优化物模型-详情
This commit is contained in:
parent
7f75c05f79
commit
bb602aecd2
|
@ -11,11 +11,8 @@
|
|||
layout === 'horizontal'
|
||||
? 'm-radio-checked-item'
|
||||
: 'm-radio-item',
|
||||
{ active: myValue === item.value },
|
||||
checkStyle && myValue === item.value ? 'checked' : '',
|
||||
disabled && myValue === item.value
|
||||
? 'active-checked-disabled'
|
||||
: '',
|
||||
{ active: myValue === item.value },
|
||||
item.disabled ? 'disabled' : '',
|
||||
]"
|
||||
v-for="(item, index) in options"
|
||||
|
@ -100,9 +97,12 @@ const handleRadio = (item: any) => {
|
|||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
.disabled {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
border-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
>div {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
border-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
&-item {
|
||||
width: 49%;
|
||||
|
@ -152,14 +152,14 @@ const handleRadio = (item: any) => {
|
|||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: rgba(0, 0, 0, 0.25) !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.active-checked-disabled {
|
||||
color: rgba(0, 0, 0, 0.25) !important;
|
||||
border: 1px #d9d9d9 solid !important;
|
||||
}
|
||||
//.disabled {
|
||||
// color: rgba(0, 0, 0, 0.25) !important;
|
||||
// cursor: not-allowed;
|
||||
//}
|
||||
//.active-checked-disabled {
|
||||
// color: rgba(0, 0, 0, 0.25) !important;
|
||||
// border: 1px #d9d9d9 solid !important;
|
||||
//}
|
||||
.checked-icon-disabled {
|
||||
color: rgba(0, 0, 0, 0.25) !important;
|
||||
border-color: #e6e6e6 !important;
|
||||
|
@ -169,17 +169,25 @@ const handleRadio = (item: any) => {
|
|||
|
||||
.m-radio {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
&.disabled {
|
||||
>div {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&-item {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
padding: 10px 15px;
|
||||
margin-right: 15px;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
.img {
|
||||
width: 100px;
|
||||
|
@ -189,6 +197,8 @@ const handleRadio = (item: any) => {
|
|||
color: #1d39c4;
|
||||
border-color: #1d39c4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -9,6 +9,7 @@ import NormalUpload from './NormalUpload/index.vue'
|
|||
import FileFormat from './FileFormat/index.vue'
|
||||
import JProUpload from './Upload/index.vue'
|
||||
import { BasicLayoutPage, BlankLayoutPage, FullPage } from './Layout'
|
||||
import RadioCard from './RadioCard/index.vue'
|
||||
import { PageContainer, AIcon, Ellipsis } from 'jetlinks-ui-components'
|
||||
// import Ellipsis from './Ellipsis/index.vue'
|
||||
import JEmpty from './Empty/index.vue'
|
||||
|
@ -39,5 +40,6 @@ export default {
|
|||
.component('ValueItem', ValueItem)
|
||||
.component('RowPagination', RowPagination)
|
||||
.component('FullPage', FullPage)
|
||||
.component('RadioCard', RadioCard)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,9 +160,9 @@
|
|||
style="padding: 0"
|
||||
danger
|
||||
:pop-confirm="{
|
||||
title: '确认删除?',
|
||||
title: dataSource.length === 1 ? '这是最后一条数据了,确认删除?' : '确认删除?',
|
||||
onConfirm: async () => {
|
||||
await removeItem(data.index);
|
||||
await removeItem(data.index, dataSource.length === 1);
|
||||
},
|
||||
}"
|
||||
:tooltip="{
|
||||
|
@ -354,22 +354,29 @@ const handleAddClick = async (_data?: any, index?: number) => {
|
|||
};
|
||||
|
||||
const copyItem = (record: any, index: number) => {
|
||||
const copyData = omit(record, ['_uuid'])
|
||||
const copyData = omit(record, ['_uuid', '_sortIndex'])
|
||||
copyData.id = `copy_${copyData.id}`.slice(0,64)
|
||||
handleAddClick(copyData, index)
|
||||
}
|
||||
|
||||
const removeItem = (index: number) => {
|
||||
const removeItem = (index: number, isSave: false) => {
|
||||
const data = [...dataSource.value];
|
||||
data.splice(index, 1);
|
||||
dataSource.value = data
|
||||
if (isSave) {
|
||||
handleSaveClick()
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveClick = async () => {
|
||||
const resp = await tableRef.value.getData().finally(() => {
|
||||
let resp = []
|
||||
if (dataSource.value.length) {
|
||||
resp = await tableRef.value.getData().finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
if(resp) {
|
||||
|
||||
});
|
||||
if(resp && resp.length) {
|
||||
const virtual: any[] = [];
|
||||
const arr = resp.map((item: any) => {
|
||||
if(item.expands?.virtualRule) {
|
||||
|
@ -408,7 +415,8 @@ const handleSaveClick = async () => {
|
|||
}
|
||||
}
|
||||
const _detail: ProductItem | DeviceInstance = target === 'device' ? instanceStore.detail : productStore.current
|
||||
const _data = updateMetadata(props.type!, arr, _detail, updateStore)
|
||||
let _data = updateMetadata(props.type!, arr, _detail, updateStore)
|
||||
|
||||
const result = await asyncUpdateMetadata(target, _data)
|
||||
if(result.success) {
|
||||
dataSource.value = resp
|
||||
|
|
|
@ -19,22 +19,7 @@
|
|||
<a-descriptions-item label="事件级别">{{ EventLevel[data.expands.level] }}</a-descriptions-item>
|
||||
<a-descriptions-item label="输出参数"></a-descriptions-item>
|
||||
<a-descriptions-item>
|
||||
<j-table
|
||||
:columns="dataTypeTable.columns"
|
||||
:dataSource="dataTypeTable.dataSource"
|
||||
:pagination="false"
|
||||
:scroll="{y: 200}"
|
||||
size="small"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'type'">
|
||||
{{ record.valueType?.type }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'valueType'">
|
||||
<OtherConfigInfo :value="record.valueType" />
|
||||
</template>
|
||||
</template>
|
||||
</j-table>
|
||||
<JsonView :value="dataTypeTable.dataSource"/>
|
||||
</a-descriptions-item>
|
||||
</j-descriptions>
|
||||
<template #footer>
|
||||
|
@ -44,7 +29,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts" name="EventModal">
|
||||
import {OtherConfigInfo} from "@/views/device/components/Metadata/Base/components";
|
||||
import JsonView from "./JsonView.vue";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
@ -59,13 +44,7 @@ const EventLevel = {
|
|||
urgent: '紧急'
|
||||
}
|
||||
|
||||
const dataTypeTable = reactive<{ columns: any[], dataSource: any }>({
|
||||
columns: [
|
||||
{ title: '参数标识', dataIndex: 'id', width: 150, ellipsis: true },
|
||||
{ title: '参数名称', dataIndex: 'name', width: 150, ellipsis: true },
|
||||
{ title: '数据类型', dataIndex: 'type', width: 100 },
|
||||
{ title: '其它配置', dataIndex: 'valueType', ellipsis: true },
|
||||
],
|
||||
const dataTypeTable = reactive<{ dataSource: any }>({
|
||||
dataSource: props.data?.valueType?.properties || []
|
||||
})
|
||||
|
||||
|
|
|
@ -19,22 +19,11 @@
|
|||
<a-descriptions-item label="是否异步">{{ data.async ? '是' : '否' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="输入参数"></a-descriptions-item>
|
||||
<a-descriptions-item>
|
||||
<j-table
|
||||
:columns="dataTypeTable.columns"
|
||||
:dataSource="dataTypeTable.dataSource"
|
||||
:pagination="false"
|
||||
:scroll="{y: 200}"
|
||||
size="small"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'type'">
|
||||
{{ record.valueType?.type }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'valueType'">
|
||||
<OtherConfigInfo :value="record.valueType" />
|
||||
</template>
|
||||
</template>
|
||||
</j-table>
|
||||
<JsonView :value="dataTypeTable.input"/>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="输出参数"></a-descriptions-item>
|
||||
<a-descriptions-item>
|
||||
<JsonView :value="dataTypeTable.output"/>
|
||||
</a-descriptions-item>
|
||||
</j-descriptions>
|
||||
<template #footer>
|
||||
|
@ -44,7 +33,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts" name="FunctionModal">
|
||||
import {OtherConfigInfo} from "@/views/device/components/Metadata/Base/components";
|
||||
import JsonView from './JsonView.vue'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
@ -53,14 +42,9 @@ const props = defineProps({
|
|||
}
|
||||
})
|
||||
|
||||
const dataTypeTable = reactive<{ columns: any[], dataSource: any }>({
|
||||
columns: [
|
||||
{ title: '参数标识', dataIndex: 'id', width: 120, ellipsis: true },
|
||||
{ title: '参数名称', dataIndex: 'name', width: 120, ellipsis: true },
|
||||
{ title: '数据类型', dataIndex: 'type', width: 100 },
|
||||
{ title: '其它配置', dataIndex: 'valueType', ellipsis: true },
|
||||
],
|
||||
dataSource: props.data?.inputs || []
|
||||
const dataTypeTable = reactive<{ input: any[], output: any[] }>({
|
||||
input: props.data?.inputs || [],
|
||||
output: props.data?.output || []
|
||||
})
|
||||
|
||||
const emit = defineEmits(['cancel'])
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div class="json-view-box">
|
||||
<div class="json-view-border">
|
||||
<j-scrollbar :height="height">
|
||||
<JsonViewer :value="value" :expanded="true" :expandDepth="4" />
|
||||
</j-scrollbar>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="JsonView">
|
||||
import 'vue3-json-viewer/dist/index.css';
|
||||
import { JsonViewer } from 'vue3-json-viewer';
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: [Object, Array],
|
||||
default: () => ({})
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 250
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.json-view-box {
|
||||
width: 100%;
|
||||
padding-left: 32px;
|
||||
.json-view-border {
|
||||
border: 1px solid rgba(0,0,0,.15);
|
||||
border-radius:2px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -16,34 +16,18 @@
|
|||
<a-descriptions-item label="属性标识">{{ data.id }}</a-descriptions-item>
|
||||
<a-descriptions-item label="属性名称">{{ data.name }}</a-descriptions-item>
|
||||
<a-descriptions-item label="属性类型">{{ data.valueType.type }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="['int', 'long', 'float', 'double'].includes(data.valueType.type)" label="单位">{{ data.valueType?.unit }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="['int', 'long', 'float', 'double'].includes(data.valueType.type)" label="单位">{{ unitLabel }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="['float', 'double'].includes(data.valueType.type)" label="精度">{{ data.valueType?.scale }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="['string', 'password'].includes(data.valueType.type)" label="最大长度">{{ data.valueType?.maxLength }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="data.valueType.type === 'file'" label="文件类型">{{ data.valueType?.fileType }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="data.valueType.type === 'date'" label="格式">{{ data.valueType?.format }}</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="
|
||||
['enum', 'object', 'boolean'].includes(data.valueType.type) ||
|
||||
(data.valueType.type === 'array' && data.valueType.elementType === 'enum')
|
||||
"
|
||||
['enum', 'object', 'boolean', 'array'].includes(data.valueType.type)"
|
||||
>
|
||||
<j-table
|
||||
:columns="dataTypeTable.columns"
|
||||
:dataSource="dataTypeTable.dataSource"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'type'">
|
||||
{{ record.valueType?.type }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'valueType'">
|
||||
<OtherConfigInfo :value="record.valueType" />
|
||||
</template>
|
||||
</template>
|
||||
</j-table>
|
||||
<JsonView :value="dataTypeTable.dataSource"/>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="来源">
|
||||
<a-descriptions-item label="属性来源">
|
||||
{{ sourceMap[data.expands.source] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="读写类型">{{ readTypeText }}</a-descriptions-item>
|
||||
|
@ -70,6 +54,8 @@
|
|||
import {OtherConfigInfo} from "@/views/device/components/Metadata/Base/components";
|
||||
import {omit} from "lodash-es";
|
||||
import {watch} from "vue";
|
||||
import JsonView from './JsonView.vue'
|
||||
import {getUnit} from "@/api/device/instance";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
@ -96,6 +82,8 @@ const readTypeText = computed(() => {
|
|||
return props.data?.expands?.type?.map?.((key: string) => type[key]).join('、')
|
||||
})
|
||||
|
||||
const unitLabel = ref('')
|
||||
|
||||
const dataTypeTable = reactive<{ columns: any[], dataSource: any }>({
|
||||
columns: [],
|
||||
dataSource: []
|
||||
|
@ -135,7 +123,7 @@ const handleDataTable = (type: string) => {
|
|||
{ title: 'Value', dataIndex: 'value'},
|
||||
{ title: 'Text', dataIndex: 'text'},
|
||||
]
|
||||
dataTypeTable.dataSource = [{ unit: props.data.valueType?.unit }]
|
||||
dataTypeTable.dataSource = props.data.valueType?.elements
|
||||
break;
|
||||
case 'object':
|
||||
dataTypeTable.columns = [
|
||||
|
@ -143,13 +131,32 @@ const handleDataTable = (type: string) => {
|
|||
{ title: '名称', dataIndex: 'name'},
|
||||
{ title: '名称', dataIndex: 'name'},
|
||||
]
|
||||
dataTypeTable.dataSource = [{ unit: props.data.valueType?.unit, scale: props.data.valueType?.scale }]
|
||||
dataTypeTable.dataSource = props.data.valueType?.properties
|
||||
break;
|
||||
case 'boolean':
|
||||
dataTypeTable.dataSource = {
|
||||
...props.data.valueType
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
watch(() => props.data.valueType.type, () => {
|
||||
const type = props.data.valueType.type
|
||||
handleDataTable(props.data.valueType.type === 'array' ? props.data.valueType.elementType : props.data.valueType.type)
|
||||
|
||||
if (['float', 'double', 'int', 'long'].includes(type)) {
|
||||
getUnit().then((res) => {
|
||||
if (res.success) {
|
||||
res.result.map((item) => {
|
||||
if (item.id === props.data.valueType?.unit) {
|
||||
unitLabel.value = item.description
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const cancel = () => {
|
||||
|
|
|
@ -174,7 +174,7 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', d
|
|||
rules: [{
|
||||
validator(_: any, value: any) {
|
||||
console.log('validator',value)
|
||||
if (!value?.valueType?.type) {
|
||||
if (!value?.type) {
|
||||
return Promise.reject('请选择数据类型')
|
||||
}
|
||||
return Promise.resolve()
|
||||
|
|
|
@ -15,18 +15,6 @@
|
|||
:columns="[
|
||||
{ title: '参数标识', dataIndex: 'id', type: 'text', width: 100 },
|
||||
{ title: '参数名称', dataIndex: 'name', type: 'text', width: 100 },
|
||||
{
|
||||
title: '填写约束',
|
||||
dataIndex: 'required',
|
||||
type: 'components',
|
||||
width: 100,
|
||||
components: {
|
||||
name: ConstraintSelect,
|
||||
props: {
|
||||
name: ['expands', 'required']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '数据类型',
|
||||
type: 'components',
|
||||
|
|
|
@ -77,10 +77,15 @@ const change = (v: string) => {
|
|||
};
|
||||
|
||||
const confirm = () => {
|
||||
const newObject = value.value.map((item) => {
|
||||
const { config, action, ...extra } = item
|
||||
return extra
|
||||
})
|
||||
|
||||
emit('update:value', {
|
||||
...props.value,
|
||||
valueType: {
|
||||
properties: value.value,
|
||||
properties: newObject,
|
||||
type: props.value.valueType.type,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<DataTableDate v-else-if="type === 'date'" v-model:value="data.date" @confirm="valueChange"/>
|
||||
<DataTableString
|
||||
v-else-if="['string', 'password'].includes(type)"
|
||||
v-model:value="data.expands.maxLength"
|
||||
v-model:value="data.maxLength"
|
||||
@confirm="valueChange"
|
||||
/>
|
||||
</div>
|
||||
|
@ -119,6 +119,10 @@ watch(
|
|||
);
|
||||
|
||||
const valueChange = () => {
|
||||
console.log({
|
||||
...props.value,
|
||||
output: {...data.value, type: type.value},
|
||||
})
|
||||
emit('update:value', {
|
||||
...props.value,
|
||||
output: {...data.value, type: type.value},
|
||||
|
|
|
@ -16,7 +16,8 @@ const useMetadata = (type: 'device' | 'product', key?: MetadataType, ): {
|
|||
const data = computed(() => {
|
||||
const _metadataStr = type === 'product' ? productStore.current?.metadata : instanceStore.current.metadata
|
||||
const _metadata = JSON.parse(_metadataStr || '{}')
|
||||
const newMetadata = (key ? _metadata[key] : []) as MetadataItem[]
|
||||
const newMetadata = (key ? _metadata?.[key] || [] : []) as MetadataItem[]
|
||||
console.log(key, _metadata, newMetadata)
|
||||
const indexs = newMetadata.map((item, index) => index)
|
||||
noEdit.value.id = indexs
|
||||
if (key === 'properties') {
|
||||
|
|
|
@ -36,9 +36,11 @@ import type { DeviceMetadata, MetadataItem, MetadataType, ProductItem } from "..
|
|||
} else {
|
||||
console.warn('未触发物模型修改');
|
||||
}
|
||||
console.log('config', config, type)
|
||||
console.log('updateMetadata', config, type)
|
||||
// @ts-ignore
|
||||
metadata[type] = config.sort((a, b) => b?.sortsIndex - a?.sortsIndex);
|
||||
// metadata[type] = config.sort((a, b) => b?.sortsIndex - a?.sortsIndex);
|
||||
metadata[type] = item.sort((a, b) => b?.sortsIndex - a?.sortsIndex);
|
||||
console.log('updateMetadata',metadata)
|
||||
data.metadata = JSON.stringify(metadata);
|
||||
onEvent?.(data.metadata)
|
||||
return data;
|
||||
|
|
|
@ -1431,7 +1431,7 @@ export default [
|
|||
permissions: [
|
||||
{
|
||||
permission: 'plugin-driver',
|
||||
actions: ['save'],
|
||||
actions: ['view'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -34,7 +34,7 @@ export default defineConfig(({ mode}) => {
|
|||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
sourcemap: true,
|
||||
sourcemap: false,
|
||||
cssCodeSplit: false,
|
||||
manifest: true,
|
||||
chunkSizeWarningLimit: 2000,
|
||||
|
|
|
@ -3825,8 +3825,8 @@ jetlinks-store@^0.0.3:
|
|||
|
||||
jetlinks-ui-components@^1.0.23, jetlinks-ui-components@^1.0.24:
|
||||
version "1.0.24"
|
||||
resolved "http://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.24.tgz#c40d77f2e4544f3bfccd5736670dc6ec1c1c7745"
|
||||
integrity sha512-oggX6nWZ8uDoA7EVdc7y5xj5EbxvHmeFJx3TDif1S+3O0oH4ejx387nV3nvpE1d3QB4R463VHeB5Lv4a64GgRQ==
|
||||
resolved "http://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.24.tgz#95afb70c227efcda4d387f4c48da21140f532ecd"
|
||||
integrity sha512-4VmgsQwOuDNxasLy9yFIm17kEQNkExfBGFo5gyJvtoo27XTrsKnM6J7gbsNOFxbyIHDsD5B8Un+D3S2dGRpLhA==
|
||||
dependencies:
|
||||
"@vueuse/core" "^9.12.0"
|
||||
"@vueuse/router" "^9.13.0"
|
||||
|
|
Loading…
Reference in New Issue