diff --git a/src/views/device/Instance/typings.d.ts b/src/views/device/Instance/typings.d.ts index 035c56f0..c8eb3f29 100644 --- a/src/views/device/Instance/typings.d.ts +++ b/src/views/device/Instance/typings.d.ts @@ -10,6 +10,7 @@ export type DeviceInstance = { protocolName: string; security: any; deriveMetadata: string; + productMetadata: string; metadata: string; binds: any; state: { diff --git a/src/views/device/Product/Save/index.vue b/src/views/device/Product/Save/index.vue index 5f05f4ff..ebee7942 100644 --- a/src/views/device/Product/Save/index.vue +++ b/src/views/device/Product/Save/index.vue @@ -331,8 +331,9 @@ const submitData = () => { form.classifiedName ? form.classifiedName : (form.classifiedName = ''); - const res = await editProduct(form); - loading.value = false + const res = await editProduct(form).finally(() => { + loading.value = false + }); if (res.status === 200) { message.success('保存成功!'); emit('success'); diff --git a/src/views/device/components/Metadata/Base/Base.vue b/src/views/device/components/Metadata/Base/Base.vue index 3649d91b..0642095d 100644 --- a/src/views/device/components/Metadata/Base/Base.vue +++ b/src/views/device/components/Metadata/Base/Base.vue @@ -12,10 +12,10 @@ + + \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/DetailModal/index.ts b/src/views/device/components/Metadata/Base/DetailModal/index.ts index 54dcd73e..10ef794c 100644 --- a/src/views/device/components/Metadata/Base/DetailModal/index.ts +++ b/src/views/device/components/Metadata/Base/DetailModal/index.ts @@ -1,3 +1,4 @@ export { default as PropertiesModal } from './PropertiesModal.vue' export { default as FunctionModal } from './FunctionModal.vue' -export { default as EventModal } from './EventModal.vue' \ No newline at end of file +export { default as EventModal } from './EventModal.vue' +export { default as TagsModal } from './TagsModal.vue' \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/columns.tsx b/src/views/device/components/Metadata/Base/columns.tsx index 0969b385..98d1b418 100644 --- a/src/views/device/components/Metadata/Base/columns.tsx +++ b/src/views/device/components/Metadata/Base/columns.tsx @@ -6,6 +6,7 @@ import { EventLevel } from "@/views/device/data"; import {MetadataType} from "@/views/device/Product/typings"; import { getUnit } from '@/api/device/instance'; import {Ref} from "vue"; +import {omit} from "lodash-es"; interface DataTableColumnProps extends ColumnProps { type?: string, components?: { @@ -39,7 +40,9 @@ export const handleTypeValue = (type:string, value: any = {}) => { obj.elementType = value break; case 'object': - obj.properties = value + obj.properties = (value || []).map((item: any) => { + return omit(item, ['config', 'action', '_sortIndex']) + }) break; case 'int': case 'long': @@ -119,13 +122,19 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n const fieldIndex = Number(field[1]) const hasId = dataSource.some((item, index) => item.id === value && fieldIndex !== index) if (hasId) { - return Promise.reject('该标识存在') + return Promise.reject('该标识已存在') } return Promise.resolve() } return Promise.reject('请输入标识') - } - }] + }, + }, + { max: 64, message: '最多可输入64个字符' }, + { + pattern: /^[a-zA-Z0-9_\-]+$/, + message: 'ID只能由数字、字母、下划线、中划线组成', + }, + ] }, doubleClick(record) { const ids = (noEdit?.value?.id || []) as any[] @@ -139,10 +148,13 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n type: 'text', form: { required: true, - rules: [{ - required: true, - message: '请输入名称' - }] + rules: [ + { + required: true, + message: '请输入名称' + }, + { max: 64, message: '最多可输入64个字符' }, + ] } }, ]; @@ -262,9 +274,10 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n }, form: { required: true, - rules: [ + rules: target !== 'device' ? [ { validator: async (_: Record, value: any) => { + console.log('expands',value) if (value.source) { if(value.source !== 'rule') { if(value.type?.length) { @@ -284,7 +297,7 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n } } }, - ] + ]: [] }, width: 150 }, @@ -307,7 +320,19 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n type: 'components', components: { name: DataType, - } + }, + form: { + required: true, + rules: [{ + validator(_: any, value: any) { + console.log('validator',value) + if (!value?.type) { + return Promise.reject('请选择数据类型') + } + return Promise.resolve() + } + }] + }, }, { title: '读写类型', @@ -332,7 +357,6 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n const columns = ref([]) watch(() => JSON.stringify(noEdit!.value), () => { - console.log(noEdit!.value) switch(type) { case 'properties': columns.value = PropertyColumns @@ -356,22 +380,40 @@ export const useUnit = (type: Ref) => { const unitOptions = ref>([]) watch(() => type.value, () => { + console.log('type.value',type.value) if (['float', 'double', 'int', 'long'].includes(type.value) && !unitOptions.value.length) { getUnit().then((res) => { if (res.success) { unitOptions.value = res.result.map((item: any) => ({ label: item.description, value: item.id, - })); - } - }); - } - }) + })); + } + }); + } + }, { immediate: true }) + return { unitOptions } } +export const TypeStringMap = { + int: 'int(整数型)', + long: 'long(长整数型)', + float: 'float(单精度浮点型)', + double: 'double(双精度浮点数)', + string: 'text(字符串)', + boolean: 'boolean(布尔型)', + date: 'date(时间型)', + enum: 'enum(枚举)', + array: 'array(数组)', + object: 'object(结构体)', + file: 'file(文件)', + password: 'password(密码)', + geoPoint: 'geoPoint(地理位置)', +} + // const MetadataMapping = new Map(); // MetadataMapping.set('properties', PropertyColumns); // MetadataMapping.set('events', EventColumns); diff --git a/src/views/device/components/Metadata/Base/components/ConfigModal.vue b/src/views/device/components/Metadata/Base/components/ConfigModal.vue index 75cce7de..f8b76f82 100644 --- a/src/views/device/components/Metadata/Base/components/ConfigModal.vue +++ b/src/views/device/components/Metadata/Base/components/ConfigModal.vue @@ -6,94 +6,23 @@ placement="topRight" @confirm="valueChange" > - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + - - - 配置 - + 无 @@ -203,11 +112,16 @@ const props = defineProps({ valueKey: { type: String, default: 'valueType' + }, + showOther: { + type: Boolean, + default: true } }) const emit = defineEmits(['update:value']) -import {useUnit} from "@/views/device/components/Metadata/Base/columns"; +import {handleTypeValue, TypeStringMap, useUnit} from "@/views/device/components/Metadata/Base/columns"; +import ModelButton from '@/views/device/components/Metadata/Base/components/ModelButton.vue' const objectAdd = () => { return { @@ -221,20 +135,113 @@ const objectAdd = () => { const options = ref([]) -const type = ref(props.value?.[props.valueKey]?.type) +const type = ref(props.value?.type) const { unitOptions } = useUnit(type) -const myValue = ref(props.value?.[props.valueKey]) +const myValue = ref(props.value) -const valueChange = () => { +const columns = [ + { + title: '参数标识', + dataIndex: 'id', + type: 'text', + width: 100, + form: { + required: true, + rules: [ + { + callback(rule:any,value: any, _dataSource: any[]) { + if (value) { + const field = rule.field.split('.') + const fieldIndex = Number(field[1]) + const hasId = _dataSource.some((item, index) => item.id === value && fieldIndex !== index) + if (hasId) { + return Promise.reject('该标识已存在') + } + return Promise.resolve() + } + return Promise.reject('请输入标识') + } + }, + { max: 64, message: '最多可输入64个字符' }, + { + pattern: /^[a-zA-Z0-9_\-]+$/, + message: 'ID只能由数字、字母、下划线、中划线组成', + }, + ] + } + }, + { + title: '参数名称', + dataIndex: 'name', + type: 'text', + width: 100, + form: { + required: true, + rules: [{ + required: true, + message: '请输入参数名称' + }, + { max: 64, message: '最多可输入64个字符' } + ] + } + }, + { + title: '数据类型', + type: 'components', + dataIndex: 'valueType', + components: { + name: ValueObject, + }, + form: { + required: true, + rules: [{ + validator(_: any, value: any) { + console.log('validator',value) + if (!value?.type) { + return Promise.reject('请选择数据类型') + } + return Promise.resolve() + } + }] + }, + width: 100 + }, + { + title: '其他配置', + type: 'components', + dataIndex: 'config', + components: { + name: DataTypeObjectChild + }, + width: 100 + }, + { + title: '操作', + dataIndex: 'action', + width: 60 + } +] +const valueChange = (data: any) => { + console.log('configModal - confirm',data, props.value, type.value) + const newObj = handleTypeValue(type.value, data) + console.log('configModal - newObj', newObj) + console.log('configModal - newObj2', { + type: type.value, + ...newObj + }) + emit('update:value', { + type: type.value, + ...newObj + }) } watch(() => JSON.stringify(props.value), () => { console.log(props.value) - type.value = props.value?.[props.valueKey]?.type - myValue.value = props.value?.[props.valueKey] + type.value = props.value?.type + myValue.value = props.value }) diff --git a/src/views/device/components/Metadata/Base/components/DataType.vue b/src/views/device/components/Metadata/Base/components/DataType.vue index 87142ea3..05475080 100644 --- a/src/views/device/components/Metadata/Base/components/DataType.vue +++ b/src/views/device/components/Metadata/Base/components/DataType.vue @@ -18,25 +18,25 @@ @confirm="(data) => {valueChange(data, 'object')}" > item.id === value && fieldIndex !== index) + if (hasId) { + return Promise.reject('该标识已存在') + } + return Promise.resolve() + } + return Promise.reject('请输入标识') + }, + }, + { max: 64, message: '最多可输入64个字符' }, + { + pattern: /^[a-zA-Z0-9_\-]+$/, + message: 'ID只能由数字、字母、下划线、中划线组成', + }, + ] } }, { @@ -102,7 +120,9 @@ const columns = [{ rules: [{ required: true, message: '请输入参数名称' - }] + }, + { max: 64, message: '最多可输入64个字符' }, + ] } }, { @@ -111,9 +131,18 @@ const columns = [{ dataIndex: 'valueType', components: { name: ValueObject, - props: { - filter: ['object'] - } + }, + form: { + required: true, + rules: [{ + validator(_: any, value: any) { + console.log('validator',value) + if (!value?.type) { + return Promise.reject('请选择数据类型') + } + return Promise.resolve() + } + }] }, width: 100 }, @@ -143,16 +172,16 @@ const typeChange = (e: string) => { ...props.value, valueType: { ...obj, type: e } }); + formItemContext.onFieldChange() }; const valueChange = (_data: any, _type: string) => { - console.log(_type, _data) const newData = handleTypeValue(_type, _data) - console.log('dataType',{...newData, type: type.value}) emit('update:value', { ...props.value, valueType: {...newData, type: type.value}, }); + formItemContext.onFieldChange() } const { unitOptions } = useUnit(type) diff --git a/src/views/device/components/Metadata/Base/components/Events/ConfigParams.vue b/src/views/device/components/Metadata/Base/components/Events/ConfigParams.vue index 0db37b6f..302125b4 100644 --- a/src/views/device/components/Metadata/Base/components/Events/ConfigParams.vue +++ b/src/views/device/components/Metadata/Base/components/Events/ConfigParams.vue @@ -1,19 +1,16 @@ - diff --git a/src/views/device/components/Metadata/Base/components/Function/OutputParams.vue b/src/views/device/components/Metadata/Base/components/Function/OutputParams.vue index 4e53c151..ab74cc92 100644 --- a/src/views/device/components/Metadata/Base/components/Function/OutputParams.vue +++ b/src/views/device/components/Metadata/Base/components/Function/OutputParams.vue @@ -12,74 +12,15 @@ v-else-if="type === 'object'" v-model:value="data.properties" placement="topRight" - :columns="[ - { - title: '参数标识', - dataIndex: 'id', - type: 'text', - form: { - required: true, - rules: [{ - callback(rule:any,value: any, dataSource: any[]) { - if (value) { - const field = rule.field.split('.') - const fieldIndex = Number(field[1]) - const hasId = dataSource.some((item, index) => item.id === value && fieldIndex !== index) - if (hasId) { - return Promise.reject('该标识存在') - } - return Promise.resolve() - } - return Promise.reject('请输入标识') - } - }] - } - }, - { - title: '参数名称', - dataIndex: 'name', - type: 'text', - form: { - required: true, - rules: [{ - required: true, - message: '请输入参数名称' - }] - } - }, - { - title: '数据类型', - type: 'components', - dataIndex: 'valueType', - components: { - name: Type, - }, - form: { - required: true, - rules: [{ - required: true, - message: '请选择数据类型' - }] - } - }, - { - title: '其他配置', - dataIndex: 'config', - }, - { - title: '操作', - dataIndex: 'action', - width: 60 - } - ]" + :columns="columns" @confirm="valueChange" :onAdd="addItem" > @@ -123,7 +64,7 @@ import { import ConfigModal from '@/views/device/components/Metadata/Base/components/ConfigModal.vue' import { cloneDeep } from 'lodash-es'; -import {typeSelectChange, useUnit} from "@/views/device/components/Metadata/Base/columns"; +import {typeSelectChange, TypeStringMap, useUnit} from "@/views/device/components/Metadata/Base/columns"; import Type from './Type.vue' const props = defineProps({ @@ -138,7 +79,7 @@ const options = ref<{ label: string; value: string }[]>([]); const emit = defineEmits(['update:value']); const type = ref(props.value?.output?.type); -const data = ref(cloneDeep(props.value?.output)); +const data = ref(props.value?.output); const { unitOptions } = useUnit(type) @@ -150,6 +91,80 @@ const typeChange = (e: string) => { }); }; +const columns = [ + { + title: '参数标识', + dataIndex: 'id', + type: 'text', + form: { + required: true, + rules: [{ + callback(rule:any,value: any, dataSource: any[]) { + if (value) { + const field = rule.field.split('.') + const fieldIndex = Number(field[1]) + const hasId = dataSource.some((item, index) => item.id === value && fieldIndex !== index) + if (hasId) { + return Promise.reject('该标识已存在') + } + return Promise.resolve() + } + return Promise.reject('请输入标识') + } + }, + { max: 64, message: '最多可输入64个字符' }, + { + pattern: /^[a-zA-Z0-9_\-]+$/, + message: 'ID只能由数字、字母、下划线、中划线组成', + }, + ] + } + }, + { + title: '参数名称', + dataIndex: 'name', + type: 'text', + form: { + required: true, + rules: [{ + required: true, + message: '请输入参数名称' + }, + { max: 64, message: '最多可输入64个字符' }, + ] + } + }, + { + title: '数据类型', + type: 'components', + dataIndex: 'valueType', + components: { + name: Type, + }, + form: { + required: true, + rules: [{ + validator(_: any, value: any) { + console.log('validator',value) + if (!value?.type) { + return Promise.reject('请选择数据类型') + } + return Promise.resolve() + } + }] + } + }, + { + title: '其他配置', + dataIndex: 'config', + }, + { + title: '操作', + dataIndex: 'action', + width: 60 + } +] + watch( () => props.value, () => { diff --git a/src/views/device/components/Metadata/Base/components/Function/Type.vue b/src/views/device/components/Metadata/Base/components/Function/Type.vue index ebe6a16d..8c194aba 100644 --- a/src/views/device/components/Metadata/Base/components/Function/Type.vue +++ b/src/views/device/components/Metadata/Base/components/Function/Type.vue @@ -1,7 +1,6 @@ diff --git a/src/views/device/components/Metadata/Base/components/ModelButton.vue b/src/views/device/components/Metadata/Base/components/ModelButton.vue new file mode 100644 index 00000000..02b64f92 --- /dev/null +++ b/src/views/device/components/Metadata/Base/components/ModelButton.vue @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/components/Properties/Metrics/Metrics.vue b/src/views/device/components/Metadata/Base/components/Properties/Metrics/Metrics.vue index c2e2eaa7..9e6512d1 100644 --- a/src/views/device/components/Metadata/Base/components/Properties/Metrics/Metrics.vue +++ b/src/views/device/components/Metadata/Base/components/Properties/Metrics/Metrics.vue @@ -11,7 +11,7 @@ {{ data.record.range === 'true' ? '范围值' : '固定值'}} - + 添加指标值 diff --git a/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue b/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue index b2957704..4bdb9c3a 100644 --- a/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue +++ b/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue @@ -37,7 +37,7 @@ - + @@ -49,10 +49,7 @@ - - - 配置 - + @@ -63,12 +60,17 @@ import {cloneDeep} from "lodash"; import {useProductStore} from "store/product"; import {useInstanceStore} from "store/instance"; import {getMetadataConfig, getMetadataDeviceConfig} from "@/api/device/product"; +import ModelButton from '@/views/device/components/Metadata/Base/components/ModelButton.vue' import {omit} from "lodash-es"; const props = defineProps({ value: { type: Object, default: () => ({}) + }, + type: { + type: String, + default: undefined } }) @@ -90,7 +92,7 @@ const config = ref([]) const configValue = ref(props.value?.expands) const showMetrics = computed(() => { - return ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(props.value?.valueType?.type as any) + return ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(props.type as any) }) const columns = ref([ @@ -114,15 +116,14 @@ const columns = ref([ const getConfig = async () => { const record = props.value const id = type === 'product' ? productStore.current?.id : deviceStore.current.id - console.log(record.id, id, record.valueType) - if(!record.id || !id || !record.valueType.type) return + if(!record.id || !id || !record.type) return const params: any = { deviceId: id, metadata: { id: record.id, type: 'property', - dataType: record.valueType.type, + dataType: record.type, }, } @@ -162,17 +163,12 @@ const confirm = () => { if (metrics) { expands.metrics = metrics } - console.log(expands) emit('update:value', { ...props.value, - expands: { - ...(props.value.expands || {}), - ...expands - } + ...expands }) resolve(true) } catch (err) { - console.log(err) reject(false) } }) @@ -180,18 +176,16 @@ const confirm = () => { const visibleChange = (e: boolean) => { if (e) { - configValue.value = omit(props.value?.expands, ['source', 'type', 'metrics', 'required']) + configValue.value = omit(props.value, ['source', 'type', 'metrics', 'required']) getConfig() } } const cancel = () => { - console.log(props.value) myValue.value = cloneDeep(props.value) } watch(() => props.value, () => { - console.log(props.value) myValue.value = cloneDeep(props.value) }, {immediate: true, deep: true}) diff --git a/src/views/device/components/Metadata/Base/components/Source.vue b/src/views/device/components/Metadata/Base/components/Source.vue index 0ac411f9..d072b385 100644 --- a/src/views/device/components/Metadata/Base/components/Source.vue +++ b/src/views/device/components/Metadata/Base/components/Source.vue @@ -8,31 +8,32 @@ :disabled="disabled" > - - - - - - + + + + + +