如何用Javascript解决跨月周度签到统计与次数限制问题?
解决跨月周签到计数错误问题(周日至周六周期,每周最多3次签到)
问题根源
当前代码存在两个核心问题导致跨月周统计错误:
- 生成周范围时使用当前系统时间而非用户的
check_in_date,如果用户在跨月周的次月日期签到,生成的周范围会和签到日期所属周不匹配。 - 数据库查询
findByPlayerIdOnWeek的逻辑大概率基于错误的周范围,导致跨月的签到记录未被计入对应周的统计,比如11/1的签到不会被算进10/29-11/04的周里。
解决方案
核心思路是基于用户签到日期计算其所属的周日至周六周范围,再用这个范围去数据库统计该用户的签到次数,确保跨月周的所有日期都被正确纳入统计。
修正后的代码
// 1. 基于签到日期计算所属周的起止日期(周日至周六) const checkInDate = new Date(check_in_date); // 获取签到日期所在周的周日(周起始) const weekStart = new Date(checkInDate); weekStart.setDate(checkInDate.getDate() - checkInDate.getDay()); // 获取签到日期所在周的周六(周结束) const weekEnd = new Date(weekStart); weekEnd.setDate(weekStart.getDate() + 6); // 若数据库存储带时间的日期,需将周结束设为周六23:59:59,避免漏统计当天签到 weekEnd.setHours(23, 59, 59, 999); // 2. 查询该用户在当前周内的所有签到记录(需调整数据库查询逻辑按起止日期过滤) const checkInOnWeek = await this.checkInsRepository.findByPlayerIdAndDateRange( player_id, weekStart, weekEnd ); // 3. 验证签到次数是否超过每周3次限制 if (checkInOnWeek.length >= 3) { console.log(`用户${player_id}本周签到次数已达上限,当前次数:${checkInOnWeek.length}`); throw new AppError('Weekly scheduling limit reached!', 400); } // 后续日期剩余名额检查和创建签到记录逻辑保持不变 const countCheckInDate = await this.checkInsRepository.countSpacesRemaining(check_in_date); const checkIn = await this.checkInsRepository.create({ player_id, check_in_date, }); return checkIn;
关键细节说明
周范围计算逻辑:
checkInDate.getDay()返回0(周日)到6(周六),checkInDate.getDate() - checkInDate.getDay()可直接得到当前周的周日。- 所有日期对象都用
new Date()复制,避免引用类型修改导致的日期混乱。
数据库查询逻辑调整:
需要确保findByPlayerIdAndDateRange方法的查询条件为:WHERE player_id = ? AND check_in_date >= ? AND check_in_date <= ?适配数据库中
check_in_date的存储格式,确保跨月日期能被正确匹配。冗余代码移除:
原代码中生成datascheckin并验证签到日期是否在周内的逻辑可直接移除,因为我们已经基于签到日期计算周范围,签到日期必然属于该周。
内容的提问来源于stack exchange,提问作者Lubnnia Morais
相关产品推荐
相关产品推荐

