diff --git a/apps/admin-web/src/lib/storeCreate.ts b/apps/admin-web/src/lib/storeCreate.ts index a1ed5b9..7073cbb 100644 --- a/apps/admin-web/src/lib/storeCreate.ts +++ b/apps/admin-web/src/lib/storeCreate.ts @@ -12,6 +12,11 @@ export type StoreCreateForm = { phone: string; address: string; intro?: string; + openTime?: string; + closeTime?: string; + openTime2?: string; + closeTime2?: string; + avgPrice?: number | null; coverUrl?: string; envPhotoUrls?: string[]; contractUrl?: string; @@ -23,6 +28,12 @@ export type StoreCreateForm = { const PHONE_RE = /^1\d{10}$/; const BANK_RE = /^\d{16,19}$/; +const TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)$/; + +function timeToMinutes(hhmm: string): number { + const [h, m] = hhmm.split(':').map(Number); + return h * 60 + m; +} export function validateStoreCreateStep1( form: Pick< @@ -35,6 +46,11 @@ export function validateStoreCreateStep1( | 'phone' | 'address' | 'intro' + | 'openTime' + | 'closeTime' + | 'openTime2' + | 'closeTime2' + | 'avgPrice' >, ): string | null { if (!form.partnerAccountId) return '请选择开城合伙人'; @@ -45,6 +61,27 @@ export function validateStoreCreateStep1( if (!form.phone?.trim()) return '请填写门店手机号'; if (!PHONE_RE.test(form.phone.trim())) return '门店手机号须为11位手机号'; if (!form.address?.trim()) return '请填写详细地址'; + + const openTime = String(form.openTime || '').trim(); + const closeTime = String(form.closeTime || '').trim(); + if (!openTime || !closeTime) return '请填写营业时间'; + if (!TIME_RE.test(openTime) || !TIME_RE.test(closeTime)) return '营业时间格式须为 HH:MM'; + if (timeToMinutes(openTime) >= timeToMinutes(closeTime)) return '营业结束时间须晚于开始时间'; + + const openTime2 = String(form.openTime2 || '').trim(); + const closeTime2 = String(form.closeTime2 || '').trim(); + if (openTime2 || closeTime2) { + if (!openTime2 || !closeTime2) return '请完整填写第二段营业时间'; + if (!TIME_RE.test(openTime2) || !TIME_RE.test(closeTime2)) return '第二段时间格式须为 HH:MM'; + if (timeToMinutes(openTime2) >= timeToMinutes(closeTime2)) return '第二段结束时间须晚于开始时间'; + if (timeToMinutes(closeTime) >= timeToMinutes(openTime2)) return '第二段开始时间须晚于第一段结束时间'; + } + + if (form.avgPrice != null && String(form.avgPrice).trim() !== '') { + const n = Number(form.avgPrice); + if (Number.isNaN(n) || n < 0) return '人均费用须为非负数字'; + } + if (form.intro?.trim()) { const len = form.intro.trim().length; if (len < 10 || len > 500) return '门店简介须为 10~500 字'; diff --git a/apps/admin-web/src/pages/StoresPage.tsx b/apps/admin-web/src/pages/StoresPage.tsx index 8d58e8b..9af91c5 100644 --- a/apps/admin-web/src/pages/StoresPage.tsx +++ b/apps/admin-web/src/pages/StoresPage.tsx @@ -405,6 +405,11 @@ export default function StoresPage() { createForm.setFieldsValue({ envPhotoUrls: ['', '', ''], settlementRate: 60, + openTime: '10:00', + closeTime: '22:00', + openTime2: undefined, + closeTime2: undefined, + avgPrice: undefined, }); setCreateStep(0); setCreateError(''); @@ -461,6 +466,14 @@ export default function StoresPage() { district: values.district.trim(), address: values.address.trim(), intro: values.intro?.trim() || undefined, + openTime: values.openTime?.trim() || '10:00', + closeTime: values.closeTime?.trim() || '22:00', + ...(values.openTime2?.trim() && values.closeTime2?.trim() + ? { openTime2: values.openTime2.trim(), closeTime2: values.closeTime2.trim() } + : {}), + ...(values.avgPrice != null && values.avgPrice !== '' + ? { avgPrice: Number(values.avgPrice) } + : {}), coverUrl: values.coverUrl?.trim() || undefined, envPhotoUrls: envPhotoUrls.length ? envPhotoUrls : undefined, contractUrl: values.contractUrl?.trim() || undefined, @@ -841,6 +854,25 @@ export default function StoresPage() {