diff --git a/apps/web-antd/src/views/components/DataPushRuleEditor.vue b/apps/web-antd/src/views/components/DataPushRuleEditor.vue index 456071b..115d67b 100644 --- a/apps/web-antd/src/views/components/DataPushRuleEditor.vue +++ b/apps/web-antd/src/views/components/DataPushRuleEditor.vue @@ -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([]); +const pushType = ref(1); +const pushServer = ref(''); +const pushInfo = ref(''); +const ruleName = ref(''); + +// 记录最近一次抛出的数组引用,识别 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 = { + 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); } diff --git a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue index 0c644a7..dd94154 100644 --- a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue +++ b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue @@ -3086,7 +3086,7 @@ async function submitDeviceDataFlowConfig() { // 仅在开启覆盖且需要推送时校验规则 if (override && needPush) { if (rules.length === 0) { - Message.error('请至少添加一条推送规则'); + Message.error('请至少选择要推送的数据类型'); return; } const invalid = rules.some( diff --git a/apps/web-antd/src/views/onenetmanagement/privateProduct/index.vue b/apps/web-antd/src/views/onenetmanagement/privateProduct/index.vue index 1995fdd..7eacc73 100644 --- a/apps/web-antd/src/views/onenetmanagement/privateProduct/index.vue +++ b/apps/web-antd/src/views/onenetmanagement/privateProduct/index.vue @@ -383,7 +383,7 @@ async function submitDataFlowConfig() { // 开启推送时校验:至少一条规则,且启用的规则必须填服务地址与推送信息 if (values.isNeedPushData) { if (rules.length === 0) { - Message.error('请至少添加一条推送规则'); + Message.error('请至少选择要推送的数据类型'); return; } const invalid = rules.some(