You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

475 lines
14 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const CommonUtil = {
/**
* 获取当前时间
*/
getCurrenTime(){
// 创建一个 Date 对象,表示当前时间
let now = new Date();
// 获取年、月、日、时、分、秒
// 获取年月日时分秒
let time = {
year: now.getFullYear().toString().slice(-2), // 获取年份后两位
month: (now.getMonth() + 1), // 月份从0开始需加1
day: now.getDate(),
hours: now.getHours(),
minutes: now.getMinutes(),
seconds: now.getSeconds()
};
return time;
},
/**
* 通过时间戳 获取年月日 时分秒
* @param {10位 时间戳} timestamp
*/
getDateByTimestamp(timestamp){
if(timestamp === 0){
return {
year:0,
month:0,
day:0,
hours:0,
minutes:0,
seconds:0
}
}
// 将时间戳转为毫秒JavaScript的Date对象使用毫秒为单位
const date = new Date(timestamp * 1000);
// 格式化为年月日时分秒
const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
console.log(formattedDate); // 输出2024-12-20 00:00:00
return {
year:date.getFullYear() - 2000,
month:date.getMonth() + 1,
day:date.getDate(),
hours:date.getHours(),
minutes:date.getMinutes(),
seconds:date.getSeconds()
}
},
/**
* 发送屏幕亮度0~5级别转换
* @param {*} level
*/
sendSBLevelConv(level){
switch(level){
case 0:
return 0x8F;
case 1:
return 0x88;
case 2:
return 0x86;
case 3:
return 0x84;
case 4:
return 0x82;
case 5:
return 0x80;
default:
return 0x84;//如果不是0~5则默认均衡亮度
}
},
/**
* 获得屏幕亮度0~5级别转换
* @param {*} level
*/
respSBLevelConv(level){
switch(level){
case 0x0F:
return 0;
case 0x0D:
return 1;
case 0x0B:
return 2;
case 0x09:
return 3;
case 0x07:
return 4;
case 0x05:
return 5;
default:
return 2;//如果不是0~5则默认均衡亮度
}
},
getWeekBinary(week) {
let binaryValue = 0;
for (let i = 0; i < week.length; i++) {
// 逐位设置week[0] 代表周天offset 0
binaryValue |= week[i] << i;
}
return binaryValue;
},
stringToBytes(str) {
let encoded = unescape(encodeURIComponent(str));
let bytes = [];
for (let i = 0; i < encoded.length; i++) {
bytes.push(encoded.charCodeAt(i));
}
console.log("bytes:",bytes)
return bytes;
},
bytesToString(bytes) {
let str = '';
for (let i = 0; i < bytes.length; i++) {
str += String.fromCharCode(bytes[i]);
}
return decodeURIComponent(escape(str)); // 确保正确解码
},
/**
* 字段转指令
* @param {字段} field
*/
fieldToCommand(field){
switch(field){
case "sleepLastTime":
return 0x53;
case "heartRateLastTime":
return 0x55;
case "temperatureLastTime":
return 0x65;
case "bloodOxygenLastTime":
return 0x66;
case "bloodPressureLastTime":
return 0x56;
case "stepLastTime":
return 0x52;
default:
return 0;
}
},
/**
* 指令转字段
* @param {指令} command
*/
commandToField(command){
switch(command){
case 0x53:
return "sleepLastTime";
case 0x55:
return "heartRateLastTime";
case 0x65:
return "temperatureLastTime";
case 0x66:
return "bloodOxygenLastTime";
case 0x56:
return "bloodPressureLastTime";
case 0x52:
return "stepLastTime";
default:
return 0;
}
},
/**
* 组装睡眠数据
*/
assembleSleepData(sleepArray) {
let compareDate = sleepArray[0].yyyyMMdd; // 获取第一个数据的时间作为比对时间
let compareMinute = sleepArray[0].minute;
let res = []; // 存放最终结果
let resItem = { // 每天的睡眠数据对象
date: '',
sleepList: []
};
// 取出第一个数据并初始化
let firstSleepData = sleepArray[0];
resItem.date = firstSleepData.yyyyMMdd;
resItem.sleepList.push(firstSleepData); // 将第一个数据放入到 `sleepList`
sleepArray.forEach((item,index) => {
// 判断是否是同一天的数据
let isSameDay = this.timeComparison(compareDate,compareMinute, item.yyyyMMdd, item.minute);
// 如果状态发生变化,且日期不同,就表示开始新的睡眠数据
if (item.status !== firstSleepData.status) {
if (isSameDay) {
resItem.sleepList.push(item);
} else {
// 取出数据
let lastItem = sleepArray[index - 1];
lastItem.minute = lastItem.minute + 1;//加1分钟作为起床点
resItem.sleepList.push(lastItem);
res.push(resItem); // 否则,将当天的数据推入结果数组
resItem = { // 新的一天开始
date: item.yyyyMMdd,
sleepList: [item] // 将当前项作为新的睡眠数据开始
};
compareDate = item.yyyyMMdd; // 更新对比日期,用于比对后续数据
compareMinute = item.minute;
}
}
firstSleepData = item; // 更新当前比对的睡眠数据
});
// 最后一次的睡眠数据也需要被加入到 `res`
if (resItem.sleepList.length > 0) {
// 获取最后一个数据添加到最后
let lastItem = sleepArray[sleepArray.length - 1];
lastItem.minute = lastItem.minute + 1;//加1分钟作为起床点
resItem.sleepList.push(lastItem);
res.push(resItem);
}
return res; // 返回按天拆分后的睡眠数据
},
/**
* 计算出一天的时间范围
* @param {对比日期} compareDate
*/
getDayTimeRange(compareDate,compareMinute) {
// 将 "YYYYMMDD" 格式的日期转换为 "YYYY-MM-DD" 格式,方便解析
const formattedDateStr = compareDate.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
// 创建目标日期对象
// const date = new Date(formattedDateStr); // 例如2024-12-12
// 获取对比日期的Date前一天的20:00:00
// const prevDayStart = new Date(date);
// prevDayStart.setDate(date.getDate() - 1); //设置为前一天
// prevDayStart.setHours(20, 0, 0, 0); // 设置为20:00:00
// // 获取对比日期的Date后一天的10:00:00
// const nextDayEnd = new Date(date);
// nextDayEnd.setDate(date.getDate()); // 设置为后一天
// nextDayEnd.setHours(10, 0, 0, 0); // 设置为10:00:00
// 获取对比日期的Date前一天的20:00:00
const date1 = new Date(formattedDateStr)
const date2 = new Date(formattedDateStr)
const prevDayStart = new Date(date1);
if(this.isEveningTime(compareMinute)){
prevDayStart.setDate(date1.getDate());
} else {
prevDayStart.setDate(date1.getDate() - 1);
}
prevDayStart.setHours(20, 0, 0, 0); // 设置为20:00:00
// 获取对比日期的Date后一天的10:00:00
const nextDayEnd = new Date(date2);
if(this.isEveningTime(compareMinute)){
nextDayEnd.setDate(date2.getDate() + 1);
} else {
nextDayEnd.setDate(date2.getDate());
}
nextDayEnd.setHours(10, 0, 0, 0); // 设置为10:00:00
// 返回时间戳
return {
startTimestamp: prevDayStart.getTime(), // 转换为10位时间戳
endTimestamp: nextDayEnd.getTime() // 转换为10位时间戳
};
},
/**
* 判断是否是晚上的20:00~00:00点
* @param {*} minute
*/
isEveningTime(minute){
return minute < 1440 && minute > 1200;
},
/**
*
* @param {日期} dateStr
* @param {一天的第N分钟} minutes
*/
getTimestampFromDateAndMinutes(dateStr, minutes) {
// 将 "YYYYMMDD" 格式的日期转换为 "YYYY-MM-DD" 格式,方便解析
const formattedDateStr = dateStr.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
// 创建目标日期对象
const date = new Date(formattedDateStr); // 例如2024-12-12
// 计算总分钟数
const totalMinutes = minutes;
// 将分钟数转化为小时和分钟
const hours = Math.floor(totalMinutes / 60); // 计算小时数
const mins = totalMinutes % 60; // 计算剩余的分钟数
// 设置时间为指定的小时和分钟
date.setHours(hours, mins, 0, 0); // 设置为相应的时分秒
// 返回时间戳转换为10位时间戳
return date.getTime();
},
/**
*
* @param {对比日期} compareDate
* @param {分钟} minute
* @param {比较值} comparisonValue
*/
timeComparison(compareDate,compareMinute,comparisonValue,minute){
let dateRange = this.getDayTimeRange(compareDate,compareMinute);
let time = this.getTimestampFromDateAndMinutes(comparisonValue,minute);
if(time >= dateRange.startTimestamp && time <= dateRange.endTimestamp){
// 在范围内,是同一天睡眠
return true;
}
return false;
},
sortSleep(data){
data.forEach((item) =>{
// 排序算法
// item.sleepList.sort((a, b) => {
// // 先比较 yyyyMMdd
// if (a.yyyyMMdd !== b.yyyyMMdd) {
// return a.yyyyMMdd.localeCompare(b.yyyyMMdd);
// }
// // 再比较 minute
// return a.minute - b.minute;
// });
// 因为后端的接口处理方式为如果第一个数据为清醒,不会作为睡眠时间,故将第一个数据作为浅睡
item.sleepList[0].status = 1
item.date = item.sleepList[item.sleepList.length - 1].yyyyMMdd
})
return data;
},
/**
*
* @param {补全数据} data
*/
completeMissingData(data){
data.sort((a, b) => {
// 先比较 yyyyMMdd
if (a.yyyyMMdd !== b.yyyyMMdd) {
return a.yyyyMMdd.localeCompare(b.yyyyMMdd);
}
// 再比较 minute
return a.minute - b.minute;
});
let result = []; // 存放最终结果
for (let i = 0; i < data.length; i++) {
result.push(data[i]); // 先将当前数据加入结果集
// 如果当前数据不是最后一个,检查与下一个数据的 minute 是否连续
if (i < data.length - 1) {
let currentMinute = data[i].minute;
let nextMinute = data[i + 1].minute;
if(data[i].yyyyMMdd == data[i + 1].yyyyMMdd && nextMinute - currentMinute < 600){
// 如果不连续,补全缺失的数据
if (nextMinute > currentMinute + 1) {
for (let j = currentMinute + 1; j < nextMinute; j++) {
result.push({
minute: j, // 补全的 minute
status: 3, // 沿用当前数据的 status
yyyyMMdd: data[i].yyyyMMdd // 沿用当前数据的日期
});
}
}
} else {
// 还要考虑隔天的情况,如果隔天有数据缺失的也需要补齐
let currentDate = data[i].yyyyMMdd;
let nextDate = data[i + 1].yyyyMMdd;
// if(CommonUtil.isNextDay(currentDate,nextDate) &&
// currentMinute > 1200 && nextDate > 480 ){
// console.log(currentDate,currentMinute);
// console.log(nextDate,nextMinute);
// console.log("相减的差值:",nextMinute - currentMinute);
// console.log("是否跨天:",CommonUtil.isNextDay(currentDate,nextDate));
// if(currentMinute < 1439){
// for (let j = currentMinute + 1; j < 1440; j++) {
// result.push({
// minute: j,
// status: 3,
// yyyyMMdd: data[i].yyyyMMdd
// });
// }
// }
// if(0 < nextMinute){
// for (let j = 0; j < nextMinute; j++) {
// result.push({
// minute: j,
// status: 3,
// yyyyMMdd: data[i + 1].yyyyMMdd
// });
// }
// }
// }
}
}
}
return result;
},
// 获取下一个日期
getNextDay(dateString) {
// 解析传入的日期字符串
let date = new Date(dateString);
// 将日期加一天
date.setDate(date.getDate() + 1);
// 格式化为 "YYYY-MM-DD" 格式
let year = date.getFullYear();
let month = ('0' + (date.getMonth() + 1)).slice(-2); // 月份需要 +1且补充 0
let day = ('0' + date.getDate()).slice(-2); // 日期补充 0
return `${year}${month}${day}`;
},
/**
* 删除已上传的睡眠数据
* @param {} arr
* @param {*} targetDate
*/
removeBeforeDate(arr, targetDate) {
// 将目标日期字符串转换为 Date 对象
let target = new Date(targetDate.substring(0, 4), targetDate.substring(4, 6) - 1, targetDate.substring(6, 8));
// 过滤掉日期小于或等于目标日期的项
return arr.filter(item => {
// 将数组中每个日期转换为 Date 对象
let itemDate = new Date(item.date.substring(0, 4), item.date.substring(4, 6) - 1, item.date.substring(6, 8));
// 只保留日期大于目标日期的项
return itemDate > target;
});
},
/**
* 是否是下一天
* @param {} date1
* @param {*} date2
*/
isNextDay(date1, date2) {
// 将日期格式化为 yyyy-MM-dd 形式
const d1 = new Date(date1.toString().slice(0, 4), date1.toString().slice(4, 6) - 1, date1.toString().slice(6, 8));
const d2 = new Date(date2.toString().slice(0, 4), date2.toString().slice(4, 6) - 1, date2.toString().slice(6, 8));
// 将时间部分清零
d1.setHours(0, 0, 0, 0);
d2.setHours(0, 0, 0, 0);
// 计算日期差值(单位:毫秒)
const diffTime = d2 - d1;
const oneDayInMillis = 24 * 60 * 60 * 1000; // 一天的毫秒数
// 判断差值是否为一天
return diffTime === oneDayInMillis;
},
}
// 导出模块
module.exports = CommonUtil;