diff --git a/sql/seed_e2e_order_lifecycle.sql b/sql/seed_e2e_order_lifecycle.sql index a6b4b71..39a66bf 100644 --- a/sql/seed_e2e_order_lifecycle.sql +++ b/sql/seed_e2e_order_lifecycle.sql @@ -1,7 +1,7 @@ -- E2E 订单全链路测试主数据(固定 ID 段 900x / 99001) -- 前置:已执行 db.sql;库中已有 t_country.US -- 用法:mysql ... oms_test < sql/seed_e2e_order_lifecycle.sql --- RBAC 菜单/权限:sql/seed_order_lab_rbac_menu.sql + sql/seed_order_lab_role_permissions.sql +-- RBAC 批量任务菜单/权限:sql/seed_order_lab_rbac_menu.sql + sql/seed_order_lab_role_permissions.sql SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; diff --git a/sql/seed_order_lab_rbac_menu.sql b/sql/seed_order_lab_rbac_menu.sql index 0fe3ac7..a186e5c 100644 --- a/sql/seed_order_lab_rbac_menu.sql +++ b/sql/seed_order_lab_rbac_menu.sql @@ -1,4 +1,4 @@ --- 订单批量任务 + 链路演练 RBAC 菜单(Fake.Rbac menu 表) +-- 订单批量任务 RBAC 菜单(Fake.Rbac menu 表) -- 执行库:RBAC 库(与 seed_xhs_rbac_menu.sql 相同) -- 幂等:可重复执行 @@ -24,8 +24,7 @@ INSERT INTO `menu` ( `Id`, `PId`, `Name`, `PermissionCode`, `Type`, `Icon`, `Route`, `Component`, `Order`, `IsHidden`, `IsCached`, `Description`, `IsDeleted`, `ConcurrencyStamp`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime` -) VALUES -( +) VALUES ( 'b1b2c3d4-e5f6-7890-abcd-ef1234567901', @ORDER_PID, '批量任务', @@ -37,19 +36,6 @@ INSERT INTO `menu` ( 4, 0, 1, '订单 RabbitMQ 批量任务治理', 0, UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() -), -( - 'b1b2c3d4-e5f6-7890-abcd-ef1234567902', - @ORDER_PID, - '链路演练', - 'Order.LifecycleLab', - 1, - NULL, - '/order/lifecycleLab', - 'views/order/lifecycleLab/index', - 5, - 0, 1, '订单全链路可视化演练(E2E)', 0, - UUID(), @ADMIN_USER_ID, NOW(), @ADMIN_USER_ID, NOW() ) ON DUPLICATE KEY UPDATE `Name` = VALUES(`Name`), @@ -61,3 +47,8 @@ ON DUPLICATE KEY UPDATE `Description` = VALUES(`Description`), `CreateUserId` = VALUES(`CreateUserId`), `UpdateUserId` = VALUES(`UpdateUserId`); + +-- 清理已废弃的链路演练菜单 +UPDATE `menu` +SET `IsDeleted` = 1, `UpdateTime` = NOW(), `UpdateUserId` = @ADMIN_USER_ID +WHERE `Route` = '/order/lifecycleLab' AND `IsDeleted` = 0; diff --git a/sql/seed_order_lab_role_permissions.sql b/sql/seed_order_lab_role_permissions.sql index 515d343..adef590 100644 --- a/sql/seed_order_lab_role_permissions.sql +++ b/sql/seed_order_lab_role_permissions.sql @@ -1,4 +1,4 @@ --- 为 Admin / Customer 角色追加批量任务、链路演练权限(幂等) +-- 为 Admin / Customer 角色追加批量任务权限(幂等) -- RBAC 库执行;执行后登录用户需重新获取 token 或刷新权限缓存 SET @ADMIN_USER_ID = ( @@ -18,13 +18,14 @@ CROSS JOIN ( SELECT 'Order.BatchJobs.Query' AS `Code` UNION ALL SELECT 'Order.BatchJobs.View' UNION ALL SELECT 'Order.BatchJobs.Retry' UNION ALL - SELECT 'Order.BatchJobs.Cancel' UNION ALL - SELECT 'Order.LifecycleLab.Query' UNION ALL - SELECT 'Order.LifecycleLab.RunStep' UNION ALL - SELECT 'Order.LifecycleLab.RunAll' + SELECT 'Order.BatchJobs.Cancel' ) p WHERE r.`Code` IN ('Admin', 'Customer') AND NOT EXISTS ( SELECT 1 FROM `role_permission` rp WHERE rp.`RoleId` = r.`Id` AND rp.`PermissionCode` = p.`Code` ); + +-- 清理已废弃的链路演练权限 +DELETE FROM `role_permission` +WHERE `PermissionCode` LIKE 'Order.LifecycleLab.%'; diff --git a/src/Oms.Application/Services/Orders/OrderService.LifecycleLab.cs b/src/Oms.Application/Services/Orders/OrderService.LifecycleLab.cs deleted file mode 100644 index 2c90865..0000000 --- a/src/Oms.Application/Services/Orders/OrderService.LifecycleLab.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Fake.Application; -using Microsoft.AspNetCore.Mvc; -using Oms.Application.Dtos.Orders; -using Oms.Application.Shared; -using Oms.Domain.OrdersAggregate.Consts; - -namespace Oms.Application.Services.Orders; - -public partial class OrderService -{ - /// - /// 链路演练:模拟签收(待上网/运输中 → 派送成功)。 - /// 仅供 E2E/演练;正式环境签收应接入轨迹同步。 - /// - [HttpPost("/order/lifecycle-lab/sign")] - public async Task LifecycleLabSignAsync([FromBody] OrderActionInput input) - { - var order = await GetOrderOrThrowAsync(input.Id); - if (order.OrderStatus == OrderStatusCodes.DeliverySuccess) - { - throw new BusinessException("订单已签收"); - } - - if (order.OrderStatus is not (OrderStatusCodes.PendingOnline or OrderStatusCodes.Shipping)) - { - throw new BusinessException( - $"当前状态「{OmsDocHelper.GetOrderStatusName(order.OrderStatus)}」不可模拟签收,请先完成出库"); - } - - var now = DateTime.Now; - if (order.OrderStatus == OrderStatusCodes.PendingOnline) - { - order.OrderStatus = OrderStatusCodes.Shipping; - } - - order.OrderStatus = OrderStatusCodes.DeliverySuccess; - order.SignTime = now; - order.UpdateTime = now; - await UpdateOrderAsync(order); - } -} diff --git a/src/Oms.E2E.Tests/Scenarios/OrderLifecycleHappyPathTests.cs b/src/Oms.E2E.Tests/Scenarios/OrderLifecycleHappyPathTests.cs index f0cc07a..30ec1ea 100644 --- a/src/Oms.E2E.Tests/Scenarios/OrderLifecycleHappyPathTests.cs +++ b/src/Oms.E2E.Tests/Scenarios/OrderLifecycleHappyPathTests.cs @@ -8,7 +8,7 @@ using Oms.E2E.Tests.Support; namespace Oms.E2E.Tests.Scenarios; /// -/// 订单主链路:创建 → 入库 → 支付 → 出库 → 签收。 +/// 订单主链路:创建 → 入库 → 支付 → 出库(至 pendingOnline)。 /// [Collection(OrderE2eCollection.Name)] [Trait("Category", "E2E")] @@ -84,21 +84,14 @@ public sealed class OrderLifecycleHappyPathTests(OrderE2eFixture fixture) await AssertOrderStatusAsync(serviceNo, OrderStatusCodes.PendingOnline); - var signResponse = await fixture.Client.PostAsync("/order/lifecycle-lab/sign", E2eJson.AsJsonContent(new { id })); - var signText = await signResponse.Content.ReadAsStringAsync(); - signResponse.IsSuccessStatusCode.Should().BeTrue($"sign failed: {signText}"); - - await AssertOrderStatusAsync(serviceNo, OrderStatusCodes.DeliverySuccess); - var detailResponse = await fixture.Client.GetAsync($"/order/detail?id={id}"); detailResponse.IsSuccessStatusCode.Should().BeTrue(); var detail = await E2eJson.ReadAsync(detailResponse); detail.Should().NotBeNull(); - detail!.OrderStatus.Should().Be(OmsDocHelper.GetOrderStatusName(OrderStatusCodes.DeliverySuccess)); + detail!.OrderStatus.Should().Be(OmsDocHelper.GetOrderStatusName(OrderStatusCodes.PendingOnline)); detail.ReceiveTime.Should().NotBeNull(); detail.PayTime.Should().NotBeNull(); detail.ShipTime.Should().NotBeNull(); - detail.SignTime.Should().NotBeNull(); } private static object BuildParcelCreateBody(string clientNo) => new