107 lines
5.3 KiB
JavaScript
107 lines
5.3 KiB
JavaScript
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
|
|
}
|