实现方案一
判断逻辑支持跳过。
handleCheckStatus ({ status = true, paymentApplyStatus = true, writeOffStatus = true }) {// 单据状态if (status && this.selectedRows.filter(item => item.status !== 'AUDITED').length) {this.$antdMessage.warning('请选择 [已审核] 状态的数据进行操作')return}// 付款申请状态if (paymentApplyStatus && this.selectedRows.filter(item => !['WAIT_APPLY'].includes(item.paymentApplyStatus)).length) {this.$antdMessage.warning('请选择 [待申请] 付款申请状态的数据进行操作')return}// 核销状态if (writeOffStatus && this.selectedRows.filter(item => !['WAIT'].includes(item.writeOffStatus)).length) {this.$antdMessage.warning('请选择 [未核销] 核销状态的数据进行操作')return}return true
},
handleCheckStatus 接收三个属性的对象作为参数,属性默认值都为 true。函数内部使用了条件语句和数组的过滤操作,用于检查选中的行数据的状态,并根据不同的状态显示警告信息。函数的功能似乎是用于检查选中的行数据是否符合特定的状态条件。
实现方案二
const validationConfig = {status: {allowedValues: ['AUDITED'],message: '请选择 [已审核] 状态的数据进行操作',},paymentApplyStatus: {allowedValues: ['WAIT_APPLY', 'PART_APPLY'],message: '请选择 [待申请] 和 [部分申请] 付款申请状态的数据进行操作',},writeOffStatus: {allowedValues: ['WAIT', 'PART'],message: '请选择 [未核销] 和 [部分核销] 核销状态的数据进行操作',},
};
handleCheckStatus (data, config) {for (const key in config) {const { allowedValues, message } = config[key]if (data.filter(item => !allowedValues.includes(item[key])).length) {this.$antdMessage.warning(message)return}}return true
},
handleCheckStatus 函数接受两个参数:data 是一个待检查的数据数组,而 object 是一个配置对象,其中包含了要检查的属性以及对应的允许值和警告消息。使用 for…in 循环来遍历 object 对象的属性,并使用 filter 函数来检查 data 数组中的元素,看它们的 key 属性的值是否包含在 list 数组中。如果有任何一个元素的属性值不在允许的列表中,就会显示相应的警告消息,并且函数会提前返回,不再继续检查其他属性。如果所有属性的值都在允许的列表中,函数将返回 true。
上述代码的优缺点
- 第一段代码的优点和缺点:
优点:
- 模块化和可维护性: 函数handleCheckStatus被设计成一个可复用的模块,可以轻松地被其他部分调用,提高了代码的可维护性和可复用性。
- 灵活性: 代码允许在函数调用时通过传入不同的参数来动态地控制状态检查的逻辑,增加了代码的灵活性。
- 可读性: 代码使用了清晰的命名和注释,提高了代码的可读性,使得其他开发者更容易理解代码的功能和意图。
缺点:
- 硬编码的状态值: 函数中的状态值(例如’已审核’、'待申请’等)被硬编码在函数内部,如果状态值需要修改,需要修改代码逻辑,可能会导致代码的维护成本增加。
- 不够灵活: 虽然函数允许动态控制状态检查的逻辑,但是逻辑仍然比较固定,不够灵活。如果需要添加更多的状态检查逻辑,可能需要修改函数内部的实现。
- 第二段代码的优点和缺点:
优点:
- 配置化: 使用了一个配置对象payValidateStatus来存储状态值和相应的提示信息,使得状态检查逻辑可以通过修改配置对象来实现,提高了可配置性。
- 可扩展性: 如果需要添加更多的状态检查逻辑,只需要修改配置对象,不需要修改函数内部的实现,增加了代码的可扩展性。
缺点:
- 配置对象的维护: 配置对象需要额外的维护工作,特别是在配置项较多或者配置逻辑较为复杂的情况下,可能会增加代码的复杂度。
- 可读性: 配置对象的结构和函数的调用关系可能不够直观,可能会降低代码的可读性,特别是对于阅读代码的新人来说。
第一段代码优化
主要问题在于硬编码的状态值,这使得代码缺乏灵活性和可维护性。将状态值和对应的警告消息配置化,使得状态值和消息可以轻松修改,代码实现如下:
const statusConfig = {AUDITED: '已审核',
};const paymentApplyStatusConfig = {WAIT_APPLY: '待申请',
};const writeOffStatusConfig = {WAIT: '未核销',
};function handleCheckStatus(selectedRows, statusConfig, paymentApplyStatusConfig, writeOffStatusConfig) {const invalidStatusItems = selectedRows.filter(item => ![statusConfig.AUDITED].includes(item.status));const invalidPaymentApplyStatusItems = selectedRows.filter(item => ![paymentApplyStatusConfig.WAIT_APPLY, paymentApplyStatusConfig.PART_APPLY].includes(item.paymentApplyStatus));const invalidWriteOffStatusItems = selectedRows.filter(item => ![writeOffStatusConfig.WAIT, writeOffStatusConfig.PART].includes(item.writeOffStatus));if (invalidStatusItems.length) {showWarningMessage(`请选择 [${statusConfig.AUDITED}] 状态的数据进行操作`);return false;}if (invalidPaymentApplyStatusItems.length) {showWarningMessage(`请选择 [${paymentApplyStatusConfig.WAIT_APPLY}] 或 [${paymentApplyStatusConfig.PART_APPLY}] 付款申请状态的数据进行操作`);return false;}if (invalidWriteOffStatusItems.length) {showWarningMessage(`请选择 [${writeOffStatusConfig.WAIT}] 或 [${writeOffStatusConfig.PART}] 核销状态的数据进行操作`);return false;}return true;
}// 错误消息的显示
function showWarningMessage(message) {this.$antdMessage.warning(message);
}// 调用示例
const isValid = handleCheckStatus(this.selectedRows, statusConfig, paymentApplyStatusConfig, writeOffStatusConfig);
if (isValid) {// 执行相应操作
}
将状态值和对应的消息被提取到了单独的配置对象,函数 handleCheckStatus 接受这些配置对象作为参数,使得验证逻辑与具体的状态值解耦,提高了代码的灵活性和可维护性,并且错误消息的显示逻辑被抽象为了一个独立的函数showWarningMessage,这样可以方便地进行统一的消息显示管理,也增加了代码的可维护性。
再次优化
如果 statusConfig, paymentApplyStatusConfig, 和 writeOffStatusConfig 是枚举值,你可以考虑将它们转换成更易于使用的对象形式,以提高代码的可读性和可维护性。你可以使用一个辅助函数来将枚举数组转换成对象,其中字典编码(dictCode)作为键,字典值(dictValue)作为值。这样,你可以使用键来代表状态值,而无需硬编码实际的状态字符串。代码实现如下:
// 将枚举数组转换为对象形式的辅助函数
function convertEnumToMap(enumArray) {return enumArray.reduce((acc, item) => {acc[item.dictCode] = item.dictValue;return acc;}, {});
}// 枚举数组
const statusEnum = [{ dictCode: 'WAIT_AUDIT', dictValue: '待审核' },{ dictCode: 'AUDITED', dictValue: '已审核' },{ dictCode: 'REJECT', dictValue: '审核拒绝' },{ dictCode: 'CANCEL', dictValue: '已取消' }
];const paymentApplyStatusEnum = [// Define your paymentApplyStatusEnum values here
];const writeOffStatusEnum = [// Define your writeOffStatusEnum values here
];// 将枚举数组转换为对象形式
const statusConfig = convertEnumToMap(statusEnum);
const paymentApplyStatusConfig = convertEnumToMap(paymentApplyStatusEnum);
const writeOffStatusConfig = convertEnumToMap(writeOffStatusEnum);function handleCheckStatus(selectedRows, statusConfig, paymentApplyStatusConfig, writeOffStatusConfig) {// 状态验证逻辑// ...
}// 调用示例
const isValid = handleCheckStatus(this.selectedRows, statusConfig, paymentApplyStatusConfig, writeOffStatusConfig);
if (isValid) {// 执行相应操作
}
convertEnumToMap 函数将枚举数组转换为对象形式,使得代码中的配置更加清晰,易于理解。通过使用枚举的键来代表状态值,代码的可读性和可维护性得到了提高。当你需要修改或者扩展枚举值时,只需要在相应的枚举数组中进行修改,而不需要修改验证逻辑,降低了代码的耦合性,使得系统更容易维护和扩展。
第二段代码优化
function validateData(data, config) {for (const key in config) {const { allowedValues, message } = config[key];if (data.some(item => !allowedValues.includes(item[key]))) {return message;}}return null;
}const errorMessage = validateData(this.selectedRows, validationConfig);
if (errorMessage) {this.$antdMessage.warning(errorMessage);
} else {// 数据通过验证,执行相应操作
}
validateData 接受数据和配置对象作为参数,使用some 函数代替filter,当数据中存在不符合条件的项时,立即返回相应的错误消息。如果所有属性的值都在允许的列表中,函数将返回 null,表示验证通过。