Files
zszq-trs/YLErpWeb/wwwroot/Scripts/app/marginTemplate/marginTemplateV2Edit.js
T

560 lines
31 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//定价格式化(来自配置)
const inputFormatPercent = Object.freeze({ precision: 2, append: '%' });
const inputFormatPercentNegative = Object.freeze({ precision: 2, append: '%', negative: true });
const inputFormatNegative = Object.freeze({ precision: 2, negative: true });
const MarginRuleTypeEnum = {
无预付金: "0",
按固定利率: "1",
按浮动盈亏: "2",
类香草预付金规则: "3",
自动赎回买入预付金规则: "4",
触发条件预付金规则1: "5",
触发条件预付金规则2: "6",
保底预付金规则: "7",
含赔付预付金计算规则: "8",
触发条件预付金规则3: "9",
交易所基本规则: "10",
标准SPAN: "11",
买入自动赎回规则1: "12",
卖出自动赎回规则1: "13",
区间追保结构: "15",
单独计算规则: "98"
};
const UnderlyingSeperateTypeEnum = {
None: "0",//不区分
CustomStock: "1",//按自定义权益分类
CustomInstrumentType: "2"//按资产类型分类
};
//允许配置期限档(SpanConfig.BondTerm)的标的资产类型标志位掩码,
//与后端 ConsMarginTerm.TermTierEnabledUnderlyingTypes 保持一致(本期仅 利率债 TBonds=1<<4=16
const TermTierEnabledUnderlyingMask = 16;
//利率债区块固定展开的4个期限档([BondTerm值, 展示文案]),与 docx 原型 4.3.1 一致
const SpanBondTerms = [['<5y', '≤5y'], ['5y-10y', '(5y-10y]'], ['10y-30y', '(10y-30y]'], ['>30y', '>30y']];
//区块键自增序号(仅前端分组用,不持久化)
var spanBlockSeq = 0;
//标的资产类型标志位 -> 名称(与明细表格 chosen 选项一致,用于规则15录入区块标题)
const UnderlyingTypeNames = [
[16, "利率债"], [32, "信用债"], [64, "其它债券"], [128, "股票"], [256, "股指"], [512, "股指期货"],
[1024, "商品期货"], [2048, "商品现货"], [4096, "新三板挂牌股票"], [8192, "香港股票"], [16384, "香港股指"],
[32768, "基金及基金专户"], [65536, "黄金期货"], [131072, "国债期货"], [262144, "其他期货"], [524288, "黄金现货"],
[1048576, "其他现货"], [2097152, "境外期货"], [4194304, "境外现货"], [8388608, "境外股票"], [16777216, "境外股指"],
[33554432, "汇率"], [67108864, "Shibor"], [134217728, "银行间回购定盘"], [268435456, "利率收益率"], [536870912, "债券指数"]
];
const vue = new Vue({
el: '#marginTemplateV2Form',
data: {
isAdd: page.isAdd,
marginTemplate: page.marginTemplate
},
created: function () {
//区间追保结构:加载时按 资产类型+期限 排序一次,再重建资产类型区块(利率债区块补齐固定4档),
//编辑过程中不再重排,避免 chosen/选择器失序
if (this.marginTemplate.RuleType == MarginRuleTypeEnum.区间追保结构 && this.marginTemplate.Details) {
var termOrder = ['', '<5y', '5y-10y', '10y-30y', '>30y'];
var that = this;
this.marginTemplate.Details.forEach(function (d) {
//兜底:历史数据可能没有 SpanConfig / 区间录入结构,补齐避免录入区块不渲染
that.ensureSpanDetail(d);
});
this.marginTemplate.Details.sort(function (a, b) {
var at = a.UnderlyingType || 0, bt = b.UnderlyingType || 0;
if (at !== bt) return at - bt;
var ai = termOrder.indexOf((a.SpanConfig && a.SpanConfig.BondTerm) || '');
var bi = termOrder.indexOf((b.SpanConfig && b.SpanConfig.BondTerm) || '');
return (ai < 0 ? termOrder.length : ai) - (bi < 0 ? termOrder.length : bi);
});
this.marginTemplate.Details = this.rebuildSpanBlocks(this.marginTemplate.Details);
}
this.changeRuleType(true);
},
computed: {
//区间追保结构:参数组按资产类型区块展示,相邻且区块键(_bk)相同的行合并(rowspan)。
//_bk 由 加载重建/新增/切换资产类型 时维护:利率债区块含固定4档行,其他区块单行。
ruleRangeDetailRows() {
var details = this.marginTemplate.Details || [];
var keyOf = function (d, i) {
return d._bk || ('idx_' + i);
};
var rows = [];
for (var i = 0; i < details.length; i++) {
var key = keyOf(details[i], i);
if (i > 0 && keyOf(details[i - 1], i - 1) === key) {
rows.push({ detail: details[i], index: i, rowspan: 0 });
continue;
}
var span = 1;
for (var j = i + 1; j < details.length; j++) {
if (keyOf(details[j], j) !== key) break;
span++;
}
rows.push({ detail: details[i], index: i, rowspan: span });
}
return rows;
},
//区间追保结构录入区块:每个资产类型区块一个;纯利率债(ut=16)区块固定展开4个期限档段(每段一条 detail),
//其他区块单段(BondTerm 为空)。段的 detail 缺失时模板侧 v-if 兜底不渲染该段
ruleRangeBlocks() {
if (this.marginTemplate.RuleType != MarginRuleTypeEnum.区间追保结构) return [];
var blocks = [];
var rows = this.ruleRangeDetailRows;
var details = this.marginTemplate.Details || [];
for (var i = 0; i < rows.length; i++) {
if (rows[i].rowspan <= 0) continue;
var head = rows[i];
var ut = head.detail.UnderlyingType || 0;
var isTBond = ut === 16;
var sections = [];
if (isTBond) {
for (var t = 0; t < SpanBondTerms.length; t++) {
var found = null;
for (var j = head.index; j < head.index + head.rowspan; j++) {
var bt = (details[j].SpanConfig && details[j].SpanConfig.BondTerm) || '';
if (bt === SpanBondTerms[t][0]) { found = details[j]; break; }
}
sections.push({ key: SpanBondTerms[t][0], termLabel: SpanBondTerms[t][1], detail: found });
}
} else {
sections.push({ key: 'single', termLabel: '', detail: head.detail });
}
blocks.push({ key: head.detail._bk || ('i' + head.index), no: blocks.length + 1, headIndex: head.index, ut: ut, isTBond: isTBond, sections: sections });
}
return blocks;
}
},
methods: {
changeRuleType(isInitial) {
switch (this.marginTemplate.RuleType.toString()) {
case MarginRuleTypeEnum.无预付金:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为零。";
break;
case MarginRuleTypeEnum.按固定利率:
this.marginTemplate.Comments = "预付金占用为成交/实时名义本金的固定比例。";
break;
case MarginRuleTypeEnum.按浮动盈亏:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为成交/实时名义本金的固定比例,加上对手方交易浮动亏损,扣除对手方交易浮动盈利。";
break;
case MarginRuleTypeEnum.类香草预付金规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为为成交/实时名义本金的浮动比例,加上对手方交易浮动亏损。浮动比例依据标的涨跌停情况判断。";
break;
case MarginRuleTypeEnum.自动赎回买入预付金规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为n+2(≤N)个票息之和,N为合约期内敲出观察日总数,n为当前经过的敲出观察日个数(当n+2>N时,n = N - 2)。";
break;
case MarginRuleTypeEnum.触发条件预付金规则1:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为成交名义本金的固定比例,加标的跌幅的市值(跌幅达到一定条件触发)";
break;
case MarginRuleTypeEnum.触发条件预付金规则2:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为成交/实时名义本金的固定比例,加标的跌幅的市值(跌幅达到一定条件触发)";
break;
case MarginRuleTypeEnum.触发条件预付金规则3:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为成交/实时名义本金的固定比例,加上对手方分段式交易浮动亏损(涨跌幅达到一定条件触发)";
break;
case MarginRuleTypeEnum.保底预付金规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为对手方最大亏损金额。";
break;
case MarginRuleTypeEnum.含赔付预付金计算规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "预付金占用为对手方最大赔付金额。";
break;
case MarginRuleTypeEnum.交易所基本规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "交易所基本规则";
break;
case MarginRuleTypeEnum.标准SPAN:
this.marginTemplate.Comments = "计算标的价格和波动率上涨下跌4个场景下的对手方最大亏损";
break;
case MarginRuleTypeEnum.买入自动赎回规则1:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "Minx*首次票息金额+y*Max(0,Pv),合约期间全部票息金额);\n若勾选了“取与保底金额孰小”,则还要与取较小的一个;\n保底金额 =ABS(执行价格 - 保底价格)* ABS(交易数量)。";
break;
case MarginRuleTypeEnum.卖出自动赎回规则1:
this.marginTemplate.Comments = "名义本金*Maxx,y-0.5*虚值比例)+ Flag*Max(0,PV)\n其中虚值比例 = max(0, P - 执行价)/期初价格,当计算日为成交日时,Flag = 0,P = 期初价格,当计算日不为成交日时,Flag = 1,P = 标的现价;\n若勾选了“取与保底金额孰小”,则取较小的一个;\n保底金额 =ABS(执行价格 - 保底价格)* ABS(交易数量)。";
break;
case MarginRuleTypeEnum.区间追保结构:
this.marginTemplate.Comments = "预付金占用为名义本金的固定比例。按利率债期限(<5y/5y-10y/10y-30y/>30y)分别设置预警线/平仓线与多空各4层追保价格区间及追保金额比例,支持再按标的资产类型(利率债/信用债/其它债券/股票/股指等全部资产类型)分组;以期初净价为基准,标的价格落入录入的追保区间时按对应比例追保,触及预警线/平仓线时触发预警或平仓。";
break;
case MarginRuleTypeEnum.单独计算规则:
this.marginTemplate.UnderlyingSeperateType = UnderlyingSeperateTypeEnum.None;
this.marginTemplate.Comments = "基于宏源定制的预付金规则,用于计算单笔交易,不参与Span预付金规则的轧差。";
break;
default:
this.marginTemplate.Comments = "";
break;
}
this.changeUnderlyingSeperateType(isInitial);
},
changeUnderlyingSeperateType(isInitial) {
if (isInitial && this.marginTemplate.Details.length >= 1) {
return;
}
if (this.marginTemplate.UnderlyingSeperateType == UnderlyingSeperateTypeEnum.None) {
this.marginTemplate.UnderlyingSeperateComments = "无论挂钩标的代码为何,都采用同一套参数";
} else if (this.marginTemplate.UnderlyingSeperateType == UnderlyingSeperateTypeEnum.CustomInstrumentType) {
this.marginTemplate.UnderlyingSeperateComments = "按标的的资产类型分类:在每组参数中选择适用的资产类型(利率债/信用债/其它债券/股票/股指/商品期货等全部资产类型),按标的资产类型匹配对应参数组的区间追保参数。";
} else {
this.marginTemplate.UnderlyingSeperateComments = "把所有标的根据代码所属区间段自动分为4类:\n【1-指数】沪深指数;\n【2-个股/ETF-核准制发行】主板股票、非科创版ETF;\n【3-个股/ETF-非核准制发行】科创版股票、科创版ETF、创业板股票;\n【4-其他】所有不满足以上分类的。";
}
let that = this
new Promise((reslove) => {
that.marginTemplate.Details = [];
reslove();
}).then(() => {
var needDetailRules = [];
needDetailRules.push(MarginRuleTypeEnum.按固定利率);
needDetailRules.push(MarginRuleTypeEnum.按浮动盈亏);
needDetailRules.push(MarginRuleTypeEnum.类香草预付金规则);
needDetailRules.push(MarginRuleTypeEnum.触发条件预付金规则1);
needDetailRules.push(MarginRuleTypeEnum.触发条件预付金规则2);
needDetailRules.push(MarginRuleTypeEnum.触发条件预付金规则3);
needDetailRules.push(MarginRuleTypeEnum.标准SPAN);
needDetailRules.push(MarginRuleTypeEnum.买入自动赎回规则1);
needDetailRules.push(MarginRuleTypeEnum.卖出自动赎回规则1);
needDetailRules.push(MarginRuleTypeEnum.区间追保结构);
needDetailRules.push(MarginRuleTypeEnum.单独计算规则);
if (needDetailRules.indexOf(that.marginTemplate.RuleType.toString()) >= 0) {
new Promise((reslove) => {
//规则15:新增的是"资产类型区块"(含区间录入结构与独立区块键);其他规则维持原样
if (that.marginTemplate.RuleType == MarginRuleTypeEnum.区间追保结构) {
var d = that.newSpanDetail(0, '');
Vue.set(d, '_bk', 'bk_' + (++spanBlockSeq));
that.marginTemplate.Details.push(d);
} else {
that.marginTemplate.Details.push(_.cloneDeep(page.detail));
}
reslove();
}).then(() => {
SetAceDropDown();
})
}
})
},
sum(items) {
var total = 0;
if (items) {
for (var index = 0; index < items.length; index++) {
total = total + parseFloat(items[index]);
}
}
return total;
},
saveMarginTemplateV2() {
if (!this.marginTemplate.Name) {
main.message("模板名称不能为空");
return;
}
this.marginTemplate.TradeTypes = $("#tradeTypes").val().join(",");
this.marginTemplate.IsDefault = false;
var that = this;
this.marginTemplate.Details.forEach((detail, index) => {
if (that.marginTemplate.UnderlyingSeperateType == 0) {
detail.UnderlyingType = 15;//15 = UnderlyingTypeEnum.All:不区分时的惰性通配值,与后端枚举对齐
}
detail.SpanConfigJson = JSON.stringify(detail.SpanConfig);
});
if (that.marginTemplate.UnderlyingSeperateType != 0) {
if (that.marginTemplate.RuleType == MarginRuleTypeEnum.区间追保结构) {
//区间追保结构表格:按区块取值——区块首行读选择器,被合并的档位行跟随本区块(区块内资产类型一致)
var groupValue = 0;
that.ruleRangeDetailRows.forEach((row) => {
if (row.rowspan > 0) {
var ut = $("#UnderlyingType" + row.index).val();
groupValue = ut ? that.sum(ut) : (row.detail.UnderlyingType || 0);
//与 onUnderlyingTypeChange 同口径兜底:含利率债(位16)时只能单选利率债
if ((groupValue & TermTierEnabledUnderlyingMask) > 0) groupValue = TermTierEnabledUnderlyingMask;
}
row.detail.UnderlyingType = groupValue;
});
}
else {
that.marginTemplate.Details.forEach((detail, index) => {
//本页仅规则15 表格渲染资产类型选择器;其他规则下元素不存在时保持原值不回写,避免静默清零
var $el = $("#UnderlyingType" + index);
if ($el.length) {
detail.UnderlyingType = that.sum($el.val());
}
});
}
}
main.post("/margin_template_v2/saveMarginTemplateV2", { marginTemplate: this.marginTemplate }).done(function (resp) {
try {
window.parent.reloadmargin_template();
(parent || window).layer.closeAll();
} catch (e) { }
});
},
addDetail() {
let that = this
new Promise((reslove) => {
//规则15:新增参数组=新增一个资产类型区块(默认未选资产类型,单行;选成纯利率债时自动展开4档)
if (that.marginTemplate.RuleType == MarginRuleTypeEnum.区间追保结构) {
var d = that.newSpanDetail(0, '');
Vue.set(d, '_bk', 'bk_' + (++spanBlockSeq));
that.marginTemplate.Details.push(d);
} else {
that.marginTemplate.Details.push(_.cloneDeep(page.detail));
}
reslove();
}).then(() => {
that.refreshChosen();
})
},
deleteDetail(index) {
//规则15:删除区块=删除该区块全部 detail 行(利率债区块4行、其他区块1行)
if (this.marginTemplate.RuleType == MarginRuleTypeEnum.区间追保结构) {
var rows = this.ruleRangeDetailRows;
for (var i = 0; i < rows.length; i++) {
if (rows[i].index === index) {
this.marginTemplate.Details.splice(index, Math.max(rows[i].rowspan, 1));
break;
}
}
} else {
this.marginTemplate.Details.splice(index, 1);
}
this.refreshChosen();
},
//资产类型 chosen 变更(区块级):含利率债(位16)时强制单选利率债;
//纯利率债区块改为不含利率债时先弹确认(4档收缩为1条,其余3档录入数据将丢弃);
//反向(非利率债 → 利率债展开4档)保留已有数据,无需确认
onUnderlyingTypeChange(index) {
var ut = this.sum($("#UnderlyingType" + index).val());
if ((ut & TermTierEnabledUnderlyingMask) > 0) ut = TermTierEnabledUnderlyingMask;
var rows = this.ruleRangeDetailRows;
var head = null;
for (var i = 0; i < rows.length; i++) {
if (rows[i].index === index) { head = rows[i]; break; }
}
if (!head) return;
if ((head.detail.UnderlyingType || 0) === TermTierEnabledUnderlyingMask && ut !== TermTierEnabledUnderlyingMask) {
var that = this;
main.confirm("该区块当前为利率债分档配置,改为其他资产类型后其余期限档的录入内容将被清除,确认修改?", function () {
that.applyUnderlyingTypeChange(index, ut);
}, function () {
//取消:Vue 数据未动,翻转一次 UnderlyingType 强制重渲染 select,再由 chosen 重读选中态回退为纯利率债
head.detail.UnderlyingType = 0;
Vue.nextTick(function () {
head.detail.UnderlyingType = TermTierEnabledUnderlyingMask;
that.refreshChosen();
});
});
return;
}
this.applyUnderlyingTypeChange(index, ut);
},
//区块资产类型变更的实际落地(onUnderlyingTypeChange 确认后调用):
//ut=纯利率债 → 区块固定展开4个期限档 detail(保留已有档位行数据,缺档补新行);
//否则 → 区块收敛为单条 detail(BondTerm 置空,保留首行数据)
applyUnderlyingTypeChange(index, ut) {
var rows = this.ruleRangeDetailRows;
var head = null;
for (var i = 0; i < rows.length; i++) {
if (rows[i].index === index) { head = rows[i]; break; }
}
if (!head) return;
var details = this.marginTemplate.Details;
var headDetail = head.detail;
var bk = headDetail._bk;
if (!bk) {
bk = 'bk_' + (++spanBlockSeq);
Vue.set(headDetail, '_bk', bk);
}
var oldCount = Math.max(head.rowspan, 1);
if (ut === TermTierEnabledUnderlyingMask) {
var byTerm = {};
details.slice(index, index + oldCount).forEach(function (r) {
var bt = (r.SpanConfig && r.SpanConfig.BondTerm) || '';
if (!byTerm[bt]) byTerm[bt] = r;
});
var merged = [];
for (var t = 0; t < SpanBondTerms.length; t++) {
var r = byTerm[SpanBondTerms[t][0]] || (t === 0 ? headDetail : null);
if (!r) r = this.newSpanDetail(TermTierEnabledUnderlyingMask, SpanBondTerms[t][0]);
r.UnderlyingType = TermTierEnabledUnderlyingMask;
r.SpanConfig.BondTerm = SpanBondTerms[t][0];
Vue.set(r, '_bk', bk);
merged.push(r);
}
details.splice.apply(details, [index, oldCount].concat(merged));
} else {
headDetail.UnderlyingType = ut;
if (headDetail.SpanConfig) headDetail.SpanConfig.BondTerm = '';
if (oldCount > 1) details.splice(index + 1, oldCount - 1);
}
this.refreshChosen();
},
//行合并重组/删除后重渲染:SetAceDropDown 只增强新出现的 select(已初始化的会跳过,见 MyJs.js:137-138),
//chosen:updated 让被 Vue 复用的 select 按最新 :selected 重读选中态,两者需同时执行
refreshChosen() {
Vue.nextTick(function () {
SetAceDropDown();
$('.chosen-select').trigger('chosen:updated');
});
},
//新建一条规则15 detail:克隆 page.detail 模板行,设置资产类型/期限档,并补齐区间录入结构
newSpanDetail(ut, bondTerm) {
var d = _.cloneDeep(page.detail);
d.UnderlyingType = ut;
this.ensureSpanDetail(d);
d.SpanConfig.BondTerm = bondTerm || '';
return d;
},
//存量回显重建资产类型区块(分配区块键 _bk):连续的纯利率债行归为一个区块并按固定4档补齐(缺档补空行);
//同档重复/异常档的利率债行、非利率债行均各自独立成块展示,不丢数据
rebuildSpanBlocks(details) {
var termValues = SpanBondTerms.map(function (t) { return t[0]; });
var result = [];
var that = this;
var i = 0;
while (i < details.length) {
var d = details[i];
var ut = d.UnderlyingType || 0;
if (ut === TermTierEnabledUnderlyingMask) {
var rows = [];
while (i < details.length && (details[i].UnderlyingType || 0) === TermTierEnabledUnderlyingMask) {
rows.push(details[i]);
i++;
}
var byTerm = {};
var anomalies = [];
rows.forEach(function (r) {
var bt = (r.SpanConfig && r.SpanConfig.BondTerm) || '';
if (termValues.indexOf(bt) >= 0 && !byTerm[bt]) byTerm[bt] = r; else anomalies.push(r);
});
var bk = 'bk_' + (++spanBlockSeq);
termValues.forEach(function (t) {
var r = byTerm[t];
if (!r) r = that.newSpanDetail(TermTierEnabledUnderlyingMask, t);
r.UnderlyingType = TermTierEnabledUnderlyingMask;
r.SpanConfig.BondTerm = t;
Vue.set(r, '_bk', bk);
result.push(r);
});
anomalies.forEach(function (r) {
Vue.set(r, '_bk', 'bk_' + (++spanBlockSeq));
result.push(r);
});
} else {
Vue.set(d, '_bk', 'bk_' + (++spanBlockSeq));
result.push(d);
i++;
}
}
return result;
},
underlyingTypeNames(mask) {
mask = parseInt(mask) || 0;
if (mask === 0) return "全部";
var names = [];
for (var i = 0; i < UnderlyingTypeNames.length; i++) {
if ((mask & UnderlyingTypeNames[i][0]) > 0) names.push(UnderlyingTypeNames[i][1]);
}
return names.length > 0 ? names.join("、") : "全部";
},
bondTermLabel(detail) {
var v = (detail.SpanConfig && detail.SpanConfig.BondTerm) || '';
var map = { '': '全部', '<5y': '≤5y', '5y-10y': '(5y-10y]', '10y-30y': '(10y-30y]', '>30y': '>30y' };
return map[v] !== undefined ? map[v] : v;
},
//规则15录入区块文案:按 detail 资产类型切换计价口径。
//债券类(利率债16/信用债32/其它债券64)及其他类型(默认债券口径):期初净价/当前净价,金额=×期初全价×券面总额;
//基金及基金专户(32768)/债券指数(536870912):参考标的期初净价/参考标的当前收盘价(空头各层统一收盘价,BUG-11 修正),
//金额=×参考标的期初价格×参考标的名义份额。
spanText(detail) {
var ut = (detail && detail.UnderlyingType) || 0;
if ((ut & 32768) > 0 || (ut & 536870912) > 0) {
return {
priceInit: '参考标的期初净价',
priceCur: '参考标的当前净价',
priceCurShort1: '参考标的当前收盘价',
priceCurShort: '参考标的当前收盘价',
amountBase: '参考标的期初价格 × 参考标的名义份额'
};
}
return {
priceInit: '期初净价',
priceCur: '当前净价',
priceCurShort1: '当前净价',
priceCurShort: '当前净价',
amountBase: '期初全价 × 券面总额'
};
},
//4个空追保区间 tier(区间边界/金额比例均存小数,null=未填)
emptySpanTiers() {
var tiers = [];
for (var i = 0; i < 4; i++) tiers.push({ Lower: null, Upper: null, AmountRate: null });
return tiers;
},
//规则15:补齐区间录入结构——SpanConfig 缺省时补空对象,WarnLine/CloseLine 缺键时补 null
//LongSpans/ShortSpans 非数组或为空时初始化为4个空 tier,tier 缺键补齐(全程 Vue.set 保证响应式,v-model 绑定点必须预先存在)
ensureSpanDetail(detail) {
if (!detail.SpanConfig) Vue.set(detail, 'SpanConfig', { BondTerm: '' });
var sc = detail.SpanConfig;
if (sc.WarnLine === undefined) Vue.set(sc, 'WarnLine', null);
if (sc.CloseLine === undefined) Vue.set(sc, 'CloseLine', null);
var that = this;
['LongSpans', 'ShortSpans'].forEach(function (key) {
if (!Array.isArray(sc[key]) || sc[key].length === 0) Vue.set(sc, key, that.emptySpanTiers());
for (var i = 0; i < 4; i++) {
if (!sc[key][i]) Vue.set(sc[key], i, { Lower: null, Upper: null, AmountRate: null });
if (sc[key][i].Lower === undefined) Vue.set(sc[key][i], 'Lower', null);
if (sc[key][i].Upper === undefined) Vue.set(sc[key][i], 'Upper', null);
if (sc[key][i].AmountRate === undefined) Vue.set(sc[key][i], 'AmountRate', null);
}
});
}
},
components: {
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput()
}
});
$(function () {
$(".datepicker").change(function () {
var dateVal = $(this).val();
if (!dateVal) return;
dateVal = dateVal.replace(/\D/g, '').padStart(4, '0');
switch (dateVal.length) {
case 4:
dateVal = new Date().getFullYear() + dateVal; break;
case 6:
dateVal = '20' + dateVal; break;
case 8: break;
default:
dateVal = dateVal.length > 8 ? dateVal.substring(0, 8) : ''; break;
}
if (dateVal) {
dateVal = moment(dateVal).format('YYYY-MM-DD');
!/^\d+/.test(dateVal) && (dateVal = '');
}
$(this).datepicker("setDate", dateVal);
});
//chosen 选中变化通过 jQuery trigger("change") 通知(chosen.jquery.js trigger_form_field_change),
//Vue 的 v-on:change(原生监听)收不到,这里用 jQuery 委托监听规则15区块的资产类型选择器
$(document).on('change', 'select.chosen-select[id^="UnderlyingType"]', function () {
var idx = parseInt(this.id.substring('UnderlyingType'.length));
if (!isNaN(idx)) vue.onUnderlyingTypeChange(idx);
});
SetAceDropDown();
});