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:
@@ -86,11 +86,12 @@ where
|
||||
|
||||
/// DELETE /api/v1/config/menus/{id}
|
||||
///
|
||||
/// 软删除单个菜单项。
|
||||
/// 软删除单个菜单项。需要请求体包含 version 字段用于乐观锁校验。
|
||||
pub async fn delete_menu<S>(
|
||||
State(state): State<ConfigState>,
|
||||
Extension(ctx): Extension<TenantContext>,
|
||||
Path(id): Path<Uuid>,
|
||||
Json(req): Json<DeleteMenuVersionReq>,
|
||||
) -> Result<JsonResponse<ApiResponse<()>>, AppError>
|
||||
where
|
||||
ConfigState: FromRef<S>,
|
||||
@@ -98,7 +99,15 @@ where
|
||||
{
|
||||
require_permission(&ctx, "menu.update")?;
|
||||
|
||||
MenuService::delete(id, ctx.tenant_id, ctx.user_id, &state.db, &state.event_bus).await?;
|
||||
MenuService::delete(
|
||||
id,
|
||||
ctx.tenant_id,
|
||||
ctx.user_id,
|
||||
req.version,
|
||||
&state.db,
|
||||
&state.event_bus,
|
||||
)
|
||||
.await?;
|
||||
Ok(JsonResponse(ApiResponse::ok(())))
|
||||
}
|
||||
|
||||
@@ -122,6 +131,7 @@ where
|
||||
for item in &req.menus {
|
||||
match item.id {
|
||||
Some(id) => {
|
||||
let version = item.version.unwrap_or(0);
|
||||
let update_req = crate::dto::UpdateMenuReq {
|
||||
title: Some(item.title.clone()),
|
||||
path: item.path.clone(),
|
||||
@@ -130,6 +140,7 @@ where
|
||||
visible: item.visible,
|
||||
permission: item.permission.clone(),
|
||||
role_ids: item.role_ids.clone(),
|
||||
version,
|
||||
};
|
||||
MenuService::update(id, ctx.tenant_id, ctx.user_id, &update_req, &state.db)
|
||||
.await?;
|
||||
@@ -164,3 +175,9 @@ where
|
||||
message: Some("菜单批量保存成功".to_string()),
|
||||
}))
|
||||
}
|
||||
|
||||
/// 删除菜单的乐观锁版本号请求体。
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct DeleteMenuVersionReq {
|
||||
pub version: i32,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user