blog / lib /notion /getPageProperties.js
sandy-try's picture
Upload 699 files
1b72d7e verified
import { getTextContent, getDateValue } from 'notion-utils'
import { NotionAPI } from 'notion-client'
import BLOG from '@/blog.config'
import formatDate from '../formatDate'
// import { createHash } from 'crypto'
import md5 from 'js-md5'
import { mapImgUrl } from './mapImage'
/**
* 获取页面元素成员属性
* @param {*} id
* @param {*} value
* @param {*} schema
* @param {*} authToken
* @param {*} tagOptions
* @returns
*/
export default async function getPageProperties(id, value, schema, authToken, tagOptions) {
const rawProperties = Object.entries(value?.properties || [])
const excludeProperties = ['date', 'select', 'multi_select', 'person']
const properties = {}
for (let i = 0; i < rawProperties.length; i++) {
const [key, val] = rawProperties[i]
properties.id = id
if (schema[key]?.type && !excludeProperties.includes(schema[key].type)) {
properties[schema[key].name] = getTextContent(val)
} else {
switch (schema[key]?.type) {
case 'date': {
const dateProperty = getDateValue(val)
delete dateProperty.type
properties[schema[key].name] = dateProperty
break
}
case 'select':
case 'multi_select': {
const selects = getTextContent(val)
if (selects[0]?.length) {
properties[schema[key].name] = selects.split(',')
}
break
}
case 'person': {
const rawUsers = val.flat()
const users = []
const api = new NotionAPI({ authToken })
for (let i = 0; i < rawUsers.length; i++) {
if (rawUsers[i][0][1]) {
const userId = rawUsers[i][0]
const res = await api.getUsers(userId)
const resValue =
res?.recordMapWithRoles?.notion_user?.[userId[1]]?.value
const user = {
id: resValue?.id,
first_name: resValue?.given_name,
last_name: resValue?.family_name,
profile_photo: resValue?.profile_photo
}
users.push(user)
}
}
properties[schema[key].name] = users
break
}
default:
break
}
}
}
// 映射键:用户自定义表头名
const fieldNames = BLOG.NOTION_PROPERTY_NAME
if (fieldNames) {
Object.keys(fieldNames).forEach(key => {
if (fieldNames[key] && properties[fieldNames[key]]) properties[key] = properties[fieldNames[key]]
})
}
// type\status\category 是单选下拉框 取数组第一个
properties.type = properties.type?.[0] || ''
properties.status = properties.status?.[0] || ''
properties.category = properties.category?.[0] || ''
// 映射值:用户个性化type和status字段的下拉框选项,在此映射回代码的英文标识
mapProperties(properties)
properties.publishDate = new Date(properties?.date?.start_date || value.created_time).getTime()
properties.publishDay = formatDate(properties.publishDate, BLOG.LANG)
properties.lastEditedDate = new Date(value?.last_edited_time)
properties.lastEditedDay = formatDate(new Date(value?.last_edited_time), BLOG.LANG)
properties.fullWidth = value.format?.page_full_width ?? false
properties.pageIcon = mapImgUrl(value?.format?.page_icon, value) ?? ''
properties.pageCover = mapImgUrl(value?.format?.page_cover, value) ?? ''
properties.pageCoverThumbnail = mapImgUrl(value?.format?.page_cover, value, 'block', 'pageCoverThumbnail') ?? ''
properties.content = value.content ?? []
properties.tagItems = properties?.tags?.map(tag => {
return { name: tag, color: tagOptions?.find(t => t.value === tag)?.color || 'gray' }
}) || []
delete properties.content
// 处理URL
if (properties.type === 'Post') {
properties.slug = (BLOG.POST_URL_PREFIX) ? generateCustomizeUrl(properties) : (properties.slug ?? properties.id)
} else if (properties.type === 'Page') {
properties.slug = properties.slug ?? properties.id
} else if (properties.type === 'Menu' || properties.type === 'SubMenu') {
// 菜单路径为空、作为可展开菜单使用
properties.to = properties.slug ?? '#'
properties.name = properties.title ?? ''
}
// 开启伪静态路径
if (JSON.parse(BLOG.PSEUDO_STATIC)) {
if (!properties?.slug?.endsWith('.html') && !properties?.slug?.startsWith('http')) {
properties.slug += '.html'
}
}
// 密码字段md5
properties.password = properties.password ? md5(properties.slug + properties.password) : ''
return properties
}
/**
* 映射用户自定义表头
*/
function mapProperties(properties) {
if (properties?.type === BLOG.NOTION_PROPERTY_NAME.type_post) {
properties.type = 'Post'
}
if (properties?.type === BLOG.NOTION_PROPERTY_NAME.type_page) {
properties.type = 'Page'
}
if (properties?.type === BLOG.NOTION_PROPERTY_NAME.type_notice) {
properties.type = 'Notice'
}
if (properties?.status === BLOG.NOTION_PROPERTY_NAME.status_publish) {
properties.status = 'Published'
}
if (properties?.status === BLOG.NOTION_PROPERTY_NAME.status_invisible) {
properties.status = 'Invisible'
}
}
/**
* 获取自定义URL
* 可以根据变量生成URL
* 支持:%year%/%month%/%day%/%slug%
* @param {*} postProperties
* @returns
*/
function generateCustomizeUrl(postProperties) {
let fullPrefix = ''
const allSlugPatterns = BLOG.POST_URL_PREFIX.split('/')
allSlugPatterns.forEach((pattern, idx) => {
if (pattern === '%year%' && postProperties?.publishDay) {
const formatPostCreatedDate = new Date(postProperties?.publishDay)
fullPrefix += formatPostCreatedDate.getUTCFullYear()
} else if (pattern === '%month%' && postProperties?.publishDay) {
const formatPostCreatedDate = new Date(postProperties?.publishDay)
fullPrefix += String(formatPostCreatedDate.getUTCMonth() + 1).padStart(2, 0)
} else if (pattern === '%day%' && postProperties?.publishDay) {
const formatPostCreatedDate = new Date(postProperties?.publishDay)
fullPrefix += String(formatPostCreatedDate.getUTCDate()).padStart(2, 0)
} else if (pattern === '%slug%') {
fullPrefix += (postProperties.slug ?? postProperties.id)
} else if (!pattern.includes('%')) {
fullPrefix += pattern
} else {
return
}
if (idx !== allSlugPatterns.length - 1) {
fullPrefix += '/'
}
})
if (fullPrefix.startsWith('/')) {
fullPrefix = fullPrefix.substring(1) // 去掉头部的"/"
}
if (fullPrefix.endsWith('/')) {
fullPrefix = fullPrefix.substring(0, fullPrefix.length - 1) // 去掉尾部部的"/"
}
return `${fullPrefix}/${(postProperties.slug ?? postProperties.id)}`
}