gallery.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. var express = require('express');
  2. var router = express.Router();
  3. const redis = require('../../libs/redis');
  4. const models = require('../../models');
  5. const common = require('./common');
  6. const { getListBuilder } = require('../../libs/pager');
  7. const { tags } = require('../../config/tag');
  8. const CACHE_PREFIX = "art_v2";
  9. // const CACHE_EXPIRES = 60; // 60s刷新一次
  10. const CACHE_EXPIRES = 600;
  11. // gallery页路由
  12. router.get('/', function (req, res, next) {
  13. (async function () {
  14. let tag = req.query.category;
  15. if (!tag) tag = 'latest';
  16. let user = req.query.author;
  17. let search = req.query.search;
  18. if (search) tag = '';
  19. let filters = (tag == 'latest' || tag == '') ? {} : { tags: tag };
  20. if (user) {
  21. let userId = await common.getUserIdByUsername(user);
  22. if (userId) filters.user = userId;
  23. }
  24. let cacheKey = `${CACHE_PREFIX}_${req.originalUrl}`;
  25. let htmlData = await redis.getAsync(cacheKey);
  26. // htmlData = null;
  27. if (!htmlData) {
  28. let query = {
  29. page: req.query.page,
  30. length: req.query.length,
  31. search,
  32. orderBy: 'publishTime',
  33. order: 'desc',
  34. base: { status: 9000 },
  35. filters,
  36. }
  37. // 内容列表
  38. let result = await getListBuilder(query, models.Art, [{ path: 'user', select: 'username' }]);
  39. common.organizeData(result.data);
  40. // 设计师列表
  41. let userDocs = await models.Art.aggregate([
  42. // 首先,过滤出 status = 9000 的文档
  43. { $match: { open: true, status: 9000 } },
  44. // 首先,根据 user 字段进行分组,并计算每个 user 出现的次数
  45. { $group: { _id: '$user', count: { $sum: 1 } } },
  46. // 然后,按照 count 字段进行降序排列
  47. { $sort: { count: -1 } },
  48. // 接着,与 users 集合进行连接,以获取用户的详细信息
  49. {
  50. $lookup: {
  51. from: 'users', // 要连接的集合名称
  52. localField: '_id', // 本地字段(即上一步分组后的 _id 字段)
  53. foreignField: '_id', // 要连接的集合中的字段
  54. as: 'userDetails' // 连接后结果存储在新字段 userDetails 中
  55. }
  56. },
  57. // 展开 userDetails 数组,以便将用户信息提升到顶层
  58. { $unwind: '$userDetails' },
  59. // 调整输出格式,只保留需要的字段
  60. { $project: { _id: 1, user: '$_id', count: 1, username: '$userDetails.username', name: '$userDetails.name' } },
  61. // 限制返回的记录数量
  62. { $limit: 16 }
  63. ]);
  64. for (let doc of userDocs) {
  65. doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`;
  66. }
  67. let data = {
  68. data: result.data,
  69. designers: userDocs,
  70. page: result.page,
  71. length: result.length,
  72. recordsFiltered: result.recordsFiltered,
  73. recordsTotal: result.recordsTotal,
  74. tag,
  75. tags: tags.filter(e => e.count && e.count > 0),
  76. searchTerm: search,
  77. uri: req.originalUrl,
  78. pageUri: common.replaceUriParams,
  79. };
  80. // 渲染EJS模板到内存中
  81. res.render('v2/gallery', data, async (err, html) => {
  82. if (err) {
  83. // 如果渲染出错,调用next()传递错误
  84. return next(err);
  85. }
  86. // 渲染成功,存redis, 发送数据到客户端
  87. htmlData = html;
  88. try {
  89. await redis.set(cacheKey, htmlData, 'EX', CACHE_EXPIRES);
  90. } catch (e) {
  91. console.error(e);
  92. }
  93. res.send(htmlData);
  94. });
  95. } else {
  96. // 缓存命中, 直接发送缓存数据
  97. res.set({ 'X-From-Cache': 'true' });
  98. res.send(htmlData);
  99. }
  100. })().catch(next);
  101. });
  102. module.exports = router;