449 lines
13 KiB
JavaScript
449 lines
13 KiB
JavaScript
/**
|
||
* 通用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) {
|
||
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)}` : '无冲突');*/ |