fix: iot
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
|
||||
import { Button, Form, FormItem, Select, Table } from 'ant-design-vue';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Button, Form, Select, Table } from 'ant-design-vue';
|
||||
|
||||
import { getSimpleDeviceList } from '#/api/iot/device/device';
|
||||
import { getSimpleProductList } from '#/api/iot/product/product';
|
||||
@@ -31,23 +33,23 @@ const upstreamMethods = computed(() => {
|
||||
});
|
||||
|
||||
/** 根据产品 ID 过滤设备 */
|
||||
const getFilteredDevices = (productId: number) => {
|
||||
function getFilteredDevices(productId: number) {
|
||||
if (!productId) return [];
|
||||
return deviceList.value.filter(
|
||||
(device: any) => device.productId === productId,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/** 判断是否需要显示标识符选择器 */
|
||||
const shouldShowIdentifierSelect = (row: any) => {
|
||||
function shouldShowIdentifierSelect(row: any) {
|
||||
return [
|
||||
IotDeviceMessageMethodEnum.EVENT_POST.method,
|
||||
IotDeviceMessageMethodEnum.PROPERTY_POST.method,
|
||||
].includes(row.method);
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取物模型选项 */
|
||||
const getThingModelOptions = (row: any) => {
|
||||
function getThingModelOptions(row: any) {
|
||||
if (!row.productId || !shouldShowIdentifierSelect(row)) {
|
||||
return [];
|
||||
}
|
||||
@@ -66,28 +68,28 @@ const getThingModelOptions = (row: any) => {
|
||||
label: `${item.name} (${item.identifier})`,
|
||||
value: item.identifier,
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
/** 加载产品列表 */
|
||||
const loadProductList = async () => {
|
||||
async function loadProductList() {
|
||||
try {
|
||||
productList.value = await getSimpleProductList();
|
||||
} catch (error) {
|
||||
console.error('加载产品列表失败:', error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 加载设备列表 */
|
||||
const loadDeviceList = async () => {
|
||||
async function loadDeviceList() {
|
||||
try {
|
||||
deviceList.value = await getSimpleDeviceList();
|
||||
} catch (error) {
|
||||
console.error('加载设备列表失败:', error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 加载物模型数据 */
|
||||
const loadThingModel = async (productId: number) => {
|
||||
async function loadThingModel(productId: number) {
|
||||
// 已缓存,无需重复加载
|
||||
if (thingModelCache.value.has(productId)) {
|
||||
return;
|
||||
@@ -98,18 +100,18 @@ const loadThingModel = async (productId: number) => {
|
||||
} catch (error) {
|
||||
console.error('加载物模型失败:', error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 产品变化时处理 */
|
||||
const handleProductChange = async (row: any, _index: number) => {
|
||||
async function handleProductChange(row: any, _index: number) {
|
||||
row.deviceId = 0;
|
||||
row.method = undefined;
|
||||
row.identifier = undefined;
|
||||
row.identifierLoading = false;
|
||||
};
|
||||
}
|
||||
|
||||
/** 消息方法变化时处理 */
|
||||
const handleMethodChange = async (row: any, _index: number) => {
|
||||
async function handleMethodChange(row: any, _index: number) {
|
||||
// 清空标识符
|
||||
row.identifier = undefined;
|
||||
// 如果需要加载物模型数据
|
||||
@@ -118,10 +120,10 @@ const handleMethodChange = async (row: any, _index: number) => {
|
||||
await loadThingModel(row.productId);
|
||||
row.identifierLoading = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
function handleAdd() {
|
||||
const row = {
|
||||
productId: undefined,
|
||||
deviceId: undefined,
|
||||
@@ -130,25 +132,25 @@ const handleAdd = () => {
|
||||
identifierLoading: false,
|
||||
};
|
||||
formData.value.push(row);
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (index: number) => {
|
||||
function handleDelete(index: number) {
|
||||
formData.value.splice(index, 1);
|
||||
};
|
||||
}
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = () => {
|
||||
function validate() {
|
||||
return formRef.value.validate();
|
||||
};
|
||||
}
|
||||
|
||||
/** 表单值 */
|
||||
const getData = () => {
|
||||
function getData() {
|
||||
return formData.value;
|
||||
};
|
||||
}
|
||||
|
||||
/** 设置表单值 */
|
||||
const setData = (data: any[]) => {
|
||||
function setData(data: any[]) {
|
||||
// 确保每个项都有必要的字段
|
||||
formData.value = (data || []).map((item) => ({
|
||||
...item,
|
||||
@@ -160,7 +162,7 @@ const setData = (data: any[]) => {
|
||||
await loadThingModel(item.productId);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
@@ -209,7 +211,7 @@ defineExpose({ validate, getData, setData });
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.dataIndex === 'productId'">
|
||||
<FormItem
|
||||
<Form.Item
|
||||
:name="['data', index, 'productId']"
|
||||
:rules="formRules.productId"
|
||||
class="mb-0"
|
||||
@@ -227,10 +229,10 @@ defineExpose({ validate, getData, setData });
|
||||
"
|
||||
@change="() => handleProductChange(record, index)"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form.Item>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'deviceId'">
|
||||
<FormItem
|
||||
<Form.Item
|
||||
:name="['data', index, 'deviceId']"
|
||||
:rules="formRules.deviceId"
|
||||
class="mb-0"
|
||||
@@ -251,10 +253,10 @@ defineExpose({ validate, getData, setData });
|
||||
})),
|
||||
]"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form.Item>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'method'">
|
||||
<FormItem
|
||||
<Form.Item
|
||||
:name="['data', index, 'method']"
|
||||
:rules="formRules.method"
|
||||
class="mb-0"
|
||||
@@ -275,10 +277,10 @@ defineExpose({ validate, getData, setData });
|
||||
"
|
||||
@change="() => handleMethodChange(record, index)"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form.Item>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'identifier'">
|
||||
<FormItem :name="['data', index, 'identifier']" class="mb-0">
|
||||
<Form.Item :name="['data', index, 'identifier']" class="mb-0">
|
||||
<Select
|
||||
v-if="shouldShowIdentifierSelect(record)"
|
||||
v-model:value="record.identifier"
|
||||
@@ -291,7 +293,7 @@ defineExpose({ validate, getData, setData });
|
||||
"
|
||||
:options="getThingModelOptions(record)"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form.Item>
|
||||
</template>
|
||||
<template v-else-if="column.title === '操作'">
|
||||
<Button type="link" danger @click="handleDelete(index)">删除</Button>
|
||||
@@ -300,7 +302,7 @@ defineExpose({ validate, getData, setData });
|
||||
</Table>
|
||||
<div class="mt-3 text-center">
|
||||
<Button type="primary" @click="handleAdd">
|
||||
<Icon icon="ant-design:plus-outlined" class="mr-1" />
|
||||
<IconifyIcon icon="ant-design:plus-outlined" class="mr-1" />
|
||||
添加数据源
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
createDataSink,
|
||||
getDataSink,
|
||||
updateDataSink,
|
||||
} from '#/api/iot/rule/data';
|
||||
} from '#/api/iot/rule/data/sink';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import {
|
||||
@@ -106,7 +106,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
|
||||
// 监听类型变化,重置配置
|
||||
watch(
|
||||
() => formApi.form.type,
|
||||
() => formApi.getValues().then((values) => values.type),
|
||||
(newType) => {
|
||||
if (formData.value && newType !== formData.value.type) {
|
||||
formData.value.config = {};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -12,7 +14,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
// noinspection HttpUrlsUsage
|
||||
/** URL处理 */
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -10,7 +12,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -10,7 +12,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -10,7 +12,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -10,7 +12,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
@@ -10,7 +12,7 @@ const props = defineProps<{
|
||||
modelValue: any;
|
||||
}>();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const config = useVModel(props, 'modelValue', emit) as Ref<any>;
|
||||
const config = useVModel(props, 'modelValue', emit) as any;
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
import { isEmpty } from '@vben/utils';
|
||||
|
||||
import { Delete, Plus } from '@element-plus/icons-vue';
|
||||
import { Button, Input } from 'ant-design-vue';
|
||||
|
||||
defineOptions({ name: 'KeyValueEditor' });
|
||||
|
||||
@@ -20,19 +23,19 @@ interface KeyValueItem {
|
||||
const items = ref<KeyValueItem[]>([]); // 内部 key-value 项列表
|
||||
|
||||
/** 添加项目 */
|
||||
const addItem = () => {
|
||||
function addItem() {
|
||||
items.value.push({ key: '', value: '' });
|
||||
updateModelValue();
|
||||
};
|
||||
}
|
||||
|
||||
/** 移除项目 */
|
||||
const removeItem = (index: number) => {
|
||||
function removeItem(index: number) {
|
||||
items.value.splice(index, 1);
|
||||
updateModelValue();
|
||||
};
|
||||
}
|
||||
|
||||
/** 更新 modelValue */
|
||||
const updateModelValue = () => {
|
||||
function updateModelValue() {
|
||||
const result: Record<string, string> = {};
|
||||
items.value.forEach((item) => {
|
||||
if (item.key) {
|
||||
@@ -40,7 +43,7 @@ const updateModelValue = () => {
|
||||
}
|
||||
});
|
||||
emit('update:modelValue', result);
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听项目变化 */
|
||||
watch(items, updateModelValue, { deep: true });
|
||||
@@ -61,19 +64,15 @@ watch(
|
||||
|
||||
<template>
|
||||
<div v-for="(item, index) in items" :key="index" class="mb-2 flex w-full">
|
||||
<el-input v-model="item.key" class="mr-2" placeholder="键" />
|
||||
<el-input v-model="item.value" placeholder="值" />
|
||||
<el-button class="ml-2" text type="danger" @click="removeItem(index)">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
<Input v-model="item.key" class="mr-2" placeholder="键" />
|
||||
<Input v-model="item.value" placeholder="值" />
|
||||
<Button class="ml-2" text danger @click="removeItem(index)">
|
||||
<IconifyIcon icon="ant-design:delete-outlined" />
|
||||
删除
|
||||
</el-button>
|
||||
</Button>
|
||||
</div>
|
||||
<el-button text type="primary" @click="addItem">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
<Button text type="primary" @click="addItem">
|
||||
<IconifyIcon icon="ant-design:plus-outlined" />
|
||||
{{ addButtonText }}
|
||||
</el-button>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<!-- 告警配置组件 -->
|
||||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { AlertConfigApi } from '#/api/iot/alert/config';
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import { Form, Select, Tag } from 'ant-design-vue';
|
||||
|
||||
import { getAlertConfigPage } from '#/api/iot/alert/config';
|
||||
|
||||
/** 告警配置组件 */
|
||||
defineOptions({ name: 'AlertConfig' });
|
||||
@@ -24,17 +27,17 @@ const alertConfigs = ref<any[]>([]); // 告警配置列表
|
||||
* 处理选择变化事件
|
||||
* @param value 选中的值
|
||||
*/
|
||||
const handleChange = (value?: number) => {
|
||||
function handleChange(value?: any) {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载告警配置列表
|
||||
*/
|
||||
const loadAlertConfigs = async () => {
|
||||
async function loadAlertConfigs() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const data = await AlertConfigApi.getAlertConfigPage({
|
||||
const data = await getAlertConfigPage({
|
||||
pageNo: 1,
|
||||
pageSize: 100,
|
||||
enabled: true, // 只加载启用的配置
|
||||
@@ -43,7 +46,7 @@ const loadAlertConfigs = async () => {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(() => {
|
||||
@@ -53,8 +56,8 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<el-form-item label="告警配置" required>
|
||||
<el-select
|
||||
<Form.Item label="告警配置" required>
|
||||
<Select
|
||||
v-model="localValue"
|
||||
placeholder="请选择告警配置"
|
||||
filterable
|
||||
@@ -63,7 +66,7 @@ onMounted(() => {
|
||||
class="w-full"
|
||||
:loading="loading"
|
||||
>
|
||||
<el-option
|
||||
<Select.Option
|
||||
v-for="config in alertConfigs"
|
||||
:key="config.id"
|
||||
:label="config.name"
|
||||
@@ -71,12 +74,12 @@ onMounted(() => {
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>{{ config.name }}</span>
|
||||
<el-tag :type="config.enabled ? 'success' : 'danger'" size="small">
|
||||
<Tag :type="config.enabled ? 'success' : 'danger'" size="small">
|
||||
{{ config.enabled ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</Tag>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { TriggerCondition } from '#/api/iot/rule/scene';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import { Col, Form, Row, Select } from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
getConditionTypeOptions,
|
||||
@@ -61,9 +64,9 @@ const propertyConfig = ref<any>(null); // 属性配置
|
||||
const isDeviceCondition = computed(() => {
|
||||
return (
|
||||
condition.value.type ===
|
||||
IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS ||
|
||||
IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS.toString() ||
|
||||
condition.value.type ===
|
||||
IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY
|
||||
IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY.toString()
|
||||
);
|
||||
}); // 计算属性:判断是否为设备相关条件
|
||||
|
||||
@@ -72,25 +75,25 @@ const isDeviceCondition = computed(() => {
|
||||
* @param field 字段名
|
||||
* @param value 字段值
|
||||
*/
|
||||
const updateConditionField = (field: any, value: any) => {
|
||||
function updateConditionField(field: any, value: any) {
|
||||
(condition.value as any)[field] = value;
|
||||
emit('update:modelValue', condition.value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新整个条件对象
|
||||
* @param newCondition 新的条件对象
|
||||
*/
|
||||
const updateCondition = (newCondition: TriggerCondition) => {
|
||||
function updateCondition(newCondition: TriggerCondition) {
|
||||
condition.value = newCondition;
|
||||
emit('update:modelValue', condition.value);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理条件类型变化事件
|
||||
* @param type 条件类型
|
||||
*/
|
||||
const handleConditionTypeChange = (type: number) => {
|
||||
function handleConditionTypeChange(type: any) {
|
||||
// 根据条件类型清理字段
|
||||
const isCurrentTime =
|
||||
type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME;
|
||||
@@ -115,26 +118,26 @@ const handleConditionTypeChange = (type: number) => {
|
||||
|
||||
// 清空参数值
|
||||
condition.value.param = '';
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理产品变化事件 */
|
||||
const handleProductChange = (_: number) => {
|
||||
function handleProductChange(_: any) {
|
||||
// 产品变化时清空设备和属性
|
||||
condition.value.deviceId = undefined;
|
||||
condition.value.identifier = '';
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理设备变化事件 */
|
||||
const handleDeviceChange = (_: number) => {
|
||||
function handleDeviceChange(_: any) {
|
||||
// 设备变化时清空属性
|
||||
condition.value.identifier = '';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理属性变化事件
|
||||
* @param propertyInfo 属性信息对象
|
||||
*/
|
||||
const handlePropertyChange = (propertyInfo: { config: any; type: string }) => {
|
||||
function handlePropertyChange(propertyInfo: { config: any; type: string }) {
|
||||
propertyType.value = propertyInfo.type;
|
||||
propertyConfig.value = propertyInfo.config;
|
||||
|
||||
@@ -142,43 +145,45 @@ const handlePropertyChange = (propertyInfo: { config: any; type: string }) => {
|
||||
condition.value.operator =
|
||||
IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value;
|
||||
condition.value.param = '';
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理操作符变化事件 */
|
||||
const handleOperatorChange = () => {
|
||||
function handleOperatorChange() {
|
||||
// 重置值
|
||||
condition.value.param = '';
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gap-16px flex flex-col">
|
||||
<!-- 条件类型选择 -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="条件类型" required>
|
||||
<el-select
|
||||
<Row :gutter="16">
|
||||
<Col :span="8">
|
||||
<Form.Item label="条件类型" required>
|
||||
<Select
|
||||
:model-value="condition.type"
|
||||
@update:model-value="(value) => updateConditionField('type', value)"
|
||||
@update:model-value="
|
||||
(value: any) => updateConditionField('type', value)
|
||||
"
|
||||
@change="handleConditionTypeChange"
|
||||
placeholder="请选择条件类型"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
<Select.Option
|
||||
v-for="option in getConditionTypeOptions()"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<!-- 产品设备选择 - 设备相关条件的公共部分 -->
|
||||
<el-row v-if="isDeviceCondition" :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品" required>
|
||||
<Row v-if="isDeviceCondition" :gutter="16">
|
||||
<Col :span="12">
|
||||
<Form.Item label="产品" required>
|
||||
<ProductSelector
|
||||
:model-value="condition.productId"
|
||||
@update:model-value="
|
||||
@@ -186,10 +191,10 @@ const handleOperatorChange = () => {
|
||||
"
|
||||
@change="handleProductChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="设备" required>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col :span="12">
|
||||
<Form.Item label="设备" required>
|
||||
<DeviceSelector
|
||||
:model-value="condition.deviceId"
|
||||
@update:model-value="
|
||||
@@ -198,9 +203,9 @@ const handleOperatorChange = () => {
|
||||
:product-id="condition.productId"
|
||||
@change="handleDeviceChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<!-- 设备状态条件配置 -->
|
||||
<div
|
||||
@@ -210,11 +215,11 @@ const handleOperatorChange = () => {
|
||||
class="gap-16px flex flex-col"
|
||||
>
|
||||
<!-- 状态和操作符选择 -->
|
||||
<el-row :gutter="16">
|
||||
<Row :gutter="16">
|
||||
<!-- 操作符选择 -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="操作符" required>
|
||||
<el-select
|
||||
<Col :span="12">
|
||||
<Form.Item label="操作符" required>
|
||||
<Select
|
||||
:model-value="condition.operator"
|
||||
@update:model-value="
|
||||
(value) => updateConditionField('operator', value)
|
||||
@@ -222,51 +227,52 @@ const handleOperatorChange = () => {
|
||||
placeholder="请选择操作符"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
<Select.Option
|
||||
v-for="option in statusOperatorOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<!-- 状态选择 -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="设备状态" required>
|
||||
<el-select
|
||||
<Col :span="12">
|
||||
<Form.Item label="设备状态" required>
|
||||
<Select
|
||||
:model-value="condition.param"
|
||||
@update:model-value="
|
||||
(value) => updateConditionField('param', value)
|
||||
(value: any) => updateConditionField('param', value)
|
||||
"
|
||||
placeholder="请选择设备状态"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
<Select.Option
|
||||
v-for="option in deviceStatusOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<!-- 设备属性条件配置 -->
|
||||
<div
|
||||
v-else-if="
|
||||
condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY
|
||||
condition.type ===
|
||||
IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY.toString()
|
||||
"
|
||||
class="space-y-16px"
|
||||
>
|
||||
<!-- 属性配置 -->
|
||||
<el-row :gutter="16">
|
||||
<Row :gutter="16">
|
||||
<!-- 属性/事件/服务选择 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="监控项" required>
|
||||
<Col :span="6">
|
||||
<Form.Item label="监控项" required>
|
||||
<PropertySelector
|
||||
:model-value="condition.identifier"
|
||||
@update:model-value="
|
||||
@@ -277,12 +283,12 @@ const handleOperatorChange = () => {
|
||||
:device-id="condition.deviceId"
|
||||
@change="handlePropertyChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<!-- 操作符选择 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="操作符" required>
|
||||
<Col :span="6">
|
||||
<Form.Item label="操作符" required>
|
||||
<OperatorSelector
|
||||
:model-value="condition.operator"
|
||||
@update:model-value="
|
||||
@@ -291,12 +297,12 @@ const handleOperatorChange = () => {
|
||||
:property-type="propertyType"
|
||||
@change="handleOperatorChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<!-- 值输入 -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="比较值" required>
|
||||
<Col :span="12">
|
||||
<Form.Item label="比较值" required>
|
||||
<ValueInput
|
||||
:model-value="condition.param"
|
||||
@update:model-value="
|
||||
@@ -306,15 +312,16 @@ const handleOperatorChange = () => {
|
||||
:operator="condition.operator"
|
||||
:property-config="propertyConfig"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<!-- 当前时间条件配置 -->
|
||||
<CurrentTimeConditionConfig
|
||||
v-else-if="
|
||||
condition.type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME
|
||||
condition.type ===
|
||||
IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME.toString()
|
||||
"
|
||||
:model-value="condition"
|
||||
@update:model-value="updateCondition"
|
||||
@@ -323,7 +330,7 @@ const handleOperatorChange = () => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.el-form-item) {
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { TriggerCondition } from '#/api/iot/rule/scene';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
|
||||
import { IotRuleSceneTriggerTimeOperatorEnum } from '#/views/iot/utils/constants';
|
||||
|
||||
Reference in New Issue
Block a user