完善数据流转配置

This commit is contained in:
ChenYi 2026-07-03 10:29:08 +08:00
parent 6873c6aa97
commit 5ac3633606
3 changed files with 89 additions and 97 deletions

View File

@ -3,7 +3,7 @@ import type { DataPushRule } from '#/api-client';
import { ref, toRaw, watch } from 'vue';
import { Button, Input, Select, Switch } from 'ant-design-vue';
import { Input, Select } from 'ant-design-vue';
defineOptions({
name: 'DataPushRuleEditor',
@ -19,150 +19,142 @@ const emit = defineEmits<{
(e: 'update:rules', value: DataPushRule[]): void;
}>();
// /
// Swagger
const dataTypeOptions = [
{ label: '属性', value: 'Property' },
{ label: '事件', value: 'Event' },
{ label: '状态', value: 'Status' },
{ label: '属性', value: 1 },
{ label: '事件', value: 2 },
{ label: '状态', value: 3 },
];
const pushTypeOptions = [
{ label: 'HTTP POST', value: 'HttpPost' },
{ label: 'Redis 普通订阅', value: 'NormalReisSubscription' },
{ label: 'Redis 可靠订阅', value: 'ReliableReisSubscription' },
{ label: 'Redis List', value: 'RedisListPush' },
{ label: 'HTTP POST', value: 1 },
{ label: 'Redis 普通订阅', value: 2 },
{ label: 'Redis 可靠订阅', value: 3 },
{ label: 'Redis List', value: 4 },
];
//
let seed = 0;
// v-model list
// / +
// " "
const selectedTypes = ref<number[]>([]);
const pushType = ref<number>(1);
const pushServer = ref<string>('');
const pushInfo = ref<string>('');
const ruleName = ref<string>('');
// v-model ref reactive toRaw
let lastEmitted: DataPushRule[] | null = null;
const list = ref<(DataPushRule & { _key: number })[]>([]);
//
function toNum(value: any): number {
if (typeof value === 'number') {
return value;
}
const map: Record<string, number> = {
Property: 1,
Event: 2,
Status: 3,
HttpPost: 1,
NormalReisSubscription: 2,
ReliableReisSubscription: 3,
RedisListPush: 4,
};
return map[value] ?? Number(value);
}
watch(
() => props.rules,
(val) => {
// emit
// ref reactive toRaw
if (toRaw(val) === lastEmitted) {
return;
}
list.value = Array.isArray(val)
? val.map((r) => ({ ...r, _key: seed++ }))
: [];
const list = Array.isArray(val) ? val : [];
if (list.length === 0) {
selectedTypes.value = [];
pushType.value = 1;
pushServer.value = '';
pushInfo.value = '';
ruleName.value = '';
return;
}
// /
const first = list[0];
selectedTypes.value = [...new Set(list.map((r) => toNum(r.dataType)))];
pushType.value = toNum(first.pushType);
pushServer.value = first.pushServer ?? '';
pushInfo.value = first.pushInfo ?? '';
ruleName.value = first.ruleName ?? '';
},
{ immediate: true },
);
function emitChange() {
// _key
const out = list.value.map((r) => ({
ruleName: r.ruleName,
enabled: r.enabled,
dataType: r.dataType,
includeNames: r.includeNames ?? null,
pushType: r.pushType,
pushServer: r.pushServer,
pushInfo: r.pushInfo,
}));
lastEmitted = out;
emit('update:rules', out);
}
function addRule() {
list.value.push({
_key: seed++,
ruleName: '',
// " + "
const out = selectedTypes.value.map((t) => ({
ruleName: ruleName.value,
enabled: true,
dataType: 'Property',
dataType: t,
includeNames: null,
pushType: 'HttpPost',
pushServer: '',
pushInfo: '',
});
emitChange();
}
function removeRule(index: number) {
list.value.splice(index, 1);
emitChange();
pushType: pushType.value,
pushServer: pushServer.value,
pushInfo: pushInfo.value,
}));
lastEmitted = out as unknown as DataPushRule[];
emit('update:rules', lastEmitted);
}
</script>
<template>
<div>
<!-- 表头 -->
<div class="mb-1 flex items-center gap-2 text-xs text-gray-500">
<span class="w-[44px] flex-shrink-0">启用</span>
<span class="w-[96px] flex-shrink-0">数据类型</span>
<span class="w-[150px] flex-shrink-0">推送方式</span>
<span class="flex-1">服务地址</span>
<span class="flex-1">路径 / 主题 / KEY</span>
<span class="w-[120px] flex-shrink-0">备注</span>
<span class="w-[48px] flex-shrink-0">操作</span>
</div>
<!-- 规则行用稳定 key v-for避免输入时被重建导致失焦 -->
<div
v-for="(item, index) in list"
:key="item._key"
class="mb-2 flex items-center gap-2"
>
<span class="w-[44px] flex-shrink-0">
<Switch
v-model:checked="item.enabled"
size="small"
:disabled="disabled"
@change="emitChange"
/>
</span>
<div class="space-y-3">
<div class="flex items-center gap-2">
<span class="w-28 flex-shrink-0 text-sm text-gray-600">数据类型</span>
<Select
v-model:value="item.dataType"
v-model:value="selectedTypes"
mode="multiple"
:options="dataTypeOptions"
:disabled="disabled"
class="w-[96px] flex-shrink-0"
class="flex-1"
placeholder="选择要推送的数据类型(可多选)"
@change="emitChange"
/>
</div>
<div class="flex items-center gap-2">
<span class="w-28 flex-shrink-0 text-sm text-gray-600">推送方式</span>
<Select
v-model:value="item.pushType"
v-model:value="pushType"
:options="pushTypeOptions"
:disabled="disabled"
class="w-[150px] flex-shrink-0"
class="flex-1"
@change="emitChange"
/>
</div>
<div class="flex items-center gap-2">
<span class="w-28 flex-shrink-0 text-sm text-gray-600">服务地址</span>
<Input
v-model:value="item.pushServer"
v-model:value="pushServer"
:disabled="disabled"
class="flex-1"
placeholder="HTTPhttp://ip:portRedisip:port"
@change="emitChange"
/>
</div>
<div class="flex items-center gap-2">
<span class="w-28 flex-shrink-0 text-sm text-gray-600">路径 / 主题 / KEY</span>
<Input
v-model:value="item.pushInfo"
v-model:value="pushInfo"
:disabled="disabled"
class="flex-1"
placeholder="HTTP 为路径Redis 为主题或 key"
placeholder="HTTP 为推送路径Redis 为主题或 key"
@change="emitChange"
/>
</div>
<div class="flex items-center gap-2">
<span class="w-28 flex-shrink-0 text-sm text-gray-600">备注</span>
<Input
v-model:value="item.ruleName"
v-model:value="ruleName"
:disabled="disabled"
class="w-[120px] flex-shrink-0"
class="flex-1"
placeholder="可空"
@change="emitChange"
/>
<span class="w-[48px] flex-shrink-0">
<Button
type="link"
danger
size="small"
:disabled="disabled"
@click="removeRule(index)"
>
删除
</Button>
</span>
</div>
<Button type="dashed" block :disabled="disabled" @click="addRule">
+ 添加推送规则
</Button>
</div>
</template>

View File

@ -3086,7 +3086,7 @@ async function submitDeviceDataFlowConfig() {
//
if (override && needPush) {
if (rules.length === 0) {
Message.error('请至少添加一条推送规则');
Message.error('请至少选择要推送的数据类型');
return;
}
const invalid = rules.some(

View File

@ -383,7 +383,7 @@ async function submitDataFlowConfig() {
//
if (values.isNeedPushData) {
if (rules.length === 0) {
Message.error('请至少添加一条推送规则');
Message.error('请至少选择要推送的数据类型');
return;
}
const invalid = rules.some(