var express = require('express'); var router = express.Router(); const redis = require('../../libs/redis'); const models = require('../../models'); const utils = require('../../libs/utils'); const common = require('./common'); const config = require('../../config/app'); const CACHE_PREFIX = "art_v2"; // const CACHE_EXPIRES = 60; // 60s刷新一次 const CACHE_EXPIRES = 600; const artSelect = 'name title desc seoTitle seoDescription width height date publishTime tags lastMod mystery hasSpecial useSpecialThumb publishVersion totalStartCount totalDoneCount completionRate'; // 所有专辑页路由 router.get('/', function (req, res, next) { (async function () { let cacheKey = `${CACHE_PREFIX}_albums`; let htmlData = await redis.getAsync(cacheKey); // htmlData = null; if (!htmlData) { // 专辑 let albums = await models.ArtAlbum .find({ pid: 'art', enabled: true }) .sort({ order: 'asc' }) .populate('title') .populate('slogon') .select('tag title slogon seoTitle seoDescription contents') .lean() .exec(); let host = config.cdnHost ?? config.resHost; for (let doc of albums) { doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.webp`; doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.webp`; doc.title = doc.title ? doc.title['en'] : ''; doc.slogon = doc.slogon ? doc.slogon['en'] : ''; doc.size = doc.contents.length; if (doc.seoTitle) { try { let titleJson = JSON.parse(doc.seoTitle); doc.seoTitle = titleJson && titleJson['en'] ? titleJson['en'] : doc.title; } catch (e) { console.error(e.message); } } else { doc.seoTitle = doc.title; } if (doc.seoDescription) { try { let descJson = JSON.parse(doc.seoDescription); doc.seoDescription = descJson && descJson['en'] ? descJson['en'] : doc.slogon; } catch (e) { console.error(e.message); } } else { doc.seoDescription = doc.slogon; } } let data = { data: albums, length: albums.length, uri: req.originalUrl, }; // 渲染EJS模板到内存中 res.render('v2/albums', data, async (err, html) => { if (err) { // 如果渲染出错,调用next()传递错误 return next(err); } // 渲染成功,存redis, 发送数据到客户端 htmlData = html; try { await redis.set(cacheKey, htmlData, 'EX', CACHE_EXPIRES); } catch (e) { console.error(e); } res.send(htmlData); }); } else { // 缓存命中, 直接发送缓存数据 res.set({ 'X-From-Cache': 'true' }); res.send(htmlData); } })().catch(next); }); // 专辑详情页路由 router.get('/:id', function (req, res, next) { (async function () { let id = req.params.id; utils.validators.validateId(id); let cacheKey = `${CACHE_PREFIX}_album_${id}`; let htmlData = await redis.getAsync(cacheKey); htmlData = null; if (!htmlData) { // 专辑 let doc = await models.ArtAlbum .findById(id) .populate('title') .populate('slogon') .populate({ path: 'contents', select: artSelect, populate: { path: 'user', select: 'username name' } }) .select('tag title slogon seoTitle seoDescription contents timeCreate') .lean() .exec(); if (!doc) throw createError(404, 'Album Not Found!'); let host = config.cdnHost ?? config.resHost; doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.webp`; doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.webp`; doc.timeCreate = common.dateFormat(doc.timeCreate); doc.title = doc.title ? doc.title['en'] : ''; doc.slogon = doc.slogon ? doc.slogon['en'] : ''; doc.size = doc.contents.length; if (doc.seoTitle) { try { let titleJson = JSON.parse(doc.seoTitle); doc.seoTitle = titleJson && titleJson['en'] ? titleJson['en'] : doc.title; } catch (e) { console.error(e.message); } } else { doc.seoTitle = doc.title; } if (doc.seoDescription) { try { let descJson = JSON.parse(doc.seoDescription); doc.seoDescription = descJson && descJson['en'] ? descJson['en'] : doc.slogon; } catch (e) { console.error(e.message); } } else { doc.seoDescription = doc.slogon; } common.organizeData(doc.contents); const comments = await models.Comment.find({ approved: true, page: id }).sort({ createdAt: -1 }); // deeplink 相关 let applink = `https://art.pcoloring.com${req.originalUrl}`; let downlink = `https://art.pcoloring.com/app`; let data = { title: doc.seoTitle, description: doc.seoDescription, data: doc, uri: req.originalUrl, pageId: id, comments, applink, downlink, }; // 渲染EJS模板到内存中 res.render('v2/album', data, async (err, html) => { if (err) { // 如果渲染出错,调用next()传递错误 return next(err); } // 渲染成功,存redis, 发送数据到客户端 htmlData = html; try { await redis.set(cacheKey, htmlData, 'EX', CACHE_EXPIRES); } catch (e) { console.error(e); } res.send(htmlData); }); } else { // 缓存命中, 直接发送缓存数据 res.set({ 'X-From-Cache': 'true' }); res.send(htmlData); } })().catch(next); }); module.exports = router;