From cee69a02eb7383dbfdace6927a326cf2625b85d9 Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 29 Jul 2026 19:20:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(EQD-6838):=20=E4=BF=AE=E5=A4=8D=E7=BA=A6?= =?UTF-8?q?=E5=AE=9A2/3=E6=A0=87=E8=AF=86=E4=B8=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84Vue=E5=93=8D=E5=BA=94=E5=BC=8F=E9=97=AE=E9=A2=98=20+?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6=E5=86=85emit=20keydown=20+=20=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E9=87=8D=E7=AE=97=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因1(约定3按键不触发): - .native 修饰符在 vue-number-input 上不可靠(jQuery在mounted中重新绑定了keydown) - 改为在组件内部 addEventListener('keydown') + $emit('keydown') - cshtml 从 v-on:keydown.native 改为 v-on:keydown 根因2(约定2/3标识不更新): - bondDriverType/bondAuto/bondRev 不在后端数据中,直接赋值不触发Vue2响应式更新 - 成功分支之前用 $forceUpdate 兜底,但失败/编辑/按键分支没有 - 新增 syncBondFlags 方法,用 $set 强制触发响应式更新 - 在所有状态变更后调用:onBondPriceEdit/onBondPriceKeydown/onDpPriceInput/ calcBondForItem成功/失败/setUnderlyingCode/加载路径 其他改动: - 去掉"重算"按钮(用户确认不再需要) - calcBondForItem 成功分支用 syncBondFlags 替代 $forceUpdate - 重建 bundle.js(fastVue.base.js 是 bundle 输入) --- YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml | 6 ++--- .../Scripts/app/swaptrade/swapTradeEdit.js | 22 ++++++++++++++++--- YLErpWeb/wwwroot/Scripts/fast/fastVue.base.js | 8 ++++++- YLErpWeb/wwwroot/Statics/bundles/bundle.js | 8 ++++++- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml index 9aaf6035..bde843bb 100644 --- a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml +++ b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml @@ -474,13 +474,13 @@ - AUTOREV + AUTOREV - AUTOREV + AUTOREV - AUTOREV重算 + AUTOREV diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js index caf160f9..fed1eb1c 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js @@ -348,10 +348,11 @@ const vue = new Vue({ onBondPriceEdit(item, type) { if (!item.isBond) return; SwapCalc.applyBondManualEdit(item, type); + this.syncBondFlags(item); }, //交互约定3(按键实时触发):vue-number-input 的 input 事件只在失焦/回车时触发, // 按键输入过程中不触发,导致用户输入时 源/AUTO 标识不会消失。 - // 此方法绑在 v-on:keydown.native 上,按键即清 源/AUTO 标识、标本字段 REV。 + // 此方法绑在 v-on:keydown 上(组件内部 addEventListener + $emit),按键即清 源/AUTO 标识、标本字段 REV。 // 回车键(13/108)除外——回车由 v-on:enter 驱动 calcBondForItem,会把标识修正为 源/AUTO。 // 修饰键(Shift/Ctrl/Alt/Tab/方向键/F键等)除外——这些不改变数值,不应清标识。 onBondPriceKeydown(item, type, event) { @@ -365,12 +366,24 @@ const vue = new Vue({ // Backspace/Delete 改变数值,需清标识 // 数字键/小键盘/小数点/减号 改变数值,需清标识 SwapCalc.applyBondManualEdit(item, type); + this.syncBondFlags(item); + }, + //确保 bondDriverType/bondAuto/bondRev 的变更触发 Vue 响应式更新。 + //swapCalc.js 的纯函数直接对 state 赋值,但这些属性不在后端数据中(非响应式), + //直接赋值不触发视图更新。用 $set 强制触发,无论属性是否已存在都能正确工作。 + syncBondFlags(item) { + this.$set(item, 'bondDriverType', item.bondDriverType); + this.$set(item, 'bondAuto', item.bondAuto); + this.$set(item, 'bondRev', item.bondRev); }, //全价列:普通标的重算名义本金;债券标的按交互约定3 标 REV(不联动)。 // 回车计算由独立的 v-on:enter="onBondPriceEnter(item,'DP')" 负责。 onDpPriceInput(item) { this.changeSpotPrice(item); // 名义本金随全价变化(非债券标的的既有逻辑) - if (item.isBond) SwapCalc.applyBondManualEdit(item, 'DP'); // 交互约定3:失焦未回车→REV + if (item.isBond) { + SwapCalc.applyBondManualEdit(item, 'DP'); // 交互约定3:失焦未回车→REV + this.syncBondFlags(item); + } }, //放弃手动标记、以当前某字段为源重新自动反算("重算"按钮)。 resetBondCalc(item) { @@ -435,6 +448,7 @@ const vue = new Vue({ // 同一错误文案连续出现只弹一次(shouldShowBondErr 维护 item._lastBondErr),抑制噪声、不影响任何计算逻辑。 if (SwapCalc.shouldShowBondErr(item, err)) main.message(err); SwapCalc.applyBondCalcFailure(item, driver); // 交互约定2:失败→清另两字段+标识 + self.syncBondFlags(item); return; } item._lastBondErr = null; // 成功则清标记,便于下次真出不同错误时仍能提示 @@ -455,10 +469,10 @@ const vue = new Vue({ item.PosiGrossPrice = SwapCalc.bondCalcPriceToStorage(proxy.dirtyPrice); item.InitYtm = SwapCalc.bondCalcPriceToStorage(proxy.ytm); SwapCalc.applyBondCalcSuccess(item, driver); // 交互约定2:成功→标 源/AUTO + self.syncBondFlags(item); // 名义本金依赖全价(PosiGrossPrice):以净价/收益率为源反算出的全价被回写后, // 直接赋值不会触发组件 input 事件,需在此显式重算,保持名义本金与全价一致。 if (self.calcNotional) self.calcNotional(); - if (self.$forceUpdate) self.$forceUpdate(); }); }, //变更收费基本单位 @@ -814,6 +828,7 @@ const vue = new Vue({ this.$set(item, 'isBond', tradeHelper.IsBond(data.InstrumentType)); // 切换标的时清空债券三字段互算的手动/源标志(D1 修复:避免旧债券手填状态污染新债券) SwapCalc.clearBondCalcFlags(item); + this.syncBondFlags(item); // 簿记基础逻辑1:不再自动调 getSpotPrice 回填价格,由用户手填或回车调计算器 // 续发(renewal)场景的初始价恢复由 refreshInitialUnderlyingPrices 独立处理 //this.initMarginRate(); @@ -1560,6 +1575,7 @@ const vue = new Vue({ var isBond = val.isBond || tradeHelper.IsBond(val.UnderlyingInstrumentType); if (isBond && hasV(val.PosiNetNoFeePrice) && hasV(val.PosiGrossPrice) && hasV(val.InitYtm)) { SwapCalc.clearBondCalcMarksOnLoad(arr[num]); + thisObj.syncBondFlags(arr[num]); } }); if (thisObj.paySwapList.length > 0) { diff --git a/YLErpWeb/wwwroot/Scripts/fast/fastVue.base.js b/YLErpWeb/wwwroot/Scripts/fast/fastVue.base.js index 14c7baa3..21fc9fad 100644 --- a/YLErpWeb/wwwroot/Scripts/fast/fastVue.base.js +++ b/YLErpWeb/wwwroot/Scripts/fast/fastVue.base.js @@ -544,7 +544,13 @@ let self = this; let options = FastVue.extend({ onchange: this.onchange }, this.format); this.inputctrl = FastVue.numberInput(this.$el, options); - this.inputctrl.setValue(this.value) + this.inputctrl.setValue(this.value); + // 按键时 emit 'keydown' 事件,供父组件监听按键输入(交互约定3) + // .native 修饰符在此组件上不可靠(jQuery 在 mounted 中重新绑定了 keydown), + // 改为在组件内部 addEventListener 并 emit,确保父组件能收到按键事件 + this.$el.addEventListener('keydown', function (e) { + self.$emit('keydown', e); + }); }, methods: { onchange(value, text, isEnter) { diff --git a/YLErpWeb/wwwroot/Statics/bundles/bundle.js b/YLErpWeb/wwwroot/Statics/bundles/bundle.js index cae56fdf..5a2a92fe 100644 --- a/YLErpWeb/wwwroot/Statics/bundles/bundle.js +++ b/YLErpWeb/wwwroot/Statics/bundles/bundle.js @@ -14601,7 +14601,13 @@ $.fn.selectpicker.Constructor.DEFAULTS = Object.assign($.fn.selectpicker.Constru let self = this; let options = FastVue.extend({ onchange: this.onchange }, this.format); this.inputctrl = FastVue.numberInput(this.$el, options); - this.inputctrl.setValue(this.value) + this.inputctrl.setValue(this.value); + // 按键时 emit 'keydown' 事件,供父组件监听按键输入(交互约定3) + // .native 修饰符在此组件上不可靠(jQuery 在 mounted 中重新绑定了 keydown), + // 改为在组件内部 addEventListener 并 emit,确保父组件能收到按键事件 + this.$el.addEventListener('keydown', function (e) { + self.$emit('keydown', e); + }); }, methods: { onchange(value, text, isEnter) {