95 lines
4.3 KiB
JavaScript
95 lines
4.3 KiB
JavaScript
import { createRequestError } from './request-client.js'
|
|
|
|
const permissionResponseError = (message) =>
|
|
createRequestError(message, 'GENEALOGY_PERMISSION_RESPONSE_INVALID')
|
|
|
|
const normalizePermissionCode = (value, subject = '权限编码') => {
|
|
if (typeof value !== 'string' || !/^[A-Z][A-Z0-9_]{2,63}$/.test(value.trim())) {
|
|
throw permissionResponseError(`${subject}无效`)
|
|
}
|
|
return value.trim()
|
|
}
|
|
|
|
const normalizePermissionIdentity = (value, subject) => {
|
|
if (typeof value === 'string' && /^[1-9]\d*$/.test(value)) return value
|
|
if (typeof value === 'number' && Number.isSafeInteger(value) && value > 0) return String(value)
|
|
throw permissionResponseError(`${subject}无效`)
|
|
}
|
|
|
|
const normalizePermissionText = (value, field, { required = false } = {}) => {
|
|
if (value === undefined || value === null) {
|
|
if (required) throw permissionResponseError(`权限响应缺少${field}`)
|
|
return ''
|
|
}
|
|
if (typeof value !== 'string') throw permissionResponseError(`权限响应${field}无效`)
|
|
const normalized = value.trim()
|
|
if (required && !normalized) throw permissionResponseError(`权限响应缺少${field}`)
|
|
return normalized
|
|
}
|
|
|
|
export const normalizePermissionCatalog = (value) => {
|
|
if (!Array.isArray(value)) throw permissionResponseError('权限目录不是列表')
|
|
const options = value.map((item) => {
|
|
if (!item || typeof item !== 'object' || Array.isArray(item) || typeof item.enabled !== 'boolean') {
|
|
throw permissionResponseError('权限目录包含无效条目')
|
|
}
|
|
return {
|
|
code: normalizePermissionCode(item.code),
|
|
label: normalizePermissionText(item.name, 'name', { required: true }),
|
|
groupCode: normalizePermissionText(item.groupCode, 'groupCode', { required: true }),
|
|
groupName: normalizePermissionText(item.groupName, 'groupName', { required: true }),
|
|
description: normalizePermissionText(item.description, 'description'),
|
|
sensitive: item.sensitive === true,
|
|
enabled: item.enabled,
|
|
disabledReason: normalizePermissionText(item.disabledReason, 'disabledReason')
|
|
}
|
|
})
|
|
if (new Set(options.map((item) => item.code)).size !== options.length) {
|
|
throw permissionResponseError('权限目录包含重复编码')
|
|
}
|
|
return options
|
|
}
|
|
|
|
export const normalizeMemberPermissionAssignment = (
|
|
value,
|
|
enabledCodes,
|
|
{ expectedGenealogyId = '', expectedMemberId = '' } = {}
|
|
) => {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value) || !Array.isArray(value.permissionCodes)) {
|
|
throw permissionResponseError('成员权限响应无效')
|
|
}
|
|
const permissionCodes = value.permissionCodes.map((code) => normalizePermissionCode(code))
|
|
if (new Set(permissionCodes).size !== permissionCodes.length) {
|
|
throw permissionResponseError('成员权限响应包含重复编码')
|
|
}
|
|
const allowedCodes = new Set(enabledCodes)
|
|
if (permissionCodes.some((code) => !allowedCodes.has(code))) {
|
|
throw permissionResponseError('成员权限响应包含目录外或已停用权限')
|
|
}
|
|
const genealogyId = normalizePermissionIdentity(value.genealogyId, '权限响应家谱标识')
|
|
const memberId = normalizePermissionIdentity(value.memberId, '权限响应成员标识')
|
|
if (
|
|
(expectedGenealogyId && genealogyId !== expectedGenealogyId) ||
|
|
(expectedMemberId && memberId !== expectedMemberId)
|
|
) {
|
|
throw permissionResponseError('成员权限响应归属与请求不匹配')
|
|
}
|
|
return { genealogyId, memberId, permissionCodes }
|
|
}
|
|
|
|
export const normalizeMemberPermissionPayload = (permissionCodes, reason, enabledCodes) => {
|
|
if (!Array.isArray(permissionCodes)) throw new TypeError('权限项必须是数组')
|
|
const allowedCodes = new Set(enabledCodes)
|
|
const normalizedCodes = permissionCodes.map((code) => normalizePermissionCode(code, '提交权限编码'))
|
|
if (new Set(normalizedCodes).size !== normalizedCodes.length || normalizedCodes.some((code) => !allowedCodes.has(code))) {
|
|
throw new TypeError('提交权限包含重复、目录外或已停用权限')
|
|
}
|
|
if (typeof reason !== 'string') throw new TypeError('授权原因必须是字符串')
|
|
const normalizedReason = reason.trim()
|
|
if (normalizedReason.length > 200) throw new TypeError('授权原因不能超过200个字符')
|
|
return {
|
|
permissionCodes: normalizedCodes,
|
|
...(normalizedReason ? { reason: normalizedReason } : {})
|
|
}
|
|
}
|