fix: 债券三字段调试日志改为 otcdebug gated,出问题时一键可定位
用户指出:上一笔直接删了 onBondPriceKeydown 的逐键 console.log 又没补 gated 版, 等于平时没噪音了、真出问题也看不见——这正是反复改几十遍都满足不了需求时才需要日志兜底的场景。 修复: - onBondPriceKeydown 逐键 before/after(driver/rev) trace 改为 otcDebug.log(?otcdebug=1 才输出) - onBondPriceEdit(失焦/粘贴) 补同款 gated trace - calcBondForItem 补 enter/success/calc-error/post-fail 四条 gated trace → 三字段整条链路(逐键→回车→计算器→源/AUTO或失败)开开关即得完整现场 - main.js 第226/669行 catch 内 error console.log 保留(错误日志本就应在生产可见,利于定位) - otcDebug 机制本身已存在且唯一:?otcdebug=1 或 localStorage.otcdebug=1 开启, _MainLayout 注入 jsVersion/git/built,加载时打带版本 banner,平时零噪音 测试: - diag.test.js 新增源码守卫:swapTradeEdit.js 三字段埋点必须 otcDebug.log、不得退回裸 console.log - diag 18 例 / bondCalc 81 例全过
This commit is contained in:
@@ -135,6 +135,18 @@ describe('diag: 源码守卫(防回归——不许再硬编码易过期版本
|
||||
expect(src).toMatch(/otcDebug\.banner|window\.ylotc\.__diag/);
|
||||
});
|
||||
|
||||
test('swapTradeEdit.js 三字段调试埋点必须 gated(otcDebug.log),不得裸 console.log 退回', () => {
|
||||
// 防回归:历史多次"改了不生效"靠日志兜底,曾出现①把 console.log 直接删了(出问题时看不见)
|
||||
// ②或解除了开关控制(生产噪音)。正确做法是 otcDebug.log(?otcdebug=1 才输出)。
|
||||
const src = fs.readFileSync(path.join(SCRIPTS, 'app/swaptrade/swapTradeEdit.js'), 'utf8');
|
||||
// 存在 gated 埋点
|
||||
expect(src).toMatch(/otcDebug\.log\(/);
|
||||
// 关键路径不得出现裸 console.log 调试行
|
||||
expect(src).not.toMatch(/console\.log\('\[onBondPriceKeydown\]/);
|
||||
expect(src).not.toMatch(/console\.log\('\[calcBondForItem\]/);
|
||||
expect(src).not.toMatch(/console\.log\('\[onBondPriceEdit\]/);
|
||||
});
|
||||
|
||||
test('fastVue.base.js 顶部 banner 不再硬编码 v20260729a', () => {
|
||||
const src = fs.readFileSync(path.join(SCRIPTS, 'fast/fastVue.base.js'), 'utf8');
|
||||
expect(src).not.toContain('v20260729a');
|
||||
|
||||
@@ -352,6 +352,7 @@ const vue = new Vue({
|
||||
if (!item.isBond) return;
|
||||
SwapCalc.applyBondManualEdit(item, type);
|
||||
this.syncBondFlags(item);
|
||||
otcDebug.log('[onBondPriceEdit] type=' + type + ' after: driver=' + item.bondDriverType + ' rev=' + JSON.stringify(item.bondRev));
|
||||
},
|
||||
//交互约定3(按键实时触发):vue-number-input 的 input 事件只在失焦/回车时触发,
|
||||
// 按键输入过程中不触发,导致用户输入时 源/AUTO 标识不会消失。
|
||||
@@ -360,13 +361,19 @@ const vue = new Vue({
|
||||
// 修饰键(Shift/Ctrl/Alt/Tab/方向键/F键等)除外——这些不改变数值,不应清标识。
|
||||
onBondPriceKeydown(item, type, event) {
|
||||
if (!item.isBond) return;
|
||||
var kc = event.which || event.keyCode;
|
||||
// 仅"会改变数值"的按键才清 源/AUTO 标识并标本字段 REV;
|
||||
// 回车/修饰键/导航键/功能键/纯 Shift 不改标识(见 SwapCalc.isBondPriceValueKey)。
|
||||
// 修复:此前守卫漏掉 ↑(38)/↓(40)/Insert(45)/PageUp(33)/PageDown(34)/F键/Shift(16),
|
||||
// 导致"鼠标放进去没改值、只按了方向键/功能键"也会误标 REV。
|
||||
if (!SwapCalc.isBondPriceValueKey(event)) return;
|
||||
// 调试埋点(otcDebug 仅在 ?otcdebug=1 / localStorage.otcdebug=1 时输出,平时零噪音):
|
||||
// 抓"逐键前后 driver/rev 变化",用于定位 REV 标记异常。
|
||||
otcDebug.log('[onBondPriceKeydown] type=' + type + ' kc=' + kc +
|
||||
' before: driver=' + item.bondDriverType + ' rev=' + JSON.stringify(item.bondRev));
|
||||
SwapCalc.applyBondManualEdit(item, type);
|
||||
this.syncBondFlags(item);
|
||||
otcDebug.log('[onBondPriceKeydown] after: driver=' + item.bondDriverType + ' rev=' + JSON.stringify(item.bondRev));
|
||||
},
|
||||
//确保 bondDriverType/bondAuto/bondRev 的变更触发 Vue 响应式更新。
|
||||
//swapCalc.js 的纯函数直接对 state 赋值,但这些属性不在后端数据中(非响应式),
|
||||
@@ -433,6 +440,9 @@ const vue = new Vue({
|
||||
// 该字段在页面上本就是可选择的日期控件(vue-datepicker),用户可改;现已默认即有。
|
||||
// 不再"悄悄回退到交易日(TradeDate)"——真的为空时直接报错提示,由用户填写/手动填三数(需求2)。
|
||||
var targetDate = (this.trade && this.trade.StartDate) ? this.trade.StartDate : null;
|
||||
// 调试埋点(otcDebug 仅在 ?otcdebug=1 时输出):抓"回车→调计算器→源/结果"全链路,定位三字段互算异常。
|
||||
otcDebug.log('[calcBondForItem] enter driver=' + driver + ' priceType=' + priceType +
|
||||
' price(sent)=' + SwapCalc.bondPriceToCalc(price) + ' targetDate=' + targetDate);
|
||||
var sdMsg = SwapCalc.getBondStartDateMissingMsg(targetDate);
|
||||
if (sdMsg) {
|
||||
// D3 同款去重:开始日缺失时用户在价格格逐键输入会连刷相同提示,故同一文案只弹一次
|
||||
@@ -466,6 +476,7 @@ const vue = new Vue({
|
||||
if (SwapCalc.shouldShowBondErr(item, err)) main.message(err);
|
||||
SwapCalc.applyBondCalcFailure(item, driver); // 交互约定2:失败→清另两字段+标识
|
||||
self.syncBondFlags(item);
|
||||
otcDebug.log('[calcBondForItem] calc-error driver=' + driver + ' msg=' + err);
|
||||
return;
|
||||
}
|
||||
item._lastBondErr = null; // 成功则清标记,便于下次真出不同错误时仍能提示
|
||||
@@ -487,6 +498,7 @@ const vue = new Vue({
|
||||
item.InitYtm = SwapCalc.bondCalcPriceToStorage(proxy.ytm);
|
||||
SwapCalc.applyBondCalcSuccess(item, driver); // 交互约定2:成功→标 源/AUTO
|
||||
self.syncBondFlags(item);
|
||||
otcDebug.log('[calcBondForItem] success driver=' + driver + ' auto=' + JSON.stringify(item.bondAuto) + ' rev=' + JSON.stringify(item.bondRev));
|
||||
// 名义本金依赖全价(PosiGrossPrice):以净价/收益率为源反算出的全价被回写后,
|
||||
// 直接赋值不会触发组件 input 事件,需在此显式重算,保持名义本金与全价一致。
|
||||
if (self.calcNotional) self.calcNotional();
|
||||
@@ -501,6 +513,7 @@ const vue = new Vue({
|
||||
// (与 .done 内 !resp.obj 分支行为一致;左侧 .done 的 getBondCalcErrorMessage 分支为兼容冗余,主路径在此)。
|
||||
SwapCalc.applyBondCalcFailure(item, driver);
|
||||
self.syncBondFlags(item);
|
||||
otcDebug.log('[calcBondForItem] post-fail/reject driver=' + driver);
|
||||
});
|
||||
},
|
||||
//变更收费基本单位
|
||||
|
||||
Reference in New Issue
Block a user