108 lines
3.8 KiB
TypeScript
108 lines
3.8 KiB
TypeScript
export type StoreCreateForm = {
|
|
partnerAccountId: string;
|
|
cityId: string;
|
|
regionCodes?: string[];
|
|
province?: string;
|
|
city?: string;
|
|
district: string;
|
|
districtCode?: string;
|
|
categoryParentId?: string;
|
|
categoryId: string;
|
|
name: string;
|
|
phone: string;
|
|
address: string;
|
|
latitude?: number | null;
|
|
longitude?: number | null;
|
|
intro?: string;
|
|
benefitUsageRule?: string;
|
|
openTime?: string;
|
|
closeTime?: string;
|
|
openTime2?: string;
|
|
closeTime2?: string;
|
|
avgPrice?: number | null;
|
|
coverUrl?: string;
|
|
envPhotoUrls?: string[];
|
|
contractUrl?: string;
|
|
bankAccountName: string;
|
|
bankAccountNo: string;
|
|
bankBranch: string;
|
|
settlementRate?: number;
|
|
visibilityWhitelistEnabled?: boolean;
|
|
visibilityPhones?: string[];
|
|
};
|
|
|
|
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<
|
|
StoreCreateForm,
|
|
| 'partnerAccountId'
|
|
| 'cityId'
|
|
| 'regionCodes'
|
|
| 'categoryId'
|
|
| 'name'
|
|
| 'phone'
|
|
| 'address'
|
|
| 'intro'
|
|
| 'benefitUsageRule'
|
|
| 'openTime'
|
|
| 'closeTime'
|
|
| 'openTime2'
|
|
| 'closeTime2'
|
|
| 'avgPrice'
|
|
>,
|
|
): string | null {
|
|
if (!form.partnerAccountId) return '请选择开城合伙人';
|
|
if (!form.regionCodes || form.regionCodes.length < 3) return '请选择省 / 市 / 区县';
|
|
if (!form.cityId) return '所选地区未匹配到开城城市,请先在「开城 → 城市」配置对应区划';
|
|
if (!form.categoryId?.trim()) return '请选择门店分类(细类)';
|
|
if (!form.name?.trim()) return '请填写门店名称';
|
|
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 < 2 || len > 500) return '门店简介须为 2~500 字';
|
|
}
|
|
if (form.benefitUsageRule?.trim() && form.benefitUsageRule.trim().length > 1000) {
|
|
return '好客权益券使用规则最多 1000 字';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function validateStoreCreateStep3(form: Pick<StoreCreateForm, 'bankAccountName' | 'bankAccountNo' | 'bankBranch'>): string | null {
|
|
if (!form.bankAccountName?.trim()) return '请填写户主姓名';
|
|
if (!form.bankAccountNo?.trim()) return '请填写银行卡号';
|
|
if (!BANK_RE.test(form.bankAccountNo.replace(/\s/g, ''))) return '银行卡号须为 16~19 位数字';
|
|
if (!form.bankBranch?.trim()) return '请填写开户支行';
|
|
return null;
|
|
}
|