Suzhou-SafetyToolsWarning-WX/utils/deviceUtils.js

287 lines
7.2 KiB
JavaScript
Raw Permalink Normal View History

2025-11-07 14:54:09 +08:00
/**
* 设备工具函数
* 用于设备数据处理日期计算预警判断等
*/
/**
* 计算两个日期之间的天数差
* @param {string|Date} date1 - 日期1
* @param {string|Date} date2 - 日期2
* @returns {number} 天数差
*/
function getDaysDiff(date1, date2) {
const d1 = new Date(date1);
const d2 = new Date(date2);
const diffTime = d2 - d1;
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
/**
* 计算设备距离检验到期的天数
* @param {string} nextInspectionDate - 下次检验日期
* @returns {number} 剩余天数负数表示已到期
*/
function getDaysLeft(nextInspectionDate) {
const today = new Date();
const nextDate = new Date(nextInspectionDate);
return getDaysDiff(today, nextDate);
}
/**
* 根据剩余天数判断设备状态
* @param {number} daysLeft - 剩余天数
* @param {number} warningDays - 预警天数阈值默认30天
* @returns {Object} 状态信息
*/
function getDeviceStatus(daysLeft, warningDays = 30) {
let status = 'normal';
let statusText = '正常';
let statusTheme = 'success';
let isWarning = false;
if (daysLeft < 0) {
status = 'expired';
statusText = '已到期';
statusTheme = 'danger';
isWarning = true;
} else if (daysLeft <= warningDays) {
status = 'warning';
statusText = '预警';
statusTheme = 'warning';
isWarning = true;
}
return {
status,
statusText,
statusTheme,
isWarning
};
}
/**
* 根据剩余天数获取预警等级
* @param {number} daysLeft - 剩余天数
* @returns {Object} 预警等级信息
*/
function getWarningLevel(daysLeft) {
if (daysLeft < 0) {
return {
level: 'expired',
levelText: '已到期',
tagTheme: 'danger'
};
} else if (daysLeft <= 7) {
return {
level: 'urgent',
levelText: '紧急',
tagTheme: 'danger'
};
} else if (daysLeft <= 15) {
return {
level: 'warning',
levelText: '预警',
tagTheme: 'warning'
};
} else if (daysLeft <= 30) {
return {
level: 'notice',
levelText: '提醒',
tagTheme: 'warning'
};
}
return {
level: 'normal',
levelText: '正常',
tagTheme: 'success'
};
}
/**
* 处理设备数据添加计算字段
* @param {Object} device - 设备原始数据
* @returns {Object} 处理后的设备数据
*/
function processDeviceData(device) {
const daysLeft = getDaysLeft(device.nextInspectionDate);
const statusInfo = getDeviceStatus(daysLeft);
const warningInfo = getWarningLevel(daysLeft);
return {
...device,
daysLeft,
...statusInfo,
...warningInfo
};
}
/**
* 批量处理设备数据
* @param {Array} devices - 设备数组
* @returns {Array} 处理后的设备数组
*/
function processDeviceList(devices) {
return devices.map(device => processDeviceData(device));
}
/**
* 根据检验周期计算下次检验日期
* @param {string} lastInspectionDate - 上次检验日期
* @param {number} inspectionCycle - 检验周期
* @returns {string} 下次检验日期YYYY-MM-DD
*/
function calculateNextInspectionDate(lastInspectionDate, inspectionCycle) {
const lastDate = new Date(lastInspectionDate);
const nextDate = new Date(lastDate);
nextDate.setMonth(nextDate.getMonth() + parseInt(inspectionCycle));
const year = nextDate.getFullYear();
const month = String(nextDate.getMonth() + 1).padStart(2, '0');
const day = String(nextDate.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
/**
* 格式化日期
* @param {string|Date} date - 日期
* @param {string} format - 格式默认YYYY-MM-DD
* @returns {string} 格式化后的日期
*/
function formatDate(date, format = 'YYYY-MM-DD') {
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hour = String(d.getHours()).padStart(2, '0');
const minute = String(d.getMinutes()).padStart(2, '0');
const second = String(d.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hour)
.replace('mm', minute)
.replace('ss', second);
}
/**
* 获取相对时间描述
* @param {string|Date} date - 日期
* @returns {string} 相对时间描述2分钟前1小时前
*/
function getRelativeTime(date) {
const now = new Date();
const past = new Date(date);
const diffSeconds = Math.floor((now - past) / 1000);
if (diffSeconds < 60) {
return '刚刚';
} else if (diffSeconds < 3600) {
return `${Math.floor(diffSeconds / 60)}分钟前`;
} else if (diffSeconds < 86400) {
return `${Math.floor(diffSeconds / 3600)}小时前`;
} else if (diffSeconds < 2592000) {
return `${Math.floor(diffSeconds / 86400)}天前`;
} else if (diffSeconds < 31536000) {
return `${Math.floor(diffSeconds / 2592000)}个月前`;
} else {
return `${Math.floor(diffSeconds / 31536000)}年前`;
}
}
/**
* 筛选设备列表
* @param {Array} devices - 设备数组
* @param {Object} filters - 筛选条件
* @returns {Array} 筛选后的设备数组
*/
function filterDevices(devices, filters = {}) {
let result = [...devices];
// 按状态筛选
if (filters.status && filters.status !== 'all') {
result = result.filter(device => device.status === filters.status);
}
// 按设备类型筛选
if (filters.deviceType && filters.deviceType !== '全部') {
result = result.filter(device => device.deviceType === filters.deviceType);
}
// 按使用单位筛选
if (filters.useUnit && filters.useUnit !== '全部') {
result = result.filter(device => device.useUnit === filters.useUnit);
}
// 按关键词搜索
if (filters.keyword) {
const keyword = filters.keyword.toLowerCase();
result = result.filter(device =>
device.deviceName.toLowerCase().includes(keyword) ||
device.deviceCode.toLowerCase().includes(keyword) ||
(device.specification && device.specification.toLowerCase().includes(keyword))
);
}
return result;
}
/**
* 统计设备数据
* @param {Array} devices - 设备数组
* @returns {Object} 统计结果
*/
function getDeviceStatistics(devices) {
const total = devices.length;
const normal = devices.filter(d => d.status === 'normal').length;
const warning = devices.filter(d => d.status === 'warning').length;
const expired = devices.filter(d => d.status === 'expired').length;
// 按类型统计
const typeStats = {};
devices.forEach(device => {
const type = device.deviceType;
if (!typeStats[type]) {
typeStats[type] = 0;
}
typeStats[type]++;
});
// 按单位统计
const unitStats = {};
devices.forEach(device => {
const unit = device.useUnit;
if (!unitStats[unit]) {
unitStats[unit] = 0;
}
unitStats[unit]++;
});
return {
total,
normal,
warning,
expired,
warningRate: total > 0 ? ((warning + expired) / total * 100).toFixed(1) : 0,
typeStats,
unitStats
};
}
module.exports = {
getDaysDiff,
getDaysLeft,
getDeviceStatus,
getWarningLevel,
processDeviceData,
processDeviceList,
calculateNextInspectionDate,
formatDate,
getRelativeTime,
filterDevices,
getDeviceStatistics
};