Files
dukang/apps/h5-partner/src/lib/storeDraft.ts
T
2026-07-09 23:52:00 +08:00

144 lines
4.6 KiB
TypeScript

export type StoreDraftForm = {
regionCodes: string[];
cityId: string;
province: string;
city: string;
district: string;
name: string;
phone: string;
address: string;
intro: string;
coverUrl: string;
envPhotoUrls: string[];
contractUrl: string;
bankAccountName: string;
bankAccountNo: string;
bankBranch: string;
};
export type StoreDraft = {
step: number;
form: StoreDraftForm;
};
export const STORE_DRAFT_KEY = 'partner_store_draft_v2';
export const defaultStoreForm = (): StoreDraftForm => ({
regionCodes: [],
cityId: '',
province: '',
city: '',
district: '',
name: '',
phone: '',
address: '',
intro: '',
coverUrl: '',
envPhotoUrls: ['', '', ''],
contractUrl: '',
bankAccountName: '',
bankAccountNo: '',
bankBranch: '',
});
export function normalizeStringArray(raw: unknown, length: number): string[] {
if (!Array.isArray(raw)) return Array.from({ length }, () => '');
const items = raw.map((item) => String(item ?? ''));
while (items.length < length) items.push('');
return items.slice(0, length);
}
function normalizeForm(raw: Record<string, unknown>): StoreDraftForm {
const base = defaultStoreForm();
const regionCodes = Array.isArray(raw.regionCodes)
? raw.regionCodes.map((code) => String(code))
: base.regionCodes;
return {
regionCodes,
cityId: String(raw.cityId ?? base.cityId),
province: String(raw.province ?? base.province),
city: String(raw.city ?? base.city),
district: String(raw.district ?? base.district),
name: String(raw.name ?? base.name),
phone: String(raw.phone ?? base.phone),
address: String(raw.address ?? base.address),
intro: String(raw.intro ?? base.intro),
coverUrl: String(raw.coverUrl ?? base.coverUrl),
envPhotoUrls: normalizeStringArray(raw.envPhotoUrls, 3),
contractUrl: String(raw.contractUrl ?? base.contractUrl),
bankAccountName: String(raw.bankAccountName ?? base.bankAccountName),
bankAccountNo: String(raw.bankAccountNo ?? base.bankAccountNo),
bankBranch: String(raw.bankBranch ?? base.bankBranch),
};
}
export function loadStoreDraft(): StoreDraft | null {
try {
const raw = localStorage.getItem(STORE_DRAFT_KEY);
if (!raw) return null;
const parsed = JSON.parse(raw) as Record<string, unknown>;
if (parsed.form && typeof parsed.form === 'object') {
return {
step: Math.min(3, Math.max(1, Number(parsed.step) || 1)),
form: normalizeForm(parsed.form as Record<string, unknown>),
};
}
return { step: 1, form: normalizeForm(parsed) };
} catch {
return null;
}
}
export function saveStoreDraft(draft: StoreDraft) {
localStorage.setItem(STORE_DRAFT_KEY, JSON.stringify(draft));
}
export function clearStoreDraft() {
localStorage.removeItem(STORE_DRAFT_KEY);
}
const PHONE_RE = /^1\d{10}$/;
const BANK_RE = /^\d{16,19}$/;
export function validateStoreStep1(
form: Pick<StoreDraftForm, 'regionCodes' | 'cityId' | 'name' | 'phone' | 'address' | 'intro'>,
): string | null {
if (!form.regionCodes || form.regionCodes.length < 3) return '请选择省 / 市 / 区县';
if (!form.cityId) 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 '请填写详细地址';
if (form.intro.trim()) {
const len = form.intro.trim().length;
if (len < 10 || len > 500) return '门店简介须为 10~500 字';
}
return null;
}
export function validateStoreStep2(
form: Pick<StoreDraftForm, 'coverUrl' | 'envPhotoUrls' | 'contractUrl'>,
): string | null {
if (!form.coverUrl.trim()) return '请上传门头照';
const envCount = form.envPhotoUrls.filter((u) => u.trim()).length;
if (envCount < 3) return '请上传至少 3 张环境照片';
if (!form.contractUrl.trim()) return '请上传签约合同';
return null;
}
export function patchEnvPhotoAt(urls: string[], index: number, url: string): string[] {
const envPhotoUrls = normalizeStringArray(urls, 3);
envPhotoUrls[index] = url;
return envPhotoUrls;
}
export function validateStoreStep3(
form: Pick<StoreDraftForm, '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;
}