/** * 通用js方法封装处理 * Copyright (c) 2019 agri */ // 日期格式化 export function parseTime(time, pattern) { if (arguments.length === 0 || !time) { return null } const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' let date if (typeof time === 'object') { date = time } else { if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { time = parseInt(time) } else if (typeof time === 'string') { time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '') } if ((typeof time === 'number') && (time.toString().length === 10)) { time = time * 1000 } date = new Date(time) } const formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() } const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key] // Note: getDay() returns 0 on Sunday if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } if (result.length > 0 && value < 10) { value = '0' + value } return value || 0 }) return time_str } // 获取今天的 LocalDateTime 格式(yyyy-MM-dd HH:mm:ss) function getTodayLocalDateTime() { const now = new Date(); // 年 const year = now.getFullYear(); // 月:0 开始,+1 后补零 const month = String(now.getMonth() + 1).padStart(2, '0'); // 日:补零 const day = String(now.getDate()).padStart(2, '0'); // 时:补零(24小时制) const hours = String(now.getHours()).padStart(2, '0'); // 分:补零 const minutes = String(now.getMinutes()).padStart(2, '0'); // 秒:补零 const seconds = String(now.getSeconds()).padStart(2, '0'); // 拼接成 LocalDateTime 格式 return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } // 表单重置 export function resetForm(refName) { if (this.$refs[refName]) { this.$refs[refName].resetFields() } } // 添加日期范围 export function addDateRange(params, dateRange, propName) { let search = params search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} dateRange = Array.isArray(dateRange) ? dateRange : [] if (typeof (propName) === 'undefined') { search.params['beginTime'] = dateRange[0] search.params['endTime'] = dateRange[1] } else { search.params['begin' + propName] = dateRange[0] search.params['end' + propName] = dateRange[1] } return search } // 回显数据字典 export function selectDictLabel(datas, value) { if (value === undefined) { return "" } var actions = [] Object.keys(datas).some((key) => { if (datas[key].value == ('' + value)) { actions.push(datas[key].label) return true } }) if (actions.length === 0) { actions.push(value) } return actions.join('') } // 回显数据字典(字符串、数组) export function selectDictLabels(datas, value, separator) { if (value === undefined || value.length ===0) { return "" } if (Array.isArray(value)) { value = value.join(",") } var actions = [] var currentSeparator = undefined === separator ? "," : separator var temp = value.split(currentSeparator) Object.keys(value.split(currentSeparator)).some((val) => { var match = false Object.keys(datas).some((key) => { if (datas[key].value == ('' + temp[val])) { actions.push(datas[key].label + currentSeparator) match = true } }) if (!match) { actions.push(temp[val] + currentSeparator) } }) return actions.join('').substring(0, actions.join('').length - 1) } // 字符串格式化(%s ) export function sprintf(str) { var args = arguments, flag = true, i = 1 str = str.replace(/%s/g, function () { var arg = args[i++] if (typeof arg === 'undefined') { flag = false return '' } return arg }) return flag ? str : '' } // 转换字符串,undefined,null等转化为"" export function parseStrEmpty(str) { if (!str || str == "undefined" || str == "null") { return "" } return str } // 数据合并 export function mergeRecursive(source, target) { for (var p in target) { try { if (target[p].constructor == Object) { source[p] = mergeRecursive(source[p], target[p]) } else { source[p] = target[p] } } catch (e) { source[p] = target[p] } } return source } /** * 构造树型结构数据 * @param {*} data 数据源 * @param {*} id id字段 默认 'id' * @param {*} parentId 父节点字段 默认 'parentId' * @param {*} children 孩子节点字段 默认 'children' */ export function handleTree(data, id, parentId, children) { let config = { id: id || 'id', parentId: parentId || 'parentId', childrenList: children || 'children' } var childrenListMap = {} var tree = [] for (let d of data) { let id = d[config.id] childrenListMap[id] = d if (!d[config.childrenList]) { d[config.childrenList] = [] } } for (let d of data) { let parentId = d[config.parentId] let parentObj = childrenListMap[parentId] if (!parentObj) { tree.push(d) } else { parentObj[config.childrenList].push(d) } } return tree } /** * 参数处理 * @param {*} params 参数 */ export function tansParams(params) { let result = '' for (const propName of Object.keys(params)) { const value = params[propName] var part = encodeURIComponent(propName) + "=" if (value !== null && value !== "" && typeof (value) !== "undefined") { if (typeof value === 'object') { for (const key of Object.keys(value)) { if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { let params = propName + '[' + key + ']' var subPart = encodeURIComponent(params) + "=" result += subPart + encodeURIComponent(value[key]) + "&" } } } else { result += part + encodeURIComponent(value) + "&" } } } return result } // 返回项目路径 export function getNormalPath(p) { if (p.length === 0 || !p || p == 'undefined') { return p } let res = p.replace('//', '/') if (res[res.length - 1] === '/') { return res.slice(0, res.length - 1) } return res } // 验证是否为blob格式 export function blobValidate(data) { return data.type !== 'application/json' } // 生成纯数字、无小数点、低重复率的ID // 1. 改造generateUniqueId,返回字符串类型(关键!) export function generateUniqueId() { const timestamp = Date.now(); const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); return (timestamp + random).toString(); // 转成字符串,避免数字精度丢失 } const toMin = (t) => { const [h, m] = t.split(':').map(Number); return h * 60 + (m || 0); }; // ===================== 对外导出的函数(按需导出) ===================== /** * 函数1:判断时间列表是否冲突 * @param {Array} list - 包含startTime/endTime的时间配置列表 * @returns {Object} 冲突检测结果 */ export function checkTimeConflict(list) { if (!Array.isArray(list)) return { isConflict: false }; const valid = list.filter(i => i.startTime && i.endTime); for (let i = 0; i < valid.length; i++) { const [aS, aE] = [toMin(valid[i].startTime), toMin(valid[i].endTime)]; for (let j = i + 1; j < valid.length; j++) { const [bS, bE] = [toMin(valid[j].startTime), toMin(valid[j].endTime)]; if (!(aE <= bS || bE <= aS)) return { isConflict: true, conflict: [valid[i], valid[j]] }; } } return { isConflict: false }; } /** * 判断两个时间的间隔是否大于 N 天 * @param {Date|String} time1 第一个时间 * @param {Date|String} time2 第二个时间 * @param {Number} days 天数 * @returns {Boolean} true=间隔大于N天;false=不大于 */ export function isIntervalMoreThanNDays(time1, time2, days) { var dayDiff = getExactDiffDays(time1,time2) return dayDiff > days; } /** * 计算两个时间的相差天数(精确到时分秒,返回小数) * @param {Date|String} time1 第一个时间(可含时分秒) * @param {Date|String} time2 第二个时间(可含时分秒) * @returns {Number} 相差的天数(正数,保留4位小数) */ export function getExactDiffDays(time1, time2) { // 转换为Date对象并校验合法性 const d1 = new Date(time1); const d2 = new Date(time2); if (isNaN(d1.getTime()) || isNaN(d2.getTime())) { throw new Error("时间格式不合法,请检查!"); } // 1. 计算毫秒差(绝对值,避免顺序问题) const timeDiffMs = Math.abs(d1.getTime() - d2.getTime()); // 2. 转换为天数(1天 = 86400000 毫秒) const oneDayMs = 24 * 60 * 60 * 1000; const diffDays = timeDiffMs / oneDayMs; // 保留4位小数,避免精度冗余 return Number(diffDays.toFixed(4)); } export function isTodayDate(dateInput) { if (!dateInput) return false; let targetDate; if (dateInput instanceof Date) { targetDate = new Date(dateInput); } else { targetDate = new Date(dateInput); if (isNaN(targetDate.getTime())) { console.warn("输入的日期字符串格式无效:", dateInput); return false; } } const today = new Date(); const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()); const targetDateOnly = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return targetDateOnly.getTime() === todayDate.getTime(); } export function formatTime(timeStr) { console.info('timeStr', timeStr) const now = new Date(); const target = new Date(timeStr); const diff = now - target; const day = 86400000; const week = 7 * day; // 时间 const h = String(target.getHours()).padStart(2, '0'); const m = String(target.getMinutes()).padStart(2, '0'); const time = `${h}:${m}`; // 今天 if (now.toDateString() === target.toDateString()) return `${time}`; // 昨天 const yest = new Date(now); yest.setDate(now.getDate() - 1); if (yest.toDateString() === target.toDateString()) return `昨天 ${time}`; // 7天内 if (diff <= week) { const weekMap = ['日', '一', '二', '三', '四', '五', '六']; return `星期${weekMap[target.getDay()]} ${time}`; } // 7天前 const Y = target.getFullYear(); const M = String(target.getMonth() + 1).padStart(2, '0'); const D = String(target.getDate()).padStart(2, '0'); return `${Y}-${M}-${D} ${time}`; } /** * 判断传入的日期是否是今天 * 支持格式:Date对象、时间戳、字符串(yyyy-MM-dd HH:mm:ss、yyyy-MM-dd、ISO格式等) * @param {Date|number|string} dateInput - 要判断的日期 * @returns {boolean} - 是否是今天 */ export function isToday(dateInput) { if (!dateInput) return false; let targetDate; // 处理不同类型的输入 if (dateInput instanceof Date) { targetDate = new Date(dateInput); } else if (typeof dateInput === 'number') { // 时间戳(秒或毫秒) targetDate = dateInput.toString().length === 10 ? new Date(dateInput * 1000) : new Date(dateInput); } else if (typeof dateInput === 'string') { // 字符串格式处理 if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(dateInput)) { // yyyy-MM-dd HH:mm:ss 格式 targetDate = new Date(dateInput.replace(/-/g, '/')); } else if (/^\d{4}-\d{2}-\d{2}$/.test(dateInput)) { // yyyy-MM-dd 格式 targetDate = new Date(dateInput.replace(/-/g, '/')); } else { // 其他格式(ISO等) targetDate = new Date(dateInput); } } else { return false; } // 验证日期有效性 if (isNaN(targetDate.getTime())) { console.warn("输入的日期格式无效:", dateInput); return false; } // 获取今天的日期(去掉时间部分) const today = new Date(); const todayDateOnly = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // 获取目标日期的日期部分(去掉时间) const targetDateOnly = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return targetDateOnly.getTime() === todayDateOnly.getTime(); } // // 测试示例 // const start = "2026-03-01"; // const end = "2026-03-12"; // console.log(isIntervalMoreThanNDays(start, end, 10)); // true(间隔11天,大于10天) // console.log(isIntervalMoreThanNDays(start, end, 11)); // false(刚好11天,不大于) // ===================== 测试用例 ===================== /* const rollerList = [ { imei: '123', roller: 'jm1', startTime: '08:00', endTime: '12:00' }, { imei: '123', roller: 'jm1', startTime: '10:00', endTime: '14:00' }, { imei: '123', roller: 'jm1', startTime: '15:00', endTime: '18:00' } ]; // 调用(一行搞定) const { isConflict, conflict } = checkTimeConflict(rollerList); console.log(isConflict ? `冲突:${JSON.stringify(conflict)}` : '无冲突');*/