ConditionBuilder.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <div class="space-y-2">
  3. <!-- 条件行 -->
  4. <div v-for="(condition, index) in conditions" :key="condition.id" class="flex items-center gap-1">
  5. <!-- 左侧变量选择 -->
  6. <div class="relative w-3/4">
  7. <ElSelect placeholder="选择变量" v-model="condition.leftValue">
  8. <ElOption v-for="variable in availableVariables" :key="variable.id" :value="variable.name"
  9. :label="variable.name" />
  10. </ElSelect>
  11. </div>
  12. <!-- 运算符选择 -->
  13. <ElSelect v-model="condition.operator" @change="handleConditionChange"
  14. class="w-1/4 text-sm border border-gray-200 rounded-lg bg-white ">
  15. <ElOption v-for="li in operators" :key="li.value" :value="li.value" :label="li.label" />
  16. </ElSelect>
  17. <!-- 右侧值输入 -->
  18. <div class="relative w-3/4">
  19. <ElInput v-model="condition.rightValue" type="text" placeholder="输入值" @input="handleConditionChange"
  20. class="w-full text-sm border border-gray-200 rounded-lg" />
  21. </div>
  22. <!-- 删除按钮 -->
  23. <ElButton v-if="conditions.length > 1" @click="removeCondition(index)"
  24. class="p-2 w-1/4 opacity-50 hover:opacity-100 hover:bg-red-50 rounded transition-all" title="删除条件">
  25. <Icon icon="lucide:trash-2" :height="16" :width="16" class="text-red-500" />
  26. </ElButton>
  27. </div>
  28. <!-- 添加条件按钮 -->
  29. <div class="text-right" v-if="conditions[0]?.id !== 'else'">
  30. <ElButton @click="addCondition"
  31. class="flex items-center gap-2 px-3 py-2 text-sm text-blue-600 hover:bg-blue-50 rounded-lg transition-colors">
  32. <Icon icon="lucide:git-branch-plus" :height="16" :width="16" />
  33. 添加条件
  34. </ElButton>
  35. </div>
  36. </div>
  37. </template>
  38. <script setup lang="ts">
  39. import { ref, computed, watch } from 'vue'
  40. import { Icon } from '@iconify/vue'
  41. interface Condition {
  42. id: string
  43. leftValue: string
  44. operator: string
  45. rightValue: string
  46. }
  47. interface Props {
  48. modelValue: Condition[]
  49. }
  50. interface Emits {
  51. (e: 'update:modelValue', value: Condition[]): void
  52. (e: 'openVariablePicker', index: number, side: 'left' | 'right'): void
  53. }
  54. interface Variable {
  55. id: string
  56. name: string
  57. type: string
  58. source: string
  59. }
  60. // 可用变量列表
  61. const availableVariables: Variable[] = [
  62. { id: 'var_1', name: 'sys.user_id', type: 'String', source: 'HTTP 请求' },
  63. { id: 'var_2', name: 'sys.app_id', type: 'Number', source: 'HTTP 请求' },
  64. { id: 'var_3', name: 'result', type: 'String', source: '代码执行' },
  65. { id: 'var_4', name: 'output_format', type: 'String', source: 'SQL查询' },
  66. { id: 'var_5', name: 'user_name', type: 'String', source: 'HTTP 请求' },
  67. { id: 'var_6', name: 'user_email', type: 'String', source: 'HTTP 请求' },
  68. ]
  69. interface OperatorsType {
  70. value: string
  71. label: string
  72. }
  73. // 运算符列表
  74. const operators: OperatorsType[] = [
  75. { value: 'equals', label: '等于' },
  76. { value: 'notEquals', label: '不等于' },
  77. { value: 'contains', label: '包含' },
  78. { value: 'notContains', label: '不包含' },
  79. { value: 'greaterThan', label: '大于' },
  80. { value: 'lessThan', label: '小于' },
  81. { value: 'greaterOrEqual', label: '大于等于' },
  82. { value: 'lessOrEqual', label: '小于等于' }
  83. ]
  84. const props = defineProps<Props>()
  85. const emit = defineEmits<Emits>()
  86. const conditions = ref<Condition[]>(props.modelValue || [
  87. {
  88. id: `condition_${Date.now()}`,
  89. leftValue: '',
  90. operator: '',
  91. rightValue: ''
  92. }
  93. ])
  94. watch(
  95. () => props.modelValue,
  96. (newVal) => {
  97. if (newVal && newVal.length > 0) {
  98. conditions.value = newVal
  99. }
  100. },
  101. { deep: true }
  102. )
  103. const addCondition = () => {
  104. conditions.value.push({
  105. id: `condition_${Date.now()}`,
  106. leftValue: '',
  107. operator: '',
  108. rightValue: ''
  109. })
  110. handleConditionChange()
  111. }
  112. const removeCondition = (index: number) => {
  113. conditions.value.splice(index, 1)
  114. handleConditionChange()
  115. }
  116. const handleConditionChange = () => {
  117. emit('update:modelValue', conditions.value)
  118. }
  119. // const openVariablePicker = (index: number, side: 'left' | 'right') => {
  120. // emit('openVariablePicker', index, side)
  121. // }
  122. </script>