//依赖类库:lodash.js + jquery + jquery.validate + bootstrap.emodal.js // 统一调试日志工具:仅在 otcdebug 开启时输出,默认静默(生产零噪音)。 // 开启:URL 加 ?otcdebug=1(会自动写入 localStorage,同源 iframe/弹窗自动继承); // 或控制台 localStorage.setItem('otcdebug','1')。关闭:localStorage.removeItem('otcdebug')。 // 业务脚本用 otcDebug.banner / otcDebug.log 替代裸 console.log(见 swapTradeEdit.js / fastVue.base.js)。 // // 命名约定(避免 __私有对象 + otcDebug.API 大小写混搭): // __diag —— 版本元数据对象(仅 _MainLayout 灌入 ylotc.__diag 时存在,仅供 banner 展示,不参与开关判定) // __debug —— 调试开关布尔值(唯一真相来源:localStorage 优先 → URL 参数 → 兜底 __diag.debug) var __diag = (window.ylotc && window.ylotc.__diag) || {}; var __debug = (function () { try { // 1) URL 参数优先(排查最直观);命中即写入 localStorage,供同源 iframe/弹窗继承 if (/[?&]otcdebug=1/.test(location.search)) { localStorage.setItem('otcdebug', '1'); return true; } // 2) 已持久化的开关(父页面开过一次,_InfoLayout 弹窗自动生效) if (localStorage.getItem('otcdebug') === '1') return true; } catch (e) { /* localStorage 不可用时忽略,继续走兜底 */ } // 3) 兜底:layout 灌入的 ylotc.__diag.debug(仅 _MainLayout 有) return !!__diag.debug; })(); window.otcDebug = { // 模块加载横幅:F12 一眼看到模块名+版本,用于排查"是不是加载了旧代码/旧缓存" banner: function (name, ver) { if (!__debug || !window.console) return; var git = (__diag.git || '').slice(0, 7); console.log('%c[' + name + '] v' + ver + ' (bundle=' + __diag.jsVersion + ', git=' + git + ', built=' + __diag.built + ')', 'color:#06c;font-weight:bold'); }, // 普通调试日志:透传参数,仅 debug 开启时输出 log: function () { if (!__debug || !window.console) return; console.log.apply(console, arguments); } }; var main = window.main || { version: "1.0" }; main.extend = $.extend; //数字格式化 /** * 构建数字格式化函数(依赖lodash.js) * @see Intl.NumberFormat * @param {any} precision - 小数位精度,默认2,如果是对象类,则当做带precision属性的options处理 * @param {object} options - 格式化选项 * @param {boolean} options.rounded - 是否四舍五入,明确传入false时禁止四舍五入 * @param {boolean} options.grouping - 是否使用千位分隔符,默认false * @param {boolean} options.percent - 是否百分比格式,默认false * @param {boolean} options.trimTailZeros - 是否去除小数点后的尾部的0,默认false * @param {any} options.prefmt * - 预先格式化,支持多种形式处理 * - 如果传入数组类型的参数值,则循环执行数组中的函数,如果执行结果为string或number类型,则prefmt值取此结果并跳出循环 * - 如果传入函数类型的参数值,prefmt值取函数执行结果 * - 如果prefmt值为数字类型,则格式化prefmt值 * - 如果prefmt值不为undefined|null|false,则返回prefmt值,否则忽略prefmt * @param {string} options.nanfmt - 输入值解析成数字为NAN时的格式化处理,类型为字符串,默认返回0的格式化数值 * @return {function} - 返回带fromat函数的格式化对象 */ main.numberFormat = function (precision, options) { if (typeof precision === 'object') { options = precision; precision = options.precision; } else if (!options || typeof options !== 'object') { options = {}; } //解析小数位精度 precision = parseInt(precision); if (isNaN(precision)) { precision = 2; } else if (precision < 0) { precision = 0; } else if (precision > 10) { precision = 10; } //构建Intl.NumberFormat const fmt = new Intl.NumberFormat('en', { useGrouping: !!options.grouping, minimumFractionDigits: precision, maximumFractionDigits: precision, style: options.percent ? 'percent' : 'decimal' }); //百分比格式特殊精度位处理 if (options.percent) precision += 2; //预格式化处理 function preformat(prefmt, fmtArgs) { //如果是数组类型,则以管道形式执行函数 if (Array.isArray(prefmt)) { var result = false; _.each(prefmt, x => { let match = typeof x === 'function'; while (match) { x = x.apply(this, fmtArgs); switch (typeof x) { case 'function': continue; case 'number': case 'string': result = x; return false; default: return true; } } }); return result; } //执行函数处理 while (typeof prefmt === 'function') { prefmt = prefmt.apply(this, fmtArgs); } return prefmt; } function _format(val) { //预格式化处理 let prefmt = preformat(options.prefmt, arguments); let type = typeof prefmt; if (type === 'number') { val = prefmt; } else if (type !== 'undefined' && prefmt !== null && prefmt !== false) { return prefmt; } if (precision <= 4) { val = _.round(val, precision + 4); } //数值格式化 if (options.rounded !== false) { let negative = val < 0; val = _.round(negative ? -val : val, precision); negative && (val = -val); } else { val = _.floor(val, precision); } if (isNaN(val)) { return typeof options.nanfmt === 'string' ? options.nanfmt : fmt.format(0); } return fmt.format(Math.abs(val) < 1e-6 ? 0 : val); } function format(val) { let str = _format(val); return options.trimTailZeros && str.endsWith("0") && precision > 0 ? str.replace(/\.?0+$/, '') : str; } format.precision = precision; return format; }; /** * 格式化数字(依赖lodash.js) * @param {object} number - 数字数值 * @param {any} precision - 小数位精度,默认2,如果是对象类,则当做带precision属性的options处理 * @param {object} options - 格式化选项 * @param {boolean} options.rounded - 是否四舍五入,类型为布尔值,默认true * @param {boolean} options.grouping - 是否使用千位分隔符,类型为布尔值,默认false * @param {boolean} options.percent - 是否百分比格式,类型为布尔值,默认false * @param {string} options.nanfmt - 输入值解析成数字为NAN时的格式化处理,类型为字符串,默认返回0的格式化数值 * @param {any} options.prefmt - 参考main.numberFormat * @return {function} - 返回带fromat函数的格式化对象 */ main.formatNumber = function (number, precision, options) { return new main.numberFormat(precision, options)(number); }; //各种常用处理 const __alert = function (message) { window.alert(message); return false; }; /** * 显示页面加载组件,等待操作执行完成 * @param {string} method -- 'show'||'hide' * @returns {jQuery} -- jQuery对象 */ $.fn.waitMe = function (method) { return this.each(function () { if (this.showCount === undefined || this.showCount === null) { this.showCount = 0; } var isBody = $(this).is('body'); var $waitme = $(this).children(".yl-waitme"); if (method === "show") { if (!$waitme.length) { !isBody && $(this).css("position") === "static" && $(this).css("position", "relative"); $waitme = $('
'); $waitme.appendTo($(this)); } $waitme.show(); this.showCount++; } else if (this.showCount > 0) { (this.showCount -= 1) === 0 && $waitme.remove(); } }); }; main.logError = function (data) { if (!data) return; if (console && typeof console.error === "function") { console.error(data); } else if ($.isPlainObject(data) || data.length) { alert(JSON.stringify(data)); } else { alert(data); } }; const _systemmsg = []; /** * 显示通知消息 * @param {any} message -- 消息文本 * @param {any} time -- 显示时间 * @returns {boolean} -- false */ main.message = function (message, time) { main.toast(message, time); try { if (_systemmsg.length >= 3) { _systemmsg.splice(0, 1); } _systemmsg.push(message); $("#systemspanmsg").html(_systemmsg.join(";")); } catch (e) { console.log("[ERROR:main.message]" + e); } return false; }; main.toast = function (message, delay) { if (!$('#toast-container').length) { $('