| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- var express = require('express');
- var router = express.Router();
- const models = require('../../models');
- const common = require('./common');
- const utils = require('../../libs/utils');
- const redis = require('../../libs/redis');
- 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';
- // 获得所有video coloring pages
- router.get('/', (req, res, next) => {
- (async function () {
- let uri = req.originalUrl.substring(1);
- let cacheKey = `${CACHE_PREFIX}_video-coloring-pages`;
- let htmlData = await redis.getAsync(cacheKey);
- htmlData = null;
- if (!htmlData) {
- let videos = await models.ArtVideoStory
- .find({ enabled: true, seoTitle: { $exists: true } })
- .populate({ path: 'contents', model: 'Art', select: 'name title width height date publishTime tags lastMod publishVersion' })
- .sort({ order: 'asc' })
- .lean()
- .exec();
- let host = config.cdnHost ?? config.resHost;
- for (let doc of videos) {
- doc.poster = `${host}/thumbs/coloring-page/vs-poster/320/${doc._id}.webp`;
- doc.size = doc.contents.length;
- if (doc.seoTitle) {
- try {
- let titleJson = JSON.parse(doc.seoTitle);
- doc.seoTitle = titleJson && titleJson['en'] ? titleJson['en'] : doc.name;
- } catch (e) {
- console.error(e.message);
- }
- } else {
- doc.seoTitle = doc.name;
- }
- if (doc.seoDescription) {
- try {
- let descJson = JSON.parse(doc.seoDescription);
- doc.seoDescription = descJson && descJson['en'] ? descJson['en'] : doc.seoTitle;
- } catch (e) {
- console.error(e.message);
- }
- } else {
- doc.seoDescription = doc.seoTitle;
- }
- common.organizeData(doc.contents);
- delete doc.seoDescription;
- let jsonStr = JSON.stringify(doc, (key, value) => {
- if (key == 'seoTitle' || key == 'seoDescription') {
- value = value.replace(/"/g, '\\\"');
- }
- return value;
- });
- doc.jsonStr = jsonStr;
- }
- pageId = 'Video Coloring Pages';
- const comments = await models.Comment.find({ approved: true, page: pageId }).sort({ createdAt: -1 });
- let data = {
- uri: req.originalUrl,
- data: videos,
- pageId,
- comments,
- dateFormat: common.dateFormat,
- };
- // 渲染EJS模板到内存中
- res.render('v2/video-coloring-pages', 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);
- });
- // video coloring page详情页路由
- router.get('/:id', function (req, res, next) {
- (async function () {
- let id = req.params.id;
- utils.validators.validateId(id);
- let cacheKey = `${CACHE_PREFIX}_video_${id}`;
- let htmlData = await redis.getAsync(cacheKey);
- htmlData = null;
- if (!htmlData) {
- // 专辑
- let doc = await models.ArtVideoStory
- .findById(id)
- .populate({ path: 'contents', model: 'Art', select: artSelect, populate: { path: 'user', select: 'username name' } })
- .lean()
- .exec();
- if (!doc) throw createError(404, 'Page Not Found!');
- let host = config.cdnHost ?? config.resHost;
- doc.poster = `${host}/thumbs/coloring-page/vs-poster/320/${doc._id}.webp`;
- doc.size = doc.contents.length;
- doc.timeCreate = common.dateFormat(doc.timeCreate);
- if (doc.seoTitle) {
- try {
- let titleJson = JSON.parse(doc.seoTitle);
- doc.seoTitle = titleJson && titleJson['en'] ? titleJson['en'] : doc.name;
- } catch (e) {
- console.error(e.message);
- }
- } else {
- doc.seoTitle = doc.name;
- }
- if (doc.seoDescription) {
- try {
- let descJson = JSON.parse(doc.seoDescription);
- doc.seoDescription = descJson && descJson['en'] ? descJson['en'] : doc.seoTitle;
- } catch (e) {
- console.error(e.message);
- }
- } else {
- doc.seoDescription = doc.seoTitle;
- }
- 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://pcoloring.com/anc/`;
- let data = {
- title: doc.seoTitle,
- description: doc.seoDescription,
- data: doc,
- uri: req.originalUrl,
- pageId: id,
- comments,
- applink,
- downlink,
- };
- // 渲染EJS模板到内存中
- res.render('v2/video-coloring-page', 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;
|