fix(iot): 修复场景联动动作类型切换 + 数据规则弹窗 4 处 bug

- B50 动作类型切换清理失效:updateActionType 先调 onActionTypeChange
  (此时 action.type 仍是旧值)再赋新值;onActionTypeChange 内恒真的
  type !== action.type 简化为 if (action.identifier)
- B16 新增弹窗不重置主表单:onOpenChange 关闭分支补 formApi.resetForm()
- B17 允许空数据源提交:source-config-form.validate() 补空数组校验
- B18 子表单校验 reject 未处理(弹窗关闭不掉):onConfirm 内 try/catch
  包子表单校验,失败 return 中止提交
pull/345/head
YunaiV 2026-05-22 20:24:30 +08:00
parent f8c869f1ff
commit 152964395d
6 changed files with 28 additions and 8 deletions

View File

@ -47,7 +47,11 @@ const [Modal, modalApi] = useVbenModal({
return;
}
//
await sourceConfigRef.value?.validate();
try {
await sourceConfigRef.value?.validate();
} catch {
return;
}
modalApi.lock();
//
const data = (await formApi.getValues()) as DataRuleApi.DataRule;
@ -65,6 +69,7 @@ const [Modal, modalApi] = useVbenModal({
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
await formApi.resetForm();
sourceConfigRef.value?.setData([]);
return;
}

View File

@ -154,6 +154,10 @@ async function handleDelete(rowIndex: number) {
/** 校验全部行;返回 Promise失败时 reject 第一条错误信息 */
function validate() {
if (formData.value.length === 0) {
message.error('请至少添加一条数据源配置');
return Promise.reject(new Error('数据源配置不能为空'));
}
for (let i = 0; i < formData.value.length; i++) {
const row = formData.value[i];
if (!row.productId) {

View File

@ -99,8 +99,9 @@ function removeAction(index: number) {
* @param type 执行器类型
*/
function updateActionType(index: number, type: number) {
actions.value[index]!.type = type;
onActionTypeChange(actions.value[index] as RuleSceneApi.Action, type);
const action = actions.value[index] as RuleSceneApi.Action;
onActionTypeChange(action, type); // action.type
action.type = type;
}
/**
@ -134,7 +135,7 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
action.params = '';
}
// identifier
if (action.identifier && type !== action.type) {
if (action.identifier) {
action.identifier = undefined;
}
} else if (isAlertAction(type)) {

View File

@ -47,7 +47,11 @@ const [Modal, modalApi] = useVbenModal({
return;
}
//
await sourceConfigRef.value?.validate();
try {
await sourceConfigRef.value?.validate();
} catch {
return;
}
modalApi.lock();
//
const data = (await formApi.getValues()) as DataRuleApi.DataRule;
@ -65,6 +69,7 @@ const [Modal, modalApi] = useVbenModal({
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
await formApi.resetForm();
sourceConfigRef.value?.setData([]);
return;
}

View File

@ -154,6 +154,10 @@ async function handleDelete(rowIndex: number) {
/** 校验全部行;返回 Promise失败时 reject 第一条错误信息 */
function validate() {
if (formData.value.length === 0) {
ElMessage.error('请至少添加一条数据源配置');
return Promise.reject(new Error('数据源配置不能为空'));
}
for (let i = 0; i < formData.value.length; i++) {
const row = formData.value[i];
if (!row.productId) {

View File

@ -107,8 +107,9 @@ function removeAction(index: number) {
* @param type 执行器类型
*/
function updateActionType(index: number, type: number) {
actions.value[index]!.type = type;
onActionTypeChange(actions.value[index] as RuleSceneApi.Action, type);
const action = actions.value[index] as RuleSceneApi.Action;
onActionTypeChange(action, type); // action.type
action.type = type;
}
/**
@ -142,7 +143,7 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
action.params = '';
}
// identifier
if (action.identifier && type !== action.type) {
if (action.identifier) {
action.identifier = undefined;
}
} else if (isAlertAction(type)) {