ConditionConfig.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <!-- 单个条件配置组件 -->
  2. <template>
  3. <div class="flex flex-col gap-16px">
  4. <!-- 条件类型选择 -->
  5. <el-row :gutter="16">
  6. <el-col :span="8">
  7. <el-form-item label="条件类型" required>
  8. <el-select
  9. :model-value="condition.type"
  10. @update:model-value="(value) => updateConditionField('type', value)"
  11. @change="handleConditionTypeChange"
  12. placeholder="请选择条件类型"
  13. class="w-full"
  14. >
  15. <el-option
  16. v-for="option in getConditionTypeOptions()"
  17. :key="option.value"
  18. :label="option.label"
  19. :value="option.value"
  20. />
  21. </el-select>
  22. </el-form-item>
  23. </el-col>
  24. </el-row>
  25. <!-- 产品设备选择 - 设备相关条件的公共部分 -->
  26. <el-row v-if="isDeviceCondition" :gutter="16">
  27. <el-col :span="12">
  28. <el-form-item label="产品" required>
  29. <ProductSelector
  30. :model-value="condition.productId"
  31. @update:model-value="(value) => updateConditionField('productId', value)"
  32. @change="handleProductChange"
  33. />
  34. </el-form-item>
  35. </el-col>
  36. <el-col :span="12">
  37. <el-form-item label="设备" required>
  38. <DeviceSelector
  39. :model-value="condition.deviceId"
  40. @update:model-value="(value) => updateConditionField('deviceId', value)"
  41. :product-id="condition.productId"
  42. @change="handleDeviceChange"
  43. />
  44. </el-form-item>
  45. </el-col>
  46. </el-row>
  47. <!-- 设备状态条件配置 -->
  48. <div
  49. v-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS"
  50. class="flex flex-col gap-16px"
  51. >
  52. <!-- 状态和操作符选择 -->
  53. <el-row :gutter="16">
  54. <!-- 操作符选择 -->
  55. <el-col :span="12">
  56. <el-form-item label="操作符" required>
  57. <el-select
  58. :model-value="condition.operator"
  59. @update:model-value="(value) => updateConditionField('operator', value)"
  60. placeholder="请选择操作符"
  61. class="w-full"
  62. >
  63. <el-option
  64. v-for="option in statusOperatorOptions"
  65. :key="option.value"
  66. :label="option.label"
  67. :value="option.value"
  68. />
  69. </el-select>
  70. </el-form-item>
  71. </el-col>
  72. <!-- 状态选择 -->
  73. <el-col :span="12">
  74. <el-form-item label="设备状态" required>
  75. <el-select
  76. :model-value="condition.param"
  77. @update:model-value="(value) => updateConditionField('param', value)"
  78. placeholder="请选择设备状态"
  79. class="w-full"
  80. >
  81. <el-option
  82. v-for="option in deviceStatusOptions"
  83. :key="option.value"
  84. :label="option.label"
  85. :value="option.value"
  86. />
  87. </el-select>
  88. </el-form-item>
  89. </el-col>
  90. </el-row>
  91. </div>
  92. <!-- 设备属性条件配置 -->
  93. <div
  94. v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY"
  95. class="space-y-16px"
  96. >
  97. <!-- 属性配置 -->
  98. <el-row :gutter="16">
  99. <!-- 属性/事件/服务选择 -->
  100. <el-col :span="6">
  101. <el-form-item label="监控项" required>
  102. <PropertySelector
  103. :model-value="condition.identifier"
  104. @update:model-value="(value) => updateConditionField('identifier', value)"
  105. :trigger-type="triggerType"
  106. :product-id="condition.productId"
  107. :device-id="condition.deviceId"
  108. @change="handlePropertyChange"
  109. />
  110. </el-form-item>
  111. </el-col>
  112. <!-- 操作符选择 -->
  113. <el-col :span="6">
  114. <el-form-item label="操作符" required>
  115. <OperatorSelector
  116. :model-value="condition.operator"
  117. @update:model-value="(value) => updateConditionField('operator', value)"
  118. :property-type="propertyType"
  119. @change="handleOperatorChange"
  120. />
  121. </el-form-item>
  122. </el-col>
  123. <!-- 值输入 -->
  124. <el-col :span="12">
  125. <el-form-item label="比较值" required>
  126. <ValueInput
  127. :model-value="condition.param"
  128. @update:model-value="(value) => updateConditionField('param', value)"
  129. :property-type="propertyType"
  130. :operator="condition.operator"
  131. :property-config="propertyConfig"
  132. />
  133. </el-form-item>
  134. </el-col>
  135. </el-row>
  136. </div>
  137. <!-- 当前时间条件配置 -->
  138. <CurrentTimeConditionConfig
  139. v-else-if="condition.type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME"
  140. :model-value="condition"
  141. @update:model-value="updateCondition"
  142. />
  143. </div>
  144. </template>
  145. <script setup lang="ts">
  146. import { useVModel } from '@vueuse/core'
  147. import CurrentTimeConditionConfig from './CurrentTimeConditionConfig.vue'
  148. import ProductSelector from '../selectors/ProductSelector.vue'
  149. import DeviceSelector from '../selectors/DeviceSelector.vue'
  150. import PropertySelector from '../selectors/PropertySelector.vue'
  151. import OperatorSelector from '../selectors/OperatorSelector.vue'
  152. import ValueInput from '../inputs/ValueInput.vue'
  153. import type { TriggerCondition } from '@/api/iot/rule/scene'
  154. import {
  155. IotRuleSceneTriggerConditionTypeEnum,
  156. IotRuleSceneTriggerConditionParameterOperatorEnum,
  157. getConditionTypeOptions,
  158. IoTDeviceStatusEnum
  159. } from '@/views/iot/utils/constants'
  160. /** 单个条件配置组件 */
  161. defineOptions({ name: 'ConditionConfig' })
  162. const props = defineProps<{
  163. modelValue: TriggerCondition
  164. triggerType: number
  165. }>()
  166. const emit = defineEmits<{
  167. (e: 'update:modelValue', value: TriggerCondition): void
  168. }>()
  169. /** 获取设备状态选项 */
  170. const deviceStatusOptions = [
  171. {
  172. value: IoTDeviceStatusEnum.ONLINE.value,
  173. label: IoTDeviceStatusEnum.ONLINE.label
  174. },
  175. {
  176. value: IoTDeviceStatusEnum.OFFLINE.value,
  177. label: IoTDeviceStatusEnum.OFFLINE.label
  178. }
  179. ]
  180. /** 获取状态操作符选项 */
  181. const statusOperatorOptions = [
  182. {
  183. value: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value,
  184. label: IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.name
  185. },
  186. {
  187. value: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.value,
  188. label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name
  189. }
  190. ]
  191. const condition = useVModel(props, 'modelValue', emit)
  192. const propertyType = ref<string>('string') // 属性类型
  193. const propertyConfig = ref<any>(null) // 属性配置
  194. const isDeviceCondition = computed(() => {
  195. return (
  196. condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS ||
  197. condition.value.type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_PROPERTY
  198. )
  199. }) // 计算属性:判断是否为设备相关条件
  200. /**
  201. * 更新条件字段
  202. * @param field 字段名
  203. * @param value 字段值
  204. */
  205. const updateConditionField = (field: any, value: any) => {
  206. ;(condition.value as any)[field] = value
  207. emit('update:modelValue', condition.value)
  208. }
  209. /**
  210. * 更新整个条件对象
  211. * @param newCondition 新的条件对象
  212. */
  213. const updateCondition = (newCondition: TriggerCondition) => {
  214. condition.value = newCondition
  215. emit('update:modelValue', condition.value)
  216. }
  217. /**
  218. * 处理条件类型变化事件
  219. * @param type 条件类型
  220. */
  221. const handleConditionTypeChange = (type: number) => {
  222. // 根据条件类型清理字段
  223. const isCurrentTime = type === IotRuleSceneTriggerConditionTypeEnum.CURRENT_TIME
  224. const isDeviceStatus = type === IotRuleSceneTriggerConditionTypeEnum.DEVICE_STATUS
  225. // 清理标识符字段(时间条件和设备状态条件都不需要)
  226. if (isCurrentTime || isDeviceStatus) {
  227. condition.value.identifier = undefined
  228. }
  229. // 清理设备相关字段(仅时间条件需要)
  230. if (isCurrentTime) {
  231. condition.value.productId = undefined
  232. condition.value.deviceId = undefined
  233. }
  234. // 设置默认操作符
  235. condition.value.operator = isCurrentTime
  236. ? 'at_time'
  237. : IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value
  238. // 清空参数值
  239. condition.value.param = ''
  240. }
  241. /** 处理产品变化事件 */
  242. const handleProductChange = (_: number) => {
  243. // 产品变化时清空设备和属性
  244. condition.value.deviceId = undefined
  245. condition.value.identifier = ''
  246. }
  247. /** 处理设备变化事件 */
  248. const handleDeviceChange = (_: number) => {
  249. // 设备变化时清空属性
  250. condition.value.identifier = ''
  251. }
  252. /**
  253. * 处理属性变化事件
  254. * @param propertyInfo 属性信息对象
  255. */
  256. const handlePropertyChange = (propertyInfo: { type: string; config: any }) => {
  257. propertyType.value = propertyInfo.type
  258. propertyConfig.value = propertyInfo.config
  259. // 重置操作符和值
  260. condition.value.operator = IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.value
  261. condition.value.param = ''
  262. }
  263. /** 处理操作符变化事件 */
  264. const handleOperatorChange = () => {
  265. // 重置值
  266. condition.value.param = ''
  267. }
  268. </script>
  269. <style scoped>
  270. :deep(.el-form-item) {
  271. margin-bottom: 0;
  272. }
  273. </style>