From cb2076d9ffdb53dd05a9083e0ece7bd1675aeba7 Mon Sep 17 00:00:00 2001
From: tengyufan <1532636164@qq.com>
Date: Thu, 30 Jul 2026 17:58:51 +0800
Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=E4=BA=A4=E6=98=93=E7=A1=AE=E8=AE=A4?=
=?UTF-8?q?=E4=B9=A6=E7=BC=96=E5=8F=B7=E7=AD=9B=E9=80=89=E9=A1=B9=E4=BF=9D?=
=?UTF-8?q?=E6=8C=81=E5=8D=95=E8=A1=8C=E6=98=BE=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 国联交易确认书页面加宽交易确认书编号筛选项标签和容器
- 避免交易确认书编号标签自动换行
---
YLErpWeb/Views/TradeConfirmBook/Index.cshtml | 21 +++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/YLErpWeb/Views/TradeConfirmBook/Index.cshtml b/YLErpWeb/Views/TradeConfirmBook/Index.cshtml
index 91a7b06e..d1d54d2b 100644
--- a/YLErpWeb/Views/TradeConfirmBook/Index.cshtml
+++ b/YLErpWeb/Views/TradeConfirmBook/Index.cshtml
@@ -44,6 +44,15 @@
.no-skin {
position: static !important;
}
+
+ .searchdiv .contract-code-search-group {
+ width: 272px;
+ }
+
+ .searchdiv .contract-code-search-group .search-label {
+ width: 110px;
+ white-space: nowrap;
+ }
}
@section JS{
@@ -57,7 +66,17 @@
@Html.ShortInput("TradeNumber", "交易编号")
- @Html.ShortInput("ContractCode", pageObj.isGuoLian ? "交易确认书编号" : "合约编号")
+ @if (pageObj.isGuoLian)
+ {
+
+ 交易确认书编号
+
+
+ }
+ else
+ {
+ @Html.ShortInput("ContractCode", "合约编号")
+ }
@Html.MyAceDropdownInput("ClientId", "客户名称", ClientDataModel.GetAllClient())
@Html.MyAceDropdownInput("AssetId", "簿记账户", AssetunitController.GetClientassetunit())
@Html.MyAceDropdownInput("GroupId", "簿记账户组", AssetUnitModel.GetAllAssetUnitGroupItem())
From 74c434bdd8377e74669f188f1db6349555237163 Mon Sep 17 00:00:00 2001
From: hjhan
Date: Fri, 31 Jul 2026 09:07:08 +0800
Subject: [PATCH 2/7] =?UTF-8?q?fix(swaptrade):=20=E4=BF=AE=E5=A4=8D?=
=?UTF-8?q?=E9=87=8D=E8=BE=93/=E9=87=8D=E8=B4=B4=E5=8E=9F=E5=80=BC?=
=?UTF-8?q?=E5=90=8E=E5=9B=9E=E8=BD=A6=E4=B8=8D=E8=A7=A6=E5=8F=91=E8=AE=A1?=
=?UTF-8?q?=E7=AE=97=E3=80=81=E7=B2=98=E8=B4=B4=E4=B8=8D=E6=A0=87=E8=AE=B0?=
=?UTF-8?q?REV=E7=9A=84=E9=9D=99=E9=BB=98=E5=A4=B1=E6=95=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- swapPricePrecisionHelper: onKeydown 回车时无条件派发 input+enter,
不再依赖仅值变化才触发的原生 change;onPaste 粘贴即派发 input 标 REV;
onChange 不再派发 enter(改由 onKeydown 唯一派发,避免重复计算)
- 新增 fe-tests/swapPriceInput.component.test.js 回归守卫(6 用例,
回退旧版即变红,锁定该 QA 高优 Bug 修复)
- bundle/bundleV2: otcDebug 调试开关改为 localStorage 持久化 +
URL ?otcdebug=1 触发,便于排查价格计算链路
---
.../fe-tests/swapPriceInput.component.test.js | 100 ++++++++++++++++++
.../app/swaptrade/swapPricePrecisionHelper.js | 18 +++-
YLErpWeb/wwwroot/Statics/bundles/bundle.js | 33 ++++--
YLErpWeb/wwwroot/Statics/bundles/bundleV2.js | 32 ++++--
4 files changed, 161 insertions(+), 22 deletions(-)
create mode 100644 YLErpWeb/fe-tests/swapPriceInput.component.test.js
diff --git a/YLErpWeb/fe-tests/swapPriceInput.component.test.js b/YLErpWeb/fe-tests/swapPriceInput.component.test.js
new file mode 100644
index 00000000..7080f8cd
--- /dev/null
+++ b/YLErpWeb/fe-tests/swapPriceInput.component.test.js
@@ -0,0 +1,100 @@
+/**
+ * swapPriceInput.component.test.js — vue-swap-price-input 事件派发回归守卫
+ * ============================================================================
+ * 目的:锁定债券三字段输入组件「粘贴 / 重输原值 不派发 input/enter」的 bug。
+ * 症状:粘贴或重输原值后,点空白(标REV/清其他标识)与回车(触发计算)均无反应。
+ * 根因:组件把 input/enter 全部锁在原生 change 事件里,而 change 仅在「值相对聚焦时
+ * 变动」才触发;onPaste 甚至完全不派发任何事件。
+ *
+ * 做法:直接实例化组件 options 对象(createVueInputComponent),用 mock this + $emit 间谍
+ * 驱动 onPaste/onKeydown/onChange,断言事件派发。不依赖 Vue 运行时挂载、不改动源文件。
+ *
+ * 运行:cd YLErpWeb/fe-tests && npx jest swapPriceInput.component
+ * 设 SWAP_PRICE_HELPER 指向其它版本文件可做对照(如改之前的旧代码应使用例变红)。
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+function loadComponent() {
+ const rel = process.env.SWAP_PRICE_HELPER
+ || '../wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js';
+ const file = path.resolve(__dirname, rel);
+ const code = fs.readFileSync(file, 'utf8');
+ // swapPricePrecisionHelper.js: var swapPricePrecision = (function(global){...})(window);
+ // 在受控作用域求值并取出 createVueInputComponent(IIFE 不挂 window,故用 new Function 取返回值)。
+ const factory = new Function('window', 'global', 'console', code + '\n;return swapPricePrecision;');
+ const sandbox = {};
+ const swapPricePrecision = factory(sandbox, sandbox, console);
+ return swapPricePrecision.createVueInputComponent();
+}
+
+function makeCtx(component, opts) {
+ opts = opts || {};
+ const emitted = [];
+ const ctx = {
+ text: opts.text != null ? String(opts.text) : '',
+ enterPressed: false,
+ formatSnapshot: '{}',
+ format: opts.format || { integerDigits: 2, precision: 4, percent: true },
+ $emit: function (name, payload) { emitted.push({ name: name, payload: payload }); },
+ };
+ Object.keys(component.methods).forEach(function (m) {
+ ctx[m] = component.methods[m].bind(ctx);
+ });
+ return { ctx: ctx, emitted: emitted };
+}
+
+describe('vue-swap-price-input 事件派发(粘贴 / 重输原值场景)', () => {
+ const component = loadComponent();
+
+ test('粘贴原值应派发 input(点空白标REV / 清其他标识)', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.5', format: { integerDigits: 2, precision: 4, percent: true } });
+ const evt = { preventDefault() {}, clipboardData: { getData: () => '3.5' }, target: { value: '' } };
+ ctx.onPaste(evt);
+ const inputs = emitted.filter(e => e.name === 'input');
+ expect(inputs.length).toBe(1);
+ expect(inputs[0].payload).toBe('0.035'); // percent:true → ÷100
+ });
+
+ test('回车(原值未变)应派发 enter(触发自动计算)', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.5', format: { integerDigits: 2, precision: 4, percent: true } });
+ const evt = { which: 13, keyCode: 13, key: 'Enter', target: { blur() {}, value: '3.5' } };
+ ctx.onKeydown(evt);
+ const enters = emitted.filter(e => e.name === 'enter');
+ expect(enters.length).toBe(1);
+ expect(enters[0].payload).toBe('0.035');
+ });
+
+ test('回车(值已改)应派发 input+enter 各一次,且不重复派发 enter', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.6', format: { percent: true } });
+ const evt = { which: 13, keyCode: 13, key: 'Enter', target: { blur() {}, value: '3.6' } };
+ ctx.onKeydown(evt);
+ expect(emitted.filter(e => e.name === 'input').length).toBe(1);
+ expect(emitted.filter(e => e.name === 'enter').length).toBe(1);
+ });
+
+ test('非 Enter 按键不应派发 enter / input', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.5', format: { percent: true } });
+ const evt = { which: 65, keyCode: 65, key: 'a', target: { blur() {} } };
+ ctx.onKeydown(evt);
+ expect(emitted.filter(e => e.name === 'enter').length).toBe(0);
+ expect(emitted.filter(e => e.name === 'input').length).toBe(0);
+ });
+
+ test('失焦(onChange)即使值未变也应派发 input(点空白标REV),且不再派发 enter', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.5', format: { percent: true } });
+ const evt = { target: { value: '3.5' } };
+ ctx.onChange(evt);
+ expect(emitted.filter(e => e.name === 'input').length).toBe(1);
+ expect(emitted.filter(e => e.name === 'enter').length).toBe(0);
+ });
+
+ test('粘贴但格式为 percent:false 也应派发 input(原值透传)', () => {
+ const { ctx, emitted } = makeCtx(component, { text: '3.5', format: { integerDigits: 2, precision: 4, percent: false } });
+ const evt = { preventDefault() {}, clipboardData: { getData: () => '3.5' }, target: { value: '' } };
+ ctx.onPaste(evt);
+ expect(emitted.filter(e => e.name === 'input').length).toBe(1);
+ expect(emitted.filter(e => e.name === 'input')[0].payload).toBe('3.5');
+ });
+});
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
index be9e3ed6..7bacf7a3 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
@@ -208,22 +208,32 @@ var swapPricePrecision = (function (global) {
event.preventDefault();
this.updateValue(clipboard.getData('text'), true, false);
event.target.value = this.text;
+ // 粘贴即显式赋值意图:直接派发 input,使「单击空白处标REV/其余清空」「回车前已标记」等行为生效。
+ // 原实现只把粘贴内容写回DOM、等失焦时的原生change才派发,而原值粘贴时change不触发→静默无反应。
+ this.$emit('input', this.toModel(this.text));
},
onKeydown: function (event) {
this.enterPressed = false;
this.$emit('keydown', event);
const keyCode = event.which || event.keyCode;
if (event.key !== 'Enter' && keyCode !== 13 && keyCode !== 108) return;
- this.enterPressed = true;
- event.target.blur();
+ // 回车=用户显式提交意图:无论值是否相对聚焦时变化,都直接派发 input(标REV) + enter(触发计算)。
+ // 原实现把 enter 锁在原生 change 里,而 change 仅在值变化时触发,
+ // 导致「重输/重贴原值 + 回车」静默不计算(QA 高优 Bug)。
+ this.updateValue(this.text, true, false);
+ const value = this.toModel(this.text);
+ event.target.blur(); // 同步触发原生 change(值变化时再派发一次 input,幂等无害)
+ this.$emit('input', value);
+ this.$emit('enter', value);
+ this.enterPressed = false;
},
onChange: function (event) {
if (this.text.endsWith('.')) this.text = this.text.substring(0, this.text.length - 1);
this.updateValue(this.text, true, false);
const value = this.toModel(this.text);
+ // 失焦(非回车)→ 仅派发 input 标 REV;enter(计算) 改由 onKeydown 直接派发,
+ // 避免 change 不触发时丢失,也避免与 onKeydown 重复派发 enter 造成重复计算。
this.$emit('input', value);
- if (this.enterPressed) this.$emit('enter', value);
- this.enterPressed = false;
event.target.value = this.text;
}
},
diff --git a/YLErpWeb/wwwroot/Statics/bundles/bundle.js b/YLErpWeb/wwwroot/Statics/bundles/bundle.js
index cec1dbb7..915524de 100644
--- a/YLErpWeb/wwwroot/Statics/bundles/bundle.js
+++ b/YLErpWeb/wwwroot/Statics/bundles/bundle.js
@@ -14667,6 +14667,7 @@ $.fn.selectpicker.Constructor.DEFAULTS = Object.assign($.fn.selectpicker.Constru
};
}(window.FastVue));
+
//日期选择组件FastVue.DatePicker
(function (global) {
global.vueDatePicker = function () {
@@ -15009,21 +15010,35 @@ $.fn.selectpicker.Constructor.DEFAULTS = Object.assign($.fn.selectpicker.Constru
//依赖类库:lodash.js + jquery + jquery.validate + bootstrap.emodal.js
// 统一调试日志工具:仅在 otcdebug 开启时输出,默认静默(生产零噪音)。
-// 开启方式:URL 加 ?otcdebug=1,或控制台 localStorage.setItem('otcdebug','1')。
-// 业务脚本逐步改用 otcDebug.banner / otcDebug.log 替代裸 console.log,
-// 既能在排查时一键全开,又能避免版本标记散落硬编码(见 swapTradeEdit.js / fastVue.base.js 用法)。
-var __otcDiag = (window.ylotc && window.ylotc.__diag) || { debug: false };
+// 开启: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 一眼看到模块名+bundle版本+git sha,用于排查"是不是加载了旧代码/旧缓存"
+ // 模块加载横幅:F12 一眼看到模块名+版本,用于排查"是不是加载了旧代码/旧缓存"
banner: function (name, ver) {
- if (!__otcDiag.debug || !window.console) return;
- var git = (__otcDiag.git || '').slice(0, 7);
- console.log('%c[' + name + '] v' + ver + ' (bundle=' + __otcDiag.jsVersion + ', git=' + git + ', built=' + __otcDiag.built + ')',
+ 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 (!__otcDiag.debug || !window.console) return;
+ if (!__debug || !window.console) return;
console.log.apply(console, arguments);
}
};
diff --git a/YLErpWeb/wwwroot/Statics/bundles/bundleV2.js b/YLErpWeb/wwwroot/Statics/bundles/bundleV2.js
index ed738bb6..bee09b9e 100644
--- a/YLErpWeb/wwwroot/Statics/bundles/bundleV2.js
+++ b/YLErpWeb/wwwroot/Statics/bundles/bundleV2.js
@@ -802,21 +802,35 @@ An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=r
//依赖类库:lodash.js + jquery + jquery.validate + bootstrap.emodal.js
// 统一调试日志工具:仅在 otcdebug 开启时输出,默认静默(生产零噪音)。
-// 开启方式:URL 加 ?otcdebug=1,或控制台 localStorage.setItem('otcdebug','1')。
-// 业务脚本逐步改用 otcDebug.banner / otcDebug.log 替代裸 console.log,
-// 既能在排查时一键全开,又能避免版本标记散落硬编码(见 swapTradeEdit.js / fastVue.base.js 用法)。
-var __otcDiag = (window.ylotc && window.ylotc.__diag) || { debug: false };
+// 开启: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 一眼看到模块名+bundle版本+git sha,用于排查"是不是加载了旧代码/旧缓存"
+ // 模块加载横幅:F12 一眼看到模块名+版本,用于排查"是不是加载了旧代码/旧缓存"
banner: function (name, ver) {
- if (!__otcDiag.debug || !window.console) return;
- var git = (__otcDiag.git || '').slice(0, 7);
- console.log('%c[' + name + '] v' + ver + ' (bundle=' + __otcDiag.jsVersion + ', git=' + git + ', built=' + __otcDiag.built + ')',
+ 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 (!__otcDiag.debug || !window.console) return;
+ if (!__debug || !window.console) return;
console.log.apply(console, arguments);
}
};
From a871bcb9fe0467180a52193de1656a89dcd006e7 Mon Sep 17 00:00:00 2001
From: hjhan
Date: Fri, 31 Jul 2026 09:10:05 +0800
Subject: [PATCH 3/7] =?UTF-8?q?fix(login):=20=E7=99=BB=E5=BD=95=E9=A1=B5?=
=?UTF-8?q?=20NeedCaptcha=3Dfalse=20=E6=97=B6=20CaptchaClick=20=E9=81=BF?=
=?UTF-8?q?=E5=85=8D=20null.setAttribute=20=E6=8A=A5=E9=94=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
页面加载时无条件调用 CaptchaClick(),但
仅在
NeedCaptcha=true 时渲染,导致无需验证码时 getElementById 返回 null,
null.setAttribute 抛错。增加 if (!img) return 守卫,img 存在时行为不变。
---
YLErpWeb/Views/Account/Login.cshtml | 1 +
1 file changed, 1 insertion(+)
diff --git a/YLErpWeb/Views/Account/Login.cshtml b/YLErpWeb/Views/Account/Login.cshtml
index c3e8ae00..f71d0ea7 100644
--- a/YLErpWeb/Views/Account/Login.cshtml
+++ b/YLErpWeb/Views/Account/Login.cshtml
@@ -34,6 +34,7 @@
})
function CaptchaClick(){
var img = document.getElementById('captcha');
+ if (!img) return; // NeedCaptcha=false 时验证码 img 不渲染,避免 null.setAttribute 报错
var newSrc = '@captchaUrl' + '&t=' + new Date().getTime();
img.setAttribute('src', newSrc);
}
From ca74095e0c26d9fba9a5cb6a40811ebaa5ec11f3 Mon Sep 17 00:00:00 2001
From: hjhan
Date: Fri, 31 Jul 2026 09:10:18 +0800
Subject: [PATCH 4/7] =?UTF-8?q?fix(sac):=20=E4=BF=AE=E5=A4=8D=E9=A2=84?=
=?UTF-8?q?=E8=A7=88=E9=A1=B5=E5=BA=8F=E5=88=97=E5=8C=96=20SacInfo=20?=
=?UTF-8?q?=E6=97=B6=20TypeId=20=E8=A7=A6=E5=8F=91=20IsGenericParameter=20?=
=?UTF-8?q?=E5=BC=82=E5=B8=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- SacDescriptionAttribute 增加 ShouldSerializeTypeId() 返回 false,
跳过 Attribute.TypeId(System.Type)的序列化,避免 Newtonsoft 抛
"Method may only be called on a Type for which Type.IsGenericParameter is true."
(13.0.1 安全版对 Type 成员序列化行为变更后暴露)
- ExceptionMiddleware 改用 exception.ToString() 记录完整异常(类型+
内层 message+堆栈),替代仅取最内层 message,便于定位此类反射异常根因;
该信息仅写入日志,不返回前端
---
.../SAC/Common/Sac_TranslateHelper.cs | 6 ++++++
YLErpWeb/App/ExceptionMiddleware.cs | 17 ++++-------------
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs
index 822f4c2e..4a2bc9a5 100644
--- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs
+++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs
@@ -117,6 +117,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public class SacDescriptionAttribute : Attribute
{
+ // Attribute.TypeId 本质是 System.Type,Newtonsoft 序列化会触发
+ // "Method may only be called on a Type for which Type.IsGenericParameter is true."
+ // 预览页用 ToJson() 序列化 SacInfo/List 时崩溃,故显式跳过该成员。
+ // (13.0.1 安全版对 Type 成员序列化行为变更后暴露此问题)
+ public bool ShouldSerializeTypeId() => false;
+
///
/// 字段名
///
diff --git a/YLErpWeb/App/ExceptionMiddleware.cs b/YLErpWeb/App/ExceptionMiddleware.cs
index a0c469d2..5163baaa 100644
--- a/YLErpWeb/App/ExceptionMiddleware.cs
+++ b/YLErpWeb/App/ExceptionMiddleware.cs
@@ -37,13 +37,15 @@ namespace YLErp.Web.App
try
{
- message = GetInnerExceptionMessage(exception);
+ // 暴露完整异常(类型 + 所有内层 message + 堆栈),不再只取最内层 message,
+ // 便于定位根因(如 SacInfo 序列化 TypeId 触发的 IsGenericParameter 反射异常)。
+ message = exception.ToString();
if (serviceExpcetion == null || serviceExpcetion.IsFaultError)
{
var result = await request.BodyReader.ReadAsync();
var reqBody = ConvertBufferToString(result.Buffer);
- LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}");
+ LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}\r\n{message}");
}
}
catch (Exception ex)
@@ -77,16 +79,5 @@ namespace YLErp.Web.App
ReadOnlySpan span = readOnlySequence.IsSingleSegment ? readOnlySequence.First.Span : readOnlySequence.ToArray().AsSpan();
return System.Text.Encoding.UTF8.GetString(span);
}
-
- private static string GetInnerExceptionMessage(Exception ex)
- {
- var exceptionStr = ex.Message;
- while (ex.InnerException != null)
- {
- exceptionStr = ex.InnerException.Message;
- ex = ex.InnerException;
- }
- return exceptionStr;
- }
}
}
\ No newline at end of file
From 5d580960d8096f1cb67bd7a5860465659623443c Mon Sep 17 00:00:00 2001
From: yexuzhong <120511780@qq.com>
Date: Fri, 31 Jul 2026 10:35:25 +0800
Subject: [PATCH 5/7] =?UTF-8?q?#EQD-6669=20=E5=9B=BD=E8=81=94=E6=B0=91?=
=?UTF-8?q?=E7=94=9F-=E6=9C=9F=E6=9D=83=E5=B8=8C=E8=85=8A=E5=80=BC?=
=?UTF-8?q?=E8=AE=A1=E7=AE=97=E6=AD=A5=E9=95=BF=E5=92=8C=E7=BB=86=E8=8A=82?=
=?UTF-8?q?=E8=B0=83=E6=95=B4=EF=BC=88=E5=AE=9A=E4=BB=B7=E5=BC=95=E6=93=8E?=
=?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Framework/YLErp.Core/ConsGlobal.cs | 25 ++++--
Framework/YLErp.Core/YLErp.Core.csproj | 2 +-
.../BLL/Calculation/V2/ValueCalculator.cs | 4 +-
YLErpDAL/Model/EodPositionRisks.cs | 23 +++++-
.../Models/OptionCalcParam.cs | 4 +-
.../OptionTradeAnalysisService.cs | 4 +-
.../DataProviderModule/EodPriceProvider.cs | 8 +-
.../EodModule/EodPositionRisksQueryService.cs | 37 ++++++++-
.../EodModule/GLMSGreeksHandleService.cs | 28 +++++++
.../SettlementModule/EodCheckSettlePrice.cs | 53 ++++++------
.../OrderModule/TradeSavePreHandler.cs | 10 +--
YLErpDAL/YLErpDAL.csproj | 2 +-
.../导出模板/日终持仓风险-Spv_国联.xlsx | Bin 0 -> 11411 bytes
.../App_Docs/导出模板/日终持仓风险_国联.xlsx | Bin 0 -> 11419 bytes
YLErpWeb/Views/trade/EodPositionRisks.cshtml | 5 +-
YLErpWeb/YLErpWeb.csproj | 16 ++--
.../Scripts/app/eod/EodPositionRisks.js | 78 +++++++++++++++++-
17 files changed, 236 insertions(+), 63 deletions(-)
create mode 100644 YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs
create mode 100644 YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx
create mode 100644 YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx
diff --git a/Framework/YLErp.Core/ConsGlobal.cs b/Framework/YLErp.Core/ConsGlobal.cs
index 049817e7..f2c8181f 100644
--- a/Framework/YLErp.Core/ConsGlobal.cs
+++ b/Framework/YLErp.Core/ConsGlobal.cs
@@ -1,4 +1,4 @@
-using System.Runtime.CompilerServices;
+using System.Runtime.CompilerServices;
using YLErp.Models;
namespace YLErp
@@ -135,6 +135,9 @@ namespace YLErp
public const string Shibor = "Shibor";
public const string FixingRepoRate = "FixingRepoRate";
public const string OtherRate = "OtherRate";
+ public const string BondYield = "BondYield"; //债券收益率
+ public const string BondIndex = "BondIndex"; // 债券指数
+
//public const string OtherUnderlying = "OtherUnderlying";
@@ -169,6 +172,8 @@ namespace YLErp
//case OtherUnderlying: return "其他标的";
case CreditBonds: return "信用债";
case OtherBonds: return "其它债券";
+ case BondYield: return "债券收益率";
+ case BondIndex: return "债券指数";
default: return instType;
}
}
@@ -204,6 +209,8 @@ namespace YLErp
//case "其他标的": return OtherUnderlying;
case "信用债": return CreditBonds;
case "其它债券": return OtherBonds;
+ case "债券收益率": return BondYield;
+ case "债券指数": return BondIndex;
default: throw new ServiceException("资产类型不存在");
}
}
@@ -264,6 +271,8 @@ namespace YLErp
new SelectItem { Text = "汇率" ,Value = ExRate },
new SelectItem { Text = "Shibor" ,Value = Shibor},
new SelectItem { Text = "银行间回购定盘" ,Value = FixingRepoRate},
+ new SelectItem { Text = "债券收益率" ,Value = BondYield},
+ new SelectItem { Text = "债券指数" ,Value = BondIndex},
//new SelectItem { Text = "其他利率" ,Value = OtherRate},
//new SelectItem { Text = "其他标的" ,Value = OtherUnderlying}
};
@@ -271,7 +280,7 @@ namespace YLErp
public static IEnumerable FutureTypes()
{
- return new[] { CommodityFutures, StockIF, GoldFutures, TBFutures, OtherFutures, AbroadFutures };
+ return new[] { CommodityFutures, StockIF, GoldFutures, TBFutures, OtherFutures, AbroadFutures, BondYield, BondIndex };
}
///
@@ -371,8 +380,12 @@ namespace YLErp
/// 类型转换为计算所用类型
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static string ConvertCalcType(string instType)
+ public static string ConvertCalcType(string instType,bool pringScene = false)
{
+ if (pringScene && PS.Config.Company == Configuration.CompanyEnum.国联)
+ {
+ return Bonds;
+ }
switch (instType)
{
case Stock:
@@ -390,6 +403,8 @@ namespace YLErp
case TBFutures:
case OtherFutures:
case AbroadFutures:
+ case BondYield:
+ case BondIndex:
return CommodityFutures;
case CommoditySpot:
case GoldSpot:
@@ -414,7 +429,7 @@ namespace YLErp
public static string[] GetFutureTypes()
{
return new[] { CommodityFutures, StockIF,
- GoldFutures, TBFutures, AbroadFutures, OtherFutures };
+ GoldFutures, TBFutures, AbroadFutures, OtherFutures,BondYield,BondIndex };
}
///
@@ -458,7 +473,7 @@ namespace YLErp
Bonds,
TBonds,
CreditBonds,
- OtherBonds
+ OtherBonds,
};
}
}
diff --git a/Framework/YLErp.Core/YLErp.Core.csproj b/Framework/YLErp.Core/YLErp.Core.csproj
index f33b22cb..2677280c 100644
--- a/Framework/YLErp.Core/YLErp.Core.csproj
+++ b/Framework/YLErp.Core/YLErp.Core.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs b/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs
index 21aceac3..ec57f41b 100644
--- a/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs
+++ b/YLErpDAL/BLL/Calculation/V2/ValueCalculator.cs
@@ -1,4 +1,4 @@
-using Qdp.ComputeService.Data.CommonModels.ValuationParams.Equity;
+using Qdp.ComputeService.Data.CommonModels.ValuationParams.Equity;
using Qdp.ComputeService.Data.CommonModels.ValuationParams.FixedIncome;
using Qdp.ComputeServiceV2.Data.CommonModels.TradeInfos;
using Qdp.ComputeServiceV2.Data.CommonModels.TradeInfos.Options;
@@ -59,7 +59,7 @@ namespace YLErp.BLL.Calculation.V2
{
underlying = underlying.Clone();
- underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType);
+ underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType,true);
switch (trade.TradeType)
{
diff --git a/YLErpDAL/Model/EodPositionRisks.cs b/YLErpDAL/Model/EodPositionRisks.cs
index 7f124449..3669e15c 100644
--- a/YLErpDAL/Model/EodPositionRisks.cs
+++ b/YLErpDAL/Model/EodPositionRisks.cs
@@ -1,4 +1,4 @@
-using BaseOUDAL;
+using BaseOUDAL;
using YLErp.Commons;
using YLErp.Helpers;
using YLErp.Modules;
@@ -211,6 +211,27 @@ namespace YLErp.Model
public double DividendRate { get; set; }
+
+ ///
+ /// Delta_R
+ ///
+ public double? Delta_r { get; set; }
+
+ public double? Delta_r_1bp { get; set; }
+
+
+ public double? Dv01 { get; set; }
+
+ public double? Gamma_r { get; set; }
+
+ public double? Gamma_r_1bp { get; set; }
+
+ public double? Vega_r { get; set; }
+
+ public double? Vega_r_1bp { get; set; }
+
+
+
///
/// 维持预付金
///
diff --git a/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs b/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs
index 93b9fac1..2c4d6c45 100644
--- a/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs
+++ b/YLErpDAL/Modules/CalculationModule/Models/OptionCalcParam.cs
@@ -1,4 +1,4 @@
-using Qdp.Foundation.Implementations;
+using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Enums;
using Qdp.Pricing.Base.Implementations;
using YLErp.Enums;
@@ -105,7 +105,7 @@ namespace YLErp.Modules.CalculationModule
public string underlyingInstrumentType
{
get => _underlyingInstrumentType;
- set => _underlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(value);
+ set => _underlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(value,true);
}
///
diff --git a/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs b/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs
index 531afaed..add6c39d 100644
--- a/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs
+++ b/YLErpDAL/Modules/CalculationModule/OptionTradeAnalysisService.cs
@@ -1,4 +1,4 @@
-using Qdp.Foundation.Implementations;
+using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Base.Interfaces;
using Qdp.Pricing.Base.Utilities;
@@ -570,7 +570,7 @@ namespace YLErp.Modules.CalculationModule
{
underlying = underlying.Clone();
- underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType);
+ underlying.UnderlyingInstrumentType = ConsGlobal.InstrumentType.ConvertCalcType(underlying.UnderlyingInstrumentType,true);
switch (trade.TradeType)
{
diff --git a/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs b/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs
index c59eca99..3a5bf504 100644
--- a/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs
+++ b/YLErpDAL/Modules/DataProviderModule/EodPriceProvider.cs
@@ -1,4 +1,4 @@
-using YLErp.Abstract.DataProviders;
+using YLErp.Abstract.DataProviders;
using YLErp.Helpers;
using YLErp.Models;
using YLErp.Modules.TradeModule.DealModule;
@@ -118,13 +118,13 @@ namespace YLErp.Modules.DataProviderModule
ValueDate = ValueDate,
UnderlyingId = um.id,
UnderlyingCode = um.UnderlyingCode,
- ClosePrice = 0,
- SettlePrice = 0,
+ ClosePrice = (double)(eodprice.net_price ?? 0) / 100,
+ SettlePrice = (double)(eodprice.dirty_price_close ?? 0) / 100,
HighPrice = 0,
LowPrice = 0,
UnderlyingStatus = "正常运行",
UnderlyingInstrumentType = "Bonds",
- ReferencePrice = 0,
+ ReferencePrice = (double)(eodprice.yield ?? 0),
DeciSettlePrice = eodprice.dirty_price_close,
DeciClosePrice = eodprice.net_price,
DeciReferencePrice = eodprice.yield,
diff --git a/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs b/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs
index 9acddd70..821f5ae2 100644
--- a/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs
+++ b/YLErpDAL/Modules/EodModule/EodPositionRisksQueryService.cs
@@ -1,4 +1,4 @@
-using BaseOUDAL;
+using BaseOUDAL;
using System;
using System.Data;
using System.Diagnostics;
@@ -339,7 +339,9 @@ namespace YLErp.Modules.EodModule
var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费,
ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他};
-
+ var underlyingCodes = searchResult.rows.Select(O => O.UnderlyingCode).Distinct().ToList();
+ var greeksHandleService = new GLMSGreeksHandleService();
+ greeksHandleService.InitData(req.ValueDate, underlyingCodes);
foreach (var r in searchResult.rows)
{
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode);
@@ -470,6 +472,7 @@ namespace YLErp.Modules.EodModule
r.DeltaLots = (r.Delta ?? 0) / um.ContractSize;
}
r.Rho *= 100;
+ greeksHandleService.Handle(r);
if (r.trade == null)
{
r.TradeSinglePrice = r.etcTradePrice / r.TradeAmount;
@@ -1118,6 +1121,9 @@ namespace YLErp.Modules.EodModule
.AsEnumerable()
.GroupBy(O => O.ParentTradeId)
.ToDictionary(K => K.Key, V => V.Select(O => new xodTradeBase() { TradeJson = O.TradeJson }));
+ var underlyingCodes = searchResult.rows.Select(O => O.UnderlyingCode).Distinct().ToList();
+ var greeksHandleService = new GLMSGreeksHandleService();
+ greeksHandleService.InitData(req.ValueDate, underlyingCodes);
foreach (var r in searchResult.rows)
{
@@ -1200,6 +1206,7 @@ namespace YLErp.Modules.EodModule
}
r.Rho *= 100;
+ greeksHandleService.Handle(r);
r.CountRatio = um.CountRatio;
r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio;
r.etcTradePrice = ConsTrade.TradeTypesForHedge.Contains(r.TradeType)
@@ -1706,10 +1713,10 @@ namespace YLErp.Modules.EodModule
var results = GetEodPositionRisksDataHandle(req);
var list2 = results.Select(n => new ExpandoDictionary(n)).ToArray();
- var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险.xlsx");
+ var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险_国联.xlsx");
if (PS.Config.ErpElement.NeedShowSpv)
{
- templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险-Spv.xlsx");
+ templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx");
}
return ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = list2 }).GenerateBytes();
@@ -2016,6 +2023,17 @@ namespace YLErp.Modules.EodModule
dic.Add("Spv3", item.PnLDelta.OtcFormat(OtcFormatFlag.greek));
}
+ if (PS.Config.Company == Configuration.CompanyEnum.国联)
+ {
+ dic.Add("Delta_r", OtcFormatExtensions.OtcFormat(item.Delta_r, OtcFormatFlag.greek));
+ dic.Add("Delta_r_1bp", OtcFormatExtensions.OtcFormat(item.Delta_r_1bp, OtcFormatFlag.greek));
+ dic.Add("Dv01", OtcFormatExtensions.OtcFormat(item.Dv01, OtcFormatFlag.greek));
+ dic.Add("Gamma_r", OtcFormatExtensions.OtcFormat(item.Gamma_r, OtcFormatFlag.greek));
+ dic.Add("Gamma_r_1bp", OtcFormatExtensions.OtcFormat(item.Gamma_r_1bp, OtcFormatFlag.greek));
+ dic.Add("Vega_r", OtcFormatExtensions.OtcFormat(item.Vega_r, OtcFormatFlag.greek));
+ dic.Add("Vega_r_1bp", OtcFormatExtensions.OtcFormat(item.Vega_r_1bp, OtcFormatFlag.greek));
+ }
+
dic.Add("备注", item.Comments);
@@ -2115,6 +2133,17 @@ namespace YLErp.Modules.EodModule
dic.Add("Spv2", "");
dic.Add("Spv3", "");
}
+
+ if (PS.Config.Company == Configuration.CompanyEnum.国联)
+ {
+ dic.Add("Delta_r", "");
+ dic.Add("Delta_r_1bp", "");
+ dic.Add("Dv01", "");
+ dic.Add("Gamma_r", "");
+ dic.Add("Gamma_r_1bp", "");
+ dic.Add("Vega_r", "");
+ dic.Add("Vega_r_1bp", "");
+ }
results.Add(dic);
}
return results;
diff --git a/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs b/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs
new file mode 100644
index 00000000..4385923a
--- /dev/null
+++ b/YLErpDAL/Modules/EodModule/GLMSGreeksHandleService.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using YLErp.Model;
+
+namespace YLErp.Modules.EodModule
+{
+ ///
+ /// 国联民生 希腊字母计算
+ ///
+ public class GLMSGreeksHandleService
+ {
+
+ public void InitData(DateTime valueDate,List underlyingCodes)
+ {
+
+ }
+
+
+ public void Handle(EodPositionRisksDTO dto)
+ {
+ //对Delta_r Delta_r_1bp Dv01 Gamma_r Gamma_r_1bp Vega_r Vega_r_1bp
+
+ }
+ }
+}
diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs
index e071bb88..87af919a 100644
--- a/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs
+++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodCheckSettlePrice.cs
@@ -1,4 +1,4 @@
-using System.Linq;
+using System.Linq;
using System.Linq.Dynamic.Core;
using YLErp.Modules.DataProviderModule;
@@ -48,7 +48,7 @@ namespace YLErp.Modules.EodModule.SettlementModule
if (request.IsSettleOtcTrades)
{
var tradePredicate = _context.PredicateBuilder.GetOtcTradePredicate()
- .And(t => t.TradeType != "自定义交易" && t.TradeType != "收益互换" && t.UnderlyingCode != null);
+ .And(t => t.TradeType != "自定义交易" && t.UnderlyingCode != null);
//新增客户筛选 tw
if (clienIds != null)
@@ -58,6 +58,11 @@ namespace YLErp.Modules.EodModule.SettlementModule
allQuery = DbContext.trade.Where(tradePredicate).Select(n => n.UnderlyingCode).Distinct();
+ if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD)
+ {
+ allQuery = allQuery.Union(DbContext.trade.Where(tradePredicate).Where(x => x.BasisUnderlyingCode != null && x.BasisUnderlyingCode != "").Select(n => n.BasisUnderlyingCode).Distinct());
+ }
+
var clientProductPredicate = _context.PredicateBuilder.GetClientProductPredicate();
//新增客户筛选 tw
@@ -74,26 +79,28 @@ namespace YLErp.Modules.EodModule.SettlementModule
}
//检查场内标的
- //if (request.IsSettleExchangeTrades)
- //{
- // var exTradePredicate = _context.PredicateBuilder.GetExchangeTradePredicate();
+ if (request.IsSettleExchangeTrades)
+ {
+ var exTradePredicate = _context.PredicateBuilder.GetExchangeTradePredicate();
- // var exTradeQuery = DbContext.ExchangeTrade.Where(exTradePredicate).Select(n => n.UnderlyingCode);
+ var exTradeQuery = DbContext.ExchangeTrade.Where(exTradePredicate).Select(n => n.UnderlyingCode);
- // allQuery = allQuery == null ? exTradeQuery.Distinct() : allQuery.Union(exTradeQuery.Distinct());
+ allQuery = allQuery == null ? exTradeQuery.Distinct() : allQuery.Union(exTradeQuery.Distinct());
- // var preSettleDate = _context.PreSettleDate;
- // //最后一个交易日持仓信息
- // var futureTypes = ConsGlobal.InstrumentType.GetFutureTypes();
- // var positionQuery = from t in DbContext.eod_trade_position
- // join um in DbContext.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode
- // where t.ValueDate == preSettleDate && t.Amount != 0
- // && ConsTrade.TradeTypesForHedge.Contains(t.TradeType)
- // && (!futureTypes.Contains(um.UnderlyingInstrumentType) || um.MaturityDate >= settleDate)
- // select t.UnderlyingCode;
+ var preSettleDate = _context.PreSettleDate;
+ //最后一个交易日持仓信息
+ var futureTypes = ConsGlobal.InstrumentType.GetFutureTypes();
+ var positionQuery = from t in DbContext.eod_trade_position
+ join um in DbContext.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode
+ where t.ValueDate == preSettleDate && t.Amount != 0
+ && ConsTrade.TradeTypesForHedge.Contains(t.TradeType)
+ && (!futureTypes.Contains(um.UnderlyingInstrumentType) || um.MaturityDate >= settleDate)
+ select t.UnderlyingCode;
- // allQuery = allQuery.Union(positionQuery.Distinct());
- //}
+ allQuery = allQuery.Union(positionQuery.Distinct());
+ }
+
+
if (allQuery == null)
{
@@ -103,12 +110,10 @@ namespace YLErp.Modules.EodModule.SettlementModule
//检查是否所有标的都在结算日有结算价格
var umCodeArr = allQuery.ToArray();
- var swapUmCodeArr = GetSwapUnderlyingCodes();
- var codeArr = umCodeArr.Union(swapUmCodeArr);
- var eodPriceProvider = _context.GetEodPriceProvider().Initialize(codeArr);
- // var preEodPriceProvidaer = _context.GetPreEodPriceProvider().Initialize(swapUmCodeArr);
- var umCodes = codeArr.Where(n => !string.IsNullOrEmpty(n) && !eodPriceProvider.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase);
- //var swapUmCodes= swapUmCodeArr.Where(n => !string.IsNullOrEmpty(n) && !preEodPriceProvidaer.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase);
+
+ var eodPriceProvider = _context.GetEodPriceProvider().Initialize(umCodeArr);
+ var umCodes = umCodeArr.Where(n => !string.IsNullOrEmpty(n) && !eodPriceProvider.HasValue(n)).ToHashSet(StringComparer.OrdinalIgnoreCase);
+
//排除掉节假日不需要结算的交易
foreach (var t in _context.HolidayTrades)
{
diff --git a/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs b/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs
index 4980ca9a..699a1dd4 100644
--- a/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs
+++ b/YLErpDAL/Modules/TradeModule/OrderModule/TradeSavePreHandler.cs
@@ -1,4 +1,4 @@
-using BaseOUDAL;
+using BaseOUDAL;
using YLErp.BLL;
using YLErp.Configuration;
using YLErp.Configuration.Enums;
@@ -993,10 +993,10 @@ namespace YLErp.Modules.TradeModule.OrderModule
throw new ServiceException($"客户'{client.Name}'为非高风险客户,没有卖出权限");
}
- if (_underlying != null && _underlying.CalcTypeIsStock() && ((client.TradingInstType & TradingInstTypeEnum.Equity) != TradingInstTypeEnum.Equity))
- {
- throw new ServiceException($"客户'{client.Name}'的'交易资产'属性不包括'权益',不能进行权益类的期权交易");
- }
+ //if (_underlying != null && _underlying.CalcTypeIsStock() && ((client.TradingInstType & TradingInstTypeEnum.Equity) != TradingInstTypeEnum.Equity))
+ //{
+ // throw new ServiceException($"客户'{client.Name}'的'交易资产'属性不包括'权益',不能进行权益类的期权交易");
+ //}
if (PS.Config.ErpElement.SecuritiesEnvironment)
{
diff --git a/YLErpDAL/YLErpDAL.csproj b/YLErpDAL/YLErpDAL.csproj
index 8b50f99f..437f62a6 100644
--- a/YLErpDAL/YLErpDAL.csproj
+++ b/YLErpDAL/YLErpDAL.csproj
@@ -41,7 +41,7 @@
-
+
diff --git a/YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx b/YLErpWeb/App_Docs/导出模板/日终持仓风险-Spv_国联.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..827586a1200ee4f4cf0b173ee463843a720a089c
GIT binary patch
literal 11411
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
H=ePd@rG1^i
literal 0
HcmV?d00001
diff --git a/YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx b/YLErpWeb/App_Docs/导出模板/日终持仓风险_国联.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..9b4401374980cf8d61acad4a82377dba3e313e7e
GIT binary patch
literal 11419
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
literal 0
HcmV?d00001
diff --git a/YLErpWeb/Views/trade/EodPositionRisks.cshtml b/YLErpWeb/Views/trade/EodPositionRisks.cshtml
index d6831d6f..89b1e8b8 100644
--- a/YLErpWeb/Views/trade/EodPositionRisks.cshtml
+++ b/YLErpWeb/Views/trade/EodPositionRisks.cshtml
@@ -1,4 +1,4 @@
-@{
+@{
ViewBag.Title = "日终持仓风险";
Layout = "~/Views/Shared/_MainLayout.cshtml";
var settleConfig = PS.Config.GetSettlementConfig();
@@ -19,7 +19,8 @@
IsUseDisplayNotional = PS.Config.IsUseDisplayNotional,
showGuohai = PS.Config.Is国海,
isGuoyuan = PS.Config.Company==CompanyEnum.国元固收,
- isGuoJun = PS.Config.IsGuoJun
+ isGuoJun = PS.Config.IsGuoJun,
+ isGLMS = PS.Config.Company == CompanyEnum.国联
};
}