import type { ChargeMode, QuantityKey, ScreenshotKey } from '@/features/listings/api/listingOptions' import type { PublishDraft, PublishForm } from '@/types/publish' export function defaultPublishForm(): PublishForm { return { server_region: '', face_owner: '', haf_coin_amount: '', rank_level: '', secret_kd: '', fire_level: '', daily_loss_m: 10, accelerated_sale_ratio: '', season_insurance: '', stamina_level: '', load_level: '', login_method: '', online_start: '', online_end: '', ban_record: '', common_regions: [], deposit_amount: '', remark: '', } } export function buildPublishDraft(options: { form: PublishForm quantityValues: Record quantityModes: Record screenshotFiles: Record selectedSkins: string[] }): PublishDraft { return { form: { ...options.form, common_regions: [...options.form.common_regions], }, quantityValues: { ...options.quantityValues }, quantityModes: { ...options.quantityModes }, screenshotFiles: cloneScreenshotFiles(options.screenshotFiles), selectedSkins: [...options.selectedSkins], } } export function readPublishDraft(draftKey: string) { const raw = localStorage.getItem(draftKey) if (!raw) return null try { const draft = JSON.parse(raw) as Partial return { form: normalizeDraftForm(draft.form), quantityValues: normalizeNumberRecord(draft.quantityValues), quantityModes: normalizeQuantityModes(draft.quantityModes), screenshotFiles: normalizeScreenshotFiles(draft.screenshotFiles), selectedSkins: Array.isArray(draft.selectedSkins) ? draft.selectedSkins.filter((skin): skin is string => typeof skin === 'string') : [], } } catch { localStorage.removeItem(draftKey) return null } } export function writePublishDraft(draftKey: string, draft: PublishDraft) { const nextValue = JSON.stringify(draft) if (localStorage.getItem(draftKey) === nextValue) return localStorage.setItem(draftKey, nextValue) } export function removePublishDraft(draftKey: string) { localStorage.removeItem(draftKey) } export function clearRecord(record: Record) { for (const key of Object.keys(record)) delete record[key] } function normalizeDraftForm(value: unknown): PublishForm { const next = defaultPublishForm() if (!isRecord(value)) return next for (const key of Object.keys(next) as Array) { if (key === 'common_regions') continue const draftValue = value[key] if (draftValue !== undefined) next[key] = draftValue as never } next.common_regions = Array.isArray(value.common_regions) ? value.common_regions.filter((region): region is string => typeof region === 'string') : [] // 默认使用参考比例:如果草稿中的 accelerated_sale_ratio 是 0 或未设置,重置为空字符串 if (!next.accelerated_sale_ratio || next.accelerated_sale_ratio === 0) { next.accelerated_sale_ratio = '' } if (next.haf_coin_amount === 0) next.haf_coin_amount = '' if (String(next.secret_kd).trim() === '0') next.secret_kd = '' if (next.fire_level === 0) next.fire_level = '' return next } function normalizeNumberRecord(value: unknown) { const record: Record = {} if (!isRecord(value)) return record for (const [key, item] of Object.entries(value)) { const parsed = Number(item) if (Number.isFinite(parsed)) record[key] = parsed } return record } function normalizeScreenshotFiles(value: unknown) { const record: Record = {} if (!isRecord(value)) return record for (const [key, item] of Object.entries(value)) { if (typeof item === 'string') { record[key] = item ? [item] : [] continue } if (Array.isArray(item)) { record[key] = item.filter((url): url is string => typeof url === 'string' && Boolean(url)) } } return record } function cloneScreenshotFiles(value: Record) { return Object.fromEntries(Object.entries(value).map(([key, urls]) => [key, [...urls]])) } function normalizeQuantityModes(value: unknown) { const record: Record = {} if (!isRecord(value)) return record for (const [key, item] of Object.entries(value)) { if (item === '赠送' || item === '收费') record[key] = item } return record } function isRecord(value: unknown): value is Record { return typeof value === 'object' && value !== null }