/** 品牌数据库(不符合ASIN)表单模型(任务 69):新建/编辑表单校验与序列化,纯逻辑。 */ import type { InvalidAsinItem } from './invalid-asin-model.ts' export const INVALID_ASIN_FIELD_MAX_LEN = 128 export interface InvalidAsinForm { dataValue: string brand: string groupId: number | null } export interface InvalidAsinFormErrors { dataValue?: string brand?: string groupId?: string } export interface InvalidAsinCreatePayload { dataValue: string brand?: string groupId: number } export interface InvalidAsinUpdatePayload { dataValue: string brand?: string groupId?: number } export function createEmptyInvalidAsinForm(): InvalidAsinForm { return { dataValue: '', brand: '', groupId: null } } /** 从列表项回填表单。 */ export function invalidAsinFormFromItem(item: InvalidAsinItem): InvalidAsinForm { return { dataValue: item.dataValue, brand: item.brand, groupId: item.groupId } } function text(value: string): string { return (value || '').trim() } /** 校验表单(镜像后端 NotBlank/@Size/NotNull 文案);manual 新增必须选分组。 */ export function validateInvalidAsinForm( form: InvalidAsinForm, options: { requireGroup: boolean }, ): { valid: boolean; errors: InvalidAsinFormErrors } { const errors: InvalidAsinFormErrors = {} const dataValue = text(form.dataValue) if (!dataValue) { errors.dataValue = 'ASIN 不能为空' } else if (dataValue.length > INVALID_ASIN_FIELD_MAX_LEN) { errors.dataValue = `ASIN 长度不能超过${INVALID_ASIN_FIELD_MAX_LEN}个字符` } const brand = text(form.brand) if (brand.length > INVALID_ASIN_FIELD_MAX_LEN) { errors.brand = `品牌长度不能超过${INVALID_ASIN_FIELD_MAX_LEN}个字符` } if (options.requireGroup && (typeof form.groupId !== 'number' || form.groupId < 1)) { errors.groupId = '请选择分组' } return { valid: Object.keys(errors).length === 0, errors } } /** 表单 → POST /api/admin/invalid-asin-data 请求体(camel)。 */ export function toInvalidAsinCreateRequest(form: InvalidAsinForm): InvalidAsinCreatePayload { const payload: InvalidAsinCreatePayload = { dataValue: text(form.dataValue), groupId: typeof form.groupId === 'number' ? form.groupId : 0, } const brand = text(form.brand) if (brand) payload.brand = brand return payload } /** 表单 → PUT /api/admin/invalid-asin-data/{id} 请求体;自动导入记录默认不迁组。 */ export function toInvalidAsinUpdateRequest( form: InvalidAsinForm, options: { includeGroup?: boolean } = {}, ): InvalidAsinUpdatePayload { const payload: InvalidAsinUpdatePayload = { dataValue: text(form.dataValue) } const brand = text(form.brand) if (brand) payload.brand = brand if (options.includeGroup && typeof form.groupId === 'number' && form.groupId >= 1) { payload.groupId = form.groupId } return payload }