/**
* 之前的时间
* @param {number} date 时间戳或时间字符串
*
*/
import { t } from "@/locale";
export const fromTime = (timer) => {
if (timer > 90000000000) { timer /= 1000; }
let now = new Date()
const nowday = now.getDate()
const nowhour = now.getHours()
const nowminute = now.getMinutes()
const nowsecond = now.getSeconds()
let todaysec = nowhour * 60 * 60 + nowminute * 60 + nowsecond
const hour = date("H", timer);
const minute = date("i", timer);
let nowTime = new Date().getTime();
let miao = parseInt((nowTime / 1000) - timer)
//一小时以内的
if (miao < 60) {
return t('刚刚')
} else if (miao >= 60 && miao < 3600) {
return Math.floor(miao / 60) + t('分钟前')
} else if (miao >= 3600 && miao <= todaysec) {
return Math.floor(miao / 3600) + t('小时前')
} else if (miao > todaysec && miao < todaysec + 86400) {
return t('昨天')
} else if (miao >= 86400 && miao < 2592000) {
return parseInt(miao / 86400) + t('天前');
} else {
return date("Y/m/d", timer);
}
}
export const timeFormat = (timestamp) => {
const now = new Date();
const datetime = new Date(timestamp);
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterday = new Date(today - 24 * 60 * 60 * 1000);
const weekStart = new Date(today - (today.getDay() - 1) * 24 * 60 * 60 * 1000);
const yearStart = new Date(now.getFullYear(), 0, 1);
if (datetime >= today) {
return date('H:i', timestamp / 1000)
} else if (datetime >= yesterday && datetime < today) {
return '昨天'
} else if (datetime >= weekStart && datetime < yesterday) {
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const weekday = weekdays[datetime.getDay()];
return weekday;
} else if (datetime >= yearStart && datetime < weekStart) {
return date('m-d', timestamp / 1000)
} else {
return date('Y-m-d', timestamp / 1000)
}
}
/**
* 传入的时间戳和当前时间作比较
* @param {number} date 时间戳或时间字符串
*
*/
export const overTime = (timer) => {
var arrTimestamp = (timer + '').split('');
for (var start = 0; start < 13; start++) {
if (!arrTimestamp[start]) {
arrTimestamp[start] = '0';
}
}
timer = arrTimestamp.join('') * 1;
var minute = 1000 * 60;
var hour = minute * 60;
var day = hour * 24;
var halfamonth = day * 15;
var month = day * 30;
var now = new Date().getTime();
var diffValue = now - timer;
// 如果本地时间反而小于变量时间
if (diffValue < 0) {
return '不久前';
}
// 计算差异时间的量级
var monthC = diffValue / month;
var weekC = diffValue / (7 * day);
var dayC = diffValue / day;
var hourC = diffValue / hour;
var minC = diffValue / minute;
// 数值补0方法
var zero = function (value) {
if (value < 10) {
return '0' + value;
}
return value;
};
// 使用
if (monthC > 12) {
// 超过1年,直接显示年月日
return (function () {
var date = new Date(timer);
return date.getFullYear() + '年' + zero(date.getMonth() + 1) + '月' + zero(date.getDate()) + '日';
})();
} else if (monthC >= 1) {
return '已过期' + parseInt(monthC) + "月";
} else if (weekC >= 1) {
return '已过期' + parseInt(weekC) + "周";
} else if (dayC >= 1) {
return '已过期' + parseInt(dayC) + "天";
} else if (hourC >= 1) {
return '已过期' + parseInt(hourC) + "小时";
} else if (minC >= 1) {
return '已过期'
parseInt(minC) + "分钟";
} else if (minC < 1) {
return parseInt(minC) + "分钟后过期";
} else if (hourC < 1) {
return parseInt(hourC) + "小时后过期";
} else if (dayC < 1) {
return parseInt(dayC) + "天后过期";
} else if (weekC < 1) {
var date = new Date(timer);
return date.getFullYear() + '年' + zero(date.getMonth() + 1) + '月' + zero(date.getDate()) + '日';
}
}
export const getExpireDaysFromTimestamp = (timer) => {
// 转为数字并转为毫秒
const expireDate = new Date(Number(timer) * 1000);
const today = new Date();
// 清除时分秒
expireDate.setHours(0, 0, 0, 0);
today.setHours(0, 0, 0, 0);
// 计算天数差
const diffTime = expireDate - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
}
/**
* 根据客户分级设置背景颜色
* @param {number} level 时间戳或时间字符串
* 1主色,2橙色,3红色,4绿色,5灰色
*/
export const bgAvatar = (level) => {
if (level === 1 || !level) {
return "bg-blue";
}
if (level === 2) {
return "bg-orange";
}
if (level === 3) {
return 'bg-red'
}
if (level === 4) {
return 'bg-green'
}
if (level === 5) {
return 'bg-grey'
}
}
//序列化url,将url链接后面的get参数序列化成json对象
export const parseUrl = (url) => {
var param = url.substring(url.indexOf("?") + 1);
var paramArr = param.split("&");
var urlArr = {};
for (let i = 0; i < paramArr.length; i++) {
urlArr[paramArr[i].split("=")[0]] = decodeURI(paramArr[i].split("=")[1]);
// 将数组元素中'='左边的内容作为对象的属性名,'='右边的内容作为对象对应属性的属性值
}
return urlArr;
}
/**
* 设置表单共有属性
*
*/
export const setFrom = (fromList, info, action, project) => {
fromList.forEach(fromIitem => {
fromIitem.rules = {
errMess: `${fromIitem.name}不能为空`
}
// 回款是多选 所以要便利value
if (fromIitem.relevant) {
fromIitem.form_type == fromIitem.relevant ? fromIitem.disabled = true : ""
}
if (fromIitem.form_type === 'money') {
fromIitem.default_value ? fromIitem.capitalize = menoyToUppercase(fromIitem.default_value) :
fromIitem.capitalize = null
}
// 如果是下拉或者 tag 设置show属性 弹出选择框才能显示
if (fromIitem.form_type === 'tags' || fromIitem.form_type === 'select' || fromIitem.form_type ===
'invoice_info' ||
fromIitem.form_type === 'pm_type' || fromIitem.form_type === 'finance_type' ||
fromIitem.form_type === 'visit_user' || fromIitem.form_type === 'area') {
fromIitem.show = false
}
// 判断有没有 setting 有的话是下拉 多选
if (fromIitem.setting) {
fromIitem.list = []
if (fromIitem.setting instanceof Array) {
// 是数组 根据index
fromIitem.setting.forEach((i, idx) => {
fromIitem.list.push({
value: idx, //最终提交拿到的值
label: i, //展示给用户的字段
})
})
} else {
for (let key in fromIitem.setting) {
fromIitem.list.push({
value: key, //最终提交拿到的值
label: fromIitem.setting[key], //展示给用户的字段
})
}
}
}
if (fromIitem.form_type === 'select' && fromIitem.default_value && fromIitem.setting) {
fromIitem.list.forEach(it => {
if (it.value == fromIitem.default_value) {
fromIitem.value = it.label
}
})
}
// 判断禁用
if (fromIitem.form_type == 'business' && action == 'add') {
fromIitem.default_value = info.leads_id
fromIitem.value = info.name
fromIitem.disabled = true
}
if (fromIitem.form_type ==
'customer' &&
info && action == 'add') {
fromIitem.default_value = info.name
fromIitem.value = info.leads_id
fromIitem.disabled = true
} else if (fromIitem.form_type == 'business' && action == 'edit' || fromIitem.form_type ==
'customer' && info && action == 'add' || fromIitem.form_type ==
'customer' && info && action == 'edit') {
fromIitem.default_value = fromIitem.value
fromIitem.value = fromIitem.default_value
fromIitem.disabled = true
}
if (fromIitem.field == 'company' && action == 'edit') {
fromIitem.disabled = true
}
// 判断项目名称有没
if (fromIitem.form_type == 'project' && action == 'add' && !info) {
fromIitem.disabled = true
}
if (fromIitem.form_type == 'project' && action == 'add' && project) {
console.log(project)
fromIitem.disabled = true
fromIitem.default_value = project.project_id
fromIitem.value = project.title
}
if (fromIitem.form_type == 'receivable') {
if (action == 'add' && !project) {
fromIitem.disabled = true
}
if (fromIitem.default_value != "") {
let val = fromIitem.value.map(i => {
return i.receivables_id
})
uni.setStorageSync('relationReceivableId', val)
fromIitem.default_value = val.join('')
fromIitem.value = fromIitem.value.map(i => {
return i.number
})
}
}
// 判断成交人回显
if (fromIitem.form_type == "user_receivables") {
if (fromIitem.value) {
fromIitem.value.forEach((i, idx) => {
fromIitem.default_value[idx].realname = fromIitem.value[idx].user_id_info
.realname
})
}
if (!fromIitem.value) {
fromIitem.default_value = []
fromIitem.default_value.push({
realname: '',
user_id: '',
proportion: ''
})
}
}
})
return fromList
}
/**
* 设置三级联动
*
*/
export const setPmType = (data) => {
let list = []
data.forEach((item, index) => {
list.push({
label: item.name,
value: item.type_id
})
if (item.children) {
list[index].children = []
item.children.forEach((i, idx) => {
list[index].children.push({
label: i.name,
value: i.type_id
})
if (item.children[idx].children) {
list[index].children[idx].children = []
item.children[idx].children.forEach((ii, iidx) => {
list[index].children[idx].children.push({
label: ii.name, //展示给用户的字段
value: ii.type_id, //最终提交拿到的值
})
})
}
})
}
})
return list;
}
export const judgeListComplete = (list) => {
let flag = ''
list.every((item) => {
for (let key in item) {
item[key] == '' ? flag = '' : flag = true
}
})
return flag;
}
export const judgeobjduplicate = (list) => {
let flag = ''
let sum = 0
list.forEach(item => {
sum += parseInt(item.proportion)
})
if (sum >= 100) {
flag = false
} else {
flag = true
}
return flag;
}
// 生成唯一ID
export const getUuid = () => {
var d = new Date().getTime();
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == "x" ? r : r & 0x3 | 0x8).toString(16);
});
return uuid;
}
// 寻找数组
export const findArray = (arr, id) => {
return arr.find(function (res) {
var newId = res.id;
return id == newId;
});
}
// 二维数组排序
export const sortContacts = (data) => {
const arr = JSON.parse(JSON.stringify(data));
arr.sort((a, b) => {
// 将字符串时间戳转换为数字
const timeA = parseInt(a.lastSendTime, 10);
const timeB = parseInt(b.lastSendTime, 10);
// 如果转换失败(例如,非数字字符串),则将它们视为无效并放在数组末尾
// 这里可以根据实际情况调整逻辑,比如抛出错误或忽略这些项
if (isNaN(timeA)) return 1; // 将a视为大于b
if (isNaN(timeB)) return -1; // 将b视为小于a
// 使用转换后的数字进行比较
return timeB - timeA;
});
return arr;
}
// 将数字转换成大写中文
export const menoyToUppercase = (money) => {
var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'); //汉字的数字
var cnIntRadice = new Array('', '拾', '佰', '仟'); //基本单位
var cnIntUnits = new Array('', '万', '亿', '兆'); //对应整数部分扩展单位
var cnDecUnits = new Array('角', '分', '毫', '厘'); //对应小数部分单位
var cnInteger = '整'; //整数金额时后面跟的字符
var cnIntLast = '元'; //整数完以后的单位
//最大处理的数字
var maxNum = 999999999999999.9999;
var integerNum; //金额整数部分
var decimalNum; //金额小数部分
//输出的中文金额字符串
var chineseStr = '';
var parts; //分离金额后用的数组,预定义
if (!money) {
return '';
}
money = parseFloat(money);
if (money >= maxNum) {
//超出最大处理数字
return '超出最大处理数字';
}
if (money == 0) {
chineseStr = cnNums[0] + cnIntLast + cnInteger;
return chineseStr;
}
//四舍五入保留两位小数,转换为字符串
money = Math.round(money * 100).toString();
integerNum = money.substr(0, money.length - 2);
decimalNum = money.substr(money.length - 2);
//获取整型部分转换
if (parseInt(integerNum, 10) > 0) {
var zeroCount = 0;
var IntLen = integerNum.length;
for (var i = 0; i < IntLen; i++) {
var n = integerNum.substr(i, 1);
var p = IntLen - i - 1;
var q = p / 4;
var m = p % 4;
if (n == '0') {
zeroCount++;
} else {
if (zeroCount > 0) {
chineseStr += cnNums[0];
}
//归零
zeroCount = 0;
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
}
if (m == 0 && zeroCount < 4) {
chineseStr += cnIntUnits[q];
}
}
chineseStr += cnIntLast;
}
//小数部分
if (decimalNum != '') {
var decLen = decimalNum.length;
for (var i = 0; i < decLen; i++) {
var n = decimalNum.substr(i, 1);
if (n != '0') {
chineseStr += cnNums[Number(n)] + cnDecUnits[i];
}
}
}
if (chineseStr == '') {
chineseStr += cnNums[0] + cnIntLast + cnInteger;
} else if (decimalNum == '' || /^0*$/.test(decimalNum)) {
chineseStr += cnInteger;
}
return chineseStr;
}
//数组转成字符串
export const filterValue = (arr, field, isTrans) => {
isTrans = typeof isTrans !== 'undefined' ? isTrans : false;
var idr = [];
for (var i = 0; i < arr.length; i++) {
idr.push(arr[i][field]);
}
if (isTrans === true) {
return idr.join(",");
} else {
return idr;
}
}
/**
* 和PHP一样的时间戳格式化函数
* @param {string} format 格式
* @param {int} timestamp 要格式化的时间 默认为当前时间
* @return {string} 格式化的时间字符串
*/
export const date = (format, timestamp) => {
if (timestamp < 90000000000) { timestamp *= 1000; }
var a, jsdate = ((timestamp) ? new Date(timestamp) : new Date());
var pad = function (n, c) {
if ((n = n + "").length < c) {
return new Array(++c - n.length).join("0") + n;
} else {
return n;
}
};
var txt_weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var txt_ordin = { 1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st" };
var txt_months = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var f = {
// Day
d: function () { return pad(f.j(), 2) },
D: function () { return f.l().substr(0, 3) },
j: function () { return jsdate.getDate() },
l: function () { return txt_weekdays[f.w()] },
N: function () { return f.w() + 1 },
S: function () { return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th' },
w: function () { return jsdate.getDay() },
z: function () { return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0 },
// Week
W: function () {
var a = f.z(),
b = 364 + f.L() - a;
var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;
if (b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b) {
return 1;
} else {
if (a <= 2 && nd >= 4 && a >= (6 - nd)) {
nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
return date("W", Math.round(nd2.getTime() / 1000));
} else {
return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
}
}
},
// Month
F: function () { return txt_months[f.n()] },
m: function () { return pad(f.n(), 2) },
M: function () { return f.F().substr(0, 3) },
n: function () { return jsdate.getMonth() + 1 },
t: function () {
var n;
if ((n = jsdate.getMonth() + 1) === 2) {
return 28 + f.L();
} else {
if (n & 1 && n < 8 || !(n & 1) && n > 7) {
return 31;
} else {
return 30;
}
}
},
// Year
L: function () { var y = f.Y(); return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0 },
//o not supported yet
Y: function () { return jsdate.getFullYear() },
y: function () { return (jsdate.getFullYear() + "").slice(2) },
// Time
a: function () { return jsdate.getHours() > 11 ? "pm" : "am" },
A: function () { return f.a().toUpperCase() },
B: function () {
// peter paul koch:
var off = (jsdate.getTimezoneOffset() + 60) * 60;
var theSeconds = (jsdate.getHours() * 3600) + (jsdate.getMinutes() * 60) + jsdate.getSeconds() + off;
var beat = Math.floor(theSeconds / 86.4);
if (beat > 1000) beat -= 1000;
if (beat < 0) beat += 1000;
if ((String(beat)).length === 1) beat = "00" + beat;
if ((String(beat)).length === 2) beat = "0" + beat;
return beat;
},
g: function () { return jsdate.getHours() % 12 || 12 },
G: function () { return jsdate.getHours() },
h: function () { return pad(f.g(), 2) },
H: function () { return pad(jsdate.getHours(), 2) },
i: function () { return pad(jsdate.getMinutes(), 2) },
s: function () { return pad(jsdate.getSeconds(), 2) },
//u not supported yet
// Timezone
//e not supported yet
//I not supported yet
O: function () {
var t = pad(Math.abs(jsdate.getTimezoneOffset() / 60 * 100), 4);
if (jsdate.getTimezoneOffset() > 0) t = "-" + t;
else t = "+" + t;
return t;
},
P: function () { var O = f.O(); return (O.substr(0, 3) + ":" + O.substr(3, 2)) },
//T not supported yet
//Z not supported yet
// Full Date/Time
c: function () { return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P() },
//r not supported yet
U: function () { return Math.round(jsdate.getTime() / 1000) }
};
let ret = '';
return format.replace(/[\\]?([a-zA-Z])/g, function (t, s) {
if (t !== s) {
// escaped
ret = s;
} else if (f[s]) {
// a date function exists
ret = f[s]();
} else {
// nothing special
ret = s;
}
return ret;
});
}
// 判断是否为今天
export const isToday = (time) => {
return new Date().getTime() - time < 86400000;
}
/*
* 返回文件大小
* @params 数字
* */
export const getFileSize = (size) => {
let units = new Array(' B', ' KB', ' MB', ' GB', ' TB');
let filesize = size + "B";
for (let i = 0; size >= 1024 && i < 4; i++) {
size /= 1024;
// filesize = `${size.toFixed(2)}${units[i + 1]}`;
if (size % 1 === 0) {
filesize = `${Math.floor(size)}${units[i + 1]}`;
} else if (size.toFixed(2) % 1 === 0) {
filesize = `${size.toFixed(1)}${units[i + 1]}`;
} else {
filesize = `${size.toFixed(2)}${units[i + 1]}`;
}
}
return filesize;
}
export const getDom = (obj, el) => {
let dom = {};
const query = uni.createSelectorQuery().in(obj);
setTimeout(() => {
query.select(el).boundingClientRect();
query.exec(data => {
dom = data[0];
});
}, 10)
return dom;
}
export const findObjectByField = (data, field, val, refield) => {
const result = data.find(obj => obj.field == val); // 使用 Array.prototype.find() 方法查找满足条件的子数组
if (result) {
return refield ? result[refield] : result; // 如果提供了字段参数,返回该字段的值;否则返回整个子数组对象
} else {
return null; // 没有找到满足条件的子数组,返回 null
}
}
/** 搜索数组*/
export const searchObject = (array, field, keywords) => {
if (typeof array !== 'object') {
return false;
} else {
var found = [];
for (var i = 0; array.length > i; i++) {
if (typeof field == 'object') {
for (var j = 0; field.length > j; j++) {
var field_str = field[j];
var str = array[i][field_str];
// 只需要匹配到一个即可
if (str.indexOf(keywords) != -1) {
found.push(array[i]);
break;
}
}
} else {
var str = array[i][field];
if (str.indexOf(keywords) != -1) {
found.push(array[i]);
}
}
}
return found;
}
}
// 合并两个数组并去除重复
export const mergeArrays = (arr1, arr2) => {
// 将两个数组合并为一个新数组
const merged = arr1.concat(arr2);
// 创建一个 Set 来去除重复项
const set = new Set(merged.map(JSON.stringify));
// 将 Set 转换回数组
const unique = Array.from(set).map(JSON.parse);
// 返回去重后的数组
return unique;
}
// 两个二维数组取交集
export const intersection = (arr1, arr2) => {
// 使用 Set 将 arr1 中的每个数组转换为字符串
const set = new Set(arr1.map(JSON.stringify));
// 使用 filter 方法过滤出和 arr1 中的每个元素相同的元素
const result = arr2.filter(item => set.has(JSON.stringify(item)));
return result;
}
export const difference = (arr1, arr2) => {
// 使用 Set 将 arr2 中的每个数组转换为字符串
const set = new Set(arr2.map(JSON.stringify));
// 使用 filter 方法过滤出不在 arr2 中的元素
const result = arr1.filter(item => !set.has(JSON.stringify(item)));
// 将 result 中的每个数组转换回对象
return result;
}
// 获取消息类型
export const getMsgType = (type, callVideo) => {
let msgName = '[暂不支持的消息类型]';
switch (type) {
case 'image':
msgName = '[图片]';
break;
case 'voice':
msgName = '[语音]';
break;
case 'video':
msgName = '[视频]';
break;
case 'file':
msgName = '[文件]';
break;
case 'webrtc':
if (callVideo) {
msgName = '[正在请求与您视频通话]';
} else {
msgName = '[正在请求与您语音通话]';
}
break;
}
return msgName;
}
export const useVibrate = () => {
const vibrate = () => {
// #ifdef APP-PLUS || MP-WEIXIN
uni.vibrateShort()
// #endif
}
return { vibrate }
}
export const getRemainingDays = (data) => {
const targetTimestamp = data * 1000;
// 1. 获取当前时间(毫秒级)
const currentTime = Date.now();
// 2. 计算时间差(目标时间 - 当前时间)
const timeDiff = targetTimestamp - currentTime;
// 3. 处理“目标时间已过期”的情况
if (timeDiff <= 0) {
return 0; // 已过期,剩余天数为 0
}
// 4. 时间差转为天数(1天 = 24小时 × 60分钟 × 60秒 × 1000毫秒)
const oneDayMs = 24 * 60 * 60 * 1000;
// 用 Math.ceil 向上取整(如剩余1.2天,按2天算;若需向下取整用 Math.floor)
const remainingDays = Math.ceil(timeDiff / oneDayMs);
return remainingDays;
}