Browse Source

【代码优化】IoT: HTTP 数据桥梁配置编辑优化

puhui999 5 tháng trước cách đây
mục cha
commit
fd0b7be89f

+ 38 - 39
src/views/iot/rule/databridge/config/HttpConfigForm.vue

@@ -1,6 +1,13 @@
 <template>
   <el-form-item label="请求地址" prop="config.url">
-    <el-input v-model="config.url" placeholder="请输入请求地址" />
+    <el-input v-model="urlPath" placeholder="请输入请求地址">
+      <template #prepend>
+        <el-select v-model="urlPrefix" placeholder="Select" style="width: 115px">
+          <el-option label="http://" value="http://" />
+          <el-option label="https://" value="https://" />
+        </el-select>
+      </template>
+    </el-input>
   </el-form-item>
   <el-form-item label="请求方法" prop="config.method">
     <el-select v-model="config.method" placeholder="请选择请求方法">
@@ -11,29 +18,21 @@
     </el-select>
   </el-form-item>
   <el-form-item label="请求头" prop="config.headers">
-    <el-input
-      v-model="headersStr"
-      placeholder="请输入请求头,格式为 JSON"
-      type="textarea"
-      @input="handleHeadersChange"
-    />
+    <key-value-editor v-model="config.headers" add-button-text="添加请求头" />
   </el-form-item>
   <el-form-item label="请求参数" prop="config.query">
-    <el-input
-      v-model="queryStr"
-      placeholder="请输入请求参数,格式为 JSON"
-      type="textarea"
-      @input="handleQueryChange"
-    />
+    <key-value-editor v-model="config.query" add-button-text="添加参数" />
   </el-form-item>
   <el-form-item label="请求体" prop="config.body">
-    <el-input v-model="config.body" placeholder="请输入请求体" type="textarea" />
+    <el-input v-model="config.body" placeholder="请输入内容" type="textarea" />
   </el-form-item>
 </template>
+
 <script lang="ts" setup>
 import { HttpConfig, IoTDataBridgeConfigType } from '@/api/iot/rule/databridge'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
+import KeyValueEditor from './components/KeyValueEditor.vue'
 
 defineOptions({ name: 'HttpConfigForm' })
 
@@ -43,43 +42,43 @@ const props = defineProps<{
 const emit = defineEmits(['update:modelValue'])
 const config = useVModel(props, 'modelValue', emit) as Ref<HttpConfig>
 
-const headersStr = ref('{}')
-const queryStr = ref('{}')
+// URL处理
+const urlPrefix = ref('http://')
+const urlPath = ref('')
+const fullUrl = computed(() => {
+  return urlPath.value ? urlPrefix.value + urlPath.value : ''
+})
+
+// 监听URL变化
+watch([urlPrefix, urlPath], () => {
+  config.value.url = fullUrl.value
+})
 
 /** 组件初始化 */
 onMounted(() => {
   if (!isEmpty(config.value)) {
+    // 初始化URL
+    if (config.value.url) {
+      if (config.value.url.startsWith('https://')) {
+        urlPrefix.value = 'https://'
+        urlPath.value = config.value.url.substring(8)
+      } else if (config.value.url.startsWith('http://')) {
+        urlPrefix.value = 'http://'
+        urlPath.value = config.value.url.substring(7)
+      } else {
+        urlPath.value = config.value.url
+      }
+    }
     return
   }
+
   config.value = {
     type: IoTDataBridgeConfigType.HTTP,
     url: '',
-    method: 'GET',
+    method: 'POST',
     headers: {},
     query: {},
     body: ''
   }
-
-  // 初始化字符串形式
-  headersStr.value = JSON.stringify(config.value.headers || {}, null, 2)
-  queryStr.value = JSON.stringify(config.value.query || {}, null, 2)
 })
-
-// 处理headers输入变化
-const handleHeadersChange = (val: string) => {
-  try {
-    config.value.headers = JSON.parse(val)
-  } catch (e) {
-    // 解析失败,保留原始字符串
-  }
-}
-
-// 处理query输入变化
-const handleQueryChange = (val: string) => {
-  try {
-    config.value.query = JSON.parse(val)
-  } catch (e) {
-    // 解析失败,保留原始字符串
-  }
-}
 </script>

+ 71 - 0
src/views/iot/rule/databridge/config/components/KeyValueEditor.vue

@@ -0,0 +1,71 @@
+<template>
+  <div v-for="(item, index) in items" :key="index" class="flex mb-2">
+    <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>
+      删除
+    </el-button>
+  </div>
+  <el-button text type="primary" @click="addItem">
+    <el-icon>
+      <Plus />
+    </el-icon>
+    {{ addButtonText }}
+  </el-button>
+</template>
+
+<script lang="ts" setup>
+import { Delete, Plus } from '@element-plus/icons-vue'
+import { isEmpty } from '@/utils/is'
+
+defineOptions({ name: 'KeyValueEditor' })
+
+interface KeyValueItem {
+  key: string
+  value: string
+}
+
+const props = defineProps<{
+  modelValue: Record<string, string>
+  addButtonText: string
+}>()
+const emit = defineEmits(['update:modelValue'])
+// 内部key-value项列表
+const items = ref<KeyValueItem[]>([])
+
+// 添加项目
+const addItem = () => {
+  items.value.push({ key: '', value: '' })
+  updateModelValue()
+}
+
+// 移除项目
+const removeItem = (index: number) => {
+  items.value.splice(index, 1)
+  updateModelValue()
+}
+
+// 更新modelValue
+const updateModelValue = () => {
+  const result: Record<string, string> = {}
+  items.value.forEach((item) => {
+    if (item.key) {
+      result[item.key] = item.value
+    }
+  })
+  emit('update:modelValue', result)
+}
+
+// 监听项目变化
+watch(items, updateModelValue, { deep: true })
+onMounted(() => {
+  if (isEmpty(props.modelValue)) {
+    return
+  }
+
+  items.value = Object.entries(props.modelValue).map(([key, value]) => ({ key, value }))
+})
+</script>