Spaces:
Paused
Paused
File size: 3,704 Bytes
00b9b23 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | // EyeTimeQuery.js - 仅统计用眼分钟数(日/周/月), 支持时区
const { mongoose } = require('../index');
const DateRangeHelper = require('../utils/DateRange');
const TimezoneUtils = require('../utils/timezone');
const DailyEyeTime = mongoose.model('DailyEyeTime');
class EyeTimeQuery {
constructor(timezoneOffset = 8) {
// 初始化时区工具与日期范围助手
this.timezoneOffset = timezoneOffset;
this.timezoneUtils = new TimezoneUtils(timezoneOffset);
this.dateHelper = new DateRangeHelper(timezoneOffset);
}
/**
* 获取某日的用眼分钟数
* @param {Date} date - 查询目标日期(UTC 或本地时间均可)
* @param {number} timezoneOffset - 时区偏移(小时)
*/
async getDailyMinutes(date, timezoneOffset = this.timezoneOffset) {
const tzUtils = new TimezoneUtils(timezoneOffset);
// 解析输入日期为本地日期
const localDate = tzUtils.parseDate(date);
// 构建数据库查询的日期(本地零点对应的 UTC 时间)
const localDayStart = new Date(Date.UTC(
localDate.getUTCFullYear(),
localDate.getUTCMonth(),
localDate.getUTCDate(),
0, 0, 0, 0
));
const dbDate = tzUtils.localToUtc(localDayStart);
// 查询记录
const dayRecords = await DailyEyeTime.find({
date: dbDate
}).lean();
// 初始化小时分布
const hourlyStats = Array(24).fill(0);
for (const rec of dayRecords) {
if (rec.hourlyUsage && Array.isArray(rec.hourlyUsage)) {
for (let i = 0; i < 24; i++) {
hourlyStats[i] += rec.hourlyUsage[i] || 0;
}
}
}
// 总分钟数直接用小时分布求和
const totalUsage = Math.round(hourlyStats.reduce((a, b) => a + b, 0) * 100) / 100;
return {
date: localDate.toISOString().split('T')[0],
totalUsage,
hourlyStats: hourlyStats.map(v => Math.round(v * 100) / 100),
timezoneOffset
};
}
/**
* 获取周统计结果
*/
async getWeeklyMinutes(weekOffset = 0, timezoneOffset = this.timezoneOffset) {
const { startDate, endDate } = this.dateHelper.getWeekRange(weekOffset);
const result = {};
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
const stats = await this.getDailyMinutes(new Date(d), timezoneOffset);
result[stats.date] = stats.totalUsage;
}
return {
weekOffset,
weekRange: {
start: startDate.toISOString().split('T')[0],
end: endDate.toISOString().split('T')[0]
},
dailyTotals: result,
timezoneOffset
};
}
/**
* 获取月统计结果
*/
async getMonthlyMinutes(monthOffset = 0, timezoneOffset = this.timezoneOffset) {
const { startDate, endDate } = this.dateHelper.getMonthRange(monthOffset, timezoneOffset);
const result = {};
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
const stats = await this.getDailyMinutes(new Date(d), timezoneOffset);
result[stats.date] = stats.totalUsage;
}
return {
monthOffset,
monthRange: {
start: startDate.toISOString().split('T')[0],
end: endDate.toISOString().split('T')[0]
},
dailyTotals: result,
timezoneOffset
};
}
}
module.exports = EyeTimeQuery; |