/* refer to: ./tag.js (author: @StevenREC0) */ const got = require('@/utils/got'); module.exports = async (ctx) => { // get params const { collection } = ctx.params; // feed info const baseUrl = `https://www.gcores.com/gapi/v1/collections/${collection}`; const baseRes = await got(baseUrl); const feedTitle = baseRes.data.data.attributes.title; const feedUrl = `https://www.gcores.com/collections/${collection}`; // resolve articles const dataUrl = `${baseUrl}/articles?sort=-published-at`; const res = await got(dataUrl); const list = res.data.data; const items = list.map((item) => { const articleUrl = `https://www.gcores.com/${item.type}/${item.id}`; return ctx.cache.tryGet(articleUrl, () => { let cover = ''; if (item.attributes.cover) { cover = ``; } else if (item.attributes.thumb) { cover = ``; } const contentBlocks = JSON.parse(item.attributes.content); const { blocks, entityMap } = contentBlocks; function wrapInlineTag(strArr, startIdx, endIdx, preString, sufString) { if (startIdx === endIdx - 1) { strArr[startIdx] = `${preString}${strArr[startIdx]}${sufString}`; } else { strArr[startIdx] = `${preString}${strArr[startIdx]}`; strArr[endIdx - 1] = `${strArr[endIdx - 1]}${sufString}`; } } function convertBlockToContent(block) { const { type, text, entityRanges, inlineStyleRanges } = block; let formattedText = text; if (entityRanges.length || inlineStyleRanges.length) { // split string and insert HTML tag const strArr = text.split(''); let isMedia = false; if (entityRanges.length) { entityRanges.forEach((entityRange) => { const { key, offset, length } = entityRange; const startIdx = offset, endIdx = offset + length; const { data, type } = entityMap[key]; switch (type) { case 'LINK': wrapInlineTag(strArr, startIdx, endIdx, ``, ``); break; case 'IMAGE': formattedText = `
${data.caption ? `
${data.caption}
` : ''}
`; isMedia = true; break; case 'EMBED': formattedText = `
${data.content}${data.caption ? `
${data.caption}
` : ''}
`; isMedia = true; break; case 'GALLERY': formattedText = `
${data.images.map((image) => `
`).join('')}
`; isMedia = true; break; default: break; } }); } if (inlineStyleRanges.length) { inlineStyleRanges.forEach((inlineStyleRange) => { const { style, offset, length } = inlineStyleRange; const startIdx = offset, endIdx = offset + length; switch (style) { case 'BOLD': wrapInlineTag(strArr, startIdx, endIdx, ``, ``); break; case 'UNDERLINE': wrapInlineTag(strArr, startIdx, endIdx, ``, ``); break; case 'ITALIC': wrapInlineTag(strArr, startIdx, endIdx, ``, ``); break; default: break; } }); } formattedText = isMedia ? formattedText : strArr.join(''); } /* 未兼容列表,仅展示为段落,有兴趣可以补全:unordered-list-item、ordered-list-item */ switch (type) { case 'unstyled': return `

${formattedText}

`; case 'header-one': return `

${formattedText}

`; case 'header-two': return `

${formattedText}

`; case 'header-three': return `

${formattedText}

`; case 'header-four': return `

${formattedText}

`; case 'header-five': return `
${formattedText}
`; case 'header-six': return `
${formattedText}
`; case 'atomic': return formattedText; default: return `

${formattedText}

`; } } const content = blocks.map((block) => convertBlockToContent(block)); return { title: item.attributes.title, description: cover + content.join(''), link: articleUrl, }; }); }); // return data ctx.state.data = { title: feedTitle, link: feedUrl, item: items, }; };