Skip to content

JPwise 配置验证规则

本文档与 列表配置规范 配合使用,提供完整的配置验证机制。

配置完整性验证

必要字段检查

javascript
const requiredConfigFields = [
  'id', 'fullName', 'enCode', 'state', 'type',
  'tables', 'formData', 'columnData', 'sqlStr',
  'interfaceInfo', 'webType', 'modelType'
];

function validateRequiredFields(config) {
  const errors = [];
  
  requiredConfigFields.forEach(field => {
    if (!config.hasOwnProperty(field)) {
      errors.push(`缺少必要字段: ${field}`);
    }
    
    if (config[field] === undefined || config[field] === '') {
      errors.push(`字段 ${field} 不能为空`);
    }
  });
  
  return errors;
}

JSON格式验证

javascript
function validateJSONFields(config) {
  const errors = [];
  const jsonFields = ['tables', 'formData', 'columnData'];
  
  jsonFields.forEach(field => {
    if (config[field]) {
      try {
        const parsed = JSON.parse(config[field]);
        if (typeof parsed !== 'object') {
          errors.push(`${field} 必须是有效的JSON对象`);
        }
      } catch (e) {
        errors.push(`${field} JSON格式错误: ${e.message}`);
      }
    }
  });
  
  return errors;
}

// 列表配置验证
function validateColumnDataFields(config) {
  const errors = [];
  
  try {
    const columnData = JSON.parse(config.columnData);
    
    // 验证基础配置
    const requiredFields = ['type', 'columnList', 'customBtnsList', 'customTopBtnsList', 'multiple', 'hasPage'];
    requiredFields.forEach(field => {
      if (!columnData.hasOwnProperty(field)) {
        errors.push(`列表配置缺少必需字段: ${field}`);
      }
    });
    
    // 验证列表类型
    if (columnData.type && ![1, 2, 3, 4].includes(columnData.type)) {
      errors.push('列表类型 type 必须是 1, 2, 3, 4 中的一个');
    }
    
    // 验证分页配置
    if (columnData.hasPage && columnData.pageSize && columnData.pageSize <= 0) {
      errors.push('分页大小 pageSize 必须大于 0');
    }
    
  } catch (e) {
    errors.push(`列表配置JSON格式错误: ${e.message}`);
  }
  
  return errors;
}

数据格式验证

javascript
const formatValidators = {
  // ID格式验证(19位数字字符串)
  id: {
    pattern: /^\d{19}$/,
    message: 'ID必须是19位数字字符串'
  },
  
  // 时间格式验证
  datetime: {
    pattern: /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/,
    message: '时间格式必须是 yyyy-MM-dd HH:mm:ss'
  },
  
  // 表名格式验证
  tableName: {
    pattern: /^[A-Z][A-Z0-9_]*$/,
    message: '表名必须是大写字母开头的大写下划线格式'
  },
  
  // 字段名格式验证
  fieldName: {
    pattern: /^[A-Z][A-Z0-9_]*$/,
    message: '字段名必须是大写字母开头的大写下划线格式'
  },
  
  // 编码格式验证(驼峰命名)
  enCode: {
    pattern: /^[A-Z][a-zA-Z0-9]*$/,
    message: 'enCode必须是大写字母开头的驼峰命名格式'
  }
};

function validateFormats(config) {
  const errors = [];
  
  // 验证ID格式
  if (!formatValidators.id.pattern.test(config.id)) {
    errors.push(formatValidators.id.message);
  }
  
  // 验证时间格式
  if (config.creatorTime && !formatValidators.datetime.pattern.test(config.creatorTime)) {
    errors.push(`创建时间格式错误: ${formatValidators.datetime.message}`);
  }
  
  // 验证编码格式
  if (!formatValidators.enCode.pattern.test(config.enCode)) {
    errors.push(formatValidators.enCode.message);
  }
  
  return errors;
}

字段一致性验证

表单字段与表结构一致性

