Suzhou-SafetyToolsWarning-WX/utils/deviceUtils.js

287 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 设备工具函数
* 用于设备数据处理、日期计算、预警判断等
*/
/**
* 计算两个日期之间的天数差
* @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
};