feat(store): dual business hours, avg price, and status lock
CI / verify (pull_request) Has been cancelled

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 <cursoragent@cursor.com>
This commit is contained in:
2026-07-26 10:16:22 +08:00
parent 94d2a88581
commit 92cf51ba3d
25 changed files with 560 additions and 146 deletions
+43 -2
View File
@@ -6,6 +6,8 @@ import {
calcOrderBoxCount,
shouldHoldAutoCourierDispatch,
validateMinPurchase,
validateBusinessHours,
formatBusinessHours,
validateRedeemAmount,
allocateBenefitCoupons,
calcBenefitSummary,
@@ -36,9 +38,48 @@ describe('validateMinPurchase', () => {
expect(validateMinPurchase('CROSS_CITY', 6, 2, 6).ok).toBe(true);
});
it('on-site pickup requires at least 1 bottle', () => {
it('on-site pickup requires at least local min (2 bottles)', () => {
expect(validateMinPurchase('ON_SITE_PICKUP', 0, 2, 6).ok).toBe(false);
expect(validateMinPurchase('ON_SITE_PICKUP', 1, 2, 6).ok).toBe(true);
expect(validateMinPurchase('ON_SITE_PICKUP', 1, 2, 6).ok).toBe(false);
expect(validateMinPurchase('ON_SITE_PICKUP', 2, 2, 6).ok).toBe(true);
});
});
describe('validateBusinessHours', () => {
it('accepts one segment', () => {
expect(validateBusinessHours([{ open: '09:00', close: '22:00' }]).ok).toBe(true);
});
it('accepts two non-overlapping segments', () => {
expect(
validateBusinessHours([
{ open: '09:00', close: '14:00' },
{ open: '17:00', close: '21:00' },
]).ok,
).toBe(true);
});
it('rejects overlapping second segment', () => {
expect(
validateBusinessHours([
{ open: '09:00', close: '14:00' },
{ open: '13:00', close: '21:00' },
]).ok,
).toBe(false);
});
});
describe('formatBusinessHours', () => {
it('formats one or two segments', () => {
expect(formatBusinessHours({ openTime: '9:00', closeTime: '22:00' })).toBe('9:00-22:00');
expect(
formatBusinessHours({
openTime: '09:00',
closeTime: '14:00',
openTime2: '17:00',
closeTime2: '21:00',
}),
).toBe('09:00-14:0017:00-21:00');
});
});