javascript
function validateFormFieldConsistency(config) {
  const errors = [];
  
  try {
    const tables = JSON.parse(config.tables);
    const formData = JSON.parse(config.formData);
    
    // 获取主表字段
    const mainTable = tables.find(t => t.typeId === "1");
    if (!mainTable) {
      errors.push('找不到主表定义');
      return errors;
    }
    
    const tableFields = mainTable.fields.map(f => f.field);
    const formFields = extractFormFields(formData.fields);
    
    // 检查表单字段是否都在表结构中
    formFields.forEach(formField => {
      if (!tableFields.includes(formField) && !isSystemField(formField)) {
        errors.push(`表单字段 ${formField} 在表结构中不存在`);
      }
    });
    
    // 检查必要的业务字段是否在表单中
    const businessFields = tableFields.filter(f => 
      !isSystemField(f) && !isIdField(f)
    );
    
    businessFields.forEach(tableField => {
      if (!formFields.includes(tableField)) {
        errors.push(`表结构字段 ${tableField} 缺少对应的表单组件`);
      }
    });
    
  } catch (e) {
    errors.push(`字段一致性验证失败: ${e.message}`);
  }
  
  return errors;
}

列表字段与表结构一致性

javascript
function validateColumnFieldConsistency(config) {
  const errors = [];
  
  try {
    const tables = JSON.parse(config.tables);
    const columnData = JSON.parse(config.columnData);
    
    const mainTable = tables.find(t => t.typeId === "1");
    if (!mainTable) return errors;
    
    const tableFields = mainTable.fields.map(f => f.field);
    const columnFields = columnData.columnList.map(c => c.prop);
    
    // 检查列表字段是否都在表结构中
    columnFields.forEach(columnField => {
      if (!tableFields.includes(columnField)) {
        errors.push(`列表字段 ${columnField} 在表结构中不存在`);
      }
    });
    
  } catch (e) {
    errors.push(`列表字段一致性验证失败: ${e.message}`);
  }
  
  return errors;
}

子表关联验证

javascript
function validateSubTableRelations(config) {
  const errors = [];
  
  try {
    const tables = JSON.parse(config.tables);
    const mainTable = tables.find(t => t.typeId === "1");
    const subTables = tables.filter(t => t.typeId === "0");
    
    if (!mainTable) return errors;
    
    subTables.forEach(subTable => {
      // 验证relationTable是否是主表名
      if (subTable.relationTable !== mainTable.table) {
        errors.push(`子表 ${subTable.table} 的 relationTable 应该是 ${mainTable.table}`);
      }
      
      // 验证tableField是否正确
      const expectedTableField = mainTable.table + 'ID';
      if (subTable.tableField !== expectedTableField) {
        errors.push(`子表 ${subTable.table} 的 tableField 应该是 ${expectedTableField}`);
      }
      
      // 验证子表是否包含关联字段
      const hasRelationField = subTable.fields.some(f => 
        f.field === subTable.tableField
      );
      if (!hasRelationField) {
        errors.push(`子表 ${subTable.table} 缺少关联字段 ${subTable.tableField}`);
      }
    });
    
  } catch (e) {
    errors.push(`子表关联验证失败: ${e.message}`);
  }
  
  return errors;
}

列表配置专项验证

按钮配置验证

javascript
function validateButtonConfiguration(config) {
  const errors = [];
  
  try {
    const columnData = JSON.parse(config.columnData);
    
    // 验证行按钮配置
    if (columnData.customBtnsList && Array.isArray(columnData.customBtnsList)) {
      columnData.customBtnsList.forEach((button, index) => {
        // 验证按钮必要属性
        const requiredProps = ['value', 'icon', 'label', 'func'];
        requiredProps.forEach(prop => {
          if (!button.hasOwnProperty(prop)) {
            errors.push(`行按钮[${index}]缺少必要属性: ${prop}`);
          }
        });
        
        // 验证按钮标识唯一性
        const duplicates = columnData.customBtnsList.filter(btn => btn.value === button.value);
        if (duplicates.length > 1) {
          errors.push(`行按钮标识 ${button.value} 重复`);
        }
        
        // 验证函数代码有效性
        if (button.func) {
          try {
            new Function(button.func);
          } catch (e) {
            errors.push(`行按钮[${button.value}]函数代码语法错误: ${e.message}`);
          }
        }
      });
    }
    
    // 验证顶部按钮配置
    if (columnData.customTopBtnsList && Array.isArray(columnData.customTopBtnsList)) {
      columnData.customTopBtnsList.forEach((button, index) => {
        // 验证按钮必要属性
        const requiredProps = ['value', 'icon', 'label', 'func'];
        requiredProps.forEach(prop => {
          if (!button.hasOwnProperty(prop)) {
            errors.push(`顶部按钮[${index}]缺少必要属性: ${prop}`);
          }
        });
        
        // 验证按钮标识唯一性
        const duplicates = columnData.customTopBtnsList.filter(btn => btn.value === button.value);
        if (duplicates.length > 1) {
          errors.push(`顶部按钮标识 ${button.value} 重复`);
        }
        
        // 验证函数代码有效性
        if (button.func) {
          try {
            new Function(button.func);
          } catch (e) {
            errors.push(`顶部按钮[${button.value}]函数代码语法错误: ${e.message}`);
          }
        }
      });
    }
    
  } catch (e) {
    errors.push(`按钮配置验证失败: ${e.message}`);
  }
  
  return errors;
}

列配置验证

javascript
function validateColumnConfiguration(config) {
  const errors = [];
  
  try {
    const columnData = JSON.parse(config.columnData);
    const tables = JSON.parse(config.tables);
    
    if (!columnData.columnList) {
      errors.push('缺少列配置 columnList');
      return errors;
    }
    
    // 获取主表字段
    const mainTable = tables.find(t => t.typeId === "1");
    if (!mainTable) return errors;
    
    const tableFields = mainTable.fields.map(f => f.field);
    
    // 验证列配置的完整性
    const requiredColumnProps = ['prop', 'label', 'width', 'align'];
    
    if (Array.isArray(columnData.defaultColumnList)) {
      columnData.defaultColumnList.forEach((column, index) => {
        // 验证必要属性
        requiredColumnProps.forEach(prop => {
          if (!column.hasOwnProperty(prop)) {
            errors.push(`列配置[${index}]缺少必要属性: ${prop}`);
          }
        });
        
        // 验证字段存在性
        if (column.prop && !tableFields.includes(column.prop) && !isSystemField(column.prop)) {
          errors.push(`列配置字段 ${column.prop} 在表结构中不存在`);
        }
        
        // 验证列宽合理性
        if (column.width && (column.width < 50 || column.width > 500)) {
          errors.push(`列 ${column.prop} 的宽度 ${column.width} 超出合理范围 [50-500]`);
        }
        
        // 验证对齐方式
        if (column.align && !['left', 'center', 'right'].includes(column.align)) {
          errors.push(`列 ${column.prop} 的对齐方式 ${column.align} 无效`);
        }
      });
    }
    
  } catch (e) {
    errors.push(`列配置验证失败: ${e.message}`);
  }
  
  return errors;
}

事件函数验证

javascript
function validateEventFunctions(config) {
  const errors = [];
  
  try {
    const columnData = JSON.parse(config.columnData);
    
    if (columnData.funcs) {
      const requiredEvents = ['onload', 'mounted', 'afterOnload'];
      const validEventTypes = ['onload', 'mounted', 'afterOnload', 'beforeDestroy'];
      
      // 检查必要事件函数
      requiredEvents.forEach(eventType => {
        if (!columnData.funcs[eventType]) {
          errors.push(`缺少必要的事件函数: ${eventType}`);
        }
      });
      
      // 验证事件函数配置
      Object.keys(columnData.funcs).forEach(eventKey => {
        const eventConfig = columnData.funcs[eventKey];
        
        // 验证事件类型
        if (!eventConfig.type || !validEventTypes.includes(eventConfig.type)) {
          errors.push(`事件函数 ${eventKey} 的类型 ${eventConfig.type} 无效`);
        }
        
        // 验证函数代码
        if (!eventConfig.func) {
          errors.push(`事件函数 ${eventKey} 缺少函数代码`);
        } else {
          try {
            new Function(eventConfig.func);
          } catch (e) {
            errors.push(`事件函数 ${eventKey} 代码语法错误: ${e.message}`);
          }
        }
        
        // 验证函数名称
        if (!eventConfig.name) {
          errors.push(`事件函数 ${eventKey} 缺少名称描述`);
        }
      });
    }
    
  } catch (e) {
    errors.push(`事件函数验证失败: ${e.message}`);
  }
  
  return errors;
}

权限配置验证

javascript
function validatePermissionConfiguration(config) {
  const errors = [];
  
  try {
    const columnData = JSON.parse(config.columnData);
    
    // 验证权限开关配置
    const permissionFields = [
      'useColumnPermission', 
      'useFormPermission', 
      'useBtnPermission', 
      'useDataPermission'
    ];
    
    permissionFields.forEach(field => {
      if (columnData.hasOwnProperty(field) && typeof columnData[field] !== 'boolean') {
        errors.push(`权限配置 ${field} 必须是布尔值`);
      }
    });
    
    // 如果启用按钮权限,验证按钮权限配置
    if (columnData.useBtnPermission) {
      // 检查按钮是否有权限控制逻辑
      const hasPermissionCheck = (btnList) => {
        return btnList && btnList.some(btn => 
          btn.func && btn.func.includes('hasPermission')
        );
      };
      
      if (!hasPermissionCheck(columnData.customBtnsList) && 
          !hasPermissionCheck(columnData.customTopBtnsList)) {
        errors.push('启用了按钮权限但按钮函数中未发现权限检查逻辑');
      }
    }
    
  } catch (e) {
    errors.push(`权限配置验证失败: ${e.message}`);
  }
  
  return errors;
}

业务逻辑验证

必填字段验证

javascript
function validateRequiredFieldLogic(config) {
  const errors = [];
  
  try {
    const formData = JSON.parse(config.formData);
    const requiredFields = extractRequiredFields(formData.fields);
    
    // 检查核心业务字段是否标记为必填
    const coreFieldPatterns = ['NAME', 'TITLE', 'CODE'];
    const formFields = extractFormFields(formData.fields);
    
    formFields.forEach(field => {
      const shouldBeRequired = coreFieldPatterns.some(pattern => 
        field.includes(pattern)
      );
      
      if (shouldBeRequired && !requiredFields.includes(field)) {
        errors.push(`核心字段 ${field} 应该设置为必填`);
      }
    });
    
  } catch (e) {
    errors.push(`必填字段逻辑验证失败: ${e.message}`);
  }
  
  return errors;
}

组件类型匹配验证

javascript
function validateComponentTypeMatching(config) {
  const errors = [];
  
  try {
    const tables = JSON.parse(config.tables);
    const formData = JSON.parse(config.formData);
    
    const mainTable = tables.find(t => t.typeId === "1");
    if (!mainTable) return errors;
    
    // 创建字段类型映射
    const fieldTypeMap = {};
    mainTable.fields.forEach(field => {
      fieldTypeMap[field.field] = field.dataType;
    });
    
    // 验证表单组件与字段类型的匹配
    const formComponents = extractFormComponents(formData.fields);
    
    formComponents.forEach(component => {
      const fieldType = fieldTypeMap[component.field];
      if (fieldType && !isComponentTypeMatched(component.jnpfKey, fieldType)) {
        errors.push(`字段 ${component.field} 的组件类型 ${component.jnpfKey} 与数据类型 ${fieldType} 不匹配`);
      }
    });
    
  } catch (e) {
    errors.push(`组件类型匹配验证失败: ${e.message}`);
  }
  
  return errors;
}

自动修正机制

字段名称标准化

javascript
function normalizeFieldNames(config) {
  const corrections = [];
  
  try {
    const tables = JSON.parse(config.tables);
    
    tables.forEach(table => {
      table.fields.forEach(field => {
        const original = field.field;
        const normalized = normalizeFieldName(original);
        
        if (original !== normalized) {
          field.field = normalized;
          corrections.push(`字段名 ${original} 已标准化为 ${normalized}`);
        }
      });
    });
    
    config.tables = JSON.stringify(tables);
    
  } catch (e) {
    corrections.push(`字段名标准化失败: ${e.message}`);
  }
  
  return corrections;
}

function normalizeFieldName(name) {
  // 转换为大写下划线格式
  return name
    .replace(/([a-z])([A-Z])/g, '$1_$2')  // camelCase转下划线
    .toUpperCase()                        // 转大写
    .replace(/[^A-Z0-9_]/g, '_')         // 替换非法字符
    .replace(/_+/g, '_')                 // 合并多个下划线
    .replace(/^_|_$/g, '');              // 移除首尾下划线
}

组件配置自动补全

javascript
function autoCompleteComponentConfig(config) {
  const corrections = [];
  
  try {
    const formData = JSON.parse(config.formData);
    
    formData.fields.forEach(field => {
      if (field.__config__) {
        // 补全缺失的必要属性
        const defaultConfig = getDefaultComponentConfig(field.__config__.jnpfKey);
        
        Object.keys(defaultConfig).forEach(key => {
          if (!field.__config__.hasOwnProperty(key)) {
            field.__config__[key] = defaultConfig[key];
            corrections.push(`为组件 ${field.__config__.jnpfKey} 补全属性 ${key}`);
          }
        });
        
        // 自动设置placeholder
        if (!field.placeholder && needsPlaceholder(field.__config__.jnpfKey)) {
          field.placeholder = generatePlaceholder(field.__config__.label);
          corrections.push(`为字段 ${field.__config__.label} 生成placeholder`);
        }
      }
    });
    
    config.formData = JSON.stringify(formData);
    
  } catch (e) {
    corrections.push(`组件配置补全失败: ${e.message}`);
  }
  
  return corrections;
}

综合验证函数

javascript
function validateConfiguration(config) {
  const results = {
    errors: [],
    warnings: [],
    corrections: []
  };
  
  // 基础验证
  results.errors.push(...validateRequiredFields(config));
  results.errors.push(...validateJSONFields(config));
  results.errors.push(...validateColumnDataFields(config));
  results.errors.push(...validateFormats(config));
  
  // 列表配置专项验证
  results.errors.push(...validateButtonConfiguration(config));
  results.errors.push(...validateColumnConfiguration(config));
  results.errors.push(...validateEventFunctions(config));
  results.warnings.push(...validatePermissionConfiguration(config));
  
  // 一致性验证
  results.errors.push(...validateFormFieldConsistency(config));
  results.errors.push(...validateColumnFieldConsistency(config));
  results.errors.push(...validateSubTableRelations(config));
  
  // 业务逻辑验证
  results.warnings.push(...validateRequiredFieldLogic(config));
  results.warnings.push(...validateComponentTypeMatching(config));
  
  // 自动修正
  results.corrections.push(...normalizeFieldNames(config));
  results.corrections.push(...autoCompleteComponentConfig(config));
  
  return results;
}

验证报告生成

javascript
function generateValidationReport(results) {
  let report = '# 配置验证报告\n\n';
  
  if (results.errors.length > 0) {
    report += '## ❌ 错误\n\n';
    results.errors.forEach(error => {
      report += `- ${error}\n`;
    });
    report += '\n';
  }
  
  if (results.warnings.length > 0) {
    report += '## ⚠️ 警告\n\n';
    results.warnings.forEach(warning => {
      report += `- ${warning}\n`;
    });
    report += '\n';
  }
  
  if (results.corrections.length > 0) {
    report += '## ✅ 自动修正\n\n';
    results.corrections.forEach(correction => {
      report += `- ${correction}\n`;
    });
    report += '\n';
  }
  
  if (results.errors.length === 0) {
    report += '## ✅ 验证通过\n\n';
    report += '配置文件符合JPWise平台标准,可以正常使用。\n';
  }
  
  return report;
}