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

This commit is contained in:
puhui999 2025-03-09 19:30:31 +08:00
parent 2fd3422c06
commit fd0b7be89f
2 changed files with 109 additions and 39 deletions

View File

@ -1,6 +1,13 @@
<template> <template>
<el-form-item label="请求地址" prop="config.url"> <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>
<el-form-item label="请求方法" prop="config.method"> <el-form-item label="请求方法" prop="config.method">
<el-select v-model="config.method" placeholder="请选择请求方法"> <el-select v-model="config.method" placeholder="请选择请求方法">
@ -11,29 +18,21 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="请求头" prop="config.headers"> <el-form-item label="请求头" prop="config.headers">
<el-input <key-value-editor v-model="config.headers" add-button-text="添加请求头" />
v-model="headersStr"
placeholder="请输入请求头,格式为 JSON"
type="textarea"
@input="handleHeadersChange"
/>
</el-form-item> </el-form-item>
<el-form-item label="请求参数" prop="config.query"> <el-form-item label="请求参数" prop="config.query">
<el-input <key-value-editor v-model="config.query" add-button-text="添加参数" />
v-model="queryStr"
placeholder="请输入请求参数,格式为 JSON"
type="textarea"
@input="handleQueryChange"
/>
</el-form-item> </el-form-item>
<el-form-item label="请求体" prop="config.body"> <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> </el-form-item>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { HttpConfig, IoTDataBridgeConfigType } from '@/api/iot/rule/databridge' import { HttpConfig, IoTDataBridgeConfigType } from '@/api/iot/rule/databridge'
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import { isEmpty } from '@/utils/is' import { isEmpty } from '@/utils/is'
import KeyValueEditor from './components/KeyValueEditor.vue'
defineOptions({ name: 'HttpConfigForm' }) defineOptions({ name: 'HttpConfigForm' })
@ -43,43 +42,43 @@ const props = defineProps<{
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const config = useVModel(props, 'modelValue', emit) as Ref<HttpConfig> const config = useVModel(props, 'modelValue', emit) as Ref<HttpConfig>
const headersStr = ref('{}') // URL
const queryStr = ref('{}') 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(() => { onMounted(() => {
if (!isEmpty(config.value)) { 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 return
} }
config.value = { config.value = {
type: IoTDataBridgeConfigType.HTTP, type: IoTDataBridgeConfigType.HTTP,
url: '', url: '',
method: 'GET', method: 'POST',
headers: {}, headers: {},
query: {}, query: {},
body: '' 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> </script>

View File

@ -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>