Skip to content

Commit f3fc44f

Browse files
authored
Merge pull request notionnext-org#3932 from tangly1024/release/4.9.4.2
Fix: 读取Notion列表窜数据
2 parents 766c1f8 + 1701e26 commit f3fc44f

2 files changed

Lines changed: 106 additions & 131 deletions

File tree

lib/db/SiteDataApi.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ async function convertNotionToSiteData(
352352
for (const id of pageIds) {
353353
const pageBlock = normalizePageBlock(block[id])
354354
if (!pageBlock) continue
355+
// Notion升级后数据发生乱窜,意外读取到其它数据库的列表,这里筛选
356+
if (pageBlock.parent_id !== collectionId) continue
355357
const properties = (await getPageProperties(id, pageBlock, schema, null, getTagOptions(schema))) || null
356358
if (properties) collectionData.push(properties)
357359
}

lib/db/notion/getNotionConfig.js

Lines changed: 104 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -11,204 +11,177 @@ import { deepClone } from '../../utils'
1111
import getAllPageIds from './getAllPageIds'
1212
import { fetchNotionPageBlocks } from './getPostBlocks'
1313
import { encryptEmail } from '@/lib/plugins/mailEncrypt'
14-
import { normalizeNotionMetadata, normalizeCollection, normalizeSchema, normalizePageBlock } from './normalizeUtil'
14+
import { normalizeCollection, normalizeSchema, normalizePageBlock } from './normalizeUtil'
1515

1616
/**
1717
* 从Notion中读取Config配置表
1818
* @param {*} allPages
1919
* @returns
2020
*/
2121
export async function getConfigMapFromConfigPage(allPages) {
22-
// 默认返回配置文件
23-
const notionConfig = {}
24-
25-
if (!allPages || !Array.isArray(allPages) || allPages.length === 0) {
22+
if (!allPages?.length) {
2623
console.warn('[Notion配置] 忽略的配置')
2724
return null
2825
}
29-
// 找到Config类
30-
const configPage = allPages?.find(post => {
31-
return (
32-
post &&
33-
post?.type &&
34-
(post?.type === 'CONFIG' ||
35-
post?.type === 'config' ||
36-
post?.type === 'Config')
37-
)
38-
})
3926

40-
if (!configPage) {
41-
// console.warn('[Notion配置] 未找到配置页面')
27+
// ✅ 1. 找配置页
28+
const configPage = findConfigPage(allPages)
29+
if (!configPage) return null
30+
31+
// ✅ 2. 拉数据
32+
const data = await fetchConfigPageData(configPage.id)
33+
if (!data) return null
34+
35+
// ✅ 3. 解析
36+
return parseConfigFromPage(data.pageRecordMap, data.content)
37+
}
38+
39+
40+
function normalizeId(id) {
41+
return String(id || '').replace(/-/g, '')
42+
}
43+
44+
export function findConfigPage(allPages) {
45+
const configPages = (allPages || []).filter(post =>
46+
post?.type && ['CONFIG', 'config', 'Config'].includes(post.type)
47+
)
48+
49+
if (!configPages.length) {
50+
console.warn('[Notion配置] 未找到配置页面')
4251
return null
4352
}
44-
const configPageId = configPage.id
45-
// console.log('[Notion配置]请求配置数据 ', configPage.id)
53+
54+
const selected = configPages[0]
55+
56+
console.warn('[Notion配置] ✅:', {
57+
id: selected.id,
58+
title: selected.title
59+
})
60+
61+
return selected
62+
}
63+
64+
65+
export async function fetchConfigPageData(configPageId) {
4666
let pageRecordMap = await fetchNotionPageBlocks(configPageId, 'config-table')
47-
// console.log('配置中心Page', configPageId, pageRecordMap)
48-
let content = normalizePageBlock(pageRecordMap.block[configPageId].value)?.content
67+
68+
const pageBlock = pageRecordMap?.block?.[configPageId]?.value
69+
let content = normalizePageBlock(pageBlock)?.content
70+
71+
4972
for (const table of ['Config-Table', 'CONFIG-TABLE']) {
5073
if (content) break
5174
pageRecordMap = await fetchNotionPageBlocks(configPageId, table)
5275
content = pageRecordMap.block[configPageId]?.value?.content
5376
}
5477

5578
if (!content) {
56-
// console.warn(
57-
// '[Notion配置] 未找到配置表格',
58-
// pageRecordMap.block[configPageId],
59-
// pageRecordMap.block[configPageId].value
60-
// )
79+
console.warn('[Notion配置] 未找到配置表')
6180
return null
6281
}
6382

64-
// 找到PAGE文件中的database
65-
const configTableId = content?.find(contentId => {
66-
return normalizePageBlock(pageRecordMap.block[contentId].value)?.type === 'collection_view'
83+
return { pageRecordMap, content }
84+
}
85+
86+
87+
export function parseConfigFromPage(pageRecordMap, content) {
88+
const notionConfig = {}
89+
90+
const configTableId = content.find(contentId => {
91+
const blockItem = pageRecordMap.block?.[contentId]?.value
92+
return normalizePageBlock(blockItem)?.type === 'collection_view'
6793
})
6894

69-
// eslint-disable-next-line no-constant-condition, no-self-compare
70-
if (!configTableId) {
71-
// console.warn(
72-
// '[Notion配置]未找到配置表格数据',
73-
// pageRecordMap.block[configPageId],
74-
// pageRecordMap.block[configPageId].value
75-
// )
76-
return null
77-
}
95+
if (!configTableId) return null
7896

79-
// 页内查找数据表格
8097
const block = pageRecordMap.block || {}
8198
const rawMetadata = normalizePageBlock(pageRecordMap.block[configTableId])
82-
// Check Type Page-Database和Inline-Database
99+
83100
if (
84101
rawMetadata?.type !== 'collection_view_page' &&
85102
rawMetadata?.type !== 'collection_view'
86103
) {
87104
console.error(`pageId "${configTableId}" is not a database`)
88105
return null
89106
}
90-
const collectionId = rawMetadata?.collection_id
91-
const collection = normalizeCollection(pageRecordMap.collection[collectionId].value)
92-
const collectionQuery = pageRecordMap.collection_query
93-
const collectionView = pageRecordMap.collection_view
107+
108+
const collectionId = rawMetadata.collection_id
109+
const collection = normalizeCollection(
110+
pageRecordMap.collection[collectionId].value
111+
)
94112
const schema = normalizeSchema(collection?.schema || {})
95-
const viewIds = rawMetadata?.view_ids
96-
const pageIds = getAllPageIds(
97-
collectionQuery,
113+
114+
const rowPageIds = getAllPageIds(
115+
pageRecordMap.collection_query,
98116
collectionId,
99-
collectionView,
100-
viewIds
117+
pageRecordMap.collection_view,
118+
rawMetadata.view_ids
101119
)
102-
if (pageIds?.length === 0) {
103-
console.error(
104-
'[Notion配置]获取到的文章列表为空,请检查notion模板',
105-
collectionQuery,
106-
collection,
107-
collectionView,
108-
viewIds,
109-
databaseRecordMap
110-
)
111-
}
112-
// 遍历用户的表格
113-
for (let i = 0; i < pageIds.length; i++) {
114-
const id = pageIds[i]
120+
121+
for (const id of rowPageIds) {
115122
const value = block[id]?.value
116-
if (!value) {
117-
continue
118-
}
119-
const temp = normalizePageBlock(block?.[id]?.value)
120-
if(!temp?.properties){
121-
continue
122-
}
123-
const rawProperties = Object.entries(temp?.properties || [])
124-
const excludeProperties = ['date', 'select', 'multi_select', 'person']
125-
const properties = {}
126-
for (let i = 0; i < rawProperties.length; i++) {
127-
const [key, val] = rawProperties[i]
128-
properties.id = id
129-
if (schema[key]?.type && !excludeProperties.includes(schema[key].type)) {
123+
if (!value) continue
124+
125+
const temp = normalizePageBlock(value)
126+
if (!temp?.properties) continue
127+
128+
const rawProperties = Object.entries(temp.properties)
129+
const exclude = ['date', 'select', 'multi_select', 'person']
130+
131+
const properties = { id }
132+
133+
for (const [key, val] of rawProperties) {
134+
if (schema[key]?.type && !exclude.includes(schema[key].type)) {
130135
properties[schema[key].name] = getTextContent(val)
131136
} else {
132137
switch (schema[key]?.type) {
133138
case 'date': {
134-
const dateProperty = getDateValue(val)
135-
delete dateProperty.type
136-
properties[schema[key].name] = dateProperty
139+
const date = getDateValue(val)
140+
delete date.type
141+
properties[schema[key].name] = date
137142
break
138143
}
139144
case 'select':
140145
case 'multi_select': {
141146
const selects = getTextContent(val)
142-
if (selects[0]?.length) {
147+
if (selects) {
143148
properties[schema[key].name] = selects.split(',')
144149
}
145150
break
146151
}
147-
default:
148-
break
149152
}
150153
}
151154
}
152155

153-
if (properties && typeof properties === 'object' && !Array.isArray(properties) && Object.keys(properties).length > 0) {
154-
// 将表格中的字段映射成 英文
155-
const config = {
156-
enable: (properties['启用'] || properties.Enable) === 'Yes',
157-
key: properties['配置名'] || properties.Name,
158-
value: properties['配置值'] || properties.Value
159-
}
156+
const config = {
157+
enable: (properties['启用'] || properties.Enable) === 'Yes',
158+
key: properties['配置名'] || properties.Name,
159+
value: properties['配置值'] || properties.Value
160+
}
160161

161-
// 只导入生效的配置
162-
if (config.enable) {
163-
// console.log('[Notion配置]', config.key, config.value)
164-
if (config.key === 'CONTACT_EMAIL') {
165-
notionConfig[config.key] =
166-
(config.value && encryptEmail(config.value)) || null
167-
} else {
168-
notionConfig[config.key] =
169-
parseTextToJson(config.value) || config.value || null
170-
// 配置不能是undefined,至少是null
171-
}
162+
if (config.enable && config.key) {
163+
if (config.key === 'CONTACT_EMAIL') {
164+
notionConfig[config.key] =
165+
(config.value && encryptEmail(config.value)) || null
166+
} else {
167+
notionConfig[config.key] =
168+
parseTextToJson(config.value) || config.value || null
172169
}
173170
}
174171
}
175172

176-
let combine = notionConfig
173+
// INLINE_CONFIG 合并
177174
try {
178-
// 将INLINE_CONFIG合并,@see https://docs.tangly1024.com/article/notion-next-inline-config
179-
combine = Object.assign(
180-
{},
181-
deepClone(notionConfig),
182-
notionConfig?.INLINE_CONFIG
183-
)
175+
return {
176+
...deepClone(notionConfig),
177+
...notionConfig?.INLINE_CONFIG
178+
}
184179
} catch (err) {
185-
console.warn('解析 INLINE_CONFIG 配置时出错,请检查JSON格式', err)
180+
console.warn('INLINE_CONFIG 解析失败', err)
181+
return notionConfig
186182
}
187-
return combine
188183
}
189184

190-
/**
191-
* 解析INLINE_CONFIG
192-
* @param {*} configString
193-
* @returns
194-
*/
195-
export function parseConfig(configString) {
196-
if (!configString) {
197-
return {}
198-
}
199-
// 解析对象
200-
try {
201-
// eslint-disable-next-line no-eval
202-
const config = eval('(' + configString + ')')
203-
return config
204-
} catch (evalError) {
205-
console.warn(
206-
'解析 eval(INLINE_CONFIG) 配置时出错,请检查JSON格式',
207-
evalError
208-
)
209-
return {}
210-
}
211-
}
212185

213186
/**
214187
* 解析文本为JSON

0 commit comments

Comments
 (0)