var express = require('express'); var router = express.Router(); const redis = require('../../libs/redis'); const models = require('../../models'); const common = require('./common'); const { getListBuilder } = require('../../libs/pager'); const { tags } = require('../../config/tag'); const CACHE_PREFIX = "art_v2"; // const CACHE_EXPIRES = 60; // 60s刷新一次 const CACHE_EXPIRES = 600; // gallery页路由 router.get('/', function (req, res, next) { (async function () { let tag = req.query.category; if (!tag) tag = 'latest'; let user = req.query.author; let search = req.query.search; if (search) tag = ''; let filters = (tag == 'latest' || tag == '') ? {} : { tags: tag }; if (user) { let userId = await common.getUserIdByUsername(user); if (userId) filters.user = userId; } let cacheKey = `${CACHE_PREFIX}_${req.originalUrl}`; let htmlData = await redis.getAsync(cacheKey); htmlData = null; if (!htmlData) { let query = { page: req.query.page, length: req.query.length, search, orderBy: 'publishTime', order: 'desc', base: { status: 9000 }, filters, } // 内容列表 let result = await getListBuilder(query, models.Art, [{ path: 'user', select: 'username' }]); common.organizeData(result.data); // 设计师列表 let userDocs = await models.Art.aggregate([ // 首先,过滤出 status = 9000 的文档 { $match: { open: true, status: 9000 } }, // 首先,根据 user 字段进行分组,并计算每个 user 出现的次数 { $group: { _id: '$user', count: { $sum: 1 } } }, // 然后,按照 count 字段进行降序排列 { $sort: { count: -1 } }, // 接着,与 users 集合进行连接,以获取用户的详细信息 { $lookup: { from: 'users', // 要连接的集合名称 localField: '_id', // 本地字段(即上一步分组后的 _id 字段) foreignField: '_id', // 要连接的集合中的字段 as: 'userDetails' // 连接后结果存储在新字段 userDetails 中 } }, // 展开 userDetails 数组,以便将用户信息提升到顶层 { $unwind: '$userDetails' }, // 调整输出格式,只保留需要的字段 { $project: { _id: 1, user: '$_id', count: 1, username: '$userDetails.username', name: '$userDetails.name' } }, // 限制返回的记录数量 { $limit: 16 } ]); for (let doc of userDocs) { doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`; } let data = { data: result.data, designers: userDocs, page: result.page, length: result.length, recordsFiltered: result.recordsFiltered, recordsTotal: result.recordsTotal, tag, tags: tags.filter(e => e.count && e.count > 0), searchTerm: search, uri: req.originalUrl, pageUri: common.replaceUriParams, }; // 渲染EJS模板到内存中 res.render('v2/gallery', 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;