feat: 完成前端业务闭环与后端联调
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
} from './response-normalizers.js'
|
||||
import {
|
||||
assertPlainPayload,
|
||||
normalizeOptionalCurrencyNumber,
|
||||
normalizeOptionalNormalDisableStatus,
|
||||
normalizeOptionalSafeInteger,
|
||||
normalizeOptionalText,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
normalizeResourceCapabilities
|
||||
} from './business-file-contract.js'
|
||||
import { normalizeGenealogyPathId } from './genealogy-contract.js'
|
||||
import { normalizeBusinessOptionProjection } from './business-dictionary-contract.js'
|
||||
|
||||
const normalizeAppCeremonyCoordinate = (value, field) => {
|
||||
if (value === undefined || value === null || value === '') return null
|
||||
@@ -29,18 +31,6 @@ const normalizeAppCeremonyCoordinate = (value, field) => {
|
||||
return coordinate
|
||||
}
|
||||
|
||||
const CEREMONY_TYPE_LABELS = Object.freeze({
|
||||
ancestor: '祭祖',
|
||||
memorial: '纪念',
|
||||
funeral: '丧礼',
|
||||
wedding: '婚礼',
|
||||
birth: '出生宴',
|
||||
birthday: '生日宴',
|
||||
banquet: '宴席',
|
||||
other: '其他'
|
||||
})
|
||||
const ceremonyTypes = new Set(Object.keys(CEREMONY_TYPE_LABELS))
|
||||
|
||||
export const CEREMONY_INVITATION_STATUS = Object.freeze({
|
||||
PENDING: 'PENDING',
|
||||
ACCEPTED: 'ACCEPTED',
|
||||
@@ -79,12 +69,22 @@ export const normalizeAppCeremony = (value, expectedGenealogyId, expectedCeremon
|
||||
if ((longitude === null) !== (latitude === null)) {
|
||||
throw createRequestError('礼仪活动响应的经纬度必须同时存在或同时为空', 'CEREMONY_RESPONSE_INVALID')
|
||||
}
|
||||
const ceremonyType = normalizeBusinessOptionProjection(
|
||||
value.ceremonyType,
|
||||
value.ceremonyTypeLabel,
|
||||
value.ceremonyTypeOptionState,
|
||||
'礼仪活动类型',
|
||||
'CEREMONY_RESPONSE_INVALID'
|
||||
)
|
||||
return {
|
||||
id,
|
||||
genealogyId,
|
||||
title: normalizeResponseText(value.ceremonyTitle, 'ceremonyTitle') || '未命名活动',
|
||||
type: normalizeResponseText(value.ceremonyType, 'ceremonyType'),
|
||||
type: ceremonyType.value,
|
||||
typeLabel: ceremonyType.label,
|
||||
typeOptionState: ceremonyType.state,
|
||||
time: normalizeResponseText(value.ceremonyTime, 'ceremonyTime'),
|
||||
createTime: normalizeResponseText(value.createTime, 'createTime'),
|
||||
location,
|
||||
locationAddress,
|
||||
longitude,
|
||||
@@ -98,21 +98,13 @@ export const normalizeAppCeremony = (value, expectedGenealogyId, expectedCeremon
|
||||
}
|
||||
}
|
||||
|
||||
export const normalizeAppCeremonyWithTypeLabel = (ceremony) => {
|
||||
const typeLabel = CEREMONY_TYPE_LABELS[ceremony.type]
|
||||
if (!ceremony.type || !typeLabel) {
|
||||
throw createRequestError('礼仪活动响应包含未公开的活动类型', 'CEREMONY_RESPONSE_INVALID')
|
||||
}
|
||||
return { ...ceremony, typeLabel }
|
||||
}
|
||||
|
||||
export const normalizeAppCeremonies = (value, expectedGenealogyId) => {
|
||||
if (!Array.isArray(value)) throw createRequestError('礼仪活动响应不是列表', 'CEREMONY_RESPONSE_INVALID')
|
||||
const ceremonies = value.map((item) => normalizeAppCeremony(item, expectedGenealogyId))
|
||||
if (new Set(ceremonies.map((item) => item.id)).size !== ceremonies.length) {
|
||||
throw createRequestError('礼仪活动响应包含重复标识', 'CEREMONY_RESPONSE_INVALID')
|
||||
}
|
||||
return ceremonies.map((item) => normalizeAppCeremonyWithTypeLabel(item))
|
||||
return ceremonies
|
||||
}
|
||||
|
||||
export const normalizeAppCeremonyGift = (value, expectedGenealogyId, expectedCeremonyId) => {
|
||||
@@ -147,29 +139,12 @@ export const normalizeAppCeremonyGifts = (value, expectedGenealogyId, expectedCe
|
||||
return gifts
|
||||
}
|
||||
|
||||
export const projectPreviewCeremonies = (value, expectedGenealogyId) =>
|
||||
value.map((item) => ({
|
||||
id: String(item.ceremonyId),
|
||||
genealogyId: expectedGenealogyId,
|
||||
title: String(item.ceremonyTitle || '未命名活动'),
|
||||
type: String(item.ceremonyType || ''),
|
||||
typeLabel: CEREMONY_TYPE_LABELS[String(item.ceremonyType || '')] || '',
|
||||
time: String(item.ceremonyTime || ''),
|
||||
location: String(item.location || ''),
|
||||
description: String(item.ceremonyDesc || ''),
|
||||
coverFile: null,
|
||||
giftCount: Number.isSafeInteger(item.giftCount) ? item.giftCount : 0,
|
||||
canEdit: false,
|
||||
canDelete: false
|
||||
}))
|
||||
|
||||
export const normalizeCeremonyPayload = (payload) => {
|
||||
const allowedFields = new Set(['ceremonyType', 'ceremonyTitle', 'ceremonyDesc', 'ceremonyTime', 'location', 'locationAddress', 'longitude', 'latitude', 'coverOssId', 'sortOrder', 'status'])
|
||||
assertPlainPayload(payload, allowedFields, '礼仪活动请求')
|
||||
const ceremonyType = normalizeOptionalText(payload.ceremonyType, 'ceremonyType')
|
||||
const ceremonyTitle = normalizeOptionalText(payload.ceremonyTitle, 'ceremonyTitle')
|
||||
if (!ceremonyType || !ceremonyTitle) throw new TypeError('请填写活动类型和活动标题')
|
||||
if (!ceremonyTypes.has(ceremonyType)) throw new TypeError('请选择有效的活动类型')
|
||||
const normalizedPayload = { ceremonyType, ceremonyTitle }
|
||||
for (const field of ['ceremonyDesc', 'ceremonyTime', 'location', 'locationAddress']) {
|
||||
const normalizedText = normalizeOptionalText(payload[field], field)
|
||||
@@ -189,8 +164,9 @@ export const normalizeCeremonyPayload = (payload) => {
|
||||
normalizedPayload.longitude = longitude
|
||||
normalizedPayload.latitude = latitude
|
||||
}
|
||||
if (payload.coverOssId !== undefined && payload.coverOssId !== null && payload.coverOssId !== '') {
|
||||
normalizedPayload.coverOssId = normalizeOssIdString(payload.coverOssId, 'coverOssId')
|
||||
if (Object.prototype.hasOwnProperty.call(payload, 'coverOssId')) {
|
||||
if (payload.coverOssId === null) normalizedPayload.coverOssId = null
|
||||
else if (payload.coverOssId !== '') normalizedPayload.coverOssId = normalizeOssIdString(payload.coverOssId, 'coverOssId')
|
||||
}
|
||||
const sortOrder = normalizeOptionalSafeInteger(payload.sortOrder, 'sortOrder')
|
||||
if (sortOrder !== undefined) {
|
||||
@@ -205,8 +181,7 @@ export const normalizeCeremonyGiftPayload = (payload) => {
|
||||
if (payload.giftAmount === undefined || payload.giftAmount === null || payload.giftAmount === '') {
|
||||
throw new TypeError('请填写献礼金额')
|
||||
}
|
||||
const giftAmount = typeof payload.giftAmount === 'number' ? payload.giftAmount : Number(payload.giftAmount)
|
||||
if (!Number.isFinite(giftAmount)) throw new TypeError('献礼金额必须是有限数字')
|
||||
const giftAmount = normalizeOptionalCurrencyNumber(payload.giftAmount, '献礼金额')
|
||||
const normalizedPayload = { giftAmount }
|
||||
for (const field of ['giverName', 'giftMessage']) {
|
||||
const normalizedText = normalizeOptionalText(payload[field], field)
|
||||
|
||||
Reference in New Issue
Block a user