Merge branch 'glms/feature/1.4.2-0827' into 'glms/feature/1.4.2'

feat(um): 根据标的代码 基金管理人回显

See merge request otc-dev/zszq-trs!19
This commit is contained in:
马冰冰
2026-08-27 12:00:13 +00:00
4 changed files with 172 additions and 0 deletions
+1
View File
@@ -171,6 +171,7 @@ namespace YLErp
"yladmin" => _configuration.GetConnectionString("yladmin"),
"ylclient" => _configuration.GetConnectionString("ylclient"),
"bondoms" => _configuration.GetConnectionString("bondoms"),
"glms_bigdata" => _configuration.GetConnectionString("glms_bigdata"),
"apex_oracle"=> _configuration.GetConnectionString("apex_oracle"),
_ => string.Empty,
};
@@ -0,0 +1,94 @@
using Dapper;
using MySqlConnector;
using YieldChain.Helpers;
using YLErp.BLL;
namespace YLErp.Modules.UnderlyingModule
{
public enum FundManagerLookupStatus
{
NotFound,
Unique,
Multiple,
Unavailable
}
public sealed class FundManagerLookupResult
{
public FundManagerLookupStatus Status { get; init; }
public string InvestAdvisorName { get; init; }
}
/// <summary>
/// 查询上游基金档案中的基金管理人。上游不可用时返回降级结果,不阻断页面编辑。
/// </summary>
public sealed class FundManagerLookupService
{
private sealed class FundManagerRow
{
public string InvestAdvisorCode { get; set; }
public string InvestAdvisorName { get; set; }
}
private const string LookupSql = @"
SELECT
ia.investadvisorcode AS InvestAdvisorCode,
ia.investadvisorname AS InvestAdvisorName
FROM glms_bigdata.mf_fundarchives AS fa
INNER JOIN glms_bigdata.mf_investadvisoroutline AS ia
ON CONVERT(fa.investadvisorcode USING utf8mb4) COLLATE utf8mb4_unicode_ci =
CONVERT(ia.investadvisorcode USING utf8mb4) COLLATE utf8mb4_unicode_ci
WHERE CONVERT(fa.secucode USING utf8mb4) COLLATE utf8mb4_unicode_ci =
CONVERT(TRIM(SUBSTRING_INDEX(@UnderlyingCode, '.', 1)) USING utf8mb4) COLLATE utf8mb4_unicode_ci";
public FundManagerLookupResult Lookup(string underlyingCode)
{
var normalizedCode = NormalizeCode(underlyingCode);
if (string.IsNullOrEmpty(normalizedCode))
{
return new FundManagerLookupResult { Status = FundManagerLookupStatus.NotFound };
}
var connectionString = AppManager.GetConnectionString("glms_bigdata");
if (string.IsNullOrWhiteSpace(connectionString))
{
return new FundManagerLookupResult { Status = FundManagerLookupStatus.Unavailable };
}
try
{
using var connection = new MySqlConnection(connectionString);
var matches = connection.Query<FundManagerRow>(LookupSql, new { UnderlyingCode = normalizedCode }, commandTimeout: 10)
.Where(row => !string.IsNullOrWhiteSpace(row.InvestAdvisorName))
.GroupBy(row => (row.InvestAdvisorCode ?? string.Empty).Trim(), StringComparer.OrdinalIgnoreCase)
.Select(group => group.Select(row => row.InvestAdvisorName.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray())
.Where(names => names.Length > 0)
.ToArray();
return matches.Length switch
{
0 => new FundManagerLookupResult { Status = FundManagerLookupStatus.NotFound },
1 when matches[0].Length == 1 => new FundManagerLookupResult { Status = FundManagerLookupStatus.Unique, InvestAdvisorName = matches[0][0] },
_ => new FundManagerLookupResult { Status = FundManagerLookupStatus.Multiple }
};
}
catch (Exception ex)
{
LogFactory.GetLogger<FundManagerLookupService>().Error("查询基金管理人失败,代码:" + normalizedCode, ex);
return new FundManagerLookupResult { Status = FundManagerLookupStatus.Unavailable };
}
}
public static string NormalizeCode(string underlyingCode)
{
var trimmed = underlyingCode?.Trim();
if (string.IsNullOrEmpty(trimmed))
{
return null;
}
var dotIndex = trimmed.IndexOf('.');
return (dotIndex < 0 ? trimmed : trimmed.Substring(0, dotIndex)).TrimToNull();
}
}
}
@@ -525,6 +525,25 @@ namespace YLErp.Web.Controllers
return JsonSuccess("", underlying);
}
/// <summary>
/// 查询上游基金档案中的基金管理人。查询失败或结果不唯一时返回可降级结果。
/// </summary>
[HttpGet]
public JsonResult GetFundManager(string code, string instrumentType)
{
if (!string.Equals(instrumentType, ConsGlobal.InstrumentType.Fund, StringComparison.OrdinalIgnoreCase))
{
return JsonSuccess("", new FundManagerLookupResult { Status = FundManagerLookupStatus.NotFound });
}
var result = new FundManagerLookupService().Lookup(code);
return JsonSuccess("", new
{
result.InvestAdvisorName,
IsUnique = result.Status == FundManagerLookupStatus.Unique
});
}
/// <summary>
/// 预付金参数
/// </summary>
@@ -17,6 +17,10 @@
const consSelect = ['MarketCode', 'UnderlyingInstrumentType', 'UnderlyingState', 'UnderlyingStatus', 'UpDownLimitType', 'EtfSubType'];
var autoUpDownLimit, autoVariety;
var fundManagerLookupSeq = 0;
var fundManagerLookupTimer = null;
var fundManagerLookupXhr = null;
var fundManagerManualEdit = false;
$(function () {
@@ -46,6 +50,12 @@ $(function () {
lookup: ylotc.varieties
});
$('#InvestAdvisorName').on('input', function () {
fundManagerManualEdit = true;
});
$('#UnderlyingCode').on('input', refreshFundManagerLookup);
for (var i = 1; i <= 5; i++) {
let datas = ylotc.underlyingBlocks.filter(x => x.Group === i);
let autoBlock = FastVue.autocomplete(document.getElementById('inputBlock' + i), {
@@ -112,9 +122,57 @@ $(function () {
break;
}
$('#editForm').removeClass("form-None form-Stock form-CommodityFutures form-CommoditySpot form-Bonds form-Fund").addClass("form-" + classType);
refreshFundManagerLookup();
}).trigger('change');
});
function refreshFundManagerLookup() {
var requestSeq = ++fundManagerLookupSeq;
if (fundManagerLookupTimer) {
clearTimeout(fundManagerLookupTimer);
fundManagerLookupTimer = null;
}
if (fundManagerLookupXhr) {
fundManagerLookupXhr.abort();
fundManagerLookupXhr = null;
}
var codeInput = $('#UnderlyingCode');
var typeInput = $('#UnderlyingInstrumentType');
var managerInput = $('#InvestAdvisorName');
if (page.Model.id > 0 || !codeInput.length || !typeInput.length ||
typeInput.val() !== 'Fund' || !codeInput.val() || !managerInput.length) {
return;
}
var codeAtRequest = codeInput.val();
var managerAtRequest = managerInput.val() || '';
var manualAtRequest = fundManagerManualEdit;
fundManagerLookupTimer = setTimeout(function () {
fundManagerLookupTimer = null;
fundManagerLookupXhr = $.ajax({
url: '/underlying_manager/GetFundManager',
method: 'GET',
data: { code: codeAtRequest, instrumentType: 'Fund' }
}).done(function (resp) {
if (requestSeq !== fundManagerLookupSeq || page.Model.id > 0 ||
$('#UnderlyingCode').val() !== codeAtRequest ||
$('#UnderlyingInstrumentType').val() !== 'Fund' ||
manualAtRequest || fundManagerManualEdit) {
return;
}
var result = resp && resp.obj;
if (result && result.IsUnique && result.InvestAdvisorName) {
managerInput.val(result.InvestAdvisorName);
fundManagerManualEdit = false;
}
}).always(function () {
fundManagerLookupXhr = null;
});
}, 200);
}
function saveData() {
var data = $('#editForm').serializeObject();