fix(EQD-7049): 期权定价页标的下拉改为服务端搜索,移除全量标的下载

- vueUnderlying.lookup 不再遍历全量 ylotc.underlyings(债券十几万量级导致 29s 下载/页面卡死),改为调用 /frontdata/AjaxGetUnderlyingSelect 按关键词服务端搜索
- 默认预拉 20 条(后端 MaxShowLength 硬截断),输入时异步搜索并刷新缓存(乱序响应由 token 丢弃)
- 移除 BasicDataJs 的 标的Live 参数消除全量标的下载;IsCombined 由 IsSynthetic||IsBasket 映射,保留期权黑名单护栏(BlackLimit=1)
- 同步修改东莞定制版 Structure_DZ
This commit is contained in:
hjhan
2026-08-14 17:06:08 +08:00
parent 4a3fee9292
commit fdf6357c4f
4 changed files with 116 additions and 36 deletions
+1 -1
View File
@@ -85,7 +85,7 @@
<script src="~/Statics/libs/sortable/Sortable.min.js"></script>
<script src="~/front/calendar?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Scripts/app/tradeHelper.js?v=@HtmlUtil.JsVersion"></script>
<script src="@HtmlUtil.BasicDataJs("品种", "标的Live", "客户")"></script>
<script src="@HtmlUtil.BasicDataJs("品种", "客户")"></script>
<script>
const pageObj = @Json.Serialize(pageObj);
const pageData = @Json.Serialize(pageData);
+1 -1
View File
@@ -77,7 +77,7 @@
<script src="~/Statics/libs/sortable/Sortable.min.js"></script>
<script src="~/front/calendar?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Scripts/app/tradeHelper.js?v=@HtmlUtil.JsVersion"></script>
<script src="@HtmlUtil.BasicDataJs("品种", "标的Live", "客户")"></script>
<script src="@HtmlUtil.BasicDataJs("品种", "客户")"></script>
<script src="~/Scripts/app/trade/settag.js?v=@HtmlUtil.JsVersion" type="text/javascript"></script>
<script type="text/javascript">
const HasEditTagPermission = @Json.Serialize(CurUser.系统管理.标签编辑权限);
@@ -109,9 +109,52 @@ const vueTradeType = function () {
};
};
//标的选择组件
//标的选择组件(EQD-7049:改为服务端搜索,不再依赖全量 ylotc.underlyings,避免十几万标的整段下载卡死)
const vueUnderlying = function () {
const _suggestionTpl = _.template($('#underlyingSuggestionTpl').html());
// 标的缓存:按 品种|关键词 隔离;乱序响应由 token 丢弃(helper 收在函数内,避免全局绑定冲突)
const _cache = {};
const _tokens = {};
function _fetch(varietyId, query, cb) {
var key = (varietyId || 0) + '|' + (query || '');
var token = (_tokens[key] = (_tokens[key] || 0) + 1);
var postData = {
FilterCode: (query || '').toUpperCase(),
VarietyId: varietyId || 0,
MaxShowLength: 20,
BlackLimit: 1,
UseForTrading: true,
IncludeMatured: true,
CheckLaunch: true
};
main.post('/frontdata/AjaxGetUnderlyingSelect', postData).done(function (res) {
if (_tokens[key] !== token) return; // 丢弃过期响应
var arr = (res && (res.obj || res.data)) || [];
var norm = arr.map(function (x) {
return {
Code: x.Code,
Name: x.Name,
InstrumentType: x.InstrumentType,
VarietyId: x.VarietyId,
Disallow: !!x.Disallow,
IsCombined: !!x.IsSynthetic || !!x.IsBasket,
BlackWhiteState: x.BlackWhiteState || 0,
PinYin: x.PinYin || ''
};
});
cb && cb(norm);
});
}
function _filter(list, query, varietyId) {
if (!query) return (list || []).slice(0, 20);
query = query.toUpperCase();
return (list || []).filter(function (x) {
if (varietyId && x.VarietyId !== varietyId) return false;
if (x.IsCombined) return false; // 与原逻辑一致:搜索时排除组合标的
return (x.Code && x.Code.toUpperCase().indexOf(query) !== -1)
|| (x.PinYin && x.PinYin.toUpperCase().indexOf(query) !== -1);
}).slice(0, 20);
}
return {
props: ['underlying'],
data() {
@@ -120,27 +163,24 @@ const vueUnderlying = function () {
mounted() {
var self = this;
this.jqInput = $(this.$el).children(0);
// EQD-7049:预拉默认20条(当前品种),避免下拉空白
_fetch(self.underlying.VarietyId, '', function (list) {
_cache[self.underlying.VarietyId || 0] = list;
try { $(self.jqInput).autocomplete('search', ''); } catch (e) {}
});
this.autoctrl = FastVue.autocomplete(this.jqInput, {
valueField: 'Code',
lookup(query, callback) {
var arr = [];
if (!query) {
var varietyId = self.underlying.VarietyId;
ylotc.underlyings.forEach(x => {
(!varietyId || x.VarietyId === varietyId) && arr.push(x);
});
} else {
query = query.toUpperCase();
ylotc.underlyings.forEach(x => {
if (x.Code.toUpperCase().indexOf(query) !== -1 || x.PinYin && x.PinYin.indexOf(query) !== -1 && !x.IsCombined) {
arr.push(x);
}
var varietyId = self.underlying.VarietyId;
var cached = _cache[varietyId || 0] || [];
var immediate = _filter(cached, query, varietyId);
if (query) {
// 有输入时异步向服务端搜索并刷新缓存(乱序响应由 token 丢弃)
_fetch(varietyId, query, function (list) {
_cache[varietyId || 0] = list;
});
}
if (arr.length < 30) {
arr = _.sortBy(arr, x => x.Code);
}
return arr;
return immediate;
},
onSelect(data) {
if (self.underlying !== data) {
@@ -108,9 +108,52 @@ const vueTradeType = function () {
};
};
//标的选择组件
//标的选择组件(EQD-7049:改为服务端搜索,不再依赖全量 ylotc.underlyings,避免十几万标的整段下载卡死)
const vueUnderlying = function () {
const _suggestionTpl = _.template($('#underlyingSuggestionTpl').html());
// 标的缓存:按 品种|关键词 隔离;乱序响应由 token 丢弃(helper 收在函数内,避免全局绑定冲突)
const _cache = {};
const _tokens = {};
function _fetch(varietyId, query, cb) {
var key = (varietyId || 0) + '|' + (query || '');
var token = (_tokens[key] = (_tokens[key] || 0) + 1);
var postData = {
FilterCode: (query || '').toUpperCase(),
VarietyId: varietyId || 0,
MaxShowLength: 20,
BlackLimit: 1,
UseForTrading: true,
IncludeMatured: true,
CheckLaunch: true
};
main.post('/frontdata/AjaxGetUnderlyingSelect', postData).done(function (res) {
if (_tokens[key] !== token) return; // 丢弃过期响应
var arr = (res && (res.obj || res.data)) || [];
var norm = arr.map(function (x) {
return {
Code: x.Code,
Name: x.Name,
InstrumentType: x.InstrumentType,
VarietyId: x.VarietyId,
Disallow: !!x.Disallow,
IsCombined: !!x.IsSynthetic || !!x.IsBasket,
BlackWhiteState: x.BlackWhiteState || 0,
PinYin: x.PinYin || ''
};
});
cb && cb(norm);
});
}
function _filter(list, query, varietyId) {
if (!query) return (list || []).slice(0, 20);
query = query.toUpperCase();
return (list || []).filter(function (x) {
if (varietyId && x.VarietyId !== varietyId) return false;
if (x.IsCombined) return false; // 与原逻辑一致:搜索时排除组合标的
return (x.Code && x.Code.toUpperCase().indexOf(query) !== -1)
|| (x.PinYin && x.PinYin.toUpperCase().indexOf(query) !== -1);
}).slice(0, 20);
}
return {
props: ['underlying'],
data() {
@@ -119,27 +162,24 @@ const vueUnderlying = function () {
mounted() {
var self = this;
this.jqInput = $(this.$el).children(0);
// EQD-7049:预拉默认20条(当前品种),避免下拉空白
_fetch(self.underlying.VarietyId, '', function (list) {
_cache[self.underlying.VarietyId || 0] = list;
try { $(self.jqInput).autocomplete('search', ''); } catch (e) {}
});
this.autoctrl = FastVue.autocomplete(this.jqInput, {
valueField: 'Code',
lookup(query, callback) {
var arr = [];
if (!query) {
var varietyId = self.underlying.VarietyId;
ylotc.underlyings.forEach(x => {
(!varietyId || x.VarietyId === varietyId) && arr.push(x);
});
} else {
query = query.toUpperCase();
ylotc.underlyings.forEach(x => {
if (x.Code.toUpperCase().indexOf(query) !== -1 || x.PinYin && x.PinYin.indexOf(query) !== -1 && !x.IsCombined) {
arr.push(x);
}
var varietyId = self.underlying.VarietyId;
var cached = _cache[varietyId || 0] || [];
var immediate = _filter(cached, query, varietyId);
if (query) {
// 有输入时异步向服务端搜索并刷新缓存(乱序响应由 token 丢弃)
_fetch(varietyId, query, function (list) {
_cache[varietyId || 0] = list;
});
}
if (arr.length < 30) {
arr = _.sortBy(arr, x => x.Code);
}
return arr;
return immediate;
},
onSelect(data) {
if (self.underlying !== data) {