118 lines
4.7 KiB
JavaScript
118 lines
4.7 KiB
JavaScript
import { createRequestError } from './request-client.js'
|
|
import { normalizeResponseText } from './response-normalizers.js'
|
|
import {
|
|
assertPlainPayload,
|
|
normalizeOptionalText,
|
|
normalizeResourcePathId
|
|
} from './request-normalizers.js'
|
|
import { normalizeGenealogyPathId } from './genealogy-contract.js'
|
|
|
|
export const JOIN_APPLICATION_STATUS = Object.freeze({
|
|
PENDING: '0',
|
|
APPROVED: '1',
|
|
REJECTED: '2',
|
|
CANCELLED: '3'
|
|
})
|
|
|
|
export const JOIN_APPLICATION_STATUS_LABELS = Object.freeze({
|
|
[JOIN_APPLICATION_STATUS.PENDING]: '审核中',
|
|
[JOIN_APPLICATION_STATUS.APPROVED]: '已通过',
|
|
[JOIN_APPLICATION_STATUS.REJECTED]: '未通过',
|
|
[JOIN_APPLICATION_STATUS.CANCELLED]: '已撤回'
|
|
})
|
|
|
|
const joinApplicationAuditStatuses = new Set([
|
|
JOIN_APPLICATION_STATUS.APPROVED,
|
|
JOIN_APPLICATION_STATUS.REJECTED
|
|
])
|
|
|
|
export const normalizeJoinApplicationPayload = (payload) => {
|
|
assertPlainPayload(payload, new Set(['applicantName', 'phone', 'relationDesc', 'applyReason']), '加入申请请求')
|
|
const normalizedPayload = {}
|
|
for (const field of ['applicantName', 'phone', 'relationDesc', 'applyReason']) {
|
|
const normalizedText = normalizeOptionalText(payload[field], field)
|
|
if (normalizedText) normalizedPayload[field] = normalizedText
|
|
}
|
|
return normalizedPayload
|
|
}
|
|
|
|
export const normalizeGenealogyInvitationToken = (value) => {
|
|
if (typeof value !== 'string') throw new TypeError('邀请码必须是文本')
|
|
const token = value.trim()
|
|
if (!token) throw new TypeError('请输入邀请码')
|
|
if (token.length > 128) throw new TypeError('邀请码长度不能超过128个字符')
|
|
return token
|
|
}
|
|
|
|
export const normalizeGenealogyInvitationRedeemPayload = (payload) => {
|
|
assertPlainPayload(payload, new Set(['token']), '家谱邀请码兑换请求')
|
|
return { token: normalizeGenealogyInvitationToken(payload.token) }
|
|
}
|
|
|
|
export const normalizeGenealogyInvitation = (value, expectedStatus = '') => {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
throw createRequestError('家谱邀请码响应无效', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
const genealogyId = normalizeGenealogyPathId(value.genealogyId)
|
|
const genealogyName = normalizeResponseText(value.genealogyName, 'genealogyName')
|
|
const status = normalizeResponseText(value.status, 'status')
|
|
const expiresAt = normalizeResponseText(value.expiresAt, 'expiresAt')
|
|
if (!genealogyName || !status || !expiresAt) {
|
|
throw createRequestError('家谱邀请码响应缺少可展示信息', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
if (expectedStatus && status !== expectedStatus) {
|
|
throw createRequestError('家谱邀请码状态与当前操作不匹配', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
const redemptionResult = normalizeResponseText(value.redemptionResult, 'redemptionResult')
|
|
if (expectedStatus === 'REDEEMED' && !['DIRECT_MEMBER', 'PENDING_APPLY'].includes(redemptionResult)) {
|
|
throw createRequestError('家谱邀请码兑换结果无效', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
return {
|
|
genealogyId,
|
|
genealogyName,
|
|
status,
|
|
expiresAt,
|
|
redemptionResult
|
|
}
|
|
}
|
|
|
|
export const normalizeIssuedGenealogyInvitation = (value) => {
|
|
const invitation = normalizeGenealogyInvitation(value, 'ACTIVE')
|
|
return {
|
|
...invitation,
|
|
token: normalizeGenealogyInvitationToken(value.token)
|
|
}
|
|
}
|
|
|
|
const genealogyInvitationStatuses = new Set(['ACTIVE', 'REDEEMED', 'REVOKED', 'EXPIRED'])
|
|
|
|
export const normalizeMyGenealogyInvitations = (value) => {
|
|
if (!Array.isArray(value)) {
|
|
throw createRequestError('我的家谱邀请响应不是列表', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
const invitations = value.map((item) => {
|
|
const invitation = normalizeGenealogyInvitation(item)
|
|
const id = normalizeResourcePathId(item.inviteId, '家谱邀请标识')
|
|
if (!genealogyInvitationStatuses.has(invitation.status)) {
|
|
throw createRequestError('家谱邀请状态无效', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
return { id, ...invitation }
|
|
})
|
|
if (new Set(invitations.map((item) => item.id)).size !== invitations.length) {
|
|
throw createRequestError('我的家谱邀请响应包含重复标识', 'GENEALOGY_INVITATION_RESPONSE_INVALID')
|
|
}
|
|
return invitations
|
|
}
|
|
|
|
export const normalizeJoinAuditPayload = (payload) => {
|
|
assertPlainPayload(payload, new Set(['status', 'auditRemark']), '加入申请审核请求')
|
|
const status = normalizeOptionalText(payload.status, '审核状态')
|
|
if (!joinApplicationAuditStatuses.has(status)) {
|
|
throw new TypeError('加入申请审核状态只能是通过或拒绝')
|
|
}
|
|
const normalizedPayload = { status }
|
|
const auditRemark = normalizeOptionalText(payload.auditRemark, '审核备注')
|
|
if (auditRemark) normalizedPayload.auditRemark = auditRemark
|
|
return normalizedPayload
|
|
}
|