You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node/Express+Pug应用待审核账户通知实现及视图变量传递问题

解决方案

一、解决初始加载时Pug模板变量undefined的问题

你之前的问题根源是:Pug是服务器端渲染模板,模板中的变量是服务器在渲染页面时注入的;而Axios请求是浏览器端运行的JS代码,服务器渲染页面时还没执行这个请求,所以模板里自然拿不到变量。

正确的做法是在服务器端把初始计数传给模板,步骤如下:

  1. 新增全局中间件,自动注入待审核计数
    在所有路由定义之前,添加一个中间件,每次请求时查询数据库并把计数存入res.locals(所有Pug模板都能直接访问这个对象里的变量):
app.use(async (req, res, next) => {
  try {
    // 替换为你的实际数据库查询逻辑,比如查找status为pending的账户数量
    const pendingCount = await UserModel.countDocuments({ status: 'pending' });
    res.locals.pendingCount = pendingCount;
    next();
  } catch (err) {
    console.error('获取待审核账户数失败:', err);
    res.locals.pendingCount = 0; // 出错时默认显示0
    next();
  }
});
  1. 在header.pug中直接使用变量
    现在你可以在header的导航菜单里直接引用pendingCount,服务器渲染时会自动替换为实际数值:
// header.pug 示例
.nav-menu
  .nav-item
    span 待审核账户
    // 通知徽章,直接使用服务器注入的变量
    .notification-badge= pendingCount

二、实现账户审核后的实时更新计数

根据实时性要求,有两种简便方案:

方案1:短轮询(快速实现,适合实时性要求不高的场景)

通过前端定时请求后端接口更新计数,无需额外依赖:

  1. 保留你已有的/getNumberOfPendingRegistrations接口
    确保接口返回格式如下:
app.get('/getNumberOfPendingRegistrations', async (req, res) => {
  const numPendingUsers = await UserModel.countDocuments({ status: 'pending' });
  res.json({ numPendingUsers });
});
  1. 在header.pug中添加前端更新脚本
// header.pug 末尾添加
script.
  // 更新计数的函数
  function updatePendingCount() {
    axios.get('/getNumberOfPendingRegistrations')
      .then(res => {
        const badge = document.querySelector('.notification-badge');
        if (badge) badge.textContent = res.data.numPendingUsers;
      })
      .catch(err => console.error('更新待审核计数失败:', err));
  }
  
  // 页面加载时执行一次(可选,因为服务器已经渲染了初始值)
  updatePendingCount();
  // 每隔30秒轮询一次(可根据需求调整间隔)
  setInterval(updatePendingCount, 30000);

方案2:WebSocket(实时性高,适合需要即时更新的场景)

用Socket.io实现后端主动推送更新,当账户被批准/拒绝时,立刻通知所有客户端:

  1. 安装Socket.io依赖
npm install socket.io
  1. 后端配置Socket.io
    修改你的服务器启动代码,集成Socket.io:
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);

// 替换原来的app.listen为server.listen
server.listen(3000, () => {
  console.log('服务器运行在3000端口');
});
  1. 在审核操作的路由中推送更新
    当批准/拒绝账户后,查询最新计数并推送给所有客户端:
app.post('/approve-user', async (req, res) => {
  // 执行批准逻辑
  await UserModel.updateOne({ _id: req.body.userId }, { status: 'approved' });
  
  // 查询最新待审核数量
  const pendingCount = await UserModel.countDocuments({ status: 'pending' });
  // 向所有在线客户端推送更新
  io.emit('pendingCountUpdated', pendingCount);
  
  res.json({ success: true });
});

// 拒绝账户的路由同理,操作后推送更新
  1. 前端监听Socket更新
    在header.pug中添加Socket监听脚本:
// header.pug 末尾添加
script(src="/socket.io/socket.io.js")
script.
  const socket = io();
  // 监听后端推送的更新事件
  socket.on('pendingCountUpdated', (newCount) => {
    const badge = document.querySelector('.notification-badge');
    if (badge) badge.textContent = newCount;
  });

内容的提问来源于stack exchange,提问作者jocularWeasel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:01:04