diff --git a/admin-web/src/api/groupBuyApi.test.ts b/admin-web/src/api/groupBuyApi.test.ts index a4f6a60..3e1efa5 100644 --- a/admin-web/src/api/groupBuyApi.test.ts +++ b/admin-web/src/api/groupBuyApi.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from 'vitest' -import { filterPendingDeliveryGroupBuyOrders, groupBuyOrderDispatchLabel } from './groupBuyApi' +import { + buildGroupBuyOrderActionPath, + filterPendingDeliveryGroupBuyOrders, + groupBuyOrderDispatchLabel +} from './groupBuyApi' import type { GroupBuyOrder } from '../types' describe('group buy dispatch helpers', () => { @@ -21,6 +25,11 @@ describe('group buy dispatch helpers', () => { amountCent: 5980 }))).toBe('GB00000001 Today eggs x2 ¥59.80') }) + + it('builds admin action paths for group buy orders', () => { + expect(buildGroupBuyOrderActionPath(1, 'confirm')).toBe('/api/admin/group-buy-orders/1/confirm') + expect(buildGroupBuyOrderActionPath(1, 'ready')).toBe('/api/admin/group-buy-orders/1/ready') + }) }) function groupBuyOrder(overrides: Partial): GroupBuyOrder { diff --git a/admin-web/src/api/groupBuyApi.ts b/admin-web/src/api/groupBuyApi.ts index 6cf369b..b6ecaad 100644 --- a/admin-web/src/api/groupBuyApi.ts +++ b/admin-web/src/api/groupBuyApi.ts @@ -17,6 +17,18 @@ export function groupBuyOrderDispatchLabel(order: GroupBuyOrder) { return `${order.orderNo} ${order.groupBuyTitle} x${order.quantity} ¥${(order.amountCent / 100).toFixed(2)}` } +export function buildGroupBuyOrderActionPath(id: number, action: 'confirm' | 'ready') { + return `/api/admin/group-buy-orders/${id}/${action}` +} + +export function confirmGroupBuyOrder(id: number) { + return apiPut(buildGroupBuyOrderActionPath(id, 'confirm')) +} + +export function markGroupBuyOrderReady(id: number) { + return apiPut(buildGroupBuyOrderActionPath(id, 'ready')) +} + export function createGroupBuy(data: Partial) { return apiPost('/api/admin/group-buys', data) } diff --git a/admin-web/src/views/GroupBuyListView.vue b/admin-web/src/views/GroupBuyListView.vue index 0ff412c..5294255 100644 --- a/admin-web/src/views/GroupBuyListView.vue +++ b/admin-web/src/views/GroupBuyListView.vue @@ -1,20 +1,27 @@ @@ -79,18 +115,46 @@ onMounted(load) - + + +
+ 刷新 +
+ + + + + + + + + + + + + + + + +
+ diff --git a/backend/src/main/java/com/linhelp/groupbuy/GroupBuyController.java b/backend/src/main/java/com/linhelp/groupbuy/GroupBuyController.java index 8ada03a..35d13c6 100644 --- a/backend/src/main/java/com/linhelp/groupbuy/GroupBuyController.java +++ b/backend/src/main/java/com/linhelp/groupbuy/GroupBuyController.java @@ -77,6 +77,18 @@ public class GroupBuyController { return ApiResponse.ok(orderService.listByGroupBuy(id)); } + @PutMapping("/api/admin/group-buy-orders/{id}/confirm") + @RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN", "MERCHANT"}) + public ApiResponse confirmOrder(@PathVariable Long id) { + return ApiResponse.ok(orderService.confirm(id)); + } + + @PutMapping("/api/admin/group-buy-orders/{id}/ready") + @RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN", "MERCHANT"}) + public ApiResponse markOrderReady(@PathVariable Long id) { + return ApiResponse.ok(orderService.markReady(id)); + } + @GetMapping("/api/mini/group-buys") public ApiResponse> listMini() { CurrentUser user = authService.currentUser(); diff --git a/backend/src/test/java/com/linhelp/groupbuy/GroupBuyControllerTests.java b/backend/src/test/java/com/linhelp/groupbuy/GroupBuyControllerTests.java new file mode 100644 index 0000000..561fd00 --- /dev/null +++ b/backend/src/test/java/com/linhelp/groupbuy/GroupBuyControllerTests.java @@ -0,0 +1,60 @@ +package com.linhelp.groupbuy; + +import com.linhelp.common.enums.DeliveryMethod; +import com.linhelp.common.enums.GroupBuyOrderStatus; +import com.linhelp.common.security.AuthService; +import com.linhelp.common.security.CurrentUser; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +class GroupBuyControllerTests { + @Test + void adminCanConfirmAndMarkGroupBuyOrderReady() { + GroupBuyService groupBuyService = new GroupBuyService(); + GroupBuyOrderService orderService = new GroupBuyOrderService(groupBuyService); + GroupBuyController controller = new GroupBuyController(groupBuyService, orderService, new StubAuthService()); + GroupBuyResponse groupBuy = groupBuyService.create(groupBuyRequest()); + groupBuyService.start(groupBuy.getId()); + GroupBuyOrderResponse order = orderService.create(1000L, orderRequest(groupBuy.getId())); + + GroupBuyOrderResponse confirmed = controller.confirmOrder(order.getId()).getData(); + GroupBuyOrderResponse ready = controller.markOrderReady(order.getId()).getData(); + + assertThat(confirmed.getStatus()).isEqualTo(GroupBuyOrderStatus.CONFIRMED); + assertThat(ready.getStatus()).isEqualTo(GroupBuyOrderStatus.PENDING_DELIVERY); + } + + private GroupBuyRequest groupBuyRequest() { + GroupBuyRequest request = new GroupBuyRequest(); + request.setTenantId(1L); + request.setCommunityId(1L); + request.setTitle("Today eggs"); + request.setPriceCent(2990); + request.setStock(100); + request.setStartTime(LocalDateTime.now().minusHours(1)); + request.setEndTime(LocalDateTime.now().plusDays(1)); + request.setPickupAddress("North gate"); + return request; + } + + private GroupBuyOrderRequest orderRequest(Long groupBuyId) { + GroupBuyOrderRequest request = new GroupBuyOrderRequest(); + request.setTenantId(1L); + request.setCommunityId(1L); + request.setGroupBuyId(groupBuyId); + request.setAddressId(1L); + request.setQuantity(2); + request.setDeliveryMethod(DeliveryMethod.IMMEDIATE); + return request; + } + + private static class StubAuthService extends AuthService { + @Override + public CurrentUser currentUser() { + return new CurrentUser(1L, 1L, 1L, "COMMUNITY_ADMIN"); + } + } +}