1079 lines
23 KiB
JavaScript
1079 lines
23 KiB
JavaScript
|
|
|
|||
|
|
/*******************************************************************************
|
|||
|
|
*
|
|||
|
|
* Nx数据结构相关方法
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
* 2021.12.10
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
require( "base64" );
|
|||
|
|
require( "rseed" );
|
|||
|
|
const md = require( "md5" );
|
|||
|
|
|
|||
|
|
// 默认小数位数
|
|||
|
|
const DefPN = 2;
|
|||
|
|
|
|||
|
|
var NxMath = cc.Class( {
|
|||
|
|
|
|||
|
|
name: "NxMath",
|
|||
|
|
|
|||
|
|
// 创建
|
|||
|
|
ctor: function() {
|
|||
|
|
|
|||
|
|
this.uuTracker = 1000;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:基本的数据类型判断
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 数字
|
|||
|
|
numGood: function( _n ) {
|
|||
|
|
return _n === +_n;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 正数
|
|||
|
|
numPositive: function( _n, _inZero /* true */ ) {
|
|||
|
|
|
|||
|
|
if( !this.numGood( _n ) ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
return ( _inZero !== false ) ? ( _n >= 0 ) : ( _n > 0 );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 为X的数
|
|||
|
|
numEqual: function( _n, _t ) {
|
|||
|
|
return this.numGood( _n ) && ( _n == _t );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 大于X的数
|
|||
|
|
numGreater: function( _n, _t ) {
|
|||
|
|
return this.numGood( _n ) && ( _n > _t );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 小于X的数
|
|||
|
|
numLess: function( _n, _t ) {
|
|||
|
|
return this.numGood( _n ) && ( _n < _t );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 范围内的数
|
|||
|
|
numInRange: function( _n, _range /* [x,y] */ ) {
|
|||
|
|
|
|||
|
|
if( !this.arrGood( _range ) || _range.length != 2 ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
return this.numGood( _n ) && ( _n >= _range[ 0 ] && _n <= _range[ 1 ] );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 数字修正
|
|||
|
|
numFix: function( _num, _def = 0 ) {
|
|||
|
|
|
|||
|
|
let ret = _num;
|
|||
|
|
if( !nx.dt.numGood( ret ) ) {
|
|||
|
|
ret = _def;
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 浮点精确度
|
|||
|
|
toFixedDecimal: function( _n ) {
|
|||
|
|
|
|||
|
|
if( !this.numGood( _n ) ) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 多保留一位来保证浮点数精度
|
|||
|
|
let fixedNumber = ( _n * 100 ).toFixed( 1 );
|
|||
|
|
return Number( ( parseInt( fixedNumber ) / 100 ).toFixed( 2 ) );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 布尔
|
|||
|
|
isBool: function( _b ) {
|
|||
|
|
return _b === !!_b;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 字节数格式化
|
|||
|
|
formatBytes: function( bytes, decimals = 2 ) {
|
|||
|
|
if( bytes === 0 ) return '0 Bytes';
|
|||
|
|
const k = 1024;
|
|||
|
|
const dm = decimals & lt; 0 ? 0 : decimals;
|
|||
|
|
const sizes = [ 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' ];
|
|||
|
|
const i = Math.floor( Math.log( bytes ) / Math.log( k ) );
|
|||
|
|
return parseFloat( ( bytes / Math.pow( k, i ) ).toFixed( dm ) ) + ' ' + sizes[ i ];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:方法的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 有效方法
|
|||
|
|
fnGood: function( _f ) {
|
|||
|
|
return _f != null && typeof _f === "function";
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空方法
|
|||
|
|
fnEmpty: function() {
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空方法报错
|
|||
|
|
fnEmptyError: function( _fn ) {
|
|||
|
|
if( this.fnGood( _fn ) ) {
|
|||
|
|
nx.error( "方法已经存在:", _fn.name );
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 安全回调
|
|||
|
|
fnInvoke: function( _fn ) {
|
|||
|
|
|
|||
|
|
if( !this.fnGood( _fn ) ) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( CC_DEBUG ) {
|
|||
|
|
_fn.apply( null, Array.prototype.slice.call( arguments, 1 ) );
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
try {
|
|||
|
|
_fn.apply( null, Array.prototype.slice.call( arguments, 1 ) );
|
|||
|
|
} catch( e ) {
|
|||
|
|
nx.error( "[异常]:" + ( e ? e.message + "\n" + e.stack : "未知错误!" ) );
|
|||
|
|
if( e && cc.sys.isNative && window && window.__errorHandler ) {
|
|||
|
|
window.__errorHandler( e.message, "", "", e.stack );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:字符串的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 字符串
|
|||
|
|
strGood: function( _s ) {
|
|||
|
|
return _s === _s + "";
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 非空字符串
|
|||
|
|
strNEmpty: function( _s ) {
|
|||
|
|
return this.strGood( _s ) && _s != "";
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空字符串
|
|||
|
|
strEmpty: function( _s ) {
|
|||
|
|
return !this.strNEmpty( _s );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 字符串去空格
|
|||
|
|
strTrim: function( _s ) {
|
|||
|
|
if( this.strNEmpty( _s ) ) {
|
|||
|
|
return _s.replace( /^(\s|\u00A0)+/, "" ).replace( /(\s|\u00A0)+$/, "" );
|
|||
|
|
}
|
|||
|
|
return "";
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 获取字节长度
|
|||
|
|
strBytes: function( _s ) {
|
|||
|
|
|
|||
|
|
if( !this.strNEmpty( _s ) ) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var len = 0;
|
|||
|
|
|
|||
|
|
for( var i = 0; i < _s.length; i++ ) {
|
|||
|
|
var a = _s.charAt( i );
|
|||
|
|
if( a.match( /[^\x00-\xff]/ig ) != null ) {
|
|||
|
|
len += 2;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
len += 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return len;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 字符串省略截取
|
|||
|
|
strCut: function( str, len ) {
|
|||
|
|
if( !str || !len ) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
var build = "";
|
|||
|
|
for( var i = 0; i < str.length && len > 0; i++ ) {
|
|||
|
|
build += str.substr( i, 1 );
|
|||
|
|
len -= str.charCodeAt( i ) > 127 ? 2 : 1;
|
|||
|
|
}
|
|||
|
|
if( build.length < str.length )
|
|||
|
|
build += "..";
|
|||
|
|
return build;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 字符串省略截取(逆向)
|
|||
|
|
strCutR: function( str, len ) {
|
|||
|
|
|
|||
|
|
if( !str || !len ) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var build = "";
|
|||
|
|
for( var i = str.length - 1; i >= 0 && len > 0; i-- ) {
|
|||
|
|
build = str.substr( i, 1 ) + build;
|
|||
|
|
len -= str.charCodeAt( i ) > 127 ? 2 : 1;
|
|||
|
|
}
|
|||
|
|
if( build.length < str.length ) {
|
|||
|
|
build = "****" + build;
|
|||
|
|
}
|
|||
|
|
return build;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* key#value属性串转数组
|
|||
|
|
* @param {*} _sp
|
|||
|
|
*/
|
|||
|
|
pairSplit: function( _sp ) {
|
|||
|
|
|
|||
|
|
let a = _sp.split( '#' );
|
|||
|
|
if( a.length != 2 ) {
|
|||
|
|
nx.error( "pairSplit失败,格式无效!", _sp );
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let k = a[ 0 ];
|
|||
|
|
let v = a[ 1 ];
|
|||
|
|
|
|||
|
|
// 如果值是数字,那么转为数字
|
|||
|
|
if( Number( v ) == v ) {
|
|||
|
|
v = Number( v );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { [ k ]: v };
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 特定key#value属性串转数组
|
|||
|
|
* 用于统一拆分Array[String]数据
|
|||
|
|
* @param {*} _arr
|
|||
|
|
*/
|
|||
|
|
arrPairSplit: function( _arr ) {
|
|||
|
|
|
|||
|
|
let ret = [];
|
|||
|
|
if( this.arrEmpty( _arr ) ) {
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_arr.forEach( _sp => {
|
|||
|
|
let d = this.pairSplit( _sp );
|
|||
|
|
if( d ) {
|
|||
|
|
ret.push( d );
|
|||
|
|
}
|
|||
|
|
} );
|
|||
|
|
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 补零
|
|||
|
|
* @param num: 被操作数
|
|||
|
|
* @param n: 固定的总位数
|
|||
|
|
*/
|
|||
|
|
prefixZero: function( num, n ) {
|
|||
|
|
return ( Array( n ).join( 0 ) + num ).slice( -n );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 字符串替换
|
|||
|
|
* replaceAll
|
|||
|
|
*/
|
|||
|
|
replace: function( _str, _old, _new ) {
|
|||
|
|
return _str.replace( new RegExp( _old, "gm" ), _new );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:数组的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 数组
|
|||
|
|
arrGood: function( _a ) {
|
|||
|
|
return Object.prototype.toString.call( _a ) === "[object Array]";
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 非空数组
|
|||
|
|
arrNEmpty: function( _a ) {
|
|||
|
|
return this.arrGood( _a ) && ( _a.length > 0 );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空数组
|
|||
|
|
arrEmpty: function( _a ) {
|
|||
|
|
return !this.arrNEmpty( _a );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 是不是数组成员
|
|||
|
|
arrMember: function( _a, _m, _fn ) {
|
|||
|
|
|
|||
|
|
if( !this.arrNEmpty( _a ) ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_fn = _fn || function( _v ) {
|
|||
|
|
return _v == _m;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
for( let i = 0; i < _a.length; ++i ) {
|
|||
|
|
if( _fn( _a[ i ] ) ) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 合并数据[带关键字且不能重复]
|
|||
|
|
arrConcat: function( _a1, _a2 ) {
|
|||
|
|
|
|||
|
|
if( !this.arrGood( _a1 ) || !this.arrGood( _a2 ) ) {
|
|||
|
|
nx.error( "合并失败,参数不能为空!" );
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 合并Table绑定列表
|
|||
|
|
if( CC_DEBUG ) {
|
|||
|
|
|
|||
|
|
var _exist = function( _key ) {
|
|||
|
|
for( let k in _a1 ) {
|
|||
|
|
var m = _a1[ k ];
|
|||
|
|
if( m[ 0 ] == _key ) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
for( let i in _a2 ) {
|
|||
|
|
var binder = _a2[ i ];
|
|||
|
|
if( _exist( binder[ 0 ] ) ) {
|
|||
|
|
nx.error( "合并失败: %s,有重复关键字项!", binder[ 0 ] );
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _a1.concat( _a2 );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 从数组中删除
|
|||
|
|
arrDelete: function( _a, _fn, _once ) {
|
|||
|
|
|
|||
|
|
if( !this.arrNEmpty( _a ) ||
|
|||
|
|
!this.fnGood( _fn ) ) {
|
|||
|
|
return _a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var i = _a.length;
|
|||
|
|
while( i-- ) {
|
|||
|
|
if( _fn( _a[ i ] ) ) {
|
|||
|
|
_a.splice( i, 1 );
|
|||
|
|
if( _once != false ) {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _a;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 对象转数组对
|
|||
|
|
arrFromMap: function( _map ) {
|
|||
|
|
|
|||
|
|
if( !this.objGood( _map ) ) {
|
|||
|
|
nx.warn( "对象为空,转换失败!" );
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var pairs = [];
|
|||
|
|
for( let i in _map ) {
|
|||
|
|
pairs.push( [ i, _map[ i ] ] );
|
|||
|
|
}
|
|||
|
|
return pairs;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 数组比较(成员相同)
|
|||
|
|
arrCompare: function( _a, _b ) {
|
|||
|
|
|
|||
|
|
if( !this.arrGood( _a ) ||
|
|||
|
|
!this.arrGood( _b ) ||
|
|||
|
|
_a.length != _b.length ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for( let i in _a ) {
|
|||
|
|
if( !this.arrMember( _b, _a[ i ] ) ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:对象的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 创建一个UUID(运行时唯一)
|
|||
|
|
newUUID: function( _key ) {
|
|||
|
|
|
|||
|
|
if( !this.strNEmpty( _key ) ) {
|
|||
|
|
_key = "OBJ";
|
|||
|
|
}
|
|||
|
|
return _key + ( ++this.uuTracker );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 创建永不重复的Tag
|
|||
|
|
newTag: function( _key ) {
|
|||
|
|
let tag = this.md5( cc.sys.now().toString() );
|
|||
|
|
if( this.strEmpty( _key ) ) {
|
|||
|
|
return tag;
|
|||
|
|
}
|
|||
|
|
return _key + "." + tag;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空对象
|
|||
|
|
objGood: function( _o ) {
|
|||
|
|
return _o != null && typeof _o === "object" && Array.isArray( _o ) === false;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 非空对象
|
|||
|
|
objNEmpty: function( _o ) {
|
|||
|
|
|
|||
|
|
if( !this.objGood( _o ) ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Object.keys( _o ).length > 0;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 空对象
|
|||
|
|
objEmpty: function( _o ) {
|
|||
|
|
return !this.objNEmpty( _o );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 对象合并
|
|||
|
|
objConcat: function( _dic1, _dic2 ) {
|
|||
|
|
|
|||
|
|
if( !this.objGood( _dic1 ) ) {
|
|||
|
|
return this.objClone( _dic2 );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( !this.objGood( _dic1 ) ) {
|
|||
|
|
return this.objClone( _dic1 );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dic = this.objClone( _dic1 );
|
|||
|
|
for( let k in _dic2 ) {
|
|||
|
|
dic[ k ] = this.objClone( _dic2[ k ] );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dic;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 获取对象成员数量
|
|||
|
|
objLen: function( _dic ) {
|
|||
|
|
|
|||
|
|
if( !this.objGood( _dic ) ) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return Object.keys( _dic ).length;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 深复制
|
|||
|
|
objClone: function( _obj ) {
|
|||
|
|
|
|||
|
|
// 非对象直接使用返回
|
|||
|
|
if( !_obj || typeof ( _obj ) !== "object" ) {
|
|||
|
|
return _obj;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var out = ( _obj.constructor === Array ) ? [] : {};
|
|||
|
|
|
|||
|
|
var _clone = function( o, c ) {
|
|||
|
|
for( var i in o ) {
|
|||
|
|
if( o[ i ] && typeof o[ i ] === "object" ) {
|
|||
|
|
if( o[ i ].constructor === Array ) {
|
|||
|
|
c[ i ] = [];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
c[ i ] = {};
|
|||
|
|
}
|
|||
|
|
_clone( o[ i ], c[ i ] );
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
c[ i ] = o[ i ];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return c;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return _clone( _obj, out );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 复制属性到对象
|
|||
|
|
copyProperties: function( _object, _dic, _log = false ) {
|
|||
|
|
|
|||
|
|
if( !this.objGood( _object ) ||
|
|||
|
|
!this.objGood( _dic ) ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( _log ) {
|
|||
|
|
nx.debug( "[DT]属性更新:" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for( let k in _dic ) {
|
|||
|
|
_object[ k ] = this.objClone( _dic[ k ] );
|
|||
|
|
if( _log ) {
|
|||
|
|
nx.debug( "\t\t键值: %s", k );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:随机数的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 范围随机数
|
|||
|
|
randomRange( _min, _max ) {
|
|||
|
|
var Range = _max - _min;
|
|||
|
|
var Rand = Math.random();
|
|||
|
|
var num = _min + Math.round( Rand * Range ); //四舍五入
|
|||
|
|
return num;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:加密的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 获取md5
|
|||
|
|
md5: function( key ) {
|
|||
|
|
return md.hex_md5( key );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加密
|
|||
|
|
encode64: function( str, pwd ) {
|
|||
|
|
|
|||
|
|
str = Base64.encode( str );//Base64加密
|
|||
|
|
var prand = "";
|
|||
|
|
for( var i = 0; i < pwd.length; i++ ) {
|
|||
|
|
prand += pwd.charCodeAt( i ).toString();
|
|||
|
|
}
|
|||
|
|
var sPos = Math.floor( prand.length / 5 );
|
|||
|
|
var mult = parseInt( prand.charAt( sPos ) + prand.charAt( sPos * 2 ) + prand.charAt( sPos * 3 ) + prand.charAt( sPos * 4 ) + prand.charAt( sPos * 5 ) );
|
|||
|
|
var incr = Math.ceil( pwd.length / 2 );
|
|||
|
|
var modu = Math.pow( 2, 31 ) - 1;
|
|||
|
|
if( mult < 2 ) {
|
|||
|
|
alert( "Please choose a more complex or longer password." );
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
var salt = Math.round( Math.random() * 1000000000 ) % 100000000;
|
|||
|
|
prand += salt;
|
|||
|
|
while( prand.length > 10 ) {
|
|||
|
|
prand = ( parseInt( prand.substring( 0, 10 ) ) + parseInt( prand.substring( 10, prand.length ) ) ).toString();
|
|||
|
|
}
|
|||
|
|
prand = ( mult * prand + incr ) % modu;
|
|||
|
|
var enc_chr = "";
|
|||
|
|
var enc_str = "";
|
|||
|
|
for( var i = 0; i < str.length; i++ ) {
|
|||
|
|
enc_chr = parseInt( str.charCodeAt( i ) ^ Math.floor( ( prand / modu ) * 255 ) );
|
|||
|
|
if( enc_chr < 16 ) {
|
|||
|
|
enc_str += "0" + enc_chr.toString( 16 );
|
|||
|
|
}
|
|||
|
|
else enc_str += enc_chr.toString( 16 );
|
|||
|
|
prand = ( mult * prand + incr ) % modu;
|
|||
|
|
}
|
|||
|
|
salt = salt.toString( 16 );
|
|||
|
|
while( salt.length < 8 ) salt = "0" + salt;
|
|||
|
|
enc_str += salt;
|
|||
|
|
return enc_str;
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 解密
|
|||
|
|
decode64: function( str, pwd ) {
|
|||
|
|
|
|||
|
|
var prand = "";
|
|||
|
|
for( var i = 0; i < pwd.length; i++ ) {
|
|||
|
|
prand += pwd.charCodeAt( i ).toString();
|
|||
|
|
}
|
|||
|
|
var sPos = Math.floor( prand.length / 5 );
|
|||
|
|
var mult = parseInt( prand.charAt( sPos ) + prand.charAt( sPos * 2 ) + prand.charAt( sPos * 3 ) + prand.charAt( sPos * 4 ) + prand.charAt( sPos * 5 ) );
|
|||
|
|
var incr = Math.round( pwd.length / 2 );
|
|||
|
|
var modu = Math.pow( 2, 31 ) - 1;
|
|||
|
|
var salt = parseInt( str.substring( str.length - 8, str.length ), 16 );
|
|||
|
|
str = str.substring( 0, str.length - 8 );
|
|||
|
|
prand += salt;
|
|||
|
|
while( prand.length > 10 ) {
|
|||
|
|
prand = ( parseInt( prand.substring( 0, 10 ) ) + parseInt( prand.substring( 10, prand.length ) ) ).toString();
|
|||
|
|
}
|
|||
|
|
prand = ( mult * prand + incr ) % modu;
|
|||
|
|
var enc_chr = "";
|
|||
|
|
var enc_str = "";
|
|||
|
|
for( var i = 0; i < str.length; i += 2 ) {
|
|||
|
|
enc_chr = parseInt( parseInt( str.substring( i, i + 2 ), 16 ) ^ Math.floor( ( prand / modu ) * 255 ) );
|
|||
|
|
enc_str += String.fromCharCode( enc_chr );
|
|||
|
|
prand = ( mult * prand + incr ) % modu;
|
|||
|
|
}
|
|||
|
|
return Base64.decode( enc_str );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:JSON
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 安全执行(异常捕获)
|
|||
|
|
trycatch: function( _dosth, _error ) {
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
_dosth();
|
|||
|
|
}
|
|||
|
|
catch( e ) {
|
|||
|
|
nx.error( "[异常]:" + ( e ? e.message + "\n" + e.stack : "未知错误!" ) );
|
|||
|
|
if( _error ) { _error( e ); }
|
|||
|
|
if( e && cc.sys.isNative && window && window.__errorHandler ) {
|
|||
|
|
window.__errorHandler( e.message, "", "", e.stack );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// JSON压缩
|
|||
|
|
enjson: function( _object ) {
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
return JSON.stringify( _object );
|
|||
|
|
}
|
|||
|
|
catch( e ) {
|
|||
|
|
nx.error( "[异常]:" + ( e ? e.message + "\n" + e.stack : "未知错误!" ) );
|
|||
|
|
// if( e && cc.sys.isNative && window && window.__errorHandler ) {
|
|||
|
|
// window.__errorHandler( e.message, "", "", e.stack );
|
|||
|
|
// }
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// JSON解析
|
|||
|
|
dejson: function( _str ) {
|
|||
|
|
|
|||
|
|
// 空返回
|
|||
|
|
if( !this.strNEmpty( _str ) ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
return JSON.parse( _str );
|
|||
|
|
}
|
|||
|
|
catch( e ) {
|
|||
|
|
nx.error( "[异常]:" + ( e ? e.message + "\n" + e.stack : "未知错误!" ) );
|
|||
|
|
// if( e && cc.sys.isNative && window && window.__errorHandler ) {
|
|||
|
|
// window.__errorHandler( e.message, "", "", e.stack );
|
|||
|
|
// }
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:时间的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 秒级时间戳
|
|||
|
|
timeStamp: function() {
|
|||
|
|
return Math.floor( cc.sys.now() / 1000 );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化日期
|
|||
|
|
fmtDate: function( _date, _year = true ) {
|
|||
|
|
|
|||
|
|
_date = _date ? _date : new Date();
|
|||
|
|
if( this.numGood( _date ) ) {
|
|||
|
|
_date = new Date( _date );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _format = function( v ) {
|
|||
|
|
return ( v < 10 ) ? ( "0" + v ) : v;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if( !_year ) {
|
|||
|
|
return nx.text.formatS( "%s:%s",
|
|||
|
|
_format( _date.getMonth() + 1 ),
|
|||
|
|
_format( _date.getDate() ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nx.text.formatS( "%s-%s-%s",
|
|||
|
|
_format( _date.getFullYear() ),
|
|||
|
|
_format( _date.getMonth() + 1 ),
|
|||
|
|
_format( _date.getDate() ) );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化日期
|
|||
|
|
fmtDateLoc: function( _date, _year = true ) {
|
|||
|
|
|
|||
|
|
_date = _date ? _date : new Date();
|
|||
|
|
|
|||
|
|
if( !_year ) {
|
|||
|
|
return nx.text.formatS( "%s%s",
|
|||
|
|
nx.text.format( "month", _date.getMonth() + 1 ),
|
|||
|
|
nx.text.format( "day", _date.getDate() ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nx.text.formatS( "%s%s%s",
|
|||
|
|
nx.text.format( "year", _date.getFullYear() ),
|
|||
|
|
nx.text.format( "month", _date.getMonth() + 1 ),
|
|||
|
|
nx.text.format( "day", _date.getDate() ) );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化时间
|
|||
|
|
fmtTime: function( _date ) {
|
|||
|
|
|
|||
|
|
_date = _date ? _date : new Date();
|
|||
|
|
|
|||
|
|
var _format = function( v ) {
|
|||
|
|
return ( v < 10 ) ? ( "0" + v ) : v;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return nx.text.formatS( "%s:%s:%s",
|
|||
|
|
_format( _date.getHours() ),
|
|||
|
|
_format( _date.getMinutes() ),
|
|||
|
|
_format( _date.getSeconds() ) );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化时间
|
|||
|
|
fmtTimeFromSecs: function( _secs, _full = false ) {
|
|||
|
|
|
|||
|
|
if( !this.numPositive( _secs, false ) ) {
|
|||
|
|
return _full ? "00:00:00" : "00:00";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var f = function( v ) {
|
|||
|
|
return ( v < 10 ) ? ( "0" + v ) : v;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var h = Math.floor( _secs / 3600 );
|
|||
|
|
_secs = _secs % 3600;
|
|||
|
|
var m = Math.floor( _secs / 60 );
|
|||
|
|
var s = Math.floor( _secs % 60 );
|
|||
|
|
|
|||
|
|
// 完整版本
|
|||
|
|
if( _full ) {
|
|||
|
|
return nx.text.formatS( "%s:%s:%s", f( h ), f( m ), f( s ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 时:分:秒
|
|||
|
|
if( h > 0 ) {
|
|||
|
|
return nx.text.formatS( "%d:%s:%s", h, f( m ), f( s ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 分:秒
|
|||
|
|
if( m > 0 ) {
|
|||
|
|
return nx.text.formatS( "%s:%s", f( m ), f( s ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 秒
|
|||
|
|
return '00:' + f( s );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 计算剩余天数(向上取整)
|
|||
|
|
// _ts: 秒级时间戳
|
|||
|
|
getDaysFromNow: function( _ts ) {
|
|||
|
|
|
|||
|
|
let secs = Math.max( 0, _ts - ( cc.sys.now() / 1000 ) );
|
|||
|
|
let days = Math.ceil( secs / ( 24 * 3600 ) );
|
|||
|
|
return days;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:URL的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 格式化URL
|
|||
|
|
formatURL: function( _url, _args ) {
|
|||
|
|
|
|||
|
|
if( !this.strNEmpty( _url ) ) {
|
|||
|
|
nx.error( "WebTask:URL参数不能为空!" );
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( !this.objGood( _args ) ) {
|
|||
|
|
return encodeURI( _url );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var aline = "";
|
|||
|
|
for( var k in _args ) {
|
|||
|
|
aline += ( aline == "" ) ? "?" : "&";
|
|||
|
|
var v = _args[ k ];
|
|||
|
|
var o = ( this.objGood( v ) || this.arrGood( v ) );
|
|||
|
|
aline += k + "=" + ( o ? nx.dt.enjson( v ) : v );
|
|||
|
|
}
|
|||
|
|
return encodeURI( _url + aline );
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:数量方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 数量千分化
|
|||
|
|
* @param {*} _count : 数量
|
|||
|
|
* @param {*} _pn : 小数位数
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
fmtCount: function( _count, _pn ) {
|
|||
|
|
|
|||
|
|
if( !nx.dt.numPositive( _pn ) ||
|
|||
|
|
_pn < 0 || _pn > 20 ) {
|
|||
|
|
_pn = DefPN;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_count = parseFloat( ( _count + "" ).replace( /[^\d\.-]/g, "" ) ).toFixed( _pn ) + "";
|
|||
|
|
var l = _count.split( "." )[ 0 ].split( "" ).reverse();
|
|||
|
|
var r = _count.split( "." )[ 1 ];
|
|||
|
|
var t = "";
|
|||
|
|
for( let i = 0; i < l.length; i++ ) {
|
|||
|
|
t += l[ i ] + ( ( i + 1 ) % 3 == 0 && ( i + 1 ) != l.length ? "," : "" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( r ) {
|
|||
|
|
var ret = t.split( "" ).reverse().join( "" ) + "." + r;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
var ret = t.split( "" ).reverse().join( "" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( ( ret.charAt( 0 ) == "-" || ret.charAt( 0 ) == "+" ) && ret.charAt( 1 ) == "," ) {
|
|||
|
|
ret = ret.charAt( 0 ) + ret.slice( 2 );
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 数量简化
|
|||
|
|
* @param {*} _count 数量
|
|||
|
|
* @param {*} _sdd 强制+号
|
|||
|
|
* @param {*} _pn 小数位数
|
|||
|
|
* @param {*} _trimZero 忽略尾部0
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
shortCount: function( _count, _sdd = false, _pn = 2, _trimZero = true ) {
|
|||
|
|
|
|||
|
|
// 转数字
|
|||
|
|
_count = parseInt( _count );
|
|||
|
|
|
|||
|
|
if( !this.numGood( _count ) ) {
|
|||
|
|
_count = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lessZero = false;
|
|||
|
|
if( _count < 0 ) {
|
|||
|
|
lessZero = true;
|
|||
|
|
_count *= -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( !this.numPositive( _pn ) ) {
|
|||
|
|
_pn = DefPN;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let value = "";
|
|||
|
|
let unitKey = "";
|
|||
|
|
|
|||
|
|
// 国际通用KM小数点后保留2位来展示
|
|||
|
|
// 小于1K
|
|||
|
|
// if( _count < 1000 ) {
|
|||
|
|
if( _count < 100000000 ) {
|
|||
|
|
value = "" + this.toFixedDecimal( _count );
|
|||
|
|
if( !_trimZero ) {
|
|||
|
|
value = this.fmtCount( value, _pn );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// // 1M > _count >= 1K
|
|||
|
|
// else if( _count >= 1000 && _count < 1000000 ) {
|
|||
|
|
// value = this.toFixedDecimal( _count / 1000 ).toFixed( _pn );
|
|||
|
|
// unitKey = "K";
|
|||
|
|
// }
|
|||
|
|
// 1B > _count >= 1M
|
|||
|
|
else if( _count >= 100000000 && _count < 1000000000 ) {
|
|||
|
|
value = this.toFixedDecimal( _count / 1000000 ).toFixed( _pn );
|
|||
|
|
unitKey = "M";
|
|||
|
|
}
|
|||
|
|
// >= 1B
|
|||
|
|
else {
|
|||
|
|
value = this.toFixedDecimal( _count / 1000000000 ).toFixed( _pn );
|
|||
|
|
unitKey = "B";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 末尾0忽略
|
|||
|
|
if( _trimZero ) {
|
|||
|
|
value = Number( value ) + unitKey;
|
|||
|
|
} else {
|
|||
|
|
value += unitKey;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( lessZero ) {
|
|||
|
|
value = "-" + value;
|
|||
|
|
} else {
|
|||
|
|
if( _sdd === true ) {
|
|||
|
|
value = "+" + value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return value;
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:WEB参数解析
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 获取URL网址参数
|
|||
|
|
parseURLArgs: function() {
|
|||
|
|
|
|||
|
|
var theRequest = {};
|
|||
|
|
|
|||
|
|
// 非浏览器不处理
|
|||
|
|
if( !cc.sys.isBrowser || !location ) {
|
|||
|
|
return theRequest;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取url中"?"符后的字串
|
|||
|
|
var url = location.search;
|
|||
|
|
if( url.indexOf( "?" ) != -1 ) {
|
|||
|
|
var str = url.substr( 1 );
|
|||
|
|
var strs = str.split( "&" );
|
|||
|
|
for( var i = 0; i < strs.length; i++ ) {
|
|||
|
|
theRequest[ strs[ i ].split( "=" )[ 0 ] ] = unescape( strs[ i ].split( "=" )[ 1 ] );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return theRequest;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 针对URL不正规的参数解析
|
|||
|
|
queryURLArg: function( _key ) {
|
|||
|
|
|
|||
|
|
// 非浏览器不处理
|
|||
|
|
if( !cc.sys.isBrowser || !window.location ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var reg = new RegExp( '(^|&)' + _key + '=([^&]*)(&|$)', 'i' );
|
|||
|
|
var serach = '';
|
|||
|
|
if( window.location.search.length > 0 ) {
|
|||
|
|
serach = window.location.search.substr( 1 );
|
|||
|
|
} else {
|
|||
|
|
serach = window.location.href.split( '?' )[ 1 ] ? window.location.href.split( '?' )[ 1 ] : '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var r = serach.match( reg );
|
|||
|
|
if( r != null ) {
|
|||
|
|
return unescape( r[ 2 ] );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
// 方法集:距离的方法
|
|||
|
|
// ------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// 格式化距离
|
|||
|
|
formatDistance: function( _meters ) {
|
|||
|
|
|
|||
|
|
if( typeof _meters != "number" ) {
|
|||
|
|
return nx.text.format( "distance_none" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( _meters < 1000 ) {
|
|||
|
|
return nx.text.format( "distance_m", _meters );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var km = Math.floor( _meters / 1000 );
|
|||
|
|
return nx.text.format( "distance_km", km );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 文件大小字节转K,M,G
|
|||
|
|
formatFileSize: function( _size ) {
|
|||
|
|
|
|||
|
|
if( !_size ) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var num = 1024.00; //byte
|
|||
|
|
|
|||
|
|
if( _size < num )
|
|||
|
|
return _size + "B";
|
|||
|
|
if( _size < Math.pow( num, 2 ) )
|
|||
|
|
return ( _size / num ).toFixed( 2 ) + "K"; //kb
|
|||
|
|
if( _size < Math.pow( num, 3 ) )
|
|||
|
|
return ( _size / Math.pow( num, 2 ) ).toFixed( 2 ) + "M"; //M
|
|||
|
|
if( _size < Math.pow( num, 4 ) )
|
|||
|
|
return ( _size / Math.pow( num, 3 ) ).toFixed( 2 ) + "G"; //G
|
|||
|
|
return ( _size / Math.pow( num, 4 ) ).toFixed( 2 ) + "T"; //T
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 检测账号是否包含中文
|
|||
|
|
formatAccount: function( str ) {
|
|||
|
|
|
|||
|
|
if( typeof str !== 'string' ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//去除字符串的左右两边空格
|
|||
|
|
//+表示匹配一次或多次,|表示或者,\s和\u00A0匹配空白字符,/^以……开头,$以……结尾,/g全局匹配,/i忽略大小写
|
|||
|
|
str = ( str || "" ).replace( /^(\s|\u00A0)+|(\s|\u00A0)+$/g, "" );
|
|||
|
|
//匹配中文,match返回包含中文的数组
|
|||
|
|
const chinese = str.match( /[\u4e00-\u9fa5]/g );
|
|||
|
|
//计算字符个数
|
|||
|
|
return !!chinese;
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 检测姓名是否是中文
|
|||
|
|
formatChineseName: function( str ) {
|
|||
|
|
|
|||
|
|
if( str.length <= 1 ) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const re = /[^\u4e00-\u9fa5]/;
|
|||
|
|
return !re.test( str );
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 随机字符串生成
|
|||
|
|
randomStr: function( min, max, strRange ) {
|
|||
|
|
|
|||
|
|
const rd = function( _l, _r ) {
|
|||
|
|
if( _r > _l ) {
|
|||
|
|
return Math.round( Math.random() * ( _r - _l ) ) + _l;
|
|||
|
|
} else {
|
|||
|
|
return _l;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var str = "";
|
|||
|
|
strRange = strRange || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|||
|
|
|
|||
|
|
var n = rd( min, max );
|
|||
|
|
var len = strRange.length;
|
|||
|
|
for( var i = 0; i < n; i++ ) {
|
|||
|
|
var pos = rd( 1, len ) - 1;
|
|||
|
|
str += strRange.charAt( pos );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return str;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
} );
|
|||
|
|
|
|||
|
|
// 模块导出
|
|||
|
|
module.exports = NxMath;
|