fix: 物模型组件修改
This commit is contained in:
parent
56122ac90c
commit
23aff419a3
|
@ -2,36 +2,36 @@
|
||||||
<div class="indicator-box">
|
<div class="indicator-box">
|
||||||
<template v-if="['int', 'long', 'double', 'float'].includes(type)">
|
<template v-if="['int', 'long', 'double', 'float'].includes(type)">
|
||||||
<template v-if="value.range">
|
<template v-if="value.range">
|
||||||
<a-input-number v-model:value="value.value[0]" :max="value.value[1]" size="small"
|
<j-input-number v-model:value="value.value[0]" :max="value.value[1]" size="small"
|
||||||
style="width: 100%;"></a-input-number>
|
style="width: 100%;"></j-input-number>
|
||||||
~
|
~
|
||||||
<a-input-number v-model:value="value.value[1]" :min="value.value[0]" size="small"
|
<j-input-number v-model:value="value.value[1]" :min="value.value[0]" size="small"
|
||||||
style="width: 100%;"></a-input-number>
|
style="width: 100%;"></j-input-number>
|
||||||
</template>
|
</template>
|
||||||
<a-input-number v-else v-model:value="value.value" size="small" style="width: 100%;"></a-input-number>
|
<j-input-number v-else v-model:value="value.value" size="small" style="width: 100%;"></j-input-number>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="type === 'date'">
|
<template v-else-if="type === 'date'">
|
||||||
<a-range-picker v-if="value.range" show-time v-model:value="value.value" size="small" />
|
<j-range-picker v-if="value.range" show-time v-model:value="value.value" size="small" />
|
||||||
<a-date-picker v-else show-time v-model:value="value.value" size="small" />
|
<j-date-picker v-else show-time v-model:value="value.value" size="small" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="type === 'boolean'">
|
<template v-else-if="type === 'boolean'">
|
||||||
<a-select v-model:value="value.value[0]" :options="list" size="small" placeholder="请选择"></a-select>
|
<j-select v-model:value="value.value[0]" :options="list" size="small" placeholder="请选择"></j-select>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="type === 'string'">
|
<template v-else-if="type === 'string'">
|
||||||
<a-input v-model:value="value.value" size="small" placeholder="请输入"></a-input>
|
<j-input v-model:value="value.value" size="small" placeholder="请输入"></j-input>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-if="value.range">
|
<template v-if="value.range">
|
||||||
<a-input v-model:value="value.value[0]" :max="value.value[1]" size="small" placeholder="请输入"></a-input>
|
<j-input v-model:value="value.value[0]" :max="value.value[1]" size="small" placeholder="请输入"></j-input>
|
||||||
~
|
~
|
||||||
<a-input v-model:value="value.value[1]" :min="value.value[0]" size="small" placeholder="请输入"></a-input>
|
<j-input v-model:value="value.value[1]" :min="value.value[0]" size="small" placeholder="请输入"></j-input>
|
||||||
</template>
|
</template>
|
||||||
<a-input-number v-else v-model:value="value.value" size="small" placeholder="请输入"></a-input-number>
|
<j-input-number v-else v-model:value="value.value" size="small" placeholder="请输入"></j-input-number>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="type !== 'boolean' && type !== 'string'">
|
<div v-if="type !== 'boolean' && type !== 'string'">
|
||||||
<a-checkbox style="min-width: 60px; margin-left: 5px;" v-model:checked="value.range" @change="changeChecked">
|
<j-checkbox style="min-width: 60px; margin-left: 5px;" v-model:checked="value.range" @change="changeChecked">
|
||||||
范围
|
范围
|
||||||
</a-checkbox>
|
</j-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popover :visible="visible" placement="left">
|
<j-popover :visible="visible" placement="left">
|
||||||
<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>
|
||||||
|
@ -10,19 +10,19 @@
|
||||||
<div style="max-width: 400px;">
|
<div style="max-width: 400px;">
|
||||||
<div class="ant-form-vertical">
|
<div class="ant-form-vertical">
|
||||||
<value-type-form v-model:value="_value" :name="name" isSub key="sub"></value-type-form>
|
<value-type-form v-model:value="_value" :name="name" isSub key="sub"></value-type-form>
|
||||||
<a-form-item label="说明" :name="name.concat(['description'])" :rules="[
|
<j-form-item label="说明" :name="name.concat(['description'])" :rules="[
|
||||||
{ max: 200, message: '最多可输入200个字符' },
|
{ max: 200, message: '最多可输入200个字符' },
|
||||||
]">
|
]">
|
||||||
<a-textarea v-model:value="_value.description" size="small"></a-textarea>
|
<j-textarea v-model:value="_value.description" size="small"></j-textarea>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-button type="dashed" block @click="visible = true">
|
<j-button type="dashed" block @click="visible = true">
|
||||||
配置元素
|
配置元素
|
||||||
<AIcon type="EditOutlined" class="item-icon" />
|
<AIcon type="EditOutlined" class="item-icon" />
|
||||||
</a-button>
|
</j-button>
|
||||||
</a-popover>
|
</j-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';
|
||||||
|
@ -33,7 +33,7 @@ type ValueType = Record<any, any>;
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: {
|
value: {
|
||||||
type: Object as PropType<ValueType>,
|
type: Object as PropType<ValueType>,
|
||||||
default: () => ({ extends: {} })
|
default: () => ({ expands: {} })
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: Array as PropType<(string | number)[]>,
|
type: Array as PropType<(string | number)[]>,
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="boolean-param">
|
<div class="boolean-param">
|
||||||
<a-row :gutter="4">
|
<j-row :gutter="4">
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label=" " :name="name.concat(['trueText'])" :rules="[
|
<j-form-item label=" " :name="name.concat(['trueText'])" :rules="[
|
||||||
{ required: true, message: '请输入trueText' },
|
{ required: true, message: '请输入trueText' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.trueText" placeholder="trueText" size="small" />
|
<j-input v-model:value="value.trueText" placeholder="trueText" size="small" />
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label="-" :name="name.concat(['trueValue'])" :rules="[
|
<j-form-item label="-" :name="name.concat(['trueValue'])" :rules="[
|
||||||
{ required: true, message: '请输入trueValue' },
|
{ required: true, message: '请输入trueValue' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.trueValue" placeholder="trueValue" size="small"/>
|
<j-input v-model:value="value.trueValue" placeholder="trueValue" size="small"/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label=" " :name="name.concat(['falseText'])" :rules="[
|
<j-form-item label=" " :name="name.concat(['falseText'])" :rules="[
|
||||||
{ required: true, message: '请输入falseText' },
|
{ required: true, message: '请输入falseText' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.falseText" placeholder="falseText" size="small" />
|
<j-input v-model:value="value.falseText" placeholder="falseText" size="small" />
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label="-" :name="name.concat(['falseValue'])" :rules="[
|
<j-form-item label="-" :name="name.concat(['falseValue'])" :rules="[
|
||||||
{ required: true, message: '请输入falseValue' },
|
{ required: true, message: '请输入falseValue' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.falseValue" placeholder="falseValue" size="small" />
|
<j-input v-model:value="value.falseValue" placeholder="falseValue" size="small" />
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="BooleanParam">
|
<script setup lang="ts" name="BooleanParam">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popover placement="left" trigger="click">
|
<j-popover placement="left" trigger="click">
|
||||||
<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;">{{ config.name }}</div>
|
<div style="width: 150px;">{{ config.name }}</div>
|
||||||
|
@ -7,18 +7,18 @@
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div style="max-width: 400px;" class="ant-form-vertical">
|
<div style="max-width: 400px;" class="ant-form-vertical">
|
||||||
<a-form-item v-for="item in config.properties" :name="name.concat([item.property])" :label="item.name">
|
<j-form-item v-for="item in config.properties" :name="name.concat([item.property])" :label="item.name">
|
||||||
<a-select v-model:value="value[item.property]" :options="item.type?.elements?.map((e: { 'text': string, 'value': string }) => ({
|
<j-select v-model:value="value[item.property]" :options="item.type?.elements?.map((e: { 'text': string, 'value': string }) => ({
|
||||||
label: e.text,
|
label: e.text,
|
||||||
value: e.value,
|
value: e.value,
|
||||||
}))" size="small"></a-select>
|
}))" size="small"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-button type="dashed" block>
|
<j-button type="dashed" block>
|
||||||
存储配置<AIcon type="EditOutlined" class="item-icon"/>
|
存储配置<AIcon type="EditOutlined" class="item-icon"/>
|
||||||
</a-button>
|
</j-button>
|
||||||
</a-popover>
|
</j-popover>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="ConfigParam">
|
<script setup lang="ts" name="ConfigParam">
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<AIcon type="MenuOutlined" 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">
|
<j-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>
|
||||||
|
@ -14,34 +14,34 @@
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="ant-form-vertical">
|
<div class="ant-form-vertical">
|
||||||
<a-form-item label="Value" :name="name.concat([index, 'value'])" :rules="[
|
<j-form-item label="Value" :name="name.concat([index, 'value'])" :rules="[
|
||||||
{ required: true, message: '请输入Value' },
|
{ required: true, message: '请输入Value' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].value" size="small"></a-input>
|
<j-input v-model:value="_value[index].value" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="Text" :name="name.concat([index, 'text'])" :rules="[
|
<j-form-item label="Text" :name="name.concat([index, 'text'])" :rules="[
|
||||||
{ required: true, message: '请输入Text' },
|
{ required: true, message: '请输入Text' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].text" size="small"></a-input>
|
<j-input v-model:value="_value[index].text" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="item-edit" @click="handleEdit(index)">
|
<div class="item-edit" @click="handleEdit(index)">
|
||||||
{{ item.text || '枚举项配置' }}
|
{{ item.text || '枚举项配置' }}
|
||||||
<AIcon type="EditOutlined" class="item-icon" />
|
<AIcon type="EditOutlined" class="item-icon" />
|
||||||
</div>
|
</div>
|
||||||
</a-popover>
|
</j-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-right">
|
<div class="item-right">
|
||||||
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-button type="dashed" block @click="handleAdd">
|
<j-button type="dashed" block @click="handleAdd">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AIcon type="PlusOutlined" class="item-icon" />
|
<AIcon type="PlusOutlined" class="item-icon" />
|
||||||
</template>
|
</template>
|
||||||
新增枚举型
|
新增枚举型
|
||||||
</a-button>
|
</j-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="BooleanParam">
|
<script setup lang="ts" name="BooleanParam">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<AIcon type="MenuOutlined" 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">
|
<j-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>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div style="max-width: 400px;" class="ant-form-vertical">
|
<div style="max-width: 400px;" class="ant-form-vertical">
|
||||||
<a-form-item label="标识" :name="name.concat([index, 'id'])" :rules="[
|
<j-form-item label="标识" :name="name.concat([index, 'id'])" :rules="[
|
||||||
{ required: true, message: '请输入标识' },
|
{ required: true, message: '请输入标识' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
{
|
{
|
||||||
|
@ -22,14 +22,14 @@
|
||||||
message: 'ID只能由数字、字母、下划线、中划线组成',
|
message: 'ID只能由数字、字母、下划线、中划线组成',
|
||||||
},
|
},
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].id" size="small"></a-input>
|
<j-input v-model:value="_value[index].id" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="名称" :name="name.concat([index, 'name'])" :rules="[
|
<j-form-item label="名称" :name="name.concat([index, 'name'])" :rules="[
|
||||||
{ required: true, message: '请输入名称' },
|
{ required: true, message: '请输入名称' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].name" size="small"></a-input>
|
<j-input v-model:value="_value[index].name" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<value-type-form v-model:value="_value[index].valueType" :name="name.concat([index, 'valueType'])" isSub
|
<value-type-form v-model:value="_value[index].valueType" :name="name.concat([index, 'valueType'])" isSub
|
||||||
key="json_sub"></value-type-form>
|
key="json_sub"></value-type-form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,18 +38,18 @@
|
||||||
{{ item.name || '配置参数' }}
|
{{ item.name || '配置参数' }}
|
||||||
<AIcon type="EditOutlined" class="item-icon" />
|
<AIcon type="EditOutlined" class="item-icon" />
|
||||||
</div>
|
</div>
|
||||||
</a-popover>
|
</j-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-right">
|
<div class="item-right">
|
||||||
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-button type="dashed" block @click="handleAdd">
|
<j-button type="dashed" block @click="handleAdd">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AIcon type="PlusOutlined" class="item-icon" />
|
<AIcon type="PlusOutlined" class="item-icon" />
|
||||||
</template>
|
</template>
|
||||||
添加参数
|
添加参数
|
||||||
</a-button>
|
</j-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="JsonParam">
|
<script setup lang="ts" name="JsonParam">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{{ `#${index + 1}.` }}
|
{{ `#${index + 1}.` }}
|
||||||
</div>
|
</div>
|
||||||
<div class="item-middle item-editable">
|
<div class="item-middle item-editable">
|
||||||
<a-popover :visible="editIndex === index" placement="top" @visible-change="change" trigger="click">
|
<j-popover :visible="editIndex === index" placement="top" @visible-change="change" trigger="click">
|
||||||
<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>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
<template #content>
|
<template #content>
|
||||||
<div>
|
<div>
|
||||||
<div class="ant-form-vertical">
|
<div class="ant-form-vertical">
|
||||||
<a-form-item label="标识" :name="name.concat([index, 'id'])" :rules="[
|
<j-form-item label="标识" :name="name.concat([index, 'id'])" :rules="[
|
||||||
{ required: true, message: '请输入标识' },
|
{ required: true, message: '请输入标识' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
{
|
{
|
||||||
|
@ -24,20 +24,19 @@
|
||||||
message: 'ID只能由数字、字母、下划线、中划线组成',
|
message: 'ID只能由数字、字母、下划线、中划线组成',
|
||||||
},
|
},
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].id" size="small"></a-input>
|
<j-input v-model:value="_value[index].id" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="名称" :name="name.concat([index, 'name'])" :rules="[
|
<j-form-item label="名称" :name="name.concat([index, 'name'])" :rules="[
|
||||||
{ required: true, message: '请输入名称' },
|
{ required: true, message: '请输入名称' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="_value[index].name" size="small"></a-input>
|
<j-input v-model:value="_value[index].name" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="指标值" :name="name.concat([index, 'value'])" :rules="[
|
<j-form-item label="指标值" :name="name.concat([index, 'value'])" :rules="[
|
||||||
{ required: true, message: '请输入指标值' },
|
{ required: true, validator: () => validateIndicator(_value[index]), message: '请输入指标值' }
|
||||||
{ validator: () => validateIndicator(_value[index]), message: '请输入指标值' }
|
|
||||||
]">
|
]">
|
||||||
<JIndicators v-model:value="_value[index]" :type="type" size="small" :enum="enum" />
|
<JIndicators v-model:value="_value[index]" :type="type" size="small" :enum="enum" />
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -45,18 +44,18 @@
|
||||||
{{ item.name || '配置参数' }}
|
{{ item.name || '配置参数' }}
|
||||||
<AIcon type="EditOutlined" class="item-icon" />
|
<AIcon type="EditOutlined" class="item-icon" />
|
||||||
</div>
|
</div>
|
||||||
</a-popover>
|
</j-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-right">
|
<div class="item-right">
|
||||||
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
<AIcon type="DeleteOutlined" @click="handleDelete(index)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-button type="dashed" block @click="handleAdd">
|
<j-button type="dashed" block @click="handleAdd">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AIcon type="PlusOutlined" class="item-icon" />
|
<AIcon type="PlusOutlined" class="item-icon" />
|
||||||
</template>
|
</template>
|
||||||
添加指标
|
添加指标
|
||||||
</a-button>
|
</j-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="MetricsParam">
|
<script setup lang="ts" name="MetricsParam">
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form-item :name="name.concat(['script'])">
|
<j-form-item :name="name.concat(['script'])">
|
||||||
<f-rule-editor v-model:value="value.script" :id="id"></f-rule-editor>
|
<f-rule-editor v-model:value="value.script" :id="id"></f-rule-editor>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<template v-if="showWindow">
|
<template v-if="showWindow">
|
||||||
<a-form-item label="规则配置" :name="name.concat(['isVirtualRule'])">
|
<j-form-item label="规则配置" :name="name.concat(['isVirtualRule'])">
|
||||||
<a-switch v-model:checked="value.isVirtualRule" :checked-value="true" :un-checked-value="false"
|
<j-switch v-model:checked="value.isVirtualRule" :checked-value="true" :un-checked-value="false"
|
||||||
@change="changeWindow"></a-switch>
|
@change="changeWindow"></j-switch>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<template v-if="value.isVirtualRule">
|
<template v-if="value.isVirtualRule">
|
||||||
<a-form-item label="窗口" :name="name.concat(['windowType'])" :rules="[
|
<j-form-item label="窗口" :name="name.concat(['windowType'])" :rules="[
|
||||||
{ required: true, message: '请选择窗口' },
|
{ required: true, message: '请选择窗口' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="value.windowType" :options="windowTypeEnum" size="small" allow-clear></a-select>
|
<j-select v-model:value="value.windowType" :options="windowTypeEnum" size="small" allow-clear></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="聚合函数" :name="name.concat(['aggType'])" :rules="[
|
<j-form-item label="聚合函数" :name="name.concat(['aggType'])" :rules="[
|
||||||
{ required: true, message: '请选择聚合函数' },
|
{ required: true, message: '请选择聚合函数' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="value.aggType" :options="aggTypeOptions" size="small" allow-clear></a-select>
|
<j-select v-model:value="value.aggType" :options="aggTypeOptions" size="small" allow-clear></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item :label="spanLabel" :name="name.concat(['window', 'span'])" :rules="[
|
<j-form-item :label="spanLabel" :name="name.concat(['window', 'span'])" :rules="[
|
||||||
{ required: true, message: '请输入窗口长度' },
|
{ required: true, message: '请输入窗口长度' },
|
||||||
]">
|
]">
|
||||||
<a-input-number v-model:value="value.window.span" size="small" style="width: 100%;"></a-input-number>
|
<j-input-number v-model:value="value.window.span" size="small" style="width: 100%;"></j-input-number>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item :label="everyLabel" :name="name.concat(['window', 'every'])" :rules="[
|
<j-form-item :label="everyLabel" :name="name.concat(['window', 'every'])" :rules="[
|
||||||
{ required: true, message: '请输入步长' },
|
{ required: true, message: '请输入步长' },
|
||||||
]">
|
]">
|
||||||
<a-input-number v-model:value="value.window.every" size="small" style="width: 100%;"></a-input-number>
|
<j-input-number v-model:value="value.window.every" size="small" style="width: 100%;"></j-input-number>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form-item label="标识" name="id" :rules="[
|
<j-form-item label="标识" name="id" :rules="[
|
||||||
{ required: true, message: '请输入标识' },
|
{ required: true, message: '请输入标识' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
{
|
{
|
||||||
|
@ -7,14 +7,14 @@
|
||||||
message: 'ID只能由数字、字母、下划线、中划线组成',
|
message: 'ID只能由数字、字母、下划线、中划线组成',
|
||||||
},
|
},
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.id" size="small" @change="asyncOtherConfig" :disabled="metadataStore.model.action === 'edit'"></a-input>
|
<j-input v-model:value="value.id" size="small" @change="asyncOtherConfig" :disabled="metadataStore.model.action === 'edit'"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="名称" name="name" :rules="[
|
<j-form-item label="名称" name="name" :rules="[
|
||||||
{ required: true, message: '请输入名称' },
|
{ required: true, message: '请输入名称' },
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
]">
|
]">
|
||||||
<a-input v-model:value="value.name" size="small"></a-input>
|
<j-input v-model:value="value.name" size="small"></j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<template v-if="modelType === 'properties'">
|
<template v-if="modelType === 'properties'">
|
||||||
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="property" title="数据类型"
|
<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>
|
||||||
|
@ -22,42 +22,42 @@
|
||||||
:valueType="value.valueType"></expands-form>
|
:valueType="value.valueType"></expands-form>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="modelType === 'functions'">
|
<template v-if="modelType === 'functions'">
|
||||||
<a-form-item label="是否异步" name="async" :rules="[
|
<j-form-item label="是否异步" name="async" :rules="[
|
||||||
{ required: true, message: '请选择是否异步' },
|
{ required: true, message: '请选择是否异步' },
|
||||||
]">
|
]">
|
||||||
<a-radio-group v-model:value="value.async">
|
<j-radio-group v-model:value="value.async">
|
||||||
<a-radio :value="true">是</a-radio>
|
<j-radio :value="true">是</j-radio>
|
||||||
<a-radio :value="false">否</a-radio>
|
<j-radio :value="false">否</j-radio>
|
||||||
</a-radio-group>
|
</j-radio-group>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="输入参数" name="inputs" :rules="[
|
<j-form-item label="输入参数" name="inputs" :rules="[
|
||||||
{ required: true, message: '请输入输入参数' },
|
{ required: true, message: '请输入输入参数' },
|
||||||
]">
|
]">
|
||||||
<JsonParam v-model:value="value.inputs" :name="['inputs']"></JsonParam>
|
<JsonParam v-model:value="value.inputs" :name="['inputs']"></JsonParam>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<value-type-form :name="['output']" v-model:value="value.output" key="function" title="输出参数"></value-type-form>
|
<value-type-form :name="['output']" v-model:value="value.output" key="function" title="输出参数"></value-type-form>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="modelType === 'events'">
|
<template v-if="modelType === 'events'">
|
||||||
<a-form-item label="级别" :name="['expands', 'level']" :rules="[
|
<j-form-item label="级别" :name="['expands', 'level']" :rules="[
|
||||||
{ required: true, message: '请选择级别' },
|
{ required: true, message: '请选择级别' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="value.expands.level" :options="EventLevel" size="small"></a-select>
|
<j-select v-model:value="value.expands.level" :options="EventLevel" size="small"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="function" title="输出参数"></value-type-form>
|
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="function" title="输出参数"></value-type-form>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="modelType === 'tags'">
|
<template v-if="modelType === 'tags'">
|
||||||
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="property" title="数据类型"></value-type-form>
|
<value-type-form :name="['valueType']" v-model:value="value.valueType" key="property" title="数据类型"></value-type-form>
|
||||||
<a-form-item label="读写类型" :name="['expands', 'type']" :rules="[
|
<j-form-item label="读写类型" :name="['expands', 'type']" :rules="[
|
||||||
{ required: true, message: '请选择读写类型' },
|
{ required: true, message: '请选择读写类型' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="value.expands.type" :options="ExpandsTypeList" mode="multiple" size="small"></a-select>
|
<j-select v-model:value="value.expands.type" :options="ExpandsTypeList" mode="multiple" size="small"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<a-form-item label="说明" name="description" :rules="[
|
<j-form-item label="说明" name="description" :rules="[
|
||||||
{ max: 200, message: '最多可输入200个字符' },
|
{ max: 200, message: '最多可输入200个字符' },
|
||||||
]">
|
]">
|
||||||
<a-textarea v-model:value="value.description" size="small"></a-textarea>
|
<j-textarea v-model:value="value.description" size="small"></j-textarea>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="BaseForm">
|
<script setup lang="ts" name="BaseForm">
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form-item label="来源" :name="name.concat(['source'])" v-if="type === 'product'" :rules="[
|
<j-form-item label="来源" :name="name.concat(['source'])" v-if="type === 'product'" :rules="[
|
||||||
{ required: true, message: '请选择来源' },
|
{ required: true, message: '请选择来源' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="_value.source" :options="PropertySource" size="small"
|
<j-select v-model:value="_value.source" :options="PropertySource" size="small"
|
||||||
:disabled="metadataStore.model.action === 'edit'"></a-select>
|
:disabled="metadataStore.model.action === 'edit'"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<virtual-rule-param v-if="_value.source === 'rule'" v-model:value="_value.virtualRule"
|
<virtual-rule-param v-if="_value.source === 'rule'" v-model:value="_value.virtualRule"
|
||||||
:name="name.concat(['virtualRule'])" :id="id" :showWindow="_value.source === 'rule'"></virtual-rule-param>
|
:name="name.concat(['virtualRule'])" :id="id" :showWindow="_value.source === 'rule'"></virtual-rule-param>
|
||||||
<a-form-item label="读写类型" :name="name.concat(['type'])" :rules="[
|
<j-form-item label="读写类型" :name="name.concat(['type'])" :rules="[
|
||||||
{ required: true, message: '请选择读写类型' },
|
{ required: true, message: '请选择读写类型' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="_value.type" :options="ExpandsTypeList" mode="multiple" size="small"></a-select>
|
<j-select v-model:value="_value.type" :options="ExpandsTypeList" mode="multiple" size="small"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="其他配置" v-if="config.length > 0">
|
<j-form-item label="其他配置" v-if="config.length > 0">
|
||||||
<a-form-item v-for="(item, index) in config" :key="index">
|
<j-form-item v-for="(item, index) in config" :key="index">
|
||||||
<config-param v-model:value="_value" :config="item" :name="name"></config-param>
|
<config-param v-model:value="_value" :config="item" :name="name"></config-param>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item v-if="type === 'product' && ['int', 'float', 'double', 'long', 'date', 'string', 'boolean'].includes(valueType.type)"
|
<j-form-item
|
||||||
label="指标配置" :name="name.concat(['metrics'])">
|
v-if="type === 'product' && ['int', 'float', 'double', 'long', 'date', 'string', 'boolean'].includes(valueType.type)"
|
||||||
<metrics-param v-model:value="_value.metrics" :type="valueType.type" :enum="valueType" :name="name.concat(['metrics'])"></metrics-param>
|
label="指标配置" :name="name.concat(['metrics'])" :rules="[
|
||||||
</a-form-item>
|
{ validator: () => validateMetrics(_value.metrics), message: '请输入指标配置' }
|
||||||
|
]">
|
||||||
|
<metrics-param v-model:value="_value.metrics" :type="valueType.type" :enum="valueType"
|
||||||
|
:name="name.concat(['metrics'])"></metrics-param>
|
||||||
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="ExpandsForm">
|
<script setup lang="ts" name="ExpandsForm">
|
||||||
import { useMetadataStore } from '@/store/metadata';
|
import { useMetadataStore } from '@/store/metadata';
|
||||||
|
@ -86,5 +90,15 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const validateMetrics = (value: Record<any, any>[]) => {
|
||||||
|
const flag = value.every((item) => {
|
||||||
|
return item.id && item.name && item.value;
|
||||||
|
});
|
||||||
|
if (!flag) {
|
||||||
|
return Promise.reject(new Error('请输入指标配置'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
|
@ -1,48 +1,54 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form-item :label="title" :name="name.concat(['type'])" :rules="[
|
<j-form-item :label="title" :name="name.concat(['type'])" :rules="[
|
||||||
metadataStore.model.type !== 'functions' ? { required: true, message: `请选择${title}` } : {},
|
metadataStore.model.type !== 'functions' ? { required: true, message: `请选择${title}` } : {},
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="_value.type" :options="metadataStore.model.type === 'events' ? eventDataTypeList : _dataTypeList" size="small" @change="changeType"></a-select>
|
<j-select v-model:value="_value.type"
|
||||||
</a-form-item>
|
:options="metadataStore.model.type === 'events' ? eventDataTypeList : _dataTypeList" size="small"
|
||||||
<a-form-item label="单位" :name="name.concat(['unit'])" v-if="['int', 'float', 'long', 'double'].includes(_value.type)">
|
@change="changeType"></j-select>
|
||||||
|
</j-form-item>
|
||||||
|
<j-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>
|
</j-form-item>
|
||||||
<a-form-item label="精度" :name="name.concat(['scale'])" v-if="['float', 'double'].includes(_value.type)">
|
<j-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" :default-value="2"
|
<j-input-number v-model:value="_value.scale" size="small" :min="0" :max="2147483647" :precision="0" :default-value="2"
|
||||||
style="width: 100%"></a-input-number>
|
style="width: 100%"></j-input-number>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="布尔值" name="booleanConfig" v-if="['boolean'].includes(_value.type)">
|
<j-form-item label="布尔值" name="booleanConfig" v-if="['boolean'].includes(_value.type)">
|
||||||
<BooleanParam :name="name" v-model:value="_value"></BooleanParam>
|
<BooleanParam :name="name" v-model:value="_value"></BooleanParam>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="枚举项" :name="name.concat(['elements'])" v-if="['enum'].includes(_value.type)" :rules="[
|
<j-form-item label="枚举项" :name="name.concat(['elements'])" v-if="['enum'].includes(_value.type)" :rules="[
|
||||||
{ required: true, message: '请配置枚举项' }
|
{ required: true, validator: validateEnum, message: '请配置枚举项' }
|
||||||
]">
|
]">
|
||||||
<EnumParam v-model:value="_value.elements" :name="name.concat(['elements'])"></EnumParam>
|
<EnumParam v-model:value="_value.elements" :name="name.concat(['elements'])"></EnumParam>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item :name="name.concat(['expands', 'maxLength'])" v-if="['string', 'password'].includes(_value.type)">
|
<j-form-item :name="name.concat(['expands', 'maxLength'])" v-if="['string', 'password'].includes(_value.type)">
|
||||||
<template #label>
|
<template #label>
|
||||||
<a-space>
|
<j-space>
|
||||||
最大长度
|
最大长度
|
||||||
<a-tooltip title="字节">
|
<j-tooltip title="字节">
|
||||||
<question-circle-outlined style="color: rgb(136, 136, 136); font-size: 12px;" />
|
<question-circle-outlined style="color: rgb(136, 136, 136); font-size: 12px;" />
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<a-input-number v-model:value="_value.expands.maxLength" size="small" :max="2147483647" :min="1" :precision="0"
|
<j-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%;"></j-input-number>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="元素配置" :name="name.concat(['elementType'])" v-if="['array'].includes(_value.type)">
|
<j-form-item label="元素配置" :name="name.concat(['elementType'])" v-if="['array'].includes(_value.type)" :rules="[
|
||||||
|
{ validator: validateArray }
|
||||||
|
]">
|
||||||
<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>
|
</j-form-item>
|
||||||
<a-form-item label="JSON对象" :name="name.concat(['properties'])" v-if="['object'].includes(_value.type)" :rules="[]">
|
<j-form-item label="JSON对象" :name="name.concat(['properties'])" v-if="['object'].includes(_value.type)" :rules="[
|
||||||
|
{ validator: validateJson }
|
||||||
|
]">
|
||||||
<JsonParam v-model:value="_value.properties" :name="name.concat(['properties'])"></JsonParam>
|
<JsonParam v-model:value="_value.properties" :name="name.concat(['properties'])"></JsonParam>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="文件类型" :name="name.concat(['fileType'])" v-if="['file'].includes(_value.type)" initialValue="url"
|
<j-form-item label="文件类型" :name="name.concat(['fileType'])" v-if="['file'].includes(_value.type)" initialValue="url"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true, message: '请选择文件类型' },
|
{ required: true, message: '请选择文件类型' },
|
||||||
]">
|
]">
|
||||||
<a-select v-model:value="_value.fileType" :options="FileTypeList" size="small"></a-select>
|
<j-select v-model:value="_value.fileType" :options="FileTypeList" size="small"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup mame="BaseForm">
|
<script lang="ts" setup mame="BaseForm">
|
||||||
import { DataTypeList, FileTypeList } from '@/views/device/data';
|
import { DataTypeList, FileTypeList } from '@/views/device/data';
|
||||||
|
@ -56,6 +62,8 @@ 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';
|
import { useMetadataStore } from '@/store/metadata';
|
||||||
|
import { Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { Form } from 'ant-design-vue/es';
|
||||||
|
|
||||||
type ValueType = Record<any, any>;
|
type ValueType = Record<any, any>;
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -84,15 +92,8 @@ interface Emits {
|
||||||
}
|
}
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
|
|
||||||
// emit('update:value', { extends: {}, ...props.value })
|
|
||||||
|
|
||||||
const metadataStore = useMetadataStore()
|
const metadataStore = useMetadataStore()
|
||||||
// const _value = computed({
|
|
||||||
// get: () => props.value,
|
|
||||||
// set: val => {
|
|
||||||
// emit('update:value', val)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
const _value = ref<ValueType>({})
|
const _value = ref<ValueType>({})
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
_value.value = props.value || {
|
_value.value = props.value || {
|
||||||
|
@ -142,6 +143,79 @@ const eventDataTypeList = [
|
||||||
const changeType = (val: SelectValue) => {
|
const changeType = (val: SelectValue) => {
|
||||||
emit('changeType', val as string)
|
emit('changeType', val as string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateEnum = async (_rule: Rule, val: Record<any, any>[]) => {
|
||||||
|
if (val.length === 0) return Promise.reject(new Error('请配置枚举项'));
|
||||||
|
const flag = val.every((item) => {
|
||||||
|
return item.value && item.text;
|
||||||
|
});
|
||||||
|
if (!flag) {
|
||||||
|
return Promise.reject(new Error('请配置枚举项'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateArray = async (_rule: Rule, val: Record<any, any>) => {
|
||||||
|
if (!val) return Promise.reject(new Error('请输入元素配置'));
|
||||||
|
await validateValueType(_rule, val)
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateJson = async (_rule: Rule, val: Record<any, any>[]) => {
|
||||||
|
if (!val || val.length === 0) {
|
||||||
|
return Promise.reject(new Error('请输入配置参数'));
|
||||||
|
}
|
||||||
|
for (let item of val) {
|
||||||
|
if (!item) return Promise.reject(new Error('请输入配置参数'));
|
||||||
|
await validateValueType(_rule, item)
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateValueType = async (_rule: Rule, val: Record<any, any>) => {
|
||||||
|
if (!val) return Promise.reject(new Error('请输入元素配置'));
|
||||||
|
if (!val.id) {
|
||||||
|
return Promise.reject(new Error('请输入标识'))
|
||||||
|
}
|
||||||
|
if (!val.name) {
|
||||||
|
return Promise.reject(new Error('请输入名称'))
|
||||||
|
}
|
||||||
|
if (metadataStore.model.type !== 'functions' && !val.valueType?.type) {
|
||||||
|
return Promise.reject(new Error(`请选择${props.title}`))
|
||||||
|
}
|
||||||
|
if (['enum'].includes(val.valueType.type)) {
|
||||||
|
await validateEnum(_rule, val.valueType.elements)
|
||||||
|
}
|
||||||
|
if (['array'].includes(val.valueType.type)) {
|
||||||
|
await validateArray(_rule, val.valueType.elementType)
|
||||||
|
}
|
||||||
|
if (['object'].includes(val.valueType.type)) {
|
||||||
|
await validateJson(_rule, val.valueType.properties)
|
||||||
|
}
|
||||||
|
if (['file'].includes(val.valueType.type) && !val.valueType.fileType) {
|
||||||
|
return Promise.reject(new Error('请选择文件类型'))
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
// const rules = ref({
|
||||||
|
// type: [
|
||||||
|
// metadataStore.model.type !== 'functions' ? { required: true, message: `请选择${props.title}` } : {},
|
||||||
|
// ],
|
||||||
|
// elements: [
|
||||||
|
// { required: true, validator: validateEnum, message: '请配置枚举项' }
|
||||||
|
// ],
|
||||||
|
// elementType: [
|
||||||
|
// { validator: validateArray, message: '请输入元素配置' }
|
||||||
|
// ],
|
||||||
|
// properties: [
|
||||||
|
// { validator: validateJson, message: '请输入配置参数' }
|
||||||
|
// ],
|
||||||
|
// fileType: [
|
||||||
|
// { required: true, message: '请选择文件类型' },
|
||||||
|
// ]
|
||||||
|
// })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
:deep(.ant-form-item-label) {
|
:deep(.ant-form-item-label) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<a-drawer :mask-closable="false" width="25vw" visible :title="`${title}-${typeMapping[metadataStore.model.type]}`"
|
<j-drawer :mask-closable="false" width="25vw" visible :title="`${title}-${typeMapping[metadataStore.model.type]}`"
|
||||||
@close="close" destroy-on-close :z-index="1000" placement="right">
|
@close="close" destroy-on-close :z-index="1000" placement="right">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-button :loading="save.loading" type="primary" @click="save.saveMetadata">保存</a-button>
|
<j-button :loading="save.loading" type="primary" @click="save.saveMetadata">保存</j-button>
|
||||||
</template>
|
</template>
|
||||||
<a-form ref="formRef" :model="form.model" layout="vertical">
|
<j-form ref="formRef" :model="form.model" layout="vertical">
|
||||||
<BaseForm :model-type="metadataStore.model.type" :type="type" v-model:value="form.model"></BaseForm>
|
<BaseForm :model-type="metadataStore.model.type" :type="type" v-model:value="form.model"></BaseForm>
|
||||||
</a-form>
|
</j-form>
|
||||||
</a-drawer>
|
</j-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup name="Edit">
|
<script lang="ts" setup name="Edit">
|
||||||
import { useInstanceStore } from '@/store/instance';
|
import { useInstanceStore } from '@/store/instance';
|
||||||
|
@ -22,6 +22,7 @@ import { DeviceInstance } from '@/views/device/Instance/typings';
|
||||||
import BaseForm from './BaseForm.vue';
|
import BaseForm from './BaseForm.vue';
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
import { _deploy } from '@/api/device/product';
|
import { _deploy } from '@/api/device/product';
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
|
@ -60,7 +61,7 @@ const form = reactive({
|
||||||
model: {} as any,
|
model: {} as any,
|
||||||
})
|
})
|
||||||
if (metadataStore.model.action === 'edit') {
|
if (metadataStore.model.action === 'edit') {
|
||||||
form.model = metadataStore.model.item
|
form.model = cloneDeep(metadataStore.model.item)
|
||||||
}
|
}
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
@ -75,7 +76,9 @@ const save = reactive({
|
||||||
const type = metadataStore.model.type
|
const type = metadataStore.model.type
|
||||||
const _detail: ProductItem | DeviceInstance = props.type === 'device' ? instanceStore.detail : productStore.current
|
const _detail: ProductItem | DeviceInstance = props.type === 'device' ? instanceStore.detail : productStore.current
|
||||||
const _metadata = JSON.parse(_detail?.metadata || '{}')
|
const _metadata = JSON.parse(_detail?.metadata || '{}')
|
||||||
const list = _metadata[type] as any[]
|
console.log(_metadata)
|
||||||
|
console.log(type)
|
||||||
|
const list = (_metadata[type] as any[]) || []
|
||||||
if (formValue.id) {
|
if (formValue.id) {
|
||||||
if (metadataStore.model.action === 'add' && list.some(item => item.id === formValue.id)) {
|
if (metadataStore.model.action === 'add' && list.some(item => item.id === formValue.id)) {
|
||||||
message.error('标识已存在')
|
message.error('标识已存在')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<j-pro-table :loading="loading" :data-source="data" size="small" :columns="columns" row-key="id" model="TABLE">
|
<j-pro-table :loading="loading" :data-source="data" size="small" :columns="columns" row-key="id" model="TABLE">
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch"></a-input-search>
|
<j-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch"></j-input-search>
|
||||||
</template>
|
</template>
|
||||||
<template #rightExtraRender>
|
<template #rightExtraRender>
|
||||||
<PermissionButton type="primary" :uhas-permission="`${permission}:update`" key="add" @click="handleAddClick"
|
<PermissionButton type="primary" :uhas-permission="`${permission}:update`" key="add" @click="handleAddClick"
|
||||||
|
@ -135,6 +135,13 @@ const refreshMetadata = () => {
|
||||||
watch([route.params.id, type], refreshMetadata, { immediate: true })
|
watch([route.params.id, type], refreshMetadata, { immediate: true })
|
||||||
|
|
||||||
const metadataStore = useMetadataStore()
|
const metadataStore = useMetadataStore()
|
||||||
|
watch(() => metadataStore.model.importMetadata,
|
||||||
|
(val: boolean) => {
|
||||||
|
if (!!val) {
|
||||||
|
refreshMetadata()
|
||||||
|
metadataStore.set('importMetadata', false)
|
||||||
|
}
|
||||||
|
})
|
||||||
const handleAddClick = () => {
|
const handleAddClick = () => {
|
||||||
metadataStore.set('edit', true)
|
metadataStore.set('edit', true)
|
||||||
metadataStore.set('item', undefined)
|
metadataStore.set('item', undefined)
|
||||||
|
@ -189,6 +196,4 @@ const removeItem = async (record: MetadataItem) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less"></style>
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<a-drawer :mask-closable="false" title="查看物模型" width="700" v-model:visible="_visible" destroy-on-close @close="close">
|
<j-drawer :mask-closable="false" title="查看物模型" width="700" v-model:visible="_visible" destroy-on-close @close="close">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-space>
|
<j-space>
|
||||||
<a-button type="primary" @click="handleExport">
|
<j-button type="primary" @click="handleExport">
|
||||||
导出
|
导出
|
||||||
</a-button>
|
</j-button>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<a-spin :spinning="loading">
|
<j-spin :spinning="loading">
|
||||||
<div class="cat-content">
|
<div class="cat-content">
|
||||||
<p class="cat-tip">
|
<p class="cat-tip">
|
||||||
物模型是对设备在云端的功能描述,包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型,称之为
|
物模型是对设备在云端的功能描述,包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型,称之为
|
||||||
|
@ -15,15 +15,15 @@
|
||||||
组装上报设备的数据。您可以导出完整物模型,用于云端应用开发。
|
组装上报设备的数据。您可以导出完整物模型,用于云端应用开发。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a-tabs @change="handleConvertMetadata" destroy-inactive-tab-pane>
|
<j-tabs @change="handleConvertMetadata" destroy-inactive-tab-pane>
|
||||||
<a-tab-pane v-for="item in codecs" :key="item.id" :tab="item.name">
|
<j-tab-pane v-for="item in codecs" :key="item.id" :tab="item.name">
|
||||||
<div class="cat-panel">
|
<div class="cat-panel">
|
||||||
<MonacoEditor v-model="value" theme="vs" style="height: 100%"></MonacoEditor>
|
<MonacoEditor v-model="value" theme="vs" style="height: 100%"></MonacoEditor>
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</j-tab-pane>
|
||||||
</a-tabs>
|
</j-tabs>
|
||||||
</a-spin>
|
</j-spin>
|
||||||
</a-drawer>
|
</j-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="Cat">
|
<script setup lang="ts" name="Cat">
|
||||||
import { message } from 'ant-design-vue/es';
|
import { message } from 'ant-design-vue/es';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal :mask-closable="false" title="导入物模型" destroy-on-close v-model:visible="_visible" @cancel="close"
|
<j-modal :mask-closable="false" title="导入物模型" destroy-on-close v-model:visible="_visible" @cancel="close"
|
||||||
@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">
|
||||||
|
@ -7,46 +7,46 @@
|
||||||
导入的物模型会覆盖原来的属性、功能、事件、标签,请谨慎操作。
|
导入的物模型会覆盖原来的属性、功能、事件、标签,请谨慎操作。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a-form layout="vertical" v-model="formModel">
|
<j-form layout="vertical" v-model="formModel">
|
||||||
<a-form-item v-if="type === 'product'" label="导入方式" v-bind="validateInfos.type">
|
<j-form-item v-if="type === 'product'" label="导入方式" v-bind="validateInfos.type">
|
||||||
<a-select v-model:value="formModel.type">
|
<j-select v-model:value="formModel.type">
|
||||||
<a-select-option value="copy">拷贝产品</a-select-option>
|
<j-select-option value="copy">拷贝产品</j-select-option>
|
||||||
<a-select-option value="import">导入物模型</a-select-option>
|
<j-select-option value="import">导入物模型</j-select-option>
|
||||||
</a-select>
|
</j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="选择产品" v-bind="validateInfos.copy" v-if="formModel.type === 'copy'">
|
<j-form-item label="选择产品" v-bind="validateInfos.copy" v-if="formModel.type === 'copy'">
|
||||||
<a-select :options="productList" v-model:value="formModel.copy" option-filter-prop="label"></a-select>
|
<j-select :options="productList" v-model:value="formModel.copy" option-filter-prop="label"></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="物模型类型" v-bind="validateInfos.metadata"
|
<j-form-item label="物模型类型" v-bind="validateInfos.metadata"
|
||||||
v-if="type === 'device' || formModel.type === 'import'">
|
v-if="type === 'device' || formModel.type === 'import'">
|
||||||
<a-select v-model:value="formModel.metadata">
|
<j-select v-model:value="formModel.metadata">
|
||||||
<a-select-option value="jetlinks">Jetlinks物模型</a-select-option>
|
<j-select-option value="jetlinks">Jetlinks物模型</j-select-option>
|
||||||
<a-select-option value="alink">阿里云物模型TSL</a-select-option>
|
<j-select-option value="alink">阿里云物模型TSL</j-select-option>
|
||||||
</a-select>
|
</j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="导入类型" v-bind="validateInfos.metadataType"
|
<j-form-item label="导入类型" v-bind="validateInfos.metadataType"
|
||||||
v-if="type === 'device' || formModel.type === 'import'">
|
v-if="type === 'device' || formModel.type === 'import'">
|
||||||
<a-select v-model:value="formModel.metadataType">
|
<j-select v-model:value="formModel.metadataType">
|
||||||
<a-select-option value="file">文件上传</a-select-option>
|
<j-select-option value="file">文件上传</j-select-option>
|
||||||
<a-select-option value="script">脚本</a-select-option>
|
<j-select-option value="script">脚本</j-select-option>
|
||||||
</a-select>
|
</j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="文件上传" v-bind="validateInfos.upload" v-if="formModel.metadataType === 'file'">
|
<j-form-item label="文件上传" v-bind="validateInfos.upload" v-if="formModel.metadataType === 'file'">
|
||||||
<a-input v-model:value="formModel.upload">
|
<j-input v-model:value="formModel.upload">
|
||||||
<template #addonAfter>
|
<template #addonAfter>
|
||||||
<a-upload v-model:file-list="fileList" :before-upload="beforeUpload" accept=".json"
|
<j-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()}">
|
||||||
<AIcon type="UploadOutlined" class="upload-button" />
|
<AIcon type="UploadOutlined" class="upload-button" />
|
||||||
</a-upload>
|
</j-upload>
|
||||||
</template>
|
</template>
|
||||||
</a-input>
|
</j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="物模型" v-bind="validateInfos.import" v-if="formModel.metadataType === 'script'">
|
<j-form-item label="物模型" v-bind="validateInfos.import" v-if="formModel.metadataType === 'script'">
|
||||||
<MonacoEditor v-model="formModel.import" theme="vs" style="height: 300px"></MonacoEditor>
|
<MonacoEditor v-model="formModel.import" theme="vs" style="height: 300px"></MonacoEditor>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-form>
|
</j-form>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="Import">
|
<script setup lang="ts" name="Import">
|
||||||
import { useForm } from 'ant-design-vue/es/form';
|
import { useForm } from 'ant-design-vue/es/form';
|
||||||
|
@ -54,13 +54,14 @@ import { saveMetadata } from '@/api/device/instance'
|
||||||
import { queryNoPagingPost, convertMetadata, modify } from '@/api/device/product'
|
import { queryNoPagingPost, convertMetadata, modify } from '@/api/device/product'
|
||||||
import type { DefaultOptionType } from 'ant-design-vue/es/select';
|
import type { DefaultOptionType } from 'ant-design-vue/es/select';
|
||||||
import type { UploadProps, UploadFile, UploadChangeParam } from 'ant-design-vue/es';
|
import type { UploadProps, UploadFile, UploadChangeParam } from 'ant-design-vue/es';
|
||||||
import type { DeviceMetadata, ProductItem } from '@/views/device/Product/typings'
|
import type { DeviceMetadata } from '@/views/device/Product/typings'
|
||||||
import { message } from 'ant-design-vue/es';
|
import { message } from 'jetlinks-ui-components';
|
||||||
import { useInstanceStore } from '@/store/instance'
|
import { useInstanceStore } from '@/store/instance'
|
||||||
import { useProductStore } from '@/store/product';
|
import { useProductStore } from '@/store/product';
|
||||||
import { FILE_UPLOAD } from '@/api/comm';
|
import { FILE_UPLOAD } from '@/api/comm';
|
||||||
import { getToken } from '@/utils/comm';
|
import { getToken } from '@/utils/comm';
|
||||||
import MonacoEditor from '@/components/MonacoEditor/index.vue'
|
import MonacoEditor from '@/components/MonacoEditor/index.vue'
|
||||||
|
import { useMetadataStore } from '@/store/metadata';
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const instanceStore = useInstanceStore()
|
const instanceStore = useInstanceStore()
|
||||||
|
@ -87,7 +88,6 @@ const _visible = computed({
|
||||||
})
|
})
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
console.log(1)
|
|
||||||
emits('update:visible', false);
|
emits('update:visible', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ const operateLimits = (mdata: DeviceMetadata) => {
|
||||||
});
|
});
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
const metadataStore = useMetadataStore()
|
||||||
const handleImport = async () => {
|
const handleImport = async () => {
|
||||||
validate().then(async (data) => {
|
validate().then(async (data) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
@ -224,6 +224,7 @@ const handleImport = async () => {
|
||||||
} else {
|
} else {
|
||||||
productStore.refresh(id as string)
|
productStore.refresh(id as string)
|
||||||
}
|
}
|
||||||
|
metadataStore.set('importMetadata', true)
|
||||||
// Store.set(SystemConst.GET_METADATA, true)
|
// Store.set(SystemConst.GET_METADATA, true)
|
||||||
// Store.set(SystemConst.REFRESH_METADATA_TABLE, true)
|
// Store.set(SystemConst.REFRESH_METADATA_TABLE, true)
|
||||||
close()
|
close()
|
||||||
|
@ -263,13 +264,14 @@ const handleImport = async () => {
|
||||||
message.success('导入成功')
|
message.success('导入成功')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Store.set(SystemConst.GET_METADATA, true)
|
|
||||||
// Store.set(SystemConst.REFRESH_METADATA_TABLE, true)
|
|
||||||
if (props?.type === 'device') {
|
if (props?.type === 'device') {
|
||||||
instanceStore.refresh(id as string)
|
instanceStore.refresh(id as string)
|
||||||
} else {
|
} else {
|
||||||
productStore.refresh(id as string)
|
productStore.refresh(id as string)
|
||||||
}
|
}
|
||||||
|
metadataStore.set('importMetadata', true)
|
||||||
|
// Store.set(SystemConst.GET_METADATA, true)
|
||||||
|
// Store.set(SystemConst.REFRESH_METADATA_TABLE, true)
|
||||||
close();
|
close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|
Loading…
Reference in New Issue