feat(core): implement optimistic locking across all entities
Add VersionMismatch error variant and check_version() helper to erp-core. All 13 mutable entities now enforce version checking on update/delete: - erp-auth: user, role, organization, department, position - erp-config: dictionary, dictionary_item, menu, setting, numbering_rule - erp-workflow: process_definition, process_instance, task - erp-message: message, message_subscription Update DTOs to expose version in responses and require version in update requests. HTTP 409 Conflict returned on version mismatch.
This commit is contained in:
@@ -30,6 +30,12 @@ pub enum AppError {
|
||||
#[error("冲突: {0}")]
|
||||
Conflict(String),
|
||||
|
||||
#[error("版本冲突: 数据已被其他操作修改,请刷新后重试")]
|
||||
VersionMismatch,
|
||||
|
||||
#[error("请求过于频繁,请稍后重试")]
|
||||
TooManyRequests,
|
||||
|
||||
#[error("内部错误: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
@@ -42,6 +48,8 @@ impl IntoResponse for AppError {
|
||||
AppError::Unauthorized => (StatusCode::UNAUTHORIZED, "未授权".to_string()),
|
||||
AppError::Forbidden(_) => (StatusCode::FORBIDDEN, self.to_string()),
|
||||
AppError::Conflict(_) => (StatusCode::CONFLICT, self.to_string()),
|
||||
AppError::VersionMismatch => (StatusCode::CONFLICT, self.to_string()),
|
||||
AppError::TooManyRequests => (StatusCode::TOO_MANY_REQUESTS, self.to_string()),
|
||||
AppError::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "内部错误".to_string()),
|
||||
};
|
||||
|
||||
@@ -76,3 +84,14 @@ impl From<sea_orm::DbErr> for AppError {
|
||||
}
|
||||
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
|
||||
/// 检查乐观锁版本是否匹配。
|
||||
///
|
||||
/// 返回下一个版本号(actual + 1),或 VersionMismatch 错误。
|
||||
pub fn check_version(expected: i32, actual: i32) -> AppResult<i32> {
|
||||
if expected == actual {
|
||||
Ok(actual + 1)
|
||||
} else {
|
||||
Err(AppError::VersionMismatch)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user