fork-reap-design
Version:
A high quality UI components Library with Vue.js
481 lines (462 loc) • 13.1 kB
JavaScript
/**
* @author jonasli
* @module 常用工具类
* @date 2017/03/24
*/
;
export const getUUID = () => {
let d = new Date().getTime();
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x7) | 0x8).toString(16);
});
return uuid;
};
// 去除字符串空格 Make sure we trim BOM and NBSP
export const trim = value => (value === null ? '' : `${value}`.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''));
// 去除富文本空格、回车, 但是不能删除img标签
export const trimEditor = (value) => {
if (!value) {
return '';
}
return value
.replace(/<[^(>|img)]+>/g, '')
.replace(/ /g, '')
.replace(/(^\s+)|(\s+$)/g, '');
};
// 获取字符串长度, 不包含标签
export const getTextLen = (value) => {
if (!value) {
return 0;
}
return value.replace(/<[^>]+>/g, '').length;
};
export const filterXSS = (e) => {
if (!e) return e;
for (; e !== unescape(e);) e = unescape(e);
for (
let r = ['<', '>', '\'', '"', '%3c', '%3e', '%27', '%22', '%253c', '%253e', '%2527', '%2522'],
n = [
'<',
'>',
''',
'"',
'%26%23x3c%3B',
'%26%23x3e%3B',
'%26%23x27%3B',
'%26%23x22%3B',
'%2526%2523x3c%253B',
'%2526%2523x3e%253B',
'%2526%2523x27%253B',
'%2526%2523x22%253B',
],
a = 0;
a < r.length;
a++
) e = e.replace(new RegExp(r[a], 'gi'), n[a]);
return e;
};
export const getCookie = (b) => {
let a;
return filterXSS((a = document.cookie.match(RegExp(`(^|;\\s*)${b}=([^;]*)(;|$)`))) ? unescape(a[2]) : null);
};
export const setTitle = (b) => {
// var isAndroid = navigator.userAgent.indexOf('Android') > -1;
document.title = b;
};
/**
* 配置节流函数
* @param {[Function]} fn [要执行的函数]
* @param {[Number]} delay [延迟执行的毫秒数]
* @param {[Number]} mustRun [至少多久执行一次]
* @return {[Function]} [节流函数]
*/
export const throttle = (fn, wait, mustRun) => {
let timeout;
let startTime = new Date();
return function () {
const context = this;
// eslint-disable-next-line prefer-rest-params
const args = arguments;
const curTime = new Date();
clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if (curTime - startTime >= mustRun) {
fn.apply(context, args);
startTime = curTime;
// 没达到触发间隔,重新设定定时器
} else {
timeout = setTimeout(fn, wait);
}
};
};
const format = value => (value >= 10 ? value : `0${value}`);
const weeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
/**
* 时间格式化
* count number 当前日期的几天后
*/
export const dateFormat = (time, type, count) => {
let date = '';
if (!time) {
// time 不存在 使用当前日期
date = new Date();
} else {
// time存在 使用参数中的time 毫秒单位
date = new Date(time);
}
// count存在获取当前日期后的count天
if (count) {
date.setDate(date.getDate() + count);
}
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const second = date.getSeconds();
const week = date.getDay();
let result;
switch (type) {
case 0: // 01-05
result = `${format(month)}-${format(day)}`;
break;
case 1: // 11:12
result = `${format(hours)}:${format(minutes)}`;
break;
case 2: // 2015-01-05
result = `${year}-${format(month)}-${format(day)}`;
break;
case 3: // 2015-01-05 11:12
result = `${year}-${format(month)}-${format(day)} ${format(hours)}:${format(minutes)}`;
break;
case 4: // 2015-01-05 11:12:06
result = `${year}-${format(month)}-${format(day)} ${format(hours)}:${format(minutes)}:${format(second)}`;
break;
case 5: // 2015-01-05 周二
result = `${year}-${format(month)}-${format(day)} ${weeks[week]}`;
break;
case 6: // 11:12:06
result = `${format(hours)}:${format(minutes)}:${format(second)}`;
break;
case 7: // 2015-01-05
result = `${year}-${month}-${day}`;
break;
}
return result;
};
export const getSecond = (time) => {
const arr = time.split(':');
let str = 0;
$.each(arr, (i, n) => {
switch (i) {
case 0:
str += n * 3600;
break;
case 1:
str += n * 60;
break;
case 2:
str += n;
break;
}
});
return str;
};
/**
* 获取是否早退
* count number 时间
*/
export const isEarly = (time, delay) => {
const curTime = dateFormat(null, 6);
if (!time) {
return false;
}
if (getSecond(curTime) < getSecond(time) - delay * 60) {
// 早退
return true;
}
return false;
};
/**
* 文件大小格式化
*/
export const prettyBytes = (num) => {
if (isNaN(num)) {
return '';
// throw new TypeError('Expected a number');
}
const neg = num < 0;
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
if (neg) {
num = -num;
}
// by jonasli 2016-12-30 11:08:31 解决微信文件同步有时间差 只有url没有size的bug
if (num === 0) {
return '';
}
if (num < 1) {
return `${(neg ? '-' : '') + num}B`;
}
const exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1);
// eslint-disable-next-line no-restricted-properties
num = (num / Math.pow(1000, exponent)).toFixed(2) * 1;
const unit = units[exponent];
// feat: remove number and prettyBytes of space
return (neg ? '-' : '') + num + unit;
};
/*
* 检测浏览器是否缩放
*/
export const detectZoom = () => {
let ratio = 0;
const { screen } = window;
if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
} else if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
} else {
ratio = 0;
}
if (ratio) {
ratio = Math.round(ratio * 100);
}
return ratio;
};
/**
* 表格中文字溢出显示省略号,划过显示气泡,气泡中显示全部内容
* params 需要显示的内容(icon不传时就是展示文字,滑过的气泡也展示文字)
* icon 显示的icon, params是滑过icon显示的内容
* eg : icon的格式 icon = [h('Icon', {
'props': {
'type': 'ios-help-outline',
'size': 16,
't3': true
}
}, str)];
* h createElement的别名
*/
export const elliptical = (h, params, icon) => {
let content = params;
let onlytext = true;
if (icon) {
content = icon;
onlytext = false;
}
return h(
'Tooltip',
{
props: {
trigger: 'hover',
placement: 'top-start',
},
class: {
'd-b': onlytext,
},
},
[
h(
'div',
{
class: {
// 列表中的文字样式
'one-line': onlytext,
},
},
content,
),
h(
'div',
{
slot: 'content',
},
[
h(
'div',
{
// 气泡中的文字折行
class: {
'line-wrap': true,
},
},
params,
),
],
),
],
);
};
// 合并单元格操作
// className 需要合并的单元格的类名 默认是js-rowspan
// keys 需要合并的列的key值
// add by adahuhu 2018-08-07
export const mergeCell = (className, keys) => {
if (keys.length) {
for (let idx = 0, keyLen = keys.length; idx < keyLen; idx++) {
const name = `.${className}[data-key=${keys[idx]}]`;
// 全部需要合并的单元格
const cellsEle = $(name);
// 存储已经合并过的类名
const objectidMap = {};
for (let i = 0, len = cellsEle.length; i < len; i++) {
// 需要合并的单元格 共同类 js-rowspan-${row.objectid}
const firstCell = $(cellsEle[i]);
const objid = firstCell.attr('data-objectid');
if (objid in objectidMap) {
continue;
} else {
firstCell.attr('data-index', 1);
const otherCells = cellsEle
.parent()
.parent()
.find(`[data-objectid=${objid}][data-index!=1]`);
const rows = +firstCell.attr('data-rows');
otherCells
.parent()
.parent()
.remove();
// 增加rowspan属性 合并单元格
firstCell
.parent()
.parent()
.attr('rowspan', rows);
objectidMap[objid] = 1;
}
}
}
}
};
// 合并单元格数据处理
// list 原始数据 需要合并的单元格数据 在sub_list里
// 双层数据->单层列表
// add by adahuhu 2018-08-07
export const cellListTrans = (list) => {
const tableList = [];
for (let i = 0, len = list.length; i < len; i++) {
const item = list[i];
const objExpSubList = JSON.parse(JSON.stringify(item));
delete objExpSubList.sub_list;
for (let j = 0, sublen = item.sub_list.length; j < sublen; j++) {
const subitem = item.sub_list[j];
const tmp = Object.assign(
{
rowspan: sublen,
},
objExpSubList,
);
Object.assign(tmp, subitem);
tableList.push(tmp);
}
}
return tableList;
};
// elm-ui options 下拉匹配异步,需要手动匹配
// add by zxd 2018-08-08
export const getSelectItem = (objectid, data, attr) => {
if (!attr) {
attr = 'objectid';
}
return data.filter((n) => {
if (n[attr] === objectid) {
return n;
}
})[0];
};
// json 预览
// add by adahuhu 2018-10-15 16:20:18
export const syntaxHighlight = (json) => {
if (json) {
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
return json.replace(
// eslint-disable-next-line no-useless-escape
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
(match) => {
let cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return `<span class="${cls}">${match}</span>`;
},
);
}
return '-';
};
// form 表单数据处理
// add by adahuhu 2018-10-25 19:02:43
export const onlyCopyValue = (obj) => {
if (obj && typeof obj === 'object') {
const tmp = {};
for (const attr in obj) {
const subobj = obj[attr];
// eslint-disable-next-line no-prototype-builtins
if (typeof subobj === 'object' && subobj.hasOwnProperty('value')) {
tmp[attr] = subobj.value;
} else {
tmp[attr] = subobj;
}
}
return tmp;
}
return obj;
};
/**
* formatSelect: iview 初始化Select组件 需要 value数组
* @param data {Object}: [{"label": "请假条","value": "1"}, {"label": "素质评价","value": "2"}]
* @return ids {Array}: ["1", "2", "3"]
* @update 2018/10/11 新增单选返回
*/
export const formatSelect = (data, total) => {
if (!Array.isArray(data)) return;
// 如果是单选
if (total === 1) {
return data[0].value;
}
return data.map(n => n.value);
};
/**
* instance 检测数值类型
* @update 2018/10/11 新增单选返回
*/
export const instance = data => Object.prototype.toString
.call(data)
.slice(8, -1)
.toLocaleLowerCase();
/**
* copyObject 简单对象的浅拷贝
* @param data {Object}: [{"label": "请假条","value": "1"}, {"label": "素质评价","value": "2"}]
* @return ids {Array}: ["1", "2", "3"]
* @update 2018/10/11 新增单选返回
*/
export const copyObject = (data) => {
if (typeof data === 'object') {
return JSON.parse(JSON.stringify(data));
}
};
/**
* 设置unionid二维码样式
*/
export const qrcodeCss = () => 'data:text/css;base64,LmltcG93ZXJCb3ggLnFyY29kZSB7d2lkdGg6IDIwMHB4O30KLmltcG93ZXJCb3ggLnRpdGxlIHtkaXNwbGF5OiBub25lO30KLmltcG93ZXJCb3ggLmluZm8ge2Rpc3BsYXk6IG5vbmU7fQouc3RhdHVzX2ljb24ge2Rpc3BsYXk6IG5vbmV9Ci5pbXBvd2VyQm94IC5zdGF0dXMge3RleHQtYWxpZ246IGNlbnRlcjt9';
export const getQuery = (name) => {
const result = location.search.match(new RegExp(`[?&]${name}=([^&]+)`, 'i'));
if (result === null || result.length < 1) {
return '';
}
return filterXSS(result[1]);
};