import { createRequestError } from './request-client.js' import { NORMAL_DISABLE_STATUS } from './normal-disable-status.js' import { assertPlainPayload } from './request-normalizers.js' export const GENERATION_POEM_STATUS = Object.freeze({ ACTIVE: NORMAL_DISABLE_STATUS.NORMAL, DISABLED: NORMAL_DISABLE_STATUS.DISABLED }) const normalizeGenerationPoemId = (value, label) => { if (typeof value === 'string' && /^[1-9]\d*$/.test(value)) return value if (typeof value === 'number' && Number.isSafeInteger(value) && value > 0) return String(value) throw createRequestError(`字辈${label}无效`, 'GENERATION_POEM_RESPONSE_INVALID') } const normalizeGenerationPoemNumber = (value, label) => { if (typeof value === 'number' && Number.isSafeInteger(value) && value > 0) return value if (typeof value === 'string' && /^[1-9]\d*$/.test(value)) { const normalized = Number(value) if (Number.isSafeInteger(normalized)) return normalized } throw createRequestError(`字辈${label}无效`, 'GENERATION_POEM_RESPONSE_INVALID') } const normalizeGenerationPoemText = (value, label, { required = false, maxLength = null } = {}) => { if (value === undefined || value === null) { if (required) throw createRequestError(`字辈缺少${label}`, 'GENERATION_POEM_RESPONSE_INVALID') return '' } if (typeof value !== 'string') throw createRequestError(`字辈${label}无效`, 'GENERATION_POEM_RESPONSE_INVALID') const normalized = value.trim() if (required && !normalized) throw createRequestError(`字辈缺少${label}`, 'GENERATION_POEM_RESPONSE_INVALID') if (maxLength !== null && Array.from(normalized).length > maxLength) { throw createRequestError(`字辈${label}超出合同长度`, 'GENERATION_POEM_RESPONSE_INVALID') } return normalized } const normalizeGenerationPoemStatus = (value) => { if (Object.values(GENERATION_POEM_STATUS).includes(value)) return value throw createRequestError('字辈状态无效', 'GENERATION_POEM_RESPONSE_INVALID') } export const normalizeGenerationPoemRows = (value, expectedGenealogyId) => { if (!Array.isArray(value)) throw createRequestError('字辈响应不是列表', 'GENERATION_POEM_RESPONSE_INVALID') const rows = value.map((item) => { if (!item || typeof item !== 'object' || Array.isArray(item)) { throw createRequestError('字辈响应包含无效条目', 'GENERATION_POEM_RESPONSE_INVALID') } const genealogyId = normalizeGenerationPoemId(item.genealogyId, '家谱标识') if (genealogyId !== expectedGenealogyId) { throw createRequestError('字辈响应家谱标识与请求不匹配', 'GENERATION_POEM_RESPONSE_INVALID') } return { poemId: normalizeGenerationPoemId(item.poemId, '标识'), genealogyId, genealogyNo: normalizeGenerationPoemText(item.genealogyNo, '家谱编号'), genealogyName: normalizeGenerationPoemText(item.genealogyName, '家谱名称'), generationNo: normalizeGenerationPoemNumber(item.generationNo, '世代'), generationText: normalizeGenerationPoemText(item.generationText, '文字', { required: true, maxLength: 50 }), description: normalizeGenerationPoemText(item.description, '说明', { maxLength: 500 }), sortOrder: item.sortOrder, status: normalizeGenerationPoemStatus(item.status), } }) if (new Set(rows.map((item) => item.poemId)).size !== rows.length) { throw createRequestError('字辈响应包含重复标识', 'GENERATION_POEM_RESPONSE_INVALID') } if (new Set(rows.map((item) => item.generationNo)).size !== rows.length) { throw createRequestError('字辈响应包含重复世代', 'GENERATION_POEM_RESPONSE_INVALID') } return rows.sort((left, right) => left.generationNo - right.generationNo) } export const normalizeGenerationPoemBatchPayload = (payload) => { assertPlainPayload(payload, new Set(['poemText', 'disableMissing']), '字辈批量请求') const poemText = normalizeGenerationPoemText(payload.poemText, '内容', { required: true, maxLength: 26000 }) const normalizedPayload = { poemText } if (payload.disableMissing !== undefined) { if (typeof payload.disableMissing !== 'boolean') throw new TypeError('字辈停用策略必须是布尔值') normalizedPayload.disableMissing = payload.disableMissing } return normalizedPayload } export const normalizeGenerationPoemPreview = (value, expectedGenealogyId) => { if (!value || typeof value !== 'object' || Array.isArray(value)) { throw createRequestError('字辈批量预览响应不是对象', 'GENERATION_POEM_RESPONSE_INVALID') } const genealogyId = normalizeGenerationPoemId(value.genealogyId, '预览家谱标识') if (genealogyId !== expectedGenealogyId) { throw createRequestError('字辈预览家谱标识与请求不匹配', 'GENERATION_POEM_RESPONSE_INVALID') } const counts = ['createCount', 'updateCount', 'keepCount', 'disableCount'] const preview = { genealogyId, items: Array.isArray(value.items) ? value.items : null } for (const field of counts) { if (!Number.isSafeInteger(value[field]) || value[field] < 0) { throw createRequestError(`字辈预览${field}无效`, 'GENERATION_POEM_RESPONSE_INVALID') } preview[field] = value[field] } if (preview.items === null) { throw createRequestError('字辈预览缺少明细列表', 'GENERATION_POEM_RESPONSE_INVALID') } return preview }