Appearance
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;
}