|
|
@@ -15,8 +15,8 @@ const { format } = require('date-fns');
|
|
|
const { getListBuilder } = require('../libs/pager');
|
|
|
|
|
|
const CACHE_PREFIX = "art_v1";
|
|
|
-// const CACHE_EXPIRES = 60; // 60s刷新一次
|
|
|
-const CACHE_EXPIRES = 3600; // 1小时刷新一次即可
|
|
|
+const CACHE_EXPIRES = 60; // 60s刷新一次
|
|
|
+// const CACHE_EXPIRES = 3600; // 1小时刷新一次即可
|
|
|
|
|
|
const artSelect = 'name title desc width height date publishTime tags lastMod mystery hasSpecial useSpecialThumb publishVersion lock pageId';
|
|
|
|
|
|
@@ -64,7 +64,9 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
console.log(`${req.originalUrl} set cookie: lang=${lang}`);
|
|
|
}
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_home_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_home_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let host = config.cdnHost ?? config.resHost;
|
|
|
@@ -80,7 +82,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
.exec();
|
|
|
if (dailydocs && dailydocs.length >= 1) {
|
|
|
todayDoc = dailydocs[0];
|
|
|
- todayDoc.artInfo.thumb = `${host}/thumbs/coloring-page/page/480/${todayDoc.artInfo._id}.webp`;
|
|
|
+ todayDoc.artInfo.thumb = `${host}/thumbs/coloring-page/page/480/${todayDoc.artInfo._id}.${imageType}`;
|
|
|
}
|
|
|
|
|
|
let baseSort = { publishTime: 'desc' };
|
|
|
@@ -93,7 +95,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
.limit(12)
|
|
|
.lean()
|
|
|
.exec();
|
|
|
- organizeData(latest, lang);
|
|
|
+ organizeData(latest, lang, imageType);
|
|
|
|
|
|
// 热门精选
|
|
|
let recommend = await models.Art
|
|
|
@@ -103,7 +105,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
.limit(12)
|
|
|
.lean()
|
|
|
.exec();
|
|
|
- organizeData(recommend, lang);
|
|
|
+ organizeData(recommend, lang, imageType);
|
|
|
|
|
|
// special 专区
|
|
|
let special = await models.Art
|
|
|
@@ -113,7 +115,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
.limit(12)
|
|
|
.lean()
|
|
|
.exec();
|
|
|
- organizeData(special, lang);
|
|
|
+ organizeData(special, lang, imageType);
|
|
|
|
|
|
// 专辑
|
|
|
let albums = await models.ArtAlbum
|
|
|
@@ -127,8 +129,8 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
.exec();
|
|
|
|
|
|
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/320/${doc._id}.webp`;
|
|
|
+ doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
|
|
|
+ doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
|
|
|
doc.title = doc.title ? doc.title[lang] : '';
|
|
|
doc.slogon = doc.slogon ? doc.slogon[lang] : '';
|
|
|
doc.size = doc.contents.length;
|
|
|
@@ -166,7 +168,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) { // 限制严格
|
|
|
]);
|
|
|
|
|
|
for (let doc of designers) {
|
|
|
- doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`;
|
|
|
+ doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.${imageType}`;
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -233,8 +235,9 @@ router.get('/:lang/category/:tag?', function (req, res, next) {
|
|
|
let tag = req.params.tag;
|
|
|
if (!tag) tag = 'latest';
|
|
|
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_category_${tag}_${lang}`;
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_category_${tag}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
|
|
|
@@ -248,7 +251,7 @@ router.get('/:lang/category/:tag?', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
let data = {
|
|
|
title: meta.categoryTitle[lang],
|
|
|
@@ -305,7 +308,9 @@ router.get('/:lang/tag/:tag?', function (req, res, next) {
|
|
|
let tag = req.params.tag;
|
|
|
if (!tag) tag = 'latest';
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_tag_${tag}_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_tag_${tag}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let query = {
|
|
|
@@ -319,7 +324,7 @@ router.get('/:lang/tag/:tag?', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
let data = {
|
|
|
title: meta.tagTitle[lang],
|
|
|
@@ -374,9 +379,11 @@ router.get('/:lang/search', function (req, res, next) {
|
|
|
res.cookie('lang', lang, config.cookie);
|
|
|
}
|
|
|
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
let search = req.query.search;
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_search_${search}_${lang}`;
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_search_${search}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let query = {
|
|
|
@@ -390,7 +397,7 @@ router.get('/:lang/search', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
let data = {
|
|
|
title: meta.searchTitle[lang],
|
|
|
@@ -442,7 +449,9 @@ router.get('/:lang/special', function (req, res, next) {
|
|
|
res.cookie('lang', lang, config.cookie);
|
|
|
}
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_special_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_special_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let query = {
|
|
|
@@ -458,7 +467,7 @@ router.get('/:lang/special', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
let data = {
|
|
|
title: meta.specialTitle[lang],
|
|
|
@@ -509,7 +518,9 @@ router.get('/:lang/albums', function (req, res, next) {
|
|
|
res.cookie('lang', lang, { maxAge: 900000, httpOnly: true });
|
|
|
}
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_albums_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_albums_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
// 专辑
|
|
|
@@ -524,8 +535,8 @@ router.get('/:lang/albums', function (req, res, next) {
|
|
|
|
|
|
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.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
|
|
|
+ doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
|
|
|
doc.title = doc.title ? doc.title[lang] : '';
|
|
|
doc.slogon = doc.slogon ? doc.slogon[lang] : '';
|
|
|
doc.size = doc.contents.length;
|
|
|
@@ -580,7 +591,9 @@ router.get('/:lang/album/:id', function (req, res, next) {
|
|
|
let id = req.params.id;
|
|
|
utils.validators.validateId(id);
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_album_${id}_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_album_${id}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
// 专辑
|
|
|
@@ -596,13 +609,13 @@ router.get('/:lang/album/:id', function (req, res, next) {
|
|
|
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/640/${doc._id}.webp`;
|
|
|
+ doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
|
|
|
+ doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
|
|
|
doc.title = doc.title ? doc.title[lang] : '';
|
|
|
doc.slogon = doc.slogon ? doc.slogon[lang] : '';
|
|
|
doc.size = doc.contents.length;
|
|
|
|
|
|
- organizeData(doc.contents, lang);
|
|
|
+ organizeData(doc.contents, lang, imageType);
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
@@ -650,7 +663,9 @@ router.get('/:lang/designers', function (req, res, next) {
|
|
|
res.cookie('lang', lang, config.cookie);
|
|
|
}
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_designers_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_designers_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let docs = await models.Art.aggregate([
|
|
|
@@ -686,7 +701,7 @@ router.get('/:lang/designers', function (req, res, next) {
|
|
|
|
|
|
|
|
|
for (let doc of docs) {
|
|
|
- doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`;
|
|
|
+ doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.${imageType}`;
|
|
|
}
|
|
|
|
|
|
let data = {
|
|
|
@@ -739,14 +754,16 @@ router.get('/:lang/designer/:id', function (req, res, next) {
|
|
|
let id = req.params.id;
|
|
|
utils.validators.validateId(id);
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_designer_${id}_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_designer_${id}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let user = await models.User.findById(id).select('name username');
|
|
|
if (!user) throw createError(404, 'User Not Found!');
|
|
|
let count = await models.Art.countDocuments({ user: id, status: 9000 });
|
|
|
user.count = count;
|
|
|
- user.avatar = `/thumbs/v1/avatar/320/${user._id}.webp`;
|
|
|
+ user.avatar = `/thumbs/v1/avatar/320/${user._id}.${imageType}`;
|
|
|
|
|
|
|
|
|
// find user arts
|
|
|
@@ -762,7 +779,7 @@ router.get('/:lang/designer/:id', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
@@ -832,7 +849,9 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
|
|
|
let id = getRealId(str);
|
|
|
utils.validators.validateId(id);
|
|
|
|
|
|
- let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}`;
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let doc = await models.Art
|
|
|
@@ -843,7 +862,7 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
|
|
|
.exec();
|
|
|
if (!doc) throw createError(404, 'Art Not Found!');
|
|
|
|
|
|
- organizeDetail(doc, lang);
|
|
|
+ organizeDetail(doc, lang, imageType);
|
|
|
|
|
|
// find relate
|
|
|
let tags = [...doc.tags];
|
|
|
@@ -861,7 +880,7 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
@@ -919,7 +938,10 @@ router.get('/:lang/detail/:id', function (req, res, next) {
|
|
|
|
|
|
let id = req.params.id;
|
|
|
utils.validators.validateId(id);
|
|
|
- let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}`;
|
|
|
+
|
|
|
+ let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg'; // 浏览器支持webp就用webp
|
|
|
+
|
|
|
+ let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}_${imageType}`;
|
|
|
let htmlData = await redis.getAsync(cacheKey);
|
|
|
if (!htmlData) {
|
|
|
let doc = await models.Art
|
|
|
@@ -930,7 +952,7 @@ router.get('/:lang/detail/:id', function (req, res, next) {
|
|
|
.exec();
|
|
|
if (!doc) throw createError(404, 'Art Not Found!');
|
|
|
|
|
|
- organizeDetail(doc, lang);
|
|
|
+ organizeDetail(doc, lang, imageType);
|
|
|
|
|
|
// find relate
|
|
|
let tags = [...doc.tags];
|
|
|
@@ -948,7 +970,7 @@ router.get('/:lang/detail/:id', function (req, res, next) {
|
|
|
}
|
|
|
|
|
|
let result = await getListBuilder(query, models.Art);
|
|
|
- organizeData(result.data, lang);
|
|
|
+ organizeData(result.data, lang, imageType);
|
|
|
|
|
|
let data = {
|
|
|
// title: `${doc.name.replace(/[_]+/g, '-')}`,
|
|
|
@@ -1083,13 +1105,13 @@ router.get('/:lang/info', function (req, res, next) {
|
|
|
});
|
|
|
|
|
|
|
|
|
-const organizeData = (data, lang) => {
|
|
|
+const organizeData = (data, lang, imageType) => {
|
|
|
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.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.${imageType}`;
|
|
|
doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip`;
|
|
|
|
|
|
let uriTitle = doc.name;
|
|
|
@@ -1119,12 +1141,12 @@ const organizeData = (data, lang) => {
|
|
|
}
|
|
|
|
|
|
|
|
|
-const organizeDetail = (doc, lang) => {
|
|
|
+const organizeDetail = (doc, lang, imageType) => {
|
|
|
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.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.${imageType}`;
|
|
|
doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip`
|
|
|
|
|
|
// doc.title = translate.titleTest[lang];
|
|
|
@@ -1157,7 +1179,7 @@ const organizeDetail = (doc, lang) => {
|
|
|
let utf8name = encodeURIComponent(uriTitle.replace(/[\s_]+/g, '-')).toLowerCase();
|
|
|
doc.uri = `/${lang}/coloring-page/${utf8name}-${doc._id}`;
|
|
|
|
|
|
- doc.downlink = `${host}/thumbs/coloring-page/page/1200/${doc._id}.webp`;
|
|
|
+ doc.downlink = `${host}/thumbs/coloring-page/page/1200/${doc._id}.${imageType}`;
|
|
|
|
|
|
delete doc.hasSpecial;
|
|
|
delete doc.useSpecialThumb;
|