fix: 修复日终价格新增页自动补全失效与查询开屏报错

EodPriceService.SearchUnderlyingList 三分支 Concat 投影成员不对称(债券缺 DataSource、期货/股票缺 UpdateUser),EF 翻译期抛 'DataSource' key not present 致 eodPriceQuery 开屏崩溃,补齐成员对称。eodPriceAdd.cshtml 原用 jQuery UI .autocomplete() 但 bundle 未打包该插件,调用即抛错、脚本中断、标的无法搜索;改为自带下拉补全(纯 jQuery+ajax,不依赖外部插件)。
This commit is contained in:
hjhan
2026-07-13 11:22:12 +08:00
parent 36d8909fe0
commit 5cc24f787e
2 changed files with 116 additions and 36 deletions
@@ -57,6 +57,10 @@ namespace YLErp.Modules.EodModule
IsBond=false,
id = source.id,
DataSource = source.DataSource,
// EF Core Concat 要求各分支投影成员集合完全一致:
// 债券分支设了 UpdateUser,故期货/股票分支也必须显式设(置 null),否则翻译期抛
// "The given key 'UpdateUser/DataSource' was not present in the dictionary"。
UpdateUser = (long?)null,
LaunchState = un.LaunchState,
MarketName = un.MarketName,
UnderlyingId = un.id,
@@ -84,6 +88,7 @@ namespace YLErp.Modules.EodModule
IsBond = false,
id = stockClose.id,
DataSource = stockClose.DataSource,
UpdateUser = (long?)null, // 对齐 Concat 投影成员,见 query1 注释
LaunchState = un.LaunchState,
MarketName = un.MarketName,
UnderlyingId = un.id,
@@ -110,7 +115,9 @@ namespace YLErp.Modules.EodModule
IsBond = true,
id = bondClose.id,
UpdateUser = bondClose.update_user,
// 债券 DataSource 在后处理统一置为固定值"中债估值"(见下方 foreach
// 债券 DataSource 在后处理统一置为人名/"中债估值"(见下方 foreach
// 此处仍须显式设 null 以对齐 Concat 各分支投影成员集合(见 query1 注释)。
DataSource = null,
LaunchState = un.LaunchState,
MarketName = un.MarketName,
UnderlyingId = un.id,
+108 -35
View File
@@ -1,48 +1,109 @@
@{
@{
ViewBag.Title = "日终价格新增";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
}
@section CSS
{
<style type="text/css">
.suggest-box {
position: absolute;
z-index: 9999;
background: #fff;
border: 1px solid #c5c5c5;
max-height: 260px;
overflow-y: auto;
width: 100%;
box-shadow: 0 2px 8px rgba(0,0,0,.18);
}
.suggest-item {
padding: 7px 12px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.suggest-item:hover, .suggest-item.active {
background: #eef4ff;
}
.suggest-empty {
padding: 7px 12px;
color: #999;
}
</style>
}
@section JS
{
<script type="text/javascript">
var activeGroup = null; // 当前显示的字段组选择器
var suggestItems = []; // 当前补全项
var suggestTimer = null;
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$("#UnderlyingInput").autocomplete({
minLength: 0,
source: function (request, response) {
$.ajax({
url: "/eodPrice/UnderlyingSuggestForEod",
type: "POST",
data: { q: request.term },
success: function (res) {
var arr = res.obj || res;
response($.map(arr, function (x) {
return {
label: x.Code + " " + (x.Name || "") + " [" + (x.InstrumentType || "") + "]",
value: x.Code,
item: x
};
}));
}
});
},
select: function (event, ui) {
var it = ui.item.item;
$("#UnderlyingCode").val(it.Code);
$("#bond_id").val(it.Code);
$("#UnderlyingId").val(it.Id);
$("#UnderlyingInstrumentType").val(it.InstrumentType);
$("#MarketDisplay").val(it.Market);
$("#CodeDisplay").val(it.Code);
showGroupForType(it.InstrumentType);
return true; // 让输入框保留代码
}
// 自带下拉补全:不依赖 jQuery UI(bundle 未打包 autocomplete 插件)
$("#UnderlyingInput").on("input", function () {
clearTimeout(suggestTimer);
var q = $(this).val();
if (!q) { hideSuggest(); return; }
suggestTimer = setTimeout(function () { doSuggest(q); }, 250);
}).on("focus", function () {
if ($(this).val()) doSuggest($(this).val());
});
// 点击补全项
$("#UnderlyingSuggest").on("click", ".suggest-item", function () {
var it = suggestItems[$(this).data("i")];
selectUnderlying(it);
hideSuggest();
});
// 点击外部关闭补全
$(document).on("click", function (e) {
if (!$(e.target).closest("#UnderlyingInput, #UnderlyingSuggest").length) hideSuggest();
});
});
function doSuggest(q) {
$.ajax({
url: "/eodPrice/UnderlyingSuggestForEod",
type: "POST",
data: { q: q },
success: function (res) {
suggestItems = (res && res.obj) || [];
var box = $("#UnderlyingSuggest").empty();
if (!suggestItems.length) {
box.append("<div class='suggest-empty'>未找到匹配标的</div>").show();
return;
}
$.each(suggestItems, function (i, x) {
var label = (x.Code || "") + " " + (x.Name || "") + " [" + (x.InstrumentType || "") + "]";
$("<div class='suggest-item'></div>")
.text(label)
.data("i", i)
.appendTo(box);
});
box.show();
},
error: function () { hideSuggest(); }
});
}
function hideSuggest() {
$("#UnderlyingSuggest").hide().empty();
}
function selectUnderlying(it) {
$("#UnderlyingInput").val((it.Code || "") + " " + (it.Name || ""));
$("#UnderlyingCode").val(it.Code);
$("#bond_id").val(it.Code);
$("#UnderlyingId").val(it.Id);
$("#UnderlyingInstrumentType").val(it.InstrumentType);
$("#MarketDisplay").val(it.Market);
$("#CodeDisplay").val(it.Code);
showGroupForType(it.InstrumentType);
}
// 根据标的类型显示对应的字段组
function showGroupForType(type) {
$(".price-group").hide();
@@ -99,8 +160,19 @@
$(".price-group").not(activeGroup).find("input,select").prop("disabled", false);
main.post(url, data).done(function (res) {
window.location.href = "/eodPrice/eodPriceview?enid=" + res.obj.EncryptId + "&UnderlyingInstrumentType=" + type;
main.parentReloadData();
if (res && res.success === false) {
main.message(res.msg || "保存失败");
return;
}
var encId = res && res.obj ? res.obj.EncryptId : "";
// 规整成视图路由认的字符串(与 EodPriceView 的分支一致)
var viewType = "bond";
if (t.indexOf("future") >= 0) viewType = "CommodityFutures";
else if (t.indexOf("stock") >= 0) viewType = "Stock";
window.location.href = "/eodPrice/eodPriceview?enid=" + encId + "&UnderlyingInstrumentType=" + viewType;
if (parent && parent.reloadData) parent.reloadData();
}).fail(function (xhr) {
main.message("保存失败:" + (xhr.responseJSON && xhr.responseJSON.msg ? xhr.responseJSON.msg : xhr.statusText));
});
}
</script>
@@ -117,10 +189,11 @@
<h4>日终价格新增</h4>
<div style="margin-top:20px;">
<div style="margin-top:20px; position:relative;">
<div class='form-group col-md-6'>
<label class='formlabel'>标的</label>
<input id="UnderlyingInput" class='text-box' placeholder="输入代码/名称搜索" />
<input id="UnderlyingInput" class='text-box' placeholder="输入代码/名称搜索,如 600000 或 国债" autocomplete="off" />
<div id="UnderlyingSuggest" class="suggest-box" style="display:none;"></div>
</div>
<div class='form-group col-md-6'>
<label class='formlabel'>市场</label>