From 045361dd9b0eecb198cbeff52bc7620176a8cb95 Mon Sep 17 00:00:00 2001 From: hjhan Date: Mon, 13 Jul 2026 13:25:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=97=A5=E7=BB=88=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=87=E7=9A=84=E4=BB=A3=E7=A0=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=BE=93=E5=85=A5=E8=81=94=E6=83=B3=EF=BC=88=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF=E6=A8=A1=E7=B3=8A=E5=8C=B9=E9=85=8D+?= =?UTF-8?q?=E5=8E=9F=E7=94=9F=E4=B8=8B=E6=8B=89=EF=BC=8C=E9=98=B2=E5=A1=AB?= =?UTF-8?q?=E9=94=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SuggestUnderlyingForEod(code,kind):按代码/名称 LIKE 匹配、Take(20)、强制 LaunchState==1 与类型,与列表查询/Lookup 三处口径一致 - 三个编辑页代码输入框加 oninput 防抖联想,原生 fixed 下拉展示候选,点选回填精确代码并复用失焦校验带出市场;期货额外回填 UnderlyingId - 不依赖任何前端自动补全插件(jQuery UI 未打包),可支撑几十万标的数据量 --- YLErpWeb/Controllers/EodPriceController.cs | 57 ++++++++++++++++++ .../Views/EodPrice/eodBondPriceEdit.cshtml | 59 +++++++++++++++++- .../Views/EodPrice/eodFuturePriceEdit.cshtml | 59 +++++++++++++++++- .../Views/EodPrice/eodStockPriceEdit.cshtml | 60 ++++++++++++++++++- 4 files changed, 232 insertions(+), 3 deletions(-) diff --git a/YLErpWeb/Controllers/EodPriceController.cs b/YLErpWeb/Controllers/EodPriceController.cs index 91ce6409..62747ff9 100644 --- a/YLErpWeb/Controllers/EodPriceController.cs +++ b/YLErpWeb/Controllers/EodPriceController.cs @@ -176,6 +176,63 @@ namespace YLErp.Web.Controllers Market = u.MarketName, }); } + + /// + /// 新建日终价格时,按手工输入的片段做服务端模糊联想(代码或名称包含匹配),只回前 20 条。 + /// 与 LookupUnderlyingForEod 同样只返回已上市(LaunchState=="1")且类型匹配的标的。 + /// 用原生下拉渲染(不依赖 jQuery UI,bundle 未打包),避免几十万标的全量渲染卡死。 + /// + [HttpPost] + public JsonResult SuggestUnderlyingForEod(string q, string kind) + { + if (string.IsNullOrWhiteSpace(q)) + { + return JsonSuccess("", new List()); + } + q = q.Trim(); + + string[] types = kind switch + { + "future" => new[] + { + ConsGlobal.InstrumentType.CommodityFutures, + ConsGlobal.InstrumentType.GoldFutures, + ConsGlobal.InstrumentType.TBFutures, + ConsGlobal.InstrumentType.OtherFutures, + ConsGlobal.InstrumentType.AbroadFutures, + }, + "stock" => new[] + { + ConsGlobal.InstrumentType.Stock, + ConsGlobal.InstrumentType.StockIndex, + ConsGlobal.InstrumentType.StockIF, + ConsGlobal.InstrumentType.HKStock, + ConsGlobal.InstrumentType.HKStockIndex, + ConsGlobal.InstrumentType.NewOtcStock, + ConsGlobal.InstrumentType.AbroadStock, + ConsGlobal.InstrumentType.AbroadStockIndex, + }, + _ => new[] + { + ConsGlobal.InstrumentType.Bonds, + ConsGlobal.InstrumentType.TBonds, + ConsGlobal.InstrumentType.CreditBonds, + ConsGlobal.InstrumentType.OtherBonds, + }, + }; + var set = new HashSet(types); + + var list = yldb.underlying_manager + .Where(n => n.LaunchState == "1" && set.Contains(n.UnderlyingInstrumentType) + && (n.UnderlyingCode.Contains(q) || n.UnderlyingName.Contains(q))) + .OrderBy(n => n.UnderlyingCode) + .Take(20) + .Select(n => new { n.id, Code = n.UnderlyingCode, Name = n.UnderlyingName, Market = n.MarketName }) + .ToList(); + + return JsonSuccess("", list); + } + [HttpPost] public JsonResult EodFuturePriceEditJson(eod_commodity_future_price req) { diff --git a/YLErpWeb/Views/EodPrice/eodBondPriceEdit.cshtml b/YLErpWeb/Views/EodPrice/eodBondPriceEdit.cshtml index 7a0a89c9..417f5c25 100644 --- a/YLErpWeb/Views/EodPrice/eodBondPriceEdit.cshtml +++ b/YLErpWeb/Views/EodPrice/eodBondPriceEdit.cshtml @@ -43,6 +43,63 @@ }); } + // 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件 + var _eodSuggestTimer = null; + function eodSuggest(input, kind) { + clearTimeout(_eodSuggestTimer); + var q = (input.value || '').trim(); + if (q.length < 1) { eodHideSuggest(); return; } + _eodSuggestTimer = setTimeout(function () { + main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) { + if (res.success && res.obj && res.obj.length) { + eodRenderSuggest(res.obj, input, kind); + } else { + eodHideSuggest(); + } + }); + }, 250); + } + function eodRenderSuggest(list, input, kind) { + var box = document.getElementById('eodSuggestBox'); + if (!box) return; + box.innerHTML = ''; + list.forEach(function (item) { + var div = document.createElement('div'); + div.className = 'eod-suggest-item'; + var code = document.createElement('span'); + code.className = 'eod-suggest-code'; + code.textContent = item.Code; + var name = document.createElement('span'); + name.className = 'eod-suggest-name'; + name.textContent = item.Name || ''; + div.appendChild(code); div.appendChild(name); + div.onmousedown = function (e) { + e.preventDefault(); + input.value = item.Code; + eodHideSuggest(); + var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind]; + if (fn) fn(); + }; + box.appendChild(div); + }); + var r = input.getBoundingClientRect(); + box.style.left = r.left + 'px'; + box.style.top = (r.bottom + 2) + 'px'; + box.style.width = Math.max(r.width, 220) + 'px'; + box.style.display = 'block'; + } + function eodHideSuggest() { + var b = document.getElementById('eodSuggestBox'); + if (b) b.style.display = 'none'; + } + document.addEventListener('click', function (e) { + var b = document.getElementById('eodSuggestBox'); + if (b && b.style.display === 'block' && !b.contains(e.target) + && e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') { + b.style.display = 'none'; + } + }); + }
@@ -62,7 +119,7 @@ {
- +
diff --git a/YLErpWeb/Views/EodPrice/eodFuturePriceEdit.cshtml b/YLErpWeb/Views/EodPrice/eodFuturePriceEdit.cshtml index b4edeb1a..966f360a 100644 --- a/YLErpWeb/Views/EodPrice/eodFuturePriceEdit.cshtml +++ b/YLErpWeb/Views/EodPrice/eodFuturePriceEdit.cshtml @@ -49,6 +49,63 @@ }); } + // 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件 + var _eodSuggestTimer = null; + function eodSuggest(input, kind) { + clearTimeout(_eodSuggestTimer); + var q = (input.value || '').trim(); + if (q.length < 1) { eodHideSuggest(); return; } + _eodSuggestTimer = setTimeout(function () { + main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) { + if (res.success && res.obj && res.obj.length) { + eodRenderSuggest(res.obj, input, kind); + } else { + eodHideSuggest(); + } + }); + }, 250); + } + function eodRenderSuggest(list, input, kind) { + var box = document.getElementById('eodSuggestBox'); + if (!box) return; + box.innerHTML = ''; + list.forEach(function (item) { + var div = document.createElement('div'); + div.className = 'eod-suggest-item'; + var code = document.createElement('span'); + code.className = 'eod-suggest-code'; + code.textContent = item.Code; + var name = document.createElement('span'); + name.className = 'eod-suggest-name'; + name.textContent = item.Name || ''; + div.appendChild(code); div.appendChild(name); + div.onmousedown = function (e) { + e.preventDefault(); + input.value = item.Code; + eodHideSuggest(); + var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind]; + if (fn) fn(); + }; + box.appendChild(div); + }); + var r = input.getBoundingClientRect(); + box.style.left = r.left + 'px'; + box.style.top = (r.bottom + 2) + 'px'; + box.style.width = Math.max(r.width, 220) + 'px'; + box.style.display = 'block'; + } + function eodHideSuggest() { + var b = document.getElementById('eodSuggestBox'); + if (b) b.style.display = 'none'; + } + document.addEventListener('click', function (e) { + var b = document.getElementById('eodSuggestBox'); + if (b && b.style.display === 'block' && !b.contains(e.target) + && e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') { + b.style.display = 'none'; + } + }); + } @@ -74,7 +131,7 @@ {
- +
diff --git a/YLErpWeb/Views/EodPrice/eodStockPriceEdit.cshtml b/YLErpWeb/Views/EodPrice/eodStockPriceEdit.cshtml index 08d58bc0..b7403e24 100644 --- a/YLErpWeb/Views/EodPrice/eodStockPriceEdit.cshtml +++ b/YLErpWeb/Views/EodPrice/eodStockPriceEdit.cshtml @@ -42,6 +42,64 @@ main.parentReloadData(); }); } + + // 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件 + var _eodSuggestTimer = null; + function eodSuggest(input, kind) { + clearTimeout(_eodSuggestTimer); + var q = (input.value || '').trim(); + if (q.length < 1) { eodHideSuggest(); return; } + _eodSuggestTimer = setTimeout(function () { + main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) { + if (res.success && res.obj && res.obj.length) { + eodRenderSuggest(res.obj, input, kind); + } else { + eodHideSuggest(); + } + }); + }, 250); + } + function eodRenderSuggest(list, input, kind) { + var box = document.getElementById('eodSuggestBox'); + if (!box) return; + box.innerHTML = ''; + list.forEach(function (item) { + var div = document.createElement('div'); + div.className = 'eod-suggest-item'; + var code = document.createElement('span'); + code.className = 'eod-suggest-code'; + code.textContent = item.Code; + var name = document.createElement('span'); + name.className = 'eod-suggest-name'; + name.textContent = item.Name || ''; + div.appendChild(code); div.appendChild(name); + div.onmousedown = function (e) { + e.preventDefault(); + input.value = item.Code; + eodHideSuggest(); + var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind]; + if (fn) fn(); + }; + box.appendChild(div); + }); + var r = input.getBoundingClientRect(); + box.style.left = r.left + 'px'; + box.style.top = (r.bottom + 2) + 'px'; + box.style.width = Math.max(r.width, 220) + 'px'; + box.style.display = 'block'; + } + function eodHideSuggest() { + var b = document.getElementById('eodSuggestBox'); + if (b) b.style.display = 'none'; + } + document.addEventListener('click', function (e) { + var b = document.getElementById('eodSuggestBox'); + if (b && b.style.display === 'block' && !b.contains(e.target) + && e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') { + b.style.display = 'none'; + } + }); + } @@ -62,7 +120,7 @@ {
- +