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

Nuxt3 + Prisma分页异常:切换页面返回重复数据求助

解决Nuxt3+Prisma课程列表分页重复问题

问题根源

你的代码存在两个核心问题:

  • 非管理员逻辑缺失课程提取步骤:直接使用未定义的uniqueCourses变量进行分页,若该变量是全局缓存或未实时生成,会导致每次分页都截取同一组数据。
  • 查询未指定排序规则:管理员用户的findMany没有orderBy,数据库无排序时返回顺序不固定,可能引发分页数据重复(不过你的情况更可能是前者)。

修复代码

export default defineEventHandler(async (event) => {
  const page = parseInt(typeof event.query.page === 'string' ? event.query.page : '1')
  const pageSize = 12
  const skip = (page - 1) * pageSize

  if (user?.isManager) {
    return await prisma.course.findMany({
      include: {
        subjects: true
      },
      take: pageSize,
      skip,
      orderBy: { id: 'asc' } // 强制排序,保证分页稳定
    })
  }

  const userInfo = await prisma.user.findUnique({
    where: {
      id: user?.id
    },
    select: {
      groups: {
        select: {
          subjects: {
            select: {
              courses: {
                include: {
                  subjects: true
                }
              }
            }
          }
        }
      }
    }
  })

  // 从用户关联数据中提取所有课程并去重
  const allCourses = []
  userInfo?.groups.forEach(group => {
    group.subjects.forEach(subject => {
      subject.courses.forEach(course => {
        if (!allCourses.some(c => c.id === course.id)) {
          allCourses.push(course)
        }
      })
    })
  })

  // 排序后再分页,保证每次截取的片段一致
  allCourses.sort((a, b) => a.id - b.id)

  const paginatedCourses = allCourses.slice(skip, skip + pageSize)

  return paginatedCourses
})

关键修复点说明

  1. 补全课程提取逻辑:遍历用户的分组、科目,收集所有关联课程并通过ID去重,生成当前用户有权限查看的完整课程列表。
  2. 添加排序规则:管理员查询和普通用户的内存分页都添加排序,确保数据顺序固定,避免分页混乱。
  3. 避免全局变量依赖:每次请求实时生成课程列表,保证数据准确性和实时性。

验证步骤

  • 打印非管理员用户的allCourses长度,确认包含所有有权限的课程。
  • 切换页码时,打印skip和paginatedCourses的ID列表,确认截取的是不同片段。
  • 验证管理员用户的分页数据是否稳定无重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:54:57