gaoluyang
2026-06-24 712aa51536236d43e87273e4ce45ac5691dffad8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<script setup lang="ts">
import type { RuleSceneApi } from '#/api/iot/rule/scene';
 
import { computed, nextTick } from 'vue';
 
import {
  IotRuleSceneTriggerConditionParameterOperatorEnum,
  IotRuleSceneTriggerConditionTypeEnum,
} from '..\..\..\..\..\..\packages\constants\src';
import { IconifyIcon } from '..\..\..\..\..\..\packages\icons\src';
import { getStableObjectKey } from '..\..\..\..\..\..\packages\utils\src';
 
import { useVModel } from '@vueuse/core';
import { Button } from 'ant-design-vue';
 
import ConditionConfig from './condition-config.vue';
 
/** 子条件组配置组件 */
defineOptions({ name: 'SubConditionGroupConfig' });
 
const props = defineProps<{
  maxConditions?: number;
  modelValue: RuleSceneApi.TriggerCondition[];
  triggerType: number;
}>();
 
const emit = defineEmits<{
  (e: 'update:modelValue', value: RuleSceneApi.TriggerCondition[]): void;
}>();
 
const subGroup = useVModel(props, 'modelValue', emit);
 
const maxConditions = computed(() => props.maxConditions || 3); // 最大条件数量
 
/** 添加条件 */
async function addCondition() {
  // 确保 subGroup.value 是一个数组
  if (!subGroup.value) {
    subGroup.value = [];
  }
 
  // 检查是否达到最大条件数量限制
  if (subGroup.value?.length >= maxConditions.value) {
    return;
  }
 
  const newCondition: RuleSceneApi.TriggerCondition = {
    type: IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY, // 默认为设备属性
    productId: undefined,
    deviceId: undefined,
    identifier: '',
    operator: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value, // 使用枚举默认值
    param: '',
  };
 
  // 使用 nextTick 确保响应式更新完成后再添加新条件
  await nextTick();
  if (subGroup.value) {
    subGroup.value.push(newCondition);
  }
}
 
/**
 * 移除条件
 * @param index 条件索引
 */
function removeCondition(index: number) {
  if (subGroup.value) {
    subGroup.value.splice(index, 1);
  }
}
 
/**
 * 更新条件
 * @param index 条件索引
 * @param condition 条件对象
 */
function updateCondition(
  index: number,
  condition: RuleSceneApi.TriggerCondition,
) {
  if (subGroup.value) {
    subGroup.value[index] = condition;
  }
}
</script>
 
<template>
  <div class="p-4">
    <!-- 空状态 -->
    <div v-if="!subGroup || subGroup.length === 0" class="py-6 text-center">
      <div class="flex flex-col items-center gap-3">
        <IconifyIcon icon="lucide:plus" class="text-8 text-muted-foreground" />
        <div class="text-muted-foreground">
          <p class="mb-1 text-base font-bold">暂无条件</p>
          <p class="text-xs">点击下方按钮添加第一个条件</p>
        </div>
        <Button type="primary" @click="addCondition">
          <IconifyIcon icon="lucide:plus" />
          添加条件
        </Button>
      </div>
    </div>
 
    <!-- 条件列表 -->
    <div v-else class="space-y-4">
      <div
        v-for="(condition, conditionIndex) in subGroup"
        :key="getStableObjectKey(condition)"
        class="relative"
      >
        <!-- 条件配置 -->
        <div
          class="rounded-[3px] bg-fill-color-blank border border-border shadow-sm"
        >
          <div
            class="rounded-t-1 bg-fill-color-blank flex items-center justify-between border-b border-border p-3"
          >
            <div class="flex items-center gap-2">
              <div
                class="flex size-5 items-center justify-center rounded-full bg-primary text-xs font-bold text-white"
              >
                {{ conditionIndex + 1 }}
              </div>
              <span class="text-base font-bold text-foreground">
                条件 {{ conditionIndex + 1 }}
              </span>
            </div>
            <Button
              v-if="subGroup!.length > 1"
              danger
              size="small"
              type="link"
              class="hover:bg-red-50"
              @click="removeCondition(conditionIndex)"
            >
              <IconifyIcon icon="lucide:trash-2" />
            </Button>
          </div>
 
          <div class="p-3">
            <ConditionConfig
              :model-value="condition"
              @update:model-value="
                (value: RuleSceneApi.TriggerCondition) =>
                  updateCondition(conditionIndex, value)
              "
              :trigger-type="triggerType"
            />
          </div>
        </div>
      </div>
 
      <!-- 添加条件按钮 -->
      <div
        v-if="
          subGroup && subGroup.length > 0 && subGroup.length < maxConditions
        "
        class="py-4 text-center"
      >
        <Button type="primary" plain @click="addCondition">
          <IconifyIcon icon="lucide:plus" />
          继续添加条件
        </Button>
        <span class="mt-2 block text-xs text-muted-foreground">
          最多可添加 {{ maxConditions }} 个条件
        </span>
      </div>
    </div>
  </div>
</template>