From 92cf51ba3dce6c911396e0000ca781f010ac256b Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Sun, 26 Jul 2026 10:16:22 +0800 Subject: [PATCH] feat(store): dual business hours, avg price, and status lock Support 1-2 hour segments and optional avgPrice; show bank settlement on HQ store detail; enforce pickup min 2 bottles; Chinese order statuses; block shop reopen after permanent close. Co-authored-by: Cursor --- apps/admin-web/src/lib/constants.ts | 4 +- apps/admin-web/src/pages/StoresPage.tsx | 69 ++++++++++- apps/h5-partner/src/lib/storeDraft.ts | 115 +++++++++--------- apps/h5-partner/src/lib/storeStatus.ts | 4 +- apps/h5-partner/src/pages/StoreCreatePage.tsx | 88 +++++++++++++- apps/h5-shop/src/pages/HomePage.tsx | 16 ++- apps/h5-shop/src/pages/MinePage.tsx | 8 +- apps/h5-shop/src/pages/SelectStorePage.tsx | 3 +- apps/h5-shop/src/pages/StatusPage.tsx | 90 +++++++++----- apps/h5-user/src/pages/OrderListPage.tsx | 11 +- apps/h5-user/src/pages/StoreDetailPage.tsx | 12 +- apps/h5-user/src/pages/StoreListPage.tsx | 14 ++- .../src/pages/order-confirm-pickup/index.tsx | 12 +- apps/mini-user/src/pages/orders/index.tsx | 14 +-- .../src/pages/store-detail/index.tsx | 14 ++- apps/mini-user/src/pages/stores/index.tsx | 14 ++- packages/domain/src/index.test.ts | 45 ++++++- packages/domain/src/index.ts | 56 ++++++++- packages/shared-types/src/enums.ts | 19 +++ server/dukang-api/prisma/schema.prisma | 2 + .../src/modules/ops/admin-stores.service.ts | 12 +- .../src/modules/ops/dto/admin-mutate.dto.ts | 42 +++++++ .../src/modules/store/store.service.ts | 26 +++- .../src/modules/trade/trade.service.ts | 2 +- 杜康好客-知识库.md | 14 ++- 25 files changed, 560 insertions(+), 146 deletions(-) diff --git a/apps/admin-web/src/lib/constants.ts b/apps/admin-web/src/lib/constants.ts index b9f1799..bfb5a3c 100644 --- a/apps/admin-web/src/lib/constants.ts +++ b/apps/admin-web/src/lib/constants.ts @@ -34,8 +34,8 @@ export const ORDER_STATUS_COLORS: Record = { export const STORE_STATUS_LABELS: Record = { OPEN: '营业中', - PAUSED: '暂停', - CLOSED: '已关闭', + PAUSED: '临时闭店', + CLOSED: '永久关闭', }; export const STORE_AUDIT_STATUS_LABELS: Record = { diff --git a/apps/admin-web/src/pages/StoresPage.tsx b/apps/admin-web/src/pages/StoresPage.tsx index b82c781..8d58e8b 100644 --- a/apps/admin-web/src/pages/StoresPage.tsx +++ b/apps/admin-web/src/pages/StoresPage.tsx @@ -262,7 +262,20 @@ type StoreRow = { createdAt: string; cityRef?: { name: string; code: string }; partner?: { companyName: string }; - account?: { phone: string; name: string; status: string }; + account?: { + phone: string; + name: string; + status: string; + bankAccountName?: string | null; + bankAccountNo?: string | null; + bankBranch?: string | null; + }; + openTime?: string | null; + closeTime?: string | null; + openTime2?: string | null; + closeTime2?: string | null; + avgPrice?: number | null; + settlementRate?: number; category?: { id: string; name: string; parentId?: string | null } | null; }; @@ -525,6 +538,11 @@ export default function StoresPage() { address: d.address, district: d.district, settlementRate: d.settlementRate != null ? Number(d.settlementRate) * 100 : 60, + openTime: d.openTime || '10:00', + closeTime: d.closeTime || '22:00', + openTime2: d.openTime2 || undefined, + closeTime2: d.closeTime2 || undefined, + avgPrice: d.avgPrice != null ? Number(d.avgPrice) : undefined, }); setDrawerOpen(true); }}>详情 @@ -640,9 +658,39 @@ export default function StoresPage() { {String(detail.rejectReason || '—')} ) : null} {String(detail.province)}{String(detail.cityName)}{String(detail.district)}{String(detail.address)} + + {[ + detail.openTime && detail.closeTime + ? `${String(detail.openTime)}-${String(detail.closeTime)}` + : null, + detail.openTime2 && detail.closeTime2 + ? `${String(detail.openTime2)}-${String(detail.closeTime2)}` + : null, + ] + .filter(Boolean) + .join(',') || '—'} + + + {detail.avgPrice != null ? `¥${Number(detail.avgPrice).toFixed(0)}` : '—'} + {detail.settlementRate != null ? `${Math.round(Number(detail.settlementRate) * 100)}%` : '60%'} + + {detail.account && typeof detail.account === 'object' && 'bankAccountName' in detail.account + ? String((detail.account as { bankAccountName?: string | null }).bankAccountName || '—') + : '—'} + + + {detail.account && typeof detail.account === 'object' && 'bankBranch' in detail.account + ? String((detail.account as { bankBranch?: string | null }).bankBranch || '—') + : '—'} + + + {detail.account && typeof detail.account === 'object' && 'bankAccountNo' in detail.account + ? String((detail.account as { bankAccountNo?: string | null }).bankAccountNo || '—') + : '—'} + {String(detail.redeemCount ?? 0)}