diff --git a/apps/web-antd/src/views/aiot/device/roi/components/AlgorithmParamEditor.vue b/apps/web-antd/src/views/aiot/device/roi/components/AlgorithmParamEditor.vue index 42deca53f..44499dd42 100644 --- a/apps/web-antd/src/views/aiot/device/roi/components/AlgorithmParamEditor.vue +++ b/apps/web-antd/src/views/aiot/device/roi/components/AlgorithmParamEditor.vue @@ -13,6 +13,8 @@ import { import { updateAlgoParams } from '#/api/aiot/device'; +import WorkingHoursEditor from './WorkingHoursEditor.vue'; + interface Props { open: boolean; paramSchema: string; @@ -85,8 +87,20 @@ function removeListItem(key: string, idx: number) { formData.value[key].splice(idx, 1); } +// 判断是否为工作时间段字段 +function isWorkingHoursField(key: string): boolean { + return key === 'working_hours'; +} + async function handleSave() { try { + // 保存前验证参数 + const validation = validateParams(formData.value); + if (!validation.valid) { + message.error(validation.error || '参数格式错误'); + return; + } + await updateAlgoParams({ bindId: props.bindId, params: JSON.stringify(formData.value), @@ -94,17 +108,74 @@ async function handleSave() { message.success('参数保存成功'); emit('saved', formData.value); emit('update:open', false); - } catch { - message.error('参数保存失败'); + } catch (error: any) { + console.error('保存失败:', error); + // 改进错误提示:显示后端返回的具体错误信息 + const errorMsg = error?.response?.data?.msg || + error?.response?.data?.message || + error?.message || + '参数保存失败,请检查参数格式'; + message.error(errorMsg); } } + +// 参数校验 +function validateParams(params: Record): { + valid: boolean; + error?: string; +} { + const schema = parsedSchema.value; + + for (const [key, value] of Object.entries(params)) { + const fieldSchema = schema[key]; + if (!fieldSchema) continue; + + // 校验整数类型 + if (fieldSchema.type === 'int') { + if (typeof value !== 'number') { + return { valid: false, error: `${key} 必须是整数` }; + } + if (fieldSchema.min !== undefined && value < fieldSchema.min) { + return { + valid: false, + error: `${key} 不能小于 ${fieldSchema.min}`, + }; + } + } + + // 校验列表类型 + if (fieldSchema.type === 'list') { + if (!Array.isArray(value)) { + return { valid: false, error: `${key} 必须是数组` }; + } + + // 特殊校验 working_hours 格式 + if (key === 'working_hours' && value.length > 0) { + const isValid = value.every( + (item: any) => + typeof item === 'object' && + typeof item.start === 'string' && + typeof item.end === 'string', + ); + if (!isValid) { + return { + valid: false, + error: '工作时间段格式错误,每项需包含 start 和 end', + }; + } + } + } + } + + return { valid: true }; +} + + diff --git a/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue b/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue new file mode 100644 index 000000000..7c412ba64 --- /dev/null +++ b/apps/web-antd/src/views/aiot/device/roi/components/WorkingHoursEditor.vue @@ -0,0 +1,447 @@ + + + + +