Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev

This commit is contained in:
easy 2023-02-28 18:07:25 +08:00
commit ff52e85331
12 changed files with 175 additions and 94 deletions

View File

@ -3,7 +3,7 @@
<template #title> <template #title>
<div style="display: flex; justify-content: space-between; align-items: center;"> <div style="display: flex; justify-content: space-between; align-items: center;">
<div style="width: 150px;">配置元素</div> <div style="width: 150px;">配置元素</div>
<close-outlined @click="visible = false" /> <AIcon type="CloseOutlined" @click="visible = false"/>
</div> </div>
</template> </template>
<template #content> <template #content>
@ -19,14 +19,13 @@
</div> </div>
</template> </template>
<a-button type="dashed" block @click="visible = true"> <a-button type="dashed" block @click="visible = true">
配置元素<edit-outlined class="item-icon" /> 配置元素<AIcon type="EditOutlined" class="item-icon"/>
</a-button> </a-button>
</a-popover> </a-popover>
</template> </template>
<script setup lang="ts" name="ArrayParam"> <script setup lang="ts" name="ArrayParam">
import ValueTypeForm from '@/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue'; import ValueTypeForm from '@/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue';
import { EditOutlined, CloseOutlined } from '@ant-design/icons-vue';
import { PropType } from 'vue'; import { PropType } from 'vue';
type ValueType = Record<any, any>; type ValueType = Record<any, any>;

View File

@ -16,13 +16,12 @@
</div> </div>
</template> </template>
<a-button type="dashed" block> <a-button type="dashed" block>
存储配置<edit-outlined class="item-icon" /> 存储配置<AIcon type="EditOutlined" class="item-icon"/>
</a-button> </a-button>
</a-popover> </a-popover>
</template> </template>
<script setup lang="ts" name="ConfigParam"> <script setup lang="ts" name="ConfigParam">
import { PropType } from 'vue'; import { PropType } from 'vue';
import { EditOutlined } from '@ant-design/icons-vue';
type ValueType = Record<any, any>; type ValueType = Record<any, any>;
const props = defineProps({ const props = defineProps({

View File

@ -2,14 +2,14 @@
<div class="enum-param"> <div class="enum-param">
<div class="list-item" v-for="(item, index) in _value" :key="index"> <div class="list-item" v-for="(item, index) in _value" :key="index">
<div class="item-left"> <div class="item-left">
<menu-outlined class="item-drag item-icon" /> <AIcon type="MenuOutlined" class="item-drag item-icon" />
</div> </div>
<div class="item-middle item-editable"> <div class="item-middle item-editable">
<a-popover :visible="editIndex === index" placement="top"> <a-popover :visible="editIndex === index" placement="top">
<template #title> <template #title>
<div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;"> <div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;">
<div style="width: 150px;">枚举项配置</div> <div style="width: 150px;">枚举项配置</div>
<close-outlined @click="handleClose" /> <AIcon type="CloseOutlined" @click="handleClose" />
</div> </div>
</template> </template>
<template #content> <template #content>
@ -28,23 +28,22 @@
</template> </template>
<div class="item-edit" @click="handleEdit(index)"> <div class="item-edit" @click="handleEdit(index)">
{{ item.text || '枚举项配置' }} {{ item.text || '枚举项配置' }}
<edit-outlined class="item-icon" /> <AIcon type="EditOutlined" class="item-icon" />
</div> </div>
</a-popover> </a-popover>
</div> </div>
<div class="item-right"> <div class="item-right">
<delete-outlined @click="handleDelete(index)"/> <AIcon type="DeleteOutlined" @click="handleDelete(index)"/>
</div> </div>
</div> </div>
<a-button type="dashed" block @click="handleAdd"> <a-button type="dashed" block @click="handleAdd">
<template #icon><plus-outlined class="item-icon" /></template> <template #icon><AIcon type="PlusOutlined" class="item-icon" /></template>
新增枚举型 新增枚举型
</a-button> </a-button>
</div> </div>
</template> </template>
<script setup lang="ts" name="BooleanParam"> <script setup lang="ts" name="BooleanParam">
import { PropType } from 'vue' import { PropType } from 'vue'
import { MenuOutlined, EditOutlined, DeleteOutlined, PlusOutlined, CloseOutlined } from '@ant-design/icons-vue';
type EnumType = { type EnumType = {
text?: string, text?: string,

View File

@ -2,14 +2,14 @@
<div class="json-param"> <div class="json-param">
<div class="list-item" v-for="(item, index) in _value" :key="`object_${index}`"> <div class="list-item" v-for="(item, index) in _value" :key="`object_${index}`">
<div class="item-left"> <div class="item-left">
<menu-outlined class="item-drag item-icon" /> <AIcon type="MenuOutlined" class="item-drag item-icon" />
</div> </div>
<div class="item-middle item-editable"> <div class="item-middle item-editable">
<a-popover :visible="editIndex === index" placement="left"> <a-popover :visible="editIndex === index" placement="left">
<template #title> <template #title>
<div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;"> <div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;">
<div style="width: 150px;">配置参数</div> <div style="width: 150px;">配置参数</div>
<close-outlined @click="handleClose" /> <AIcon type="CloseOutlined" @click="handleClose" />
</div> </div>
</template> </template>
<template #content> <template #content>
@ -38,23 +38,22 @@
</template> </template>
<div class="item-edit" @click="handleEdit(index)"> <div class="item-edit" @click="handleEdit(index)">
{{ item.name || '配置参数' }} {{ item.name || '配置参数' }}
<edit-outlined class="item-icon" /> <AIcon type="EditOutlined" class="item-icon" />
</div> </div>
</a-popover> </a-popover>
</div> </div>
<div class="item-right"> <div class="item-right">
<delete-outlined @click="handleDelete(index)" /> <AIcon type="DeleteOutlined" @click="handleDelete(index)" />
</div> </div>
</div> </div>
<a-button type="dashed" block @click="handleAdd"> <a-button type="dashed" block @click="handleAdd">
<template #icon><plus-outlined class="item-icon" /></template> <template #icon><AIcon type="PlusOutlined" class="item-icon" /></template>
添加参数 添加参数
</a-button> </a-button>
</div> </div>
</template> </template>
<script setup lang="ts" name="JsonParam"> <script setup lang="ts" name="JsonParam">
import { PropType } from 'vue' import { PropType } from 'vue'
import { MenuOutlined, EditOutlined, DeleteOutlined, PlusOutlined, CloseOutlined } from '@ant-design/icons-vue';
import ValueTypeForm from '@/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue'; import ValueTypeForm from '@/views/device/components/Metadata/Base/Edit/ValueTypeForm.vue';
type JsonType = Record<any, any>; type JsonType = Record<any, any>;
@ -66,20 +65,23 @@ const emit = defineEmits<Emits>()
const props = defineProps({ const props = defineProps({
value: { value: {
type: Object as PropType<JsonType[]>, type: Object as PropType<JsonType[]>,
default: () => ([])
} }
}) })
const _value = ref<JsonType[]>([]) const _value = ref<JsonType[]>([])
watchEffect(() => { watchEffect(() => {
_value.value = props.value _value.value = props.value || [{
valueType: {
expands: {}
},
}]
}) })
watch(_value, watch(_value,
() => { () => {
emit('update:value', _value.value) emit('update:value', _value.value)
}, },
{ deep: true }) { deep: true, immediate: true })
const editIndex = ref<number>(-1) const editIndex = ref<number>(-1)
const handleEdit = (index: number) => { const handleEdit = (index: number) => {

View File

@ -2,7 +2,7 @@
<div class="json-param"> <div class="json-param">
<div class="list-item" v-for="(item, index) in _value" :key="`object_${index}`"> <div class="list-item" v-for="(item, index) in _value" :key="`object_${index}`">
<div class="item-left"> <div class="item-left">
<menu-outlined class="item-drag item-icon" /> <AIcon type="MenuOutlined" class="item-drag item-icon" />
{{ `#${index + 1}.` }} {{ `#${index + 1}.` }}
</div> </div>
<div class="item-middle item-editable"> <div class="item-middle item-editable">
@ -10,7 +10,7 @@
<template #title> <template #title>
<div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;"> <div class="edit-title" style="display: flex; justify-content: space-between; align-items: center;">
<div style="width: 150px;">配置参数</div> <div style="width: 150px;">配置参数</div>
<close-outlined @click="handleClose" /> <AIcon type="CloseOutlined" @click="handleClose" />
</div> </div>
</template> </template>
<template #content> <template #content>
@ -43,23 +43,22 @@
</template> </template>
<div class="item-edit" @click="handleEdit(index)"> <div class="item-edit" @click="handleEdit(index)">
{{ item.name || '配置参数' }} {{ item.name || '配置参数' }}
<edit-outlined class="item-icon" /> <AIcon type="EditOutlined" class="item-icon" />
</div> </div>
</a-popover> </a-popover>
</div> </div>
<div class="item-right"> <div class="item-right">
<delete-outlined @click="handleDelete(index)" /> <AIcon type="DeleteOutlined" @click="handleDelete(index)" />
</div> </div>
</div> </div>
<a-button type="dashed" block @click="handleAdd"> <a-button type="dashed" block @click="handleAdd">
<template #icon><plus-outlined class="item-icon" /></template> <template #icon><AIcon type="PlusOutlined" class="item-icon" /></template>
添加指标 添加指标
</a-button> </a-button>
</div> </div>
</template> </template>
<script setup lang="ts" name="MetricsParam"> <script setup lang="ts" name="MetricsParam">
import { PropType } from 'vue' import { PropType } from 'vue'
import { MenuOutlined, EditOutlined, DeleteOutlined, PlusOutlined, CloseOutlined } from '@ant-design/icons-vue';
import JIndicators from '@/components/JIndicators/index.vue'; import JIndicators from '@/components/JIndicators/index.vue';
interface Emits { interface Emits {

View File

@ -34,7 +34,6 @@ type ValueType = Record<any, any>;
const props = defineProps({ const props = defineProps({
value: { value: {
type: Object as PropType<ValueType>, type: Object as PropType<ValueType>,
default: () => ({})
}, },
type: { type: {
type: String type: String
@ -62,13 +61,23 @@ interface Emits {
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
const _value = computed({ // const _value = computed({
get: () => props.value, // get: () => props.value || {},
set: val => { // set: val => {
emit('update:value', val) // emit('update:value', val)
} // }
// })
const _value = ref<ValueType>({})
watchEffect(() => {
_value.value = props.value || {}
}) })
watch(_value,
() => {
emit('update:value', _value.value)
},
{ deep: true, immediate: true })
const options = [ const options = [
{ {
label: '读', label: '读',
@ -87,7 +96,7 @@ const options = [
const metadataStore = useMetadataStore() const metadataStore = useMetadataStore()
onMounted(() => { onMounted(() => {
if (props.type === 'product' || !props.value.source) { if (props.type === 'product' || !props.value?.source) {
emit('update:value', { ...props.value, source: 'device' }) emit('update:value', { ...props.value, source: 'device' })
} }
}) })

View File

@ -15,9 +15,8 @@
]"> ]">
<a-input v-model:value="value.name" size="small"></a-input> <a-input v-model:value="value.name" size="small"></a-input>
</a-form-item> </a-form-item>
{{ modelType }}
<template v-if="modelType === 'properties'"> <template v-if="modelType === 'properties'">
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="property" <value-type-form :name="['valueType']" v-model:value="value.valueType" key="property" title="数据类型"
@change-type="changeValueType"></value-type-form> @change-type="changeValueType"></value-type-form>
<expands-form :name="['expands']" v-model:value="value.expands" :type="type" :id="value.id" :config="config" <expands-form :name="['expands']" v-model:value="value.expands" :type="type" :id="value.id" :config="config"
@ -37,12 +36,15 @@
]"> ]">
<JsonParam v-model:value="value.inputs" :name="['inputs']"></JsonParam> <JsonParam v-model:value="value.inputs" :name="['inputs']"></JsonParam>
</a-form-item> </a-form-item>
<a-form-item label="输出参数" name="output"> <value-type-form :name="['output']" v-model:value="value.output" key="function" title="输出参数"></value-type-form>
<JsonParam v-model:value="value.output" :name="['output']"></JsonParam> </template>
<template v-if="modelType === 'events'">
<value-type-form :name="['output']" v-model:value="value.valueType" key="function" <a-form-item label="级别" :name="['expands', 'level']" :rules="[
@change-type="changeValueType"></value-type-form> { required: true, message: '请选择级别' },
]">
<a-select v-model:value="value.expands.level" :options="EventLevel" size="small"></a-select>
</a-form-item> </a-form-item>
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="function" title="输出参数"></value-type-form>
</template> </template>
<a-form-item label="说明" name="description" :rules="[ <a-form-item label="说明" name="description" :rules="[
{ max: 200, message: '最多可输入200个字符' }, { max: 200, message: '最多可输入200个字符' },
@ -57,6 +59,7 @@ import ValueTypeForm from './ValueTypeForm.vue'
import { useProductStore } from '@/store/product'; import { useProductStore } from '@/store/product';
import { getMetadataConfig } from '@/api/device/product' import { getMetadataConfig } from '@/api/device/product'
import JsonParam from '@/components/Metadata/JsonParam/index.vue' import JsonParam from '@/components/Metadata/JsonParam/index.vue'
import { EventLevel } from '@/views/device/data';
const props = defineProps({ const props = defineProps({
type: { type: {
@ -73,12 +76,19 @@ const props = defineProps({
default: '' default: ''
} }
}) })
if (props.modelType === 'events') {
if (!props.value.expands) {
props.value.expands = {}
}
}
const productStore = useProductStore() const productStore = useProductStore()
const config = ref<Record<any, any>[]>([]) const config = ref<Record<any, any>[]>([])
const asyncOtherConfig = async () => { const asyncOtherConfig = async () => {
if (props.type !== 'product') return if (props.type !== 'product') return
const { valueType: { type }, id } = props.value const { valueType, id } = props.value
const { type } = valueType || {}
const productId = productStore.current?.id const productId = productStore.current?.id
if (!productId || !id || !type) return if (!productId || !id || !type) return
const resp = await getMetadataConfig({ const resp = await getMetadataConfig({
@ -93,8 +103,11 @@ const asyncOtherConfig = async () => {
config.value = resp.result config.value = resp.result
} }
} }
onMounted(() => { onMounted(() => {
asyncOtherConfig() if (props.modelType === 'properties') {
asyncOtherConfig()
}
}) })
const changeValueType = (val: string) => { const changeValueType = (val: string) => {

View File

@ -1,28 +1,25 @@
<template> <template>
<a-form-item label="数据类型" :name="name.concat(['type'])" :rules="[ <a-form-item :label="title" :name="name.concat(['type'])" :rules="[
{ required: true, message: '请选择数据类型' }, metadataStore.model.type !== 'functions' ? { required: true, message: '请选择数据类型' } : {},
]"> ]">
<a-select v-model:value="value.type" :options="_dataTypeList" size="small" @change="changeType"></a-select> <a-select v-model:value="_value.type" :options="metadataStore.model.type === 'events' ? eventDataTypeList : _dataTypeList" size="small" @change="changeType"></a-select>
</a-form-item> </a-form-item>
<a-form-item label="单位" :name="name.concat(['unit'])" v-if="['int', 'float', 'long', 'double'].includes(value.type)"> <a-form-item label="单位" :name="name.concat(['unit'])" v-if="['int', 'float', 'long', 'double'].includes(_value.type)">
<InputSelect v-model:value="value.unit" :options="unit.unitOptions" size="small"></InputSelect> <InputSelect v-model:value="_value.unit" :options="unit.unitOptions" size="small"></InputSelect>
</a-form-item> </a-form-item>
<a-form-item label="精度" :name="name.concat(['scale'])" v-if="['float', 'double'].includes(value.type)"> <a-form-item label="精度" :name="name.concat(['scale'])" v-if="['float', 'double'].includes(_value.type)">
<a-input-number v-model:value="value.scale" size="small" :min="0" :max="2147483647" :precision="0" <a-input-number v-model:value="_value.scale" size="small" :min="0" :max="2147483647" :precision="0" :default-value="2"
:default-value="2" style="width: 100%"></a-input-number> style="width: 100%"></a-input-number>
</a-form-item> </a-form-item>
<a-form-item label="布尔值" name="booleanConfig" v-if="['boolean'].includes(value.type)"> <a-form-item label="布尔值" name="booleanConfig" v-if="['boolean'].includes(_value.type)">
<BooleanParam <BooleanParam :name="name" v-model:value="_value"></BooleanParam>
:name="name"
v-model:value="_value"
></BooleanParam>
</a-form-item> </a-form-item>
<a-form-item label="枚举项" :name="name.concat(['elements'])" v-if="['enum'].includes(value.type)" :rules="[ <a-form-item label="枚举项" :name="name.concat(['elements'])" v-if="['enum'].includes(_value.type)" :rules="[
{ required: true, message: '请配置枚举项' } { required: true, message: '请配置枚举项' }
]"> ]">
<EnumParam v-model:value="value.elements"></EnumParam> <EnumParam v-model:value="_value.elements"></EnumParam>
</a-form-item> </a-form-item>
<a-form-item :name="name.concat(['expands', 'maxLength'])" v-if="['string', 'password'].includes(value.type)"> <a-form-item :name="name.concat(['expands', 'maxLength'])" v-if="['string', 'password'].includes(_value.type)">
<template #label> <template #label>
<a-space> <a-space>
最大长度 最大长度
@ -31,19 +28,20 @@
</a-tooltip> </a-tooltip>
</a-space> </a-space>
</template> </template>
<a-input-number v-model:value="value.expands.maxLength" size="small" :max="2147483647" :min="1" :precision="0" <a-input-number v-model:value="_value.expands.maxLength" size="small" :max="2147483647" :min="1" :precision="0"
style="width: 100%;"></a-input-number> style="width: 100%;"></a-input-number>
</a-form-item> </a-form-item>
<a-form-item label="元素配置" :name="name.concat(['elementType'])" v-if="['array'].includes(value.type)"> <a-form-item label="元素配置" :name="name.concat(['elementType'])" v-if="['array'].includes(_value.type)">
<ArrayParam v-model:value="value.elementType" :name="name.concat(['elementType'])"></ArrayParam> <ArrayParam v-model:value="_value.elementType" :name="name.concat(['elementType'])"></ArrayParam>
</a-form-item> </a-form-item>
<a-form-item label="JSON对象" :name="name.concat(['properties'])" v-if="['object'].includes(value.type)"> <a-form-item label="JSON对象" :name="name.concat(['properties'])" v-if="['object'].includes(_value.type)">
<JsonParam v-model:value="value.jsonConfig" :name="name.concat(['properties'])"></JsonParam> <JsonParam v-model:value="_value.jsonConfig" :name="name.concat(['properties'])"></JsonParam>
</a-form-item> </a-form-item>
<a-form-item label="文件类型" :name="name.concat(['fileType'])" v-if="['file'].includes(value.type)" initialValue="url" :rules="[ <a-form-item label="文件类型" :name="name.concat(['fileType'])" v-if="['file'].includes(_value.type)" initialValue="url"
{ required: true, message: '请选择文件类型' }, :rules="[
]"> { required: true, message: '请选择文件类型' },
<a-select v-model:value="value.fileType" :options="FileTypeList" size="small"></a-select> ]">
<a-select v-model:value="_value.fileType" :options="FileTypeList" size="small"></a-select>
</a-form-item> </a-form-item>
</template> </template>
<script lang="ts" setup mame="BaseForm"> <script lang="ts" setup mame="BaseForm">
@ -57,14 +55,13 @@ import BooleanParam from '@/components/Metadata/BooleanParam/index.vue'
import EnumParam from '@/components/Metadata/EnumParam/index.vue' import EnumParam from '@/components/Metadata/EnumParam/index.vue'
import ArrayParam from '@/components/Metadata/ArrayParam/index.vue' import ArrayParam from '@/components/Metadata/ArrayParam/index.vue'
import JsonParam from '@/components/Metadata/JsonParam/index.vue' import JsonParam from '@/components/Metadata/JsonParam/index.vue'
import { useMetadataStore } from '@/store/metadata';
type ValueType = Record<any, any>; type ValueType = Record<any, any>;
const props = defineProps({ const props = defineProps({
value: { value: {
type: Object as PropType<ValueType>, type: Object as PropType<ValueType>,
default: () => ({ // default: () => ({})
extends: {}
})
}, },
isSub: { isSub: {
type: Boolean, type: Boolean,
@ -74,6 +71,10 @@ const props = defineProps({
type: Array as PropType<string[]>, type: Array as PropType<string[]>,
default: () => ([]), default: () => ([]),
required: true required: true
},
title: {
String,
default: '数据类型'
} }
}) })
@ -83,11 +84,34 @@ interface Emits {
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
// emit('update:value', { extends: {}, ...props.value })
const _value = computed({ const metadataStore = useMetadataStore()
get: () => props.value, // const _value = computed({
set: val => { // get: () => props.value,
emit('update:value', val) // set: val => {
// emit('update:value', val)
// }
// })
const _value = ref<ValueType>({})
watchEffect(() => {
_value.value = props.value || {
expands: {}
}
})
watch(_value,
() => {
emit('update:value', _value.value)
},
{ deep: true, immediate: true })
onMounted(() => {
if (metadataStore.model.type === 'events') {
_value.value = {
type: 'object',
expands: {}
}
} }
}) })
@ -108,6 +132,12 @@ const unit = {
unit.getUnit() unit.getUnit()
const _dataTypeList = computed(() => props.isSub ? DataTypeList.filter(item => item.value !== 'array' && item.value !== 'object') : DataTypeList) const _dataTypeList = computed(() => props.isSub ? DataTypeList.filter(item => item.value !== 'array' && item.value !== 'object') : DataTypeList)
const eventDataTypeList = [
{
value: 'object',
label: 'object(结构体)',
},
]
const changeType = (val: SelectValue) => { const changeType = (val: SelectValue) => {
emit('changeType', val as string) emit('changeType', val as string)

View File

@ -59,12 +59,7 @@ const title = computed(() => metadataStore.model.action === 'add' ? '新增' : '
const propertyForm = ref() const propertyForm = ref()
const form = reactive({ const form = reactive({
model: { model: {} as any,
valueType: {
expands: {}
},
expands: {}
} as any,
}) })
if (metadataStore.model.action === 'edit') { if (metadataStore.model.action === 'edit') {
form.model = metadataStore.model.item form.model = metadataStore.model.item
@ -144,6 +139,44 @@ const save = reactive({
}) })
</script> </script>
<style lang="less" scoped> <style scoped lang="less">
:deep(.ant-form-item-label) {
line-height: 1;
>label {
font-size: 12px;
&.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
font-size: 12px;
}
}
}
:deep(.ant-form-item-explain) {
font-size: 12px;
}
:deep(.ant-form-item-with-help) {
.ant-form-item-explain {
min-height: 20px;
line-height: 20px;
}
}
:deep(.ant-form-item) {
margin-bottom: 20px;
&.ant-form-item-with-help {
margin-bottom: 0;
}
input {
font-size: 12px;
}
}
:deep(.ant-input),
:deep(.ant-select) {
font-size: 12px;
}
</style> </style>

View File

@ -9,7 +9,7 @@
title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增', title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增',
}"> }">
<template #icon> <template #icon>
<PlusOutlined /> <AIcon type="PlusOutlined" />
</template> </template>
新增 新增
</PermissionButton> </PermissionButton>
@ -38,7 +38,7 @@
:udisabled="operateLimits('updata', type)" @click="handleEditClick(slotProps)" :tooltip="{ :udisabled="operateLimits('updata', type)" @click="handleEditClick(slotProps)" :tooltip="{
title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑', title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑',
}"> }">
<EditOutlined /> <AIcon type="EditOutlined" />
</PermissionButton> </PermissionButton>
<PermissionButton :uhas-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0" <PermissionButton :uhas-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0"
:pop-confirm="{ :pop-confirm="{
@ -48,7 +48,7 @@
}" :tooltip="{ }" :tooltip="{
title: '删除', title: '删除',
}"> }">
<DeleteOutlined /> <Aicon type="DeleteOutlined" />
</PermissionButton> </PermissionButton>
</a-space> </a-space>
</template> </template>
@ -62,7 +62,6 @@ import { useInstanceStore } from '@/store/instance'
import { useProductStore } from '@/store/product' import { useProductStore } from '@/store/product'
import { useMetadataStore } from '@/store/metadata' import { useMetadataStore } from '@/store/metadata'
import PermissionButton from '@/components/PermissionButton/index.vue' import PermissionButton from '@/components/PermissionButton/index.vue'
import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue/es' import { message } from 'ant-design-vue/es'
import { SystemConst } from '@/utils/consts' import { SystemConst } from '@/utils/consts'
import { Store } from 'jetlinks-store' import { Store } from 'jetlinks-store'

View File

@ -3,7 +3,7 @@
@ok="handleImport" :confirm-loading="loading"> @ok="handleImport" :confirm-loading="loading">
<div class="import-content"> <div class="import-content">
<p class="import-tip"> <p class="import-tip">
<exclamation-circle-outlined style="margin-right: 5px" /> <AIcon type="ExclamationCircleOutlined" style="margin-right: 5px" />
导入的物模型会覆盖原来的属性功能事件标签请谨慎操作 导入的物模型会覆盖原来的属性功能事件标签请谨慎操作
</p> </p>
</div> </div>
@ -37,8 +37,7 @@
<a-upload v-model:file-list="fileList" :before-upload="beforeUpload" accept=".json" <a-upload v-model:file-list="fileList" :before-upload="beforeUpload" accept=".json"
:show-upload-list="false" :action="FILE_UPLOAD" @change="fileChange" :show-upload-list="false" :action="FILE_UPLOAD" @change="fileChange"
:headers="{ 'X-Access-Token': getToken()}"> :headers="{ 'X-Access-Token': getToken()}">
<upload-outlined class="upload-button"/> <AIcon type="UploadOutlined" class="upload-button" />
<!-- <button id="uploadFile" style="display: none;"></button> -->
</a-upload> </a-upload>
</template> </template>
</a-input> </a-input>
@ -62,9 +61,8 @@ import { Store } from 'jetlinks-store';
import { SystemConst } from '@/utils/consts'; import { SystemConst } from '@/utils/consts';
import { useInstanceStore } from '@/store/instance' import { useInstanceStore } from '@/store/instance'
import { useProductStore } from '@/store/product'; import { useProductStore } from '@/store/product';
import { UploadOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { FILE_UPLOAD } from '@/api/comm'; import { FILE_UPLOAD } from '@/api/comm';
import { LocalStore, getToken } from '@/utils/comm'; import { getToken } from '@/utils/comm';
import MonacoEditor from '@/components/MonacoEditor/index.vue' import MonacoEditor from '@/components/MonacoEditor/index.vue'
const route = useRoute() const route = useRoute()
@ -258,13 +256,15 @@ const handleImport = async () => {
if (resp.status === 200) { if (resp.status === 200) {
if (props?.type === 'device') { if (props?.type === 'device') {
const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}') const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}')
// TODO
// MetadataAction.insert(metadata); // MetadataAction.insert(metadata);
instanceStore.setCurrent(metadata) // instanceStore.setCurrent(metadata)
message.success('导入成功') message.success('导入成功')
} else { } else {
const metadata: ProductItem = JSON.parse(params?.metadata || '{}') const metadata: ProductItem = JSON.parse(params?.metadata || '{}')
// TODO
// MetadataAction.insert(metadata); // MetadataAction.insert(metadata);
productStore.setCurrent(metadata) // productStore.setCurrent(metadata)
message.success('导入成功') message.success('导入成功')
} }
} }

View File

@ -6,7 +6,7 @@
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响' ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
: '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'"> : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'">
<div class="ellipsis"> <div class="ellipsis">
<info-circle-outlined style="margin-right: 3px" /> <AIcon type="InfoCircleOutlined" style="margin-right: 3px" />
{{ {{
instanceStore.detail?.independentMetadata && type === 'device' instanceStore.detail?.independentMetadata && type === 'device'
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响' ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
@ -47,7 +47,6 @@
</a-card> </a-card>
</template> </template>
<script setup lang="ts" name="Metadata"> <script setup lang="ts" name="Metadata">
import { InfoCircleOutlined } from '@ant-design/icons-vue';
import PermissionButton from '@/components/PermissionButton/index.vue' import PermissionButton from '@/components/PermissionButton/index.vue'
import { deleteMetadata } from '@/api/device/instance.js' import { deleteMetadata } from '@/api/device/instance.js'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'