const { format } = require('date-fns'); const config = require('../../config/app'); const models = require('../../models'); /** * 清理填色页标签数组。 * 执行以下过滤操作: * 1. 去除重复的标签。 * 2. 移除包含中文字符的标签。 * 3. 移除以 "album" 开头的标签(不区分大小写)。 * 4. 移除以数字开头的标签。 * * @param {string[]} tags - 原始标签数组。 * @returns {string[]} 过滤和去重后的标签数组。 */ function cleanAndFilterTags(tags) { if (!Array.isArray(tags)) { console.warn("Input is not an array. Returning empty array."); return []; } // 1. 使用 Set 去除重复项,并转换为小写以进行后续统一比较 const uniqueTags = new Set(tags.map(tag => typeof tag === 'string' ? tag.trim().toLowerCase() : '')); const filteredTags = []; // 正则表达式用于匹配中文字符 const chineseRegex = /[\u4e00-\u9fa5]/; // 正则表达式用于匹配数字开头 const startsWithNumberRegex = /^[0-9]/; for (const tag of uniqueTags) { // 确保标签非空 if (!tag) { continue; } // 2. 移除中文标签 if (chineseRegex.test(tag)) { continue; } // 3. 移除以 "album" 开头的标签 if (tag.startsWith('album')) { // 已经在转换为小写后,所以直接用'album' continue; } // 4. 移除以"ps_"开头的标签 if (tag.startsWith('ps_') || tag.startsWith('dgt') || tag.startsWith('PS_')) { continue; } // 5. 移除以数字开头的标签 if (startsWithNumberRegex.test(tag)) { continue; } filteredTags.push(tag); } return filteredTags; } function dateFormat(date) { return format(new Date(date), 'MMMM do, yyyy'); } const organizeData = (data) => { data.forEach(doc => { let host = config.cdnHost ?? config.resHost; let publishVersion = doc.publishVersion || 0; let version = publishVersion + 1500; doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.webp`; doc.work = `${host}/thumbs/coloring-page/work/480/${doc._id}.webp`; doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip`; if (doc.title) { try { let titleJson = JSON.parse(doc.title); doc.title = titleJson && titleJson['en'] ? titleJson['en'] : doc.name; } catch (e) { console.error(e.message); } } else { doc.title = doc.name; } doc.publishTime = format(new Date(doc.publishTime), 'MMMM do, yyyy'); doc.tags = cleanAndFilterTags(doc.tags); doc.uri = `/coloring-page/${doc._id}`; delete doc.hasSpecial; delete doc.useSpecialThumb; delete doc.publishVersion; delete doc.desc; }) } const organizeDetail = (doc) => { let host = config.cdnHost ?? config.resHost; let publishVersion = doc.publishVersion || 0; let version = publishVersion + 1500; doc.poster = `${host}/thumbs/coloring-page/page/640/${doc._id}.webp`; doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.webp`; doc.work = `${host}/thumbs/coloring-page/work/480/${doc._id}.webp`; doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip` doc.user.avatar = `/thumbs/v1/avatar/128/${doc.user._id}.webp`; if (doc.title) { try { let titleJson = JSON.parse(doc.title); doc.title = titleJson && titleJson['en'] ? titleJson['en'] : doc.name; } catch (e) { console.error(e.message); } } else { doc.title = doc.name; } if (doc.desc) { try { let descJson = JSON.parse(doc.desc); doc.desc = descJson && descJson['en'] ? descJson['en'] : ''; } catch (e) { console.error(e.message); } } if (doc.seoTitle) { try { let seoTitleJson = JSON.parse(doc.seoTitle); doc.seoTitle = seoTitleJson && seoTitleJson['en'] ? seoTitleJson['en'] : ''; } catch (e) { console.error(e.message); } } if (doc.seoDescription) { try { let seoDescriptionJson = JSON.parse(doc.seoDescription); doc.seoDescription = seoDescriptionJson && seoDescriptionJson['en'] ? seoDescriptionJson['en'] : ''; } catch (e) { console.error(e.message); } } doc.publishTime = format(new Date(doc.publishTime), 'MMMM do, yyyy'); doc.tags = cleanAndFilterTags(doc.tags); doc.downlink = `${host}/thumbs/coloring-page/page/1200/${doc._id}.webp`; delete doc.hasSpecial; delete doc.useSpecialThumb; delete doc.publishVersion; } // 替换URI中的page参数 function replaceUriParams(uri, page) { if (!uri.includes('page=')) { if (uri.includes('?')) uri += `&page=${page}`; else uri += `?page=${page}` } else { // 使用正则表达式替换page参数 uri = uri.replace(/(page=)\d+/, `page=${page}`); } if (page == 1) { uri = uri.replace(/(?:\?|&)((page)=\d+)/g, ''); } // 返回替换后的URI return uri; } const userMap = {}; async function getUserIdByUsername(username) { let userId = userMap[username]; if (!userId) { let doc = await models.User.findOne({ username }); if (doc) { userId = doc._id; userMap[username] = userId; } } return userId; } module.exports = { organizeData, organizeDetail, replaceUriParams, getUserIdByUsername, dateFormat, }