|
|
|
/**
|
|
|
|
* 基本函数
|
|
|
|
* Create By GUY 2014\11\17
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
import _ from "./1.lodash";
|
|
|
|
import { Widget } from "./4.widget";
|
|
|
|
import { createWidget } from "./5.inject";
|
|
|
|
import { prepares, _global } from "./0.foundation";
|
|
|
|
import { CRYPT_TYPE, aesDecrypt, aesEncrypt } from "./structure/aes";
|
|
|
|
import { Date as DateEnum, getMonthDays } from "./func/date";
|
|
|
|
|
|
|
|
const lodashFns = {};
|
|
|
|
|
|
|
|
function traverse(func, context) {
|
|
|
|
return function (value, key, obj) {
|
|
|
|
return func.call(context, key, value, obj);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function _apply(name) {
|
|
|
|
return function () {
|
|
|
|
return _[name](...arguments);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function _applyFunc(name) {
|
|
|
|
return function () {
|
|
|
|
const args = Array.prototype.slice.call(arguments, 0);
|
|
|
|
args[1] = _.isFunction(args[1]) ? traverse(args[1], args[2]) : args[1];
|
|
|
|
|
|
|
|
return _[name](...args);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function assert(v, is) {
|
|
|
|
if (isFunction(is)) {
|
|
|
|
if (!is(v)) {
|
|
|
|
throw new Error(`${v} error`);
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!isArray(is)) {
|
|
|
|
is = [is];
|
|
|
|
}
|
|
|
|
if (!deepContains(is, v)) {
|
|
|
|
throw new Error(`${v} error`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function warn(message) {
|
|
|
|
console.warn(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function UUID() {
|
|
|
|
const f = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
|
|
|
|
let str = "";
|
|
|
|
for (let i = 0; i < 16; i++) {
|
|
|
|
const r = _global.parseInt(f.length * Math.random(), 10);
|
|
|
|
str += f[r];
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isWidget(widget) {
|
|
|
|
return widget instanceof Widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createWidgets(items, options, context) {
|
|
|
|
if (!isArray(items)) {
|
|
|
|
throw new Error("items must be array", items);
|
|
|
|
}
|
|
|
|
if (isWidget(options)) {
|
|
|
|
context = options;
|
|
|
|
options = {};
|
|
|
|
} else {
|
|
|
|
options || (options = {});
|
|
|
|
}
|
|
|
|
|
|
|
|
return map(flatten(items), (i, item) => createWidget(item, deepClone(options), context));
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createItems(data, innerAttr, outerAttr) {
|
|
|
|
innerAttr = isArray(innerAttr) ? innerAttr : makeArray(flatten(data).length, innerAttr || {});
|
|
|
|
outerAttr = isArray(outerAttr) ? outerAttr : makeArray(flatten(data).length, outerAttr || {});
|
|
|
|
|
|
|
|
return map(data, (i, item) => {
|
|
|
|
if (isArray(item)) {
|
|
|
|
return createItems(item, innerAttr, outerAttr);
|
|
|
|
}
|
|
|
|
if (item instanceof Widget) {
|
|
|
|
return extend({}, innerAttr.shift(), outerAttr.shift(), {
|
|
|
|
type: null,
|
|
|
|
el: item,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (innerAttr[0] instanceof Widget) {
|
|
|
|
outerAttr.shift();
|
|
|
|
|
|
|
|
return extend({}, item, {
|
|
|
|
el: innerAttr.shift(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (item.el instanceof Widget) {
|
|
|
|
innerAttr.shift();
|
|
|
|
|
|
|
|
return extend({}, outerAttr.shift(), { type: null }, item);
|
|
|
|
}
|
|
|
|
if (item.el) {
|
|
|
|
return extend({}, outerAttr.shift(), item, {
|
|
|
|
el: extend({}, innerAttr.shift(), item.el),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return extend({}, outerAttr.shift(), {
|
|
|
|
el: extend({}, innerAttr.shift(), item),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// 用容器包装items
|
|
|
|
export function packageItems(items, layouts) {
|
|
|
|
for (let i = layouts.length - 1; i >= 0; i--) {
|
|
|
|
items = map(items, (k, it) =>
|
|
|
|
extend({}, layouts[i], {
|
|
|
|
items: [
|
|
|
|
extend({}, layouts[i].el, {
|
|
|
|
el: it,
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function formatEL(obj) {
|
|
|
|
if (obj && !obj.type && obj.el) {
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
el: obj,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// 剥开EL
|
|
|
|
export function stripEL(obj) {
|
|
|
|
return (obj.type && obj) || obj.el || obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function trans2Element(widgets) {
|
|
|
|
return map(widgets, (i, wi) => wi.element);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 集合相关方法
|
|
|
|
_.each(["where", "findWhere", "invoke", "pluck", "shuffle", "sample", "toArray", "size"], name => {
|
|
|
|
lodashFns[name] = _apply(name);
|
|
|
|
});
|
|
|
|
_.each(
|
|
|
|
[
|
|
|
|
"get",
|
|
|
|
"set",
|
|
|
|
"each",
|
|
|
|
"map",
|
|
|
|
"reduce",
|
|
|
|
"reduceRight",
|
|
|
|
"find",
|
|
|
|
"filter",
|
|
|
|
"reject",
|
|
|
|
"every",
|
|
|
|
"all",
|
|
|
|
"some",
|
|
|
|
"any",
|
|
|
|
"max",
|
|
|
|
"min",
|
|
|
|
"sortBy",
|
|
|
|
"groupBy",
|
|
|
|
"indexBy",
|
|
|
|
"countBy",
|
|
|
|
"partition",
|
|
|
|
"clamp",
|
|
|
|
],
|
|
|
|
name => {
|
|
|
|
if (name === "any") {
|
|
|
|
lodashFns[name] = _applyFunc("some");
|
|
|
|
} else {
|
|
|
|
lodashFns[name] = _applyFunc(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
export const where = lodashFns.where;
|
|
|
|
export const findWhere = lodashFns.findWhere;
|
|
|
|
export const invoke = lodashFns.invoke;
|
|
|
|
export const pluck = lodashFns.pluck;
|
|
|
|
export const shuffle = lodashFns.shuffle;
|
|
|
|
export const sample = lodashFns.sample;
|
|
|
|
export const toArray = lodashFns.toArray;
|
|
|
|
export const size = lodashFns.size;
|
|
|
|
export const get = lodashFns.get;
|
|
|
|
export const set = lodashFns.set;
|
|
|
|
export const each = lodashFns.each;
|
|
|
|
export const map = lodashFns.map;
|
|
|
|
export const reduce = lodashFns.reduce;
|
|
|
|
export const reduceRight = lodashFns.reduceRight;
|
|
|
|
export const find = lodashFns.find;
|
|
|
|
export const filter = lodashFns.filter;
|
|
|
|
export const reject = lodashFns.reject;
|
|
|
|
export const every = lodashFns.every;
|
|
|
|
export const all = lodashFns.all;
|
|
|
|
export const some = lodashFns.some;
|
|
|
|
export const any = lodashFns.any;
|
|
|
|
export const max = lodashFns.max;
|
|
|
|
export const min = lodashFns.min;
|
|
|
|
export const sortBy = lodashFns.sortBy;
|
|
|
|
export const groupBy = lodashFns.groupBy;
|
|
|
|
export const indexBy = lodashFns.indexBy;
|
|
|
|
export const countBy = lodashFns.countBy;
|
|
|
|
export const partition = lodashFns.partition;
|
|
|
|
export const clamp = lodashFns.clamp;
|
|
|
|
|
|
|
|
// 数数
|
|
|
|
export function count(from, to, predicate) {
|
|
|
|
let t;
|
|
|
|
if (predicate) {
|
|
|
|
for (t = from; t < to; t++) {
|
|
|
|
predicate(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return to - from;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 倒数
|
|
|
|
export function inverse(from, to, predicate) {
|
|
|
|
return count(to, from, predicate);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function firstKey(obj) {
|
|
|
|
let res = undefined;
|
|
|
|
any(obj, (key, value) => {
|
|
|
|
res = key;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function lastKey(obj) {
|
|
|
|
let res = undefined;
|
|
|
|
each(obj, (key, value) => {
|
|
|
|
res = key;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function firstObject(obj) {
|
|
|
|
let res = undefined;
|
|
|
|
any(obj, (key, value) => {
|
|
|
|
res = value;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function lastObject(obj) {
|
|
|
|
let res = undefined;
|
|
|
|
each(obj, (key, value) => {
|
|
|
|
res = value;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function concat(obj1, obj2) {
|
|
|
|
if (isKey(obj1)) {
|
|
|
|
return map([].slice.apply(arguments), (idx, v) => v).join("");
|
|
|
|
}
|
|
|
|
if (isArray(obj1)) {
|
|
|
|
return _.concat.apply([], arguments);
|
|
|
|
}
|
|
|
|
if (isObject(obj1)) {
|
|
|
|
return extend.apply({}, arguments);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function backEach(obj, predicate, context) {
|
|
|
|
predicate = iteratee(predicate, context);
|
|
|
|
for (let index = obj.length - 1; index >= 0; index--) {
|
|
|
|
predicate(index, obj[index], obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function backAny(obj, predicate, context) {
|
|
|
|
predicate = iteratee(predicate, context);
|
|
|
|
for (let index = obj.length - 1; index >= 0; index--) {
|
|
|
|
if (predicate(index, obj[index], obj)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function backEvery(obj, predicate, context) {
|
|
|
|
predicate = iteratee(predicate, context);
|
|
|
|
for (let index = obj.length - 1; index >= 0; index--) {
|
|
|
|
if (!predicate(index, obj[index], obj)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function backFindKey(obj, predicate, context) {
|
|
|
|
predicate = iteratee(predicate, context);
|
|
|
|
const objKeys = keys(obj);
|
|
|
|
let key;
|
|
|
|
for (let i = objKeys.length - 1; i >= 0; i--) {
|
|
|
|
key = objKeys[i];
|
|
|
|
if (predicate(obj[key], key, obj)) {
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function backFind(obj, predicate, context) {
|
|
|
|
let key;
|
|
|
|
if (isArray(obj)) {
|
|
|
|
key = findLastIndex(obj, predicate, context);
|
|
|
|
} else {
|
|
|
|
key = backFindKey(obj, predicate, context);
|
|
|
|
}
|
|
|
|
if (key !== void 0 && key !== -1) {
|
|
|
|
return obj[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function remove(obj, target, context) {
|
|
|
|
const targetIsFunction = isFunction(target);
|
|
|
|
target = targetIsFunction || isArray(target) ? target : [target];
|
|
|
|
let i;
|
|
|
|
if (isArray(obj)) {
|
|
|
|
for (i = 0; i < obj.length; i++) {
|
|
|
|
if (
|
|
|
|
(targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) ||
|
|
|
|
(!targetIsFunction && contains(target, obj[i]))
|
|
|
|
) {
|
|
|
|
obj.splice(i--, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
each(obj, (i, v) => {
|
|
|
|
if (
|
|
|
|
(targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) ||
|
|
|
|
(!targetIsFunction && contains(target, obj[i]))
|
|
|
|
) {
|
|
|
|
delete obj[i];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function removeAt(obj, index) {
|
|
|
|
index = isArray(index) ? index : [index];
|
|
|
|
const objIsArray = isArray(obj);
|
|
|
|
let i;
|
|
|
|
for (i = 0; i < index.length; i++) {
|
|
|
|
if (objIsArray) {
|
|
|
|
obj[index[i]] = "$deleteIndex";
|
|
|
|
} else {
|
|
|
|
delete obj[index[i]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (objIsArray) {
|
|
|
|
remove(obj, "$deleteIndex");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function string2Array(str) {
|
|
|
|
return str.split("&-&");
|
|
|
|
}
|
|
|
|
|
|
|
|
export function array2String(array) {
|
|
|
|
return array.join("&-&");
|
|
|
|
}
|
|
|
|
|
|
|
|
export function abc2Int(string) {
|
|
|
|
let idx = 0;
|
|
|
|
const start = "A",
|
|
|
|
str = string.toUpperCase();
|
|
|
|
for (let i = 0, len = str.length; i < len; ++i) {
|
|
|
|
idx = str.charAt(i).charCodeAt(0) - start.charCodeAt(0) + 26 * idx + 1;
|
|
|
|
if (idx > (2147483646 - str.charAt(i).charCodeAt(0) + start.charCodeAt(0)) / 26) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function int2Abc(num) {
|
|
|
|
const DIGITS = [
|
|
|
|
"A",
|
|
|
|
"B",
|
|
|
|
"C",
|
|
|
|
"D",
|
|
|
|
"E",
|
|
|
|
"F",
|
|
|
|
"G",
|
|
|
|
"H",
|
|
|
|
"I",
|
|
|
|
"J",
|
|
|
|
"K",
|
|
|
|
"L",
|
|
|
|
"M",
|
|
|
|
"N",
|
|
|
|
"O",
|
|
|
|
"P",
|
|
|
|
"Q",
|
|
|
|
"R",
|
|
|
|
"S",
|
|
|
|
"T",
|
|
|
|
"U",
|
|
|
|
"V",
|
|
|
|
"W",
|
|
|
|
"X",
|
|
|
|
"Y",
|
|
|
|
"Z",
|
|
|
|
];
|
|
|
|
let idx = num,
|
|
|
|
str = "";
|
|
|
|
if (num === 0) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
while (idx !== 0) {
|
|
|
|
let t = idx % 26;
|
|
|
|
if (t === 0) {
|
|
|
|
t = 26;
|
|
|
|
}
|
|
|
|
str = DIGITS[t - 1] + str;
|
|
|
|
idx = (idx - t) / 26;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 数组相关的方法
|
|
|
|
_.each(
|
|
|
|
[
|
|
|
|
"first",
|
|
|
|
"initial",
|
|
|
|
"last",
|
|
|
|
"rest",
|
|
|
|
"compact",
|
|
|
|
"flatten",
|
|
|
|
"without",
|
|
|
|
"union",
|
|
|
|
"intersection",
|
|
|
|
"difference",
|
|
|
|
"zip",
|
|
|
|
"unzip",
|
|
|
|
"object",
|
|
|
|
"indexOf",
|
|
|
|
"lastIndexOf",
|
|
|
|
"sortedIndex",
|
|
|
|
"range",
|
|
|
|
"take",
|
|
|
|
"takeRight",
|
|
|
|
"uniqBy",
|
|
|
|
],
|
|
|
|
name => {
|
|
|
|
lodashFns[name] = _apply(name);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
_.each(["findIndex", "findLastIndex"], name => {
|
|
|
|
lodashFns[name] = _applyFunc(name);
|
|
|
|
});
|
|
|
|
export const first = lodashFns.first;
|
|
|
|
export const initial = lodashFns.initial;
|
|
|
|
export const last = lodashFns.last;
|
|
|
|
export const rest = lodashFns.rest;
|
|
|
|
export const compact = lodashFns.compact;
|
|
|
|
export const flatten = lodashFns.flatten;
|
|
|
|
export const without = lodashFns.without;
|
|
|
|
export const union = lodashFns.union;
|
|
|
|
export const intersection = lodashFns.intersection;
|
|
|
|
export const difference = lodashFns.difference;
|
|
|
|
export const zip = lodashFns.zip;
|
|
|
|
export const unzip = lodashFns.unzip;
|
|
|
|
export const object = lodashFns.object;
|
|
|
|
export const indexOf = lodashFns.indexOf;
|
|
|
|
export const lastIndexOf = lodashFns.lastIndexOf;
|
|
|
|
export const sortedIndex = lodashFns.sortedIndex;
|
|
|
|
export const range = lodashFns.range;
|
|
|
|
export const take = lodashFns.take;
|
|
|
|
export const takeRight = lodashFns.takeRight;
|
|
|
|
export const uniqBy = lodashFns.uniqBy;
|
|
|
|
export const findIndex = lodashFns.findIndex;
|
|
|
|
export const findLastIndex = lodashFns.findLastIndex;
|
|
|
|
|
|
|
|
// 构建一个长度为length的数组
|
|
|
|
export function makeArray(length, value) {
|
|
|
|
const res = [];
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
|
if (isNull(value)) {
|
|
|
|
res.push(i);
|
|
|
|
} else {
|
|
|
|
res.push(deepClone(value));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function makeObject(array, value) {
|
|
|
|
const map = {};
|
|
|
|
for (let i = 0; i < array.length; i++) {
|
|
|
|
if (isNull(value)) {
|
|
|
|
map[array[i]] = array[i];
|
|
|
|
} else if (isFunction(value)) {
|
|
|
|
map[array[i]] = value(i, array[i]);
|
|
|
|
} else {
|
|
|
|
map[array[i]] = deepClone(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function makeArrayByArray(array, value) {
|
|
|
|
const res = [];
|
|
|
|
if (!array) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
for (let i = 0, len = array.length; i < len; i++) {
|
|
|
|
if (isArray(array[i])) {
|
|
|
|
res.push(makeArrayByArray(array[i], value));
|
|
|
|
} else {
|
|
|
|
res.push(deepClone(value));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function uniq(array, isSorted, iteratee, context) {
|
|
|
|
if (array === null) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
if (!isBoolean(isSorted)) {
|
|
|
|
context = iteratee;
|
|
|
|
iteratee = isSorted;
|
|
|
|
isSorted = false;
|
|
|
|
}
|
|
|
|
iteratee && (iteratee = traverse(iteratee, context));
|
|
|
|
|
|
|
|
return _.uniq.call(_, array, isSorted, iteratee, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 对象相关方法
|
|
|
|
_.each(
|
|
|
|
[
|
|
|
|
"keys",
|
|
|
|
"allKeys",
|
|
|
|
"values",
|
|
|
|
"pairs",
|
|
|
|
"invert",
|
|
|
|
"create",
|
|
|
|
"functions",
|
|
|
|
"extend",
|
|
|
|
"extendOwn",
|
|
|
|
"defaults",
|
|
|
|
"clone",
|
|
|
|
"property",
|
|
|
|
"propertyOf",
|
|
|
|
"matcher",
|
|
|
|
"isEqual",
|
|
|
|
"isMatch",
|
|
|
|
"isEmpty",
|
|
|
|
"isElement",
|
|
|
|
"isNumber",
|
|
|
|
"isString",
|
|
|
|
"isArray",
|
|
|
|
"isObject",
|
|
|
|
"isPlainObject",
|
|
|
|
"isArguments",
|
|
|
|
"isFunction",
|
|
|
|
"isFinite",
|
|
|
|
"isBoolean",
|
|
|
|
"isDate",
|
|
|
|
"isRegExp",
|
|
|
|
"isError",
|
|
|
|
"isNaN",
|
|
|
|
"isUndefined",
|
|
|
|
"zipObject",
|
|
|
|
"cloneDeep",
|
|
|
|
"pickBy",
|
|
|
|
],
|
|
|
|
name => {
|
|
|
|
lodashFns[name] = _apply(name);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
export const keys = lodashFns.keys;
|
|
|
|
export const allKeys = lodashFns.allKeys;
|
|
|
|
export const values = lodashFns.values;
|
|
|
|
export const pairs = lodashFns.pairs;
|
|
|
|
export const invert = lodashFns.invert;
|
|
|
|
export const create = lodashFns.create;
|
|
|
|
export const functions = lodashFns.functions;
|
|
|
|
export const extend = lodashFns.extend;
|
|
|
|
export const extendOwn = lodashFns.extendOwn;
|
|
|
|
export const defaults = lodashFns.defaults;
|
|
|
|
export const clone = lodashFns.clone;
|
|
|
|
export const property = lodashFns.property;
|
|
|
|
export const propertyOf = lodashFns.propertyOf;
|
|
|
|
export const matcher = lodashFns.matcher;
|
|
|
|
export const isEqual = lodashFns.isEqual;
|
|
|
|
export const isMatch = lodashFns.isMatch;
|
|
|
|
export const isEmpty = lodashFns.isEmpty;
|
|
|
|
export const isElement = lodashFns.isElement;
|
|
|
|
export const isNumber = lodashFns.isNumber;
|
|
|
|
export const isString = lodashFns.isString;
|
|
|
|
export const isArray = lodashFns.isArray;
|
|
|
|
export const isObject = lodashFns.isObject;
|
|
|
|
export const isPlainObject = lodashFns.isPlainObject;
|
|
|
|
export const isArguments = lodashFns.isArguments;
|
|
|
|
export const isFunction = lodashFns.isFunction;
|
|
|
|
export const isFinite = lodashFns.isFinite;
|
|
|
|
export const isBoolean = lodashFns.isBoolean;
|
|
|
|
export const isDate = lodashFns.isDate;
|
|
|
|
export const isRegExp = lodashFns.isRegExp;
|
|
|
|
export const isError = lodashFns.isError;
|
|
|
|
export const isNaN = lodashFns.isNaN;
|
|
|
|
export const isUndefined = lodashFns.isUndefined;
|
|
|
|
export const zipObject = lodashFns.zipObject;
|
|
|
|
export const cloneDeep = lodashFns.cloneDeep;
|
|
|
|
export const pickBy = lodashFns.pickBy;
|
|
|
|
|
|
|
|
_.each(["mapObject", "findKey", "pick", "omit", "tap"], name => {
|
|
|
|
lodashFns[name] = _applyFunc(name);
|
|
|
|
});
|
|
|
|
export const mapObject = lodashFns.mapObject;
|
|
|
|
export const findKey = lodashFns.findKey;
|
|
|
|
export const pick = lodashFns.pick;
|
|
|
|
export const omit = lodashFns.omit;
|
|
|
|
export const tap = lodashFns.tap;
|
|
|
|
|
|
|
|
export function inherit(sp, overrides) {
|
|
|
|
function sb() {
|
|
|
|
return sp.apply(this, arguments);
|
|
|
|
}
|
|
|
|
function F() {}
|
|
|
|
const spp = sp.prototype;
|
|
|
|
F.prototype = spp;
|
|
|
|
sb.prototype = new F();
|
|
|
|
sb.superclass = spp;
|
|
|
|
extend(sb.prototype, overrides, {
|
|
|
|
superclass: sp,
|
|
|
|
});
|
|
|
|
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function init() {
|
|
|
|
// 先把准备环境准备好
|
|
|
|
while (prepares && prepares.length > 0) {
|
|
|
|
prepares.shift()();
|
|
|
|
}
|
|
|
|
while (_global.___fineuiExposedFunction && _global.___fineuiExposedFunction.length > 0) {
|
|
|
|
_global.___fineuiExposedFunction.shift()();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_global.BI) {
|
|
|
|
_global.BI.initialized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function has(obj, keys) {
|
|
|
|
if (isArray(keys)) {
|
|
|
|
if (keys.length === 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return every(keys, (i, key) => _.has(obj, key));
|
|
|
|
}
|
|
|
|
|
|
|
|
return _.has(...arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function freeze(value) {
|
|
|
|
// 在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 TypeError
|
|
|
|
// 在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回
|
|
|
|
if (Object.freeze && isObject(value)) {
|
|
|
|
return Object.freeze(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 数字和字符串可以作为key
|
|
|
|
export function isKey(key) {
|
|
|
|
return isNumber(key) || (isString(key) && key.length > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 忽略大小写的等于
|
|
|
|
export function isCapitalEqual(a, b) {
|
|
|
|
a = isNull(a) ? a : `${a}`.toLowerCase();
|
|
|
|
b = isNull(b) ? b : `${b}`.toLowerCase();
|
|
|
|
|
|
|
|
return isEqual(a, b);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isWidthOrHeight(w) {
|
|
|
|
if (typeof w === "number") {
|
|
|
|
return w >= 0;
|
|
|
|
} else if (typeof w === "string") {
|
|
|
|
return /^\d{1,3}(\.\d)?%$/.test(w) || w === "auto" || /^\d+(\.\d+)?px$/.test(w) || /^calc/.test(w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNotNull(obj) {
|
|
|
|
return !isNull(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNull(obj) {
|
|
|
|
return typeof obj === "undefined" || obj === null;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isEmptyArray(arr) {
|
|
|
|
return isArray(arr) && isEmpty(arr);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNotEmptyArray(arr) {
|
|
|
|
return isArray(arr) && !isEmpty(arr);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isEmptyObject(obj) {
|
|
|
|
return isEqual(obj, {});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNotEmptyObject(obj) {
|
|
|
|
return isPlainObject(obj) && !isEmptyObject(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isWindow(obj) {
|
|
|
|
return obj !== null && obj === obj.window;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isPromise(obj) {
|
|
|
|
return !!obj && (isObject(obj) || isFunction(obj)) && isFunction(obj.then);
|
|
|
|
}
|
|
|
|
|
|
|
|
export const deepClone = _.cloneDeep;
|
|
|
|
export const deepExtend = _.merge;
|
|
|
|
|
|
|
|
export function isDeepMatch(object, attrs) {
|
|
|
|
const attrsKeys = keys(attrs),
|
|
|
|
length = attrsKeys.length;
|
|
|
|
if (object === null) {
|
|
|
|
return !length;
|
|
|
|
}
|
|
|
|
const obj = Object(object);
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
|
|
const key = attrsKeys[i];
|
|
|
|
if (!isEqual(attrs[key], obj[key]) || !(key in obj)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function contains(obj, target, fromIndex) {
|
|
|
|
if (!_.isArrayLike(obj)) obj = values(obj);
|
|
|
|
|
|
|
|
return indexOf(obj, target, typeof fromIndex === "number" && fromIndex) >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deepContains(obj, copy) {
|
|
|
|
if (isObject(copy)) {
|
|
|
|
return any(obj, (i, v) => isEqual(v, copy));
|
|
|
|
}
|
|
|
|
|
|
|
|
return contains(obj, copy);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deepIndexOf(obj, target) {
|
|
|
|
for (let i = 0; i < obj.length; i++) {
|
|
|
|
if (isEqual(target, obj[i])) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deepRemove(obj, target) {
|
|
|
|
let done = false;
|
|
|
|
let i;
|
|
|
|
if (isArray(obj)) {
|
|
|
|
for (i = 0; i < obj.length; i++) {
|
|
|
|
if (isEqual(target, obj[i])) {
|
|
|
|
obj.splice(i--, 1);
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
each(obj, (i, v) => {
|
|
|
|
if (isEqual(target, obj[i])) {
|
|
|
|
delete obj[i];
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return done;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deepWithout(obj, target) {
|
|
|
|
if (isArray(obj)) {
|
|
|
|
const result = [];
|
|
|
|
for (let i = 0; i < obj.length; i++) {
|
|
|
|
if (!isEqual(target, obj[i])) {
|
|
|
|
result.push(obj[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
const result = {};
|
|
|
|
each(obj, (i, v) => {
|
|
|
|
if (!isEqual(target, obj[i])) {
|
|
|
|
result[i] = v;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deepUnique(array) {
|
|
|
|
const result = [];
|
|
|
|
each(array, (i, item) => {
|
|
|
|
if (!deepContains(result, item)) {
|
|
|
|
result.push(item);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 比较两个对象得出不一样的key值
|
|
|
|
export function deepDiff(object, other) {
|
|
|
|
object || (object = {});
|
|
|
|
other || (other = {});
|
|
|
|
const result = [];
|
|
|
|
const used = [];
|
|
|
|
for (const b in object) {
|
|
|
|
if (has(object, b)) {
|
|
|
|
if (!isEqual(object[b], other[b])) {
|
|
|
|
result.push(b);
|
|
|
|
}
|
|
|
|
used.push(b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const b in other) {
|
|
|
|
if (has(other, b) && !contains(used, b)) {
|
|
|
|
result.push(b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 通用方法
|
|
|
|
_.each(["uniqueId", "result", "chain", "iteratee", "unescape", "before", "after", "chunk"], name => {
|
|
|
|
lodashFns[name] = (...args) => _[name](...args);
|
|
|
|
});
|
|
|
|
export const uniqueId = lodashFns.uniqueId;
|
|
|
|
export const result = lodashFns.result;
|
|
|
|
export const chain = lodashFns.chain;
|
|
|
|
export const iteratee = lodashFns.iteratee;
|
|
|
|
export const unescape = lodashFns.unescape;
|
|
|
|
export const before = lodashFns.before;
|
|
|
|
export const after = lodashFns.after;
|
|
|
|
export const chunk = lodashFns.chunk;
|
|
|
|
|
|
|
|
// 事件相关方法
|
|
|
|
_.each(["bind", "once", "partial", "debounce", "throttle", "delay", "defer", "wrap"], name => {
|
|
|
|
lodashFns[name] = (...args) => _[name](...args);
|
|
|
|
});
|
|
|
|
export const bind = lodashFns.bind;
|
|
|
|
export const once = lodashFns.once;
|
|
|
|
export const partial = lodashFns.partial;
|
|
|
|
export const debounce = lodashFns.debounce;
|
|
|
|
export const throttle = lodashFns.throttle;
|
|
|
|
export const delay = lodashFns.delay;
|
|
|
|
export const defer = lodashFns.defer;
|
|
|
|
export const wrap = lodashFns.wrap;
|
|
|
|
|
|
|
|
export const nextTick = (function () {
|
|
|
|
const callbacks = [];
|
|
|
|
let pending = false;
|
|
|
|
let timerFunc = void 0;
|
|
|
|
|
|
|
|
function nextTickHandler() {
|
|
|
|
pending = false;
|
|
|
|
const copies = callbacks.slice(0);
|
|
|
|
callbacks.length = 0;
|
|
|
|
for (let i = 0; i < copies.length; i++) {
|
|
|
|
copies[i]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof Promise !== "undefined") {
|
|
|
|
const p = Promise.resolve();
|
|
|
|
timerFunc = function timerFunc() {
|
|
|
|
p.then(nextTickHandler);
|
|
|
|
};
|
|
|
|
} else if (typeof MutationObserver !== "undefined") {
|
|
|
|
let counter = 1;
|
|
|
|
const observer = new MutationObserver(nextTickHandler);
|
|
|
|
const textNode = document.createTextNode(String(counter));
|
|
|
|
observer.observe(textNode, {
|
|
|
|
characterData: true,
|
|
|
|
});
|
|
|
|
timerFunc = function timerFunc() {
|
|
|
|
counter = (counter + 1) % 2;
|
|
|
|
textNode.data = String(counter);
|
|
|
|
};
|
|
|
|
} else if (typeof setImmediate !== "undefined") {
|
|
|
|
timerFunc = function timerFunc() {
|
|
|
|
setImmediate(nextTickHandler);
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
// Fallback to setTimeout.
|
|
|
|
timerFunc = function timerFunc() {
|
|
|
|
setTimeout(nextTickHandler, 0);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return function queueNextTick(cb) {
|
|
|
|
let _resolve = void 0;
|
|
|
|
const args = [].slice.call(arguments, 1);
|
|
|
|
callbacks.push(() => {
|
|
|
|
if (cb) {
|
|
|
|
try {
|
|
|
|
cb(...args);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
}
|
|
|
|
} else if (_resolve) {
|
|
|
|
_resolve(...args);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (!pending) {
|
|
|
|
pending = true;
|
|
|
|
timerFunc();
|
|
|
|
}
|
|
|
|
// $flow-disable-line
|
|
|
|
if (!cb && typeof Promise !== "undefined") {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
_resolve = resolve;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
|
|
|
|
// 数字相关方法
|
|
|
|
_.each(["random"], name => {
|
|
|
|
lodashFns[name] = _apply(name);
|
|
|
|
});
|
|
|
|
export const random = lodashFns.random;
|
|
|
|
|
|
|
|
export function parseInt(number) {
|
|
|
|
let radix = 10;
|
|
|
|
if (/^0x/g.test(number)) {
|
|
|
|
radix = 16;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
return _global.parseInt(number, radix);
|
|
|
|
} catch (e) {
|
|
|
|
throw new Error(`${number}parse int error`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function parseSafeInt(value) {
|
|
|
|
const MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
|
|
|
|
return value ? clamp(parseInt(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function parseFloat(number) {
|
|
|
|
try {
|
|
|
|
return _global.parseFloat(number);
|
|
|
|
} catch (e) {
|
|
|
|
throw new Error(`${number}parse float error`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNaturalNumber(number) {
|
|
|
|
return /^\d+$/.test(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isPositiveInteger(number) {
|
|
|
|
return /^\+?[1-9][0-9]*$/.test(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNegativeInteger(number) {
|
|
|
|
return /^-[1-9][0-9]*$/.test(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isInteger(number) {
|
|
|
|
return /^-?\d+$/.test(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNumeric(number) {
|
|
|
|
return !_global.isNaN(_global.parseFloat(number)) && _global.isFinite(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isFloat(number) {
|
|
|
|
return /^([+-]?)\d*\.\d+$/.test(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isOdd(number) {
|
|
|
|
if (!isInteger(number)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (number & 1) === 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isEven(number) {
|
|
|
|
if (!isInteger(number)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (number & 1) === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function sum(array, iteratee, context) {
|
|
|
|
let sum = 0;
|
|
|
|
each(array, (i, item) => {
|
|
|
|
if (iteratee) {
|
|
|
|
sum += Number(iteratee.apply(context, [i, item]));
|
|
|
|
} else {
|
|
|
|
sum += Number(item);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function average(array, iteratee, context) {
|
|
|
|
const sumResult = sum(array, iteratee, context);
|
|
|
|
|
|
|
|
return sumResult / array.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function trim(...args) {
|
|
|
|
return _.trim(...args);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function toUpperCase(string) {
|
|
|
|
return `${string}`.toLocaleUpperCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function toLowerCase(string) {
|
|
|
|
return `${string}`.toLocaleLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isEndWithBlank(string) {
|
|
|
|
return /(\s|\u00A0)$/.test(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isLiteral(exp) {
|
|
|
|
return /^\s?(true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/.test(exp);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function stripQuotes(str) {
|
|
|
|
const a = str.charCodeAt(0);
|
|
|
|
const b = str.charCodeAt(str.length - 1);
|
|
|
|
|
|
|
|
return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
|
|
|
|
}
|
|
|
|
|
|
|
|
// background-color => backgroundColor
|
|
|
|
export function camelize(str) {
|
|
|
|
return str.replace(/-(.)/g, (_, character) => character.toUpperCase());
|
|
|
|
}
|
|
|
|
|
|
|
|
// backgroundColor => background-color
|
|
|
|
export function hyphenate(str) {
|
|
|
|
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isNotEmptyString(str) {
|
|
|
|
return isString(str) && !isEmpty(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isEmptyString(str) {
|
|
|
|
return isString(str) && isEmpty(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 通用解密方法
|
|
|
|
* @param type 解密方式
|
|
|
|
* @param text 文本
|
|
|
|
* @param key 种子
|
|
|
|
* @return {*}
|
|
|
|
*/
|
|
|
|
export function encrypt(type, text, key) {
|
|
|
|
switch (type) {
|
|
|
|
case CRYPT_TYPE.AES:
|
|
|
|
default:
|
|
|
|
return aesEncrypt(text, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 通用解密方法
|
|
|
|
* @param type 解密方式
|
|
|
|
* @param text 文本
|
|
|
|
* @param key 种子
|
|
|
|
* @return {*}
|
|
|
|
*/
|
|
|
|
export function decrypt(type, text, key) {
|
|
|
|
switch (type) {
|
|
|
|
case CRYPT_TYPE.AES:
|
|
|
|
default:
|
|
|
|
return aesDecrypt(text, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 对字符串中的'和\做编码处理
|
|
|
|
* @static
|
|
|
|
* @param {String} string 要做编码处理的字符串
|
|
|
|
* @return {String} 编码后的字符串
|
|
|
|
*/
|
|
|
|
export function escape(string) {
|
|
|
|
return string.replace(/('|\\)/g, "\\$1");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 让字符串通过指定字符做补齐的函数
|
|
|
|
*
|
|
|
|
* var s = BI.leftPad('123', 5, '0');//s的值为:'00123'
|
|
|
|
*
|
|
|
|
* @static
|
|
|
|
* @param {String} val 原始值
|
|
|
|
* @param {Number} size 总共需要的位数
|
|
|
|
* @param {String} ch 用于补齐的字符
|
|
|
|
* @return {String} 补齐后的字符串
|
|
|
|
*/
|
|
|
|
export function leftPad(val, size, ch) {
|
|
|
|
let result = String(val);
|
|
|
|
if (!ch) {
|
|
|
|
ch = " ";
|
|
|
|
}
|
|
|
|
while (result.length < size) {
|
|
|
|
result = ch + result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 对字符串做替换的函数
|
|
|
|
*
|
|
|
|
* var cls = 'my-class', text = 'Some text';
|
|
|
|
* var res = BI.format('<div class="{0}">{1}</div>', cls, text);
|
|
|
|
* //res的值为:'<div class="my-class">Some text</div>';
|
|
|
|
*
|
|
|
|
* @static
|
|
|
|
* @param {String} format 要做替换的字符串,替换字符串1,替换字符串2...
|
|
|
|
* @return {String} 做了替换后的字符串
|
|
|
|
*/
|
|
|
|
export function format(format) {
|
|
|
|
const args = Array.prototype.slice.call(arguments, 1);
|
|
|
|
|
|
|
|
return format.replace(/\{(\d+)\}/g, (m, i) => args[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否是闰年
|
|
|
|
* @param year
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
export function isLeapYear(year) {
|
|
|
|
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 检测是否在有效期
|
|
|
|
*
|
|
|
|
* @param YY 年
|
|
|
|
* @param MM 月
|
|
|
|
* @param DD 日
|
|
|
|
* @param minDate '1900-01-01'
|
|
|
|
* @param maxDate '2099-12-31'
|
|
|
|
* @returns {Array} 若无效返回无效状态,数组第一位为无效属性,第二位缺省为超下限,1为超上限
|
|
|
|
*/
|
|
|
|
export function checkDateVoid(YY, MM, DD, minDate, maxDate) {
|
|
|
|
let back = [];
|
|
|
|
YY = YY | 0;
|
|
|
|
MM = MM | 0;
|
|
|
|
DD = DD | 0;
|
|
|
|
minDate = isString(minDate) ? minDate.match(/\d+/g) : minDate;
|
|
|
|
maxDate = isString(maxDate) ? maxDate.match(/\d+/g) : maxDate;
|
|
|
|
if (YY < minDate[0]) {
|
|
|
|
back = ["y"];
|
|
|
|
} else if (YY > maxDate[0]) {
|
|
|
|
back = ["y", 1];
|
|
|
|
} else if (YY >= minDate[0] && YY <= maxDate[0]) {
|
|
|
|
if (YY == minDate[0]) {
|
|
|
|
if (MM < minDate[1]) {
|
|
|
|
back = ["m"];
|
|
|
|
} else if (MM == minDate[1]) {
|
|
|
|
if (DD < minDate[2]) {
|
|
|
|
back = ["d"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (YY == maxDate[0]) {
|
|
|
|
if (MM > maxDate[1]) {
|
|
|
|
back = ["m", 1];
|
|
|
|
} else if (MM == maxDate[1]) {
|
|
|
|
if (DD > maxDate[2]) {
|
|
|
|
back = ["d", 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return back;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function checkDateLegal(str) {
|
|
|
|
const ar = str.match(/\d+/g);
|
|
|
|
const YY = ar[0] | 0,
|
|
|
|
MM = ar[1] | 0,
|
|
|
|
DD = ar[2] | 0;
|
|
|
|
if (ar.length <= 1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (ar.length <= 2) {
|
|
|
|
return MM >= 1 && MM <= 12;
|
|
|
|
}
|
|
|
|
const MD = DateEnum._MD.slice(0);
|
|
|
|
MD[1] = isLeapYear(YY) ? 29 : 28;
|
|
|
|
|
|
|
|
return MM >= 1 && MM <= 12 && DD <= MD[MM - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 解析日期时间字符串
|
|
|
|
*
|
|
|
|
* @param str
|
|
|
|
* @param fmt
|
|
|
|
* @returns {Date|Date}
|
|
|
|
* 年月日缺省值为当前日期, 时分秒缺省值为0
|
|
|
|
*/
|
|
|
|
export function parseDateTime(str, fmt) {
|
|
|
|
const today = getDate();
|
|
|
|
let y;
|
|
|
|
let m;
|
|
|
|
let d;
|
|
|
|
// wei : 对于fmt为‘YYYYMM’或者‘YYYYMMdd’的格式,str的值为类似'201111'的形式,因为年月之间没有分隔符,所以正则表达式分割无效,导致bug7376。
|
|
|
|
const a = str.split(/\W+/);
|
|
|
|
if (fmt.toLowerCase() === "%y%x" || fmt.toLowerCase() === "%y%x%d") {
|
|
|
|
const yearlength = 4;
|
|
|
|
const otherlength = 2;
|
|
|
|
a[0] = str.substring(0, yearlength);
|
|
|
|
a[1] = str.substring(yearlength, yearlength + otherlength);
|
|
|
|
a[2] = str.substring(yearlength + otherlength, yearlength + otherlength * 2);
|
|
|
|
}
|
|
|
|
const b = fmt.match(/%./g);
|
|
|
|
let i = 0,
|
|
|
|
j = 0;
|
|
|
|
let hr = 0;
|
|
|
|
let min = 0;
|
|
|
|
let sec = 0;
|
|
|
|
for (i = 0; i < a.length; ++i) {
|
|
|
|
switch (b[i]) {
|
|
|
|
case "%d":
|
|
|
|
case "%e":
|
|
|
|
d = _global.parseInt(a[i], 10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "%X":
|
|
|
|
m = _global.parseInt(a[i], 10) - 1;
|
|
|
|
break;
|
|
|
|
case "%x":
|
|
|
|
m = _global.parseInt(a[i], 10) - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "%Y":
|
|
|
|
case "%y":
|
|
|
|
y = _global.parseInt(a[i], 10);
|
|
|
|
y < 100 && (y += y > 29 ? 1900 : 2000);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "%b":
|
|
|
|
case "%B":
|
|
|
|
for (j = 0; j < 12; ++j) {
|
|
|
|
if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) {
|
|
|
|
m = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "%H":
|
|
|
|
case "%I":
|
|
|
|
case "%k":
|
|
|
|
case "%l":
|
|
|
|
hr = _global.parseInt(a[i], 10);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "%P":
|
|
|
|
case "%p":
|
|
|
|
if (/pm/i.test(a[i]) && hr < 12) {
|
|
|
|
hr += 12;
|
|
|
|
} else if (/am/i.test(a[i]) && hr >= 12) {
|
|
|
|
hr -= 12;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "%Q":
|
|
|
|
case "%q":
|
|
|
|
m = (_global.parseInt(a[i], 10) - 1) * 3;
|
|
|
|
break;
|
|
|
|
case "%M":
|
|
|
|
min = _global.parseInt(a[i], 10);
|
|
|
|
break;
|
|
|
|
case "%S":
|
|
|
|
sec = _global.parseInt(a[i], 10);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// if (!a[i]) {
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
if (_global.isNaN(y)) {
|
|
|
|
y = today.getFullYear();
|
|
|
|
}
|
|
|
|
if (_global.isNaN(m)) {
|
|
|
|
m = today.getMonth();
|
|
|
|
}
|
|
|
|
if (_global.isNaN(d)) {
|
|
|
|
d = Math.min(getMonthDays(getDate(y, m)), today.getDate());
|
|
|
|
}
|
|
|
|
if (_global.isNaN(hr)) {
|
|
|
|
hr = today.getHours();
|
|
|
|
}
|
|
|
|
if (_global.isNaN(min)) {
|
|
|
|
min = today.getMinutes();
|
|
|
|
}
|
|
|
|
if (_global.isNaN(sec)) {
|
|
|
|
sec = today.getSeconds();
|
|
|
|
}
|
|
|
|
if (y !== 0) {
|
|
|
|
return getDate(y, m, d, hr, min, sec);
|
|
|
|
}
|
|
|
|
y = 0;
|
|
|
|
m = -1;
|
|
|
|
d = 0;
|
|
|
|
for (i = 0; i < a.length; ++i) {
|
|
|
|
if (a[i].search(/[a-zA-Z]+/) !== -1) {
|
|
|
|
let t = -1;
|
|
|
|
for (j = 0; j < 12; ++j) {
|
|
|
|
if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) {
|
|
|
|
t = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (t !== -1) {
|
|
|
|
if (m !== -1) {
|
|
|
|
d = m + 1;
|
|
|
|
}
|
|
|
|
m = t;
|
|
|
|
}
|
|
|
|
} else if (_global.parseInt(a[i], 10) <= 12 && m === -1) {
|
|
|
|
m = a[i] - 1;
|
|
|
|
} else if (_global.parseInt(a[i], 10) > 31 && y === 0) {
|
|
|
|
y = _global.parseInt(a[i], 10);
|
|
|
|
y < 100 && (y += y > 29 ? 1900 : 2000);
|
|
|
|
} else if (d === 0) {
|
|
|
|
d = a[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (y === 0) {
|
|
|
|
y = today.getFullYear();
|
|
|
|
}
|
|
|
|
if (m === -1) {
|
|
|
|
m = today.getMonth();
|
|
|
|
}
|
|
|
|
if (m !== -1 && d !== 0) {
|
|
|
|
return getDate(y, m, d, hr, min, sec);
|
|
|
|
}
|
|
|
|
|
|
|
|
return today;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getDate(...args) {
|
|
|
|
const length = args.length;
|
|
|
|
let dt;
|
|
|
|
switch (length) {
|
|
|
|
// new Date()
|
|
|
|
case 0:
|
|
|
|
dt = new Date();
|
|
|
|
break;
|
|
|
|
// new Date(long)
|
|
|
|
case 1:
|
|
|
|
dt = new Date(args[0]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month)
|
|
|
|
case 2:
|
|
|
|
dt = new Date(args[0], args[1]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day)
|
|
|
|
case 3:
|
|
|
|
dt = new Date(args[0], args[1], args[2]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour)
|
|
|
|
case 4:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute)
|
|
|
|
case 5:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute, second)
|
|
|
|
case 6:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute, second, millisecond)
|
|
|
|
case 7:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dt = new Date();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (isNotNull(BI.timeZone) && (arguments.length === 0 || (arguments.length === 1 && isNumber(arguments[0])))) {
|
|
|
|
const localTime = dt.getTime();
|
|
|
|
// BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准
|
|
|
|
const localOffset = dt.getTimezoneOffset() * 60000; // 获得当地时间偏移的毫秒数
|
|
|
|
const utc = localTime + localOffset; // utc即GMT时间标准时区
|
|
|
|
|
|
|
|
return new Date(utc + BI.timeZone); // + Pool.timeZone.offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dt;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getTime() {
|
|
|
|
const length = arguments.length;
|
|
|
|
const args = arguments;
|
|
|
|
let dt;
|
|
|
|
switch (length) {
|
|
|
|
// new Date()
|
|
|
|
case 0:
|
|
|
|
dt = new Date();
|
|
|
|
break;
|
|
|
|
// new Date(long)
|
|
|
|
case 1:
|
|
|
|
dt = new Date(args[0]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month)
|
|
|
|
case 2:
|
|
|
|
dt = new Date(args[0], args[1]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day)
|
|
|
|
case 3:
|
|
|
|
dt = new Date(args[0], args[1], args[2]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour)
|
|
|
|
case 4:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute)
|
|
|
|
case 5:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute, second)
|
|
|
|
case 6:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
|
|
break;
|
|
|
|
// new Date(year, month, day, hour, minute, second, millisecond)
|
|
|
|
case 7:
|
|
|
|
dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dt = new Date();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (isNotNull(BI.timeZone)) {
|
|
|
|
// BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准
|
|
|
|
return dt.getTime() - BI.timeZone - new Date().getTimezoneOffset() * 60000;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dt.getTime();
|
|
|
|
}
|