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; |