feat(trade): add on-site pickup order flow
CI / verify (pull_request) Has been cancelled

Product flag, ON_SITE_PICKUP delivery, mini confirm/receive pages; pay skips warehouse auto-advance.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-23 01:17:59 +08:00
parent e93e4a7721
commit cebeefdb22
19 changed files with 580 additions and 146 deletions
+5
View File
@@ -32,6 +32,11 @@ describe('validateMinPurchase', () => {
expect(validateMinPurchase('CROSS_CITY', 5, 2, 6).ok).toBe(false);
expect(validateMinPurchase('CROSS_CITY', 6, 2, 6).ok).toBe(true);
});
it('on-site pickup requires at least 1 bottle', () => {
expect(validateMinPurchase('ON_SITE_PICKUP', 0, 2, 6).ok).toBe(false);
expect(validateMinPurchase('ON_SITE_PICKUP', 1, 2, 6).ok).toBe(true);
});
});
describe('validateRedeemAmount', () => {
+7 -1
View File
@@ -8,11 +8,17 @@ export function calcBenefitAmount(product: ProductPricing): number {
}
export function validateMinPurchase(
deliveryType: 'LOCAL' | 'CROSS_CITY',
deliveryType: 'LOCAL' | 'CROSS_CITY' | 'ON_SITE_PICKUP',
quantity: number,
localMinQty: number,
crossMinQty: number,
): { ok: boolean; message?: string } {
if (deliveryType === 'ON_SITE_PICKUP') {
if (quantity < 1) {
return { ok: false, message: '现场取货至少购买 1 瓶' };
}
return { ok: true };
}
const min = deliveryType === 'LOCAL' ? localMinQty : crossMinQty;
if (quantity < min) {
return {
+2
View File
@@ -25,6 +25,8 @@ export interface ProductDto {
/** 详情长图(bizType=DETAIL 或 detailContent JSON */
detailImageUrls?: string[];
detailContent?: ProductDetailContentDto | null;
/** 是否允许现场取货下单 */
allowOnSitePickup?: boolean;
}
export interface ProductDetailFeatureDto {
+1
View File
@@ -91,6 +91,7 @@ export enum OrderTab {
export enum DeliveryType {
LOCAL = 'LOCAL',
CROSS_CITY = 'CROSS_CITY',
ON_SITE_PICKUP = 'ON_SITE_PICKUP',
}
export enum AromaType {