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