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:
@@ -5,6 +5,7 @@ use uuid::Uuid;
|
||||
use crate::dto::{MessageSubscriptionResp, UpdateSubscriptionReq};
|
||||
use crate::entity::message_subscription;
|
||||
use crate::error::{MessageError, MessageResult};
|
||||
use erp_core::error::check_version;
|
||||
|
||||
/// 消息订阅偏好服务。
|
||||
pub struct SubscriptionService;
|
||||
@@ -46,6 +47,9 @@ impl SubscriptionService {
|
||||
let now = Utc::now();
|
||||
|
||||
if let Some(model) = existing {
|
||||
let current_version = model.version;
|
||||
let next_ver = check_version(req.version, current_version)
|
||||
.map_err(|_| MessageError::VersionMismatch)?;
|
||||
let mut active: message_subscription::ActiveModel = model.into();
|
||||
if let Some(types) = &req.notification_types {
|
||||
active.notification_types = Set(Some(types.clone()));
|
||||
@@ -64,6 +68,7 @@ impl SubscriptionService {
|
||||
}
|
||||
active.updated_at = Set(now);
|
||||
active.updated_by = Set(user_id);
|
||||
active.version = Set(next_ver);
|
||||
|
||||
let updated = active
|
||||
.update(db)
|
||||
@@ -112,6 +117,7 @@ impl SubscriptionService {
|
||||
dnd_end: m.dnd_end.clone(),
|
||||
created_at: m.created_at,
|
||||
updated_at: m.updated_at,
|
||||
version: m.version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user