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

无法实现正确编辑JS对象的算法:书籍类流媒体Web应用月度阅读页数统计需求

解决方案:基于历史最高进度的新增页数计算

核心思路是跟踪用户对单本书的历史最高阅读页码,而不是依赖当月累计或简单的当前页对比。只有当用户当前阅读的页码超过历史最高时,才将差值计入当月新增页数,这样就能完美解决回翻不计数、跳页正确统计的问题。

步骤拆解

1. 定义关键数据指标

我们需要从数据库和前端请求中获取三个核心值:

  • current_pages:前端传来的用户当前阅读到的总页码(比如首次请求30,次月请求55)
  • user_max_pages:数据库中记录的该用户对这本书的历史最高阅读页码(对应现有结构中的script.max_pages)
  • book_total_pages:书籍的总页码(对应script.full_pages)

2. 计算有效新增页数

首先对前端传来的current_pages做合法性校验(避免超过书籍总页数或负数),然后计算新增页数:

// 合法性校验:限制在0到书籍总页数之间
const valid_current_pages = Math.max(0, Math.min(current_pages, book_total_pages));
// 计算新增页数:只有当前页码超过历史最高时才计入
const added_pages = Math.max(0, valid_current_pages - user_max_pages);

3. 更新数据库记录

根据added_pages的值决定是否更新:

  • 如果added_pages > 0:
    1. 更新script.max_pages为valid_current_pages(更新历史最高进度)
    2. 定位到当前年份和月份的记录(如果对应的年份/月份不存在,需要先创建)
    3. 将该月份的pages字段加上added_pages
    4. 同步更新vpc字段(阅读百分比,公式:(user_max_pages / book_total_pages) * 100)
  • 如果added_pages = 0:说明用户在回翻或未阅读新内容,无需更新任何记录

场景验证

我们用你的例子逐一验证:

  • 首次阅读(5月,30页):
    user_max_pages初始为0,added_pages=30-0=30,更新max_pages为30,5月pages设为30,正确。
  • 次月阅读到55页:
    user_max_pages是30,added_pages=55-30=25,更新max_pages为55,当月pages设为25,正确。
  • 回翻场景(从30到29):
    valid_current_pages=29 < user_max_pages=30,added_pages=0,不计数,避免错误扣减。
  • 跳页场景(10→15→14→16):
    • 10→15:added_pages=5,计入当月,max_pages更新为15
    • 15→14:added_pages=0,不计数
    • 14→16:added_pages=1,计入当月,max_pages更新为16
      完全符合需求,既不会漏记跳页的新增,也不会回翻错误计数。

数据库操作示例(JavaScript/MongoDB)

假设我们用MongoDB操作,伪代码如下:

// 假设获取到用户ID、书籍scriptID、当前日期
const userId = "CCYSYXf";
const scriptId = "-VQD0";
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.getMonth(); // 注意:JS中月份是0-11,和数据库中的num字段对应

// 1. 查询用户对应的书籍记录
const userRecord = await User.findOne({
  user_id: userId,
  "scripts.script_id": scriptId
});

const script = userRecord.scripts.find(s => s.script_id === scriptId);
const userMaxPages = script.max_pages;
const bookTotalPages = script.full_pages;

// 2. 计算新增页数
const validCurrentPages = Math.max(0, Math.min(current_pages, bookTotalPages));
const addedPages = Math.max(0, validCurrentPages - userMaxPages);

if (addedPages > 0) {
  // 3. 更新历史最高页数
  script.max_pages = validCurrentPages;

  // 4. 定位或创建当前年份的记录
  let yearRecord = script.data.find(y => y.year === currentYear);
  if (!yearRecord) {
    yearRecord = {
      year: currentYear,
      months: Array.from({length:12}, (_, i) => ({ num: i, pages: 0, vpc: 0 }))
    };
    script.data.push(yearRecord);
  }

  // 5. 更新当月页数和百分比
  const monthRecord = yearRecord.months.find(m => m.num === currentMonth);
  monthRecord.pages += addedPages;
  monthRecord.vpc = (script.max_pages / bookTotalPages) * 100;

  // 6. 保存到数据库
  await userRecord.save();
}

这样就能实现完全符合需求的业务逻辑,同时覆盖所有边缘场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:57:32