using YLErp.Core; using YLErp.DBModels; using YLErp.Modules.EodModule; namespace YLErp.Web.Controllers { public class EodPriceController : BaseController { readonly IViewRenderService _viewRenderer; public EodPriceController(IViewRenderService viewRenderer) { _viewRenderer = viewRenderer; } [MyAuthorize("结算管理-日终价格查看")] public ActionResult EodPriceList() { return View(); } [HttpPost] public JsonResult EodPriceQuery(EodCommodityFuturePriceReq req) { var sList = new EodPriceService(CurUser).SearchUnderlyingList(req); return Json(sList); } public ActionResult EodPriceView(string enid, string UnderlyingInstrumentType) { var eodUnderlying = new EodPriceViewModel() { UnderlyingInstrumentType = UnderlyingInstrumentType }; var intid = DecryptLong(enid); if ("Stock".Equals(UnderlyingInstrumentType)) { var id = Convert.ToInt32(intid); var r = yldb.eod_stock_price.Find(id); eodUnderlying.eod_Stock_Price = r; eodUnderlying.underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode); } else if ("CommodityFutures".Equals(UnderlyingInstrumentType)) { var id = Convert.ToInt32(intid); var r = yldb.eod_commodity_future_price.Find(id); eodUnderlying.eod_commodity_future_price = r; eodUnderlying.underlying = yldb.underlying_manager.Find(r.UnderlyingId); } else { var r = yldb.china_bond_valuation.Find(intid); eodUnderlying.ChinaBondValuation = r; eodUnderlying.underlying = yldb.underlying_manager.FirstOrDefault(x => x.UnderlyingCode == r.bond_id); } return View(eodUnderlying); } public ActionResult EodFuturePriceEdit(string enid) { bool isNew = string.IsNullOrEmpty(enid) || enid == "0"; ViewBag.IsNew = isNew; if (isNew) { // 新建:手工输入标的代码,失焦时调 LookupUnderlyingForEod 校验并带出市场/UnderlyingId。 // 默认估值日期=今天:避免未填日期时落库为 0001-01-01、落在列表默认窗口(今天)之外而查不出。 return View(new eod_commodity_future_price { ValueDate = DateTime.Today }); } var intid = DecryptInt(enid); var dbmodel = yldb.eod_commodity_future_price.Find(intid); if (dbmodel == null) { return ShowError("找不到数据"); } ViewData["市场"] = DataCacheProvider.GetUnderlyingDataSource().GetData(dbmodel.UnderlyingCode)?.MarketName; return View(dbmodel); } public ActionResult EodStockPriceEdit(string enid) { bool isNew = string.IsNullOrEmpty(enid) || enid == "0"; ViewBag.IsNew = isNew; if (isNew) { // 新建:手工输入标的代码,失焦时调 LookupUnderlyingForEod 校验并带出市场。 return View(new eod_stock_price { ValueDate = DateTime.Today }); } var intid = DecryptInt(enid); var dbmodel = yldb.eod_stock_price.Find(intid); if (dbmodel == null) { return ShowError("找不到数据"); } ViewData["市场"] = DataCacheProvider.GetUnderlyingDataSource().GetData(dbmodel.UnderlyingCode)?.MarketName; return View(dbmodel); } public ActionResult EodBondPriceEdit(string enid) { bool isNew = string.IsNullOrEmpty(enid) || enid == "0"; ViewBag.IsNew = isNew; if (isNew) { // 新建:手工输入债券代码(bond_id),失焦时调 LookupUnderlyingForEod 校验并带出市场。 // 默认估值日期=今天:避免未填日期时落库为 0001-01-01、落在列表默认窗口(今天)之外而查不出。 return View(new ChinaBondValuation { valuation_date = DateTime.Today }); } var intid = DecryptLong(enid); var dbmodel = yldb.china_bond_valuation.Find(intid); if (dbmodel == null) { return ShowError("找不到数据"); } ViewData["市场"] = DataCacheProvider.GetUnderlyingDataSource().GetData(dbmodel.bond_id)?.MarketName; return View(dbmodel); } /// /// 新建日终价格时,按用户手工输入的标的代码精确查一条标的,带出名称/市场/Id。 /// 只返回已上市(LaunchState=="1")且类型匹配的标的——与列表查询 inner join 的过滤对齐, /// 从源头杜绝"新增能存但查不出"的幽灵记录。前端在输入框失焦时调用,不依赖任何下拉/补全插件。 /// /// 标的代码(用户手工输入) /// bond | future | stock,决定允许的标的类型集合 [HttpPost] public JsonResult LookupUnderlyingForEod(string code, string kind) { if (string.IsNullOrWhiteSpace(code)) { return JsonError("请输入标的代码"); } code = code.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 u = yldb.underlying_manager .Where(n => n.UnderlyingCode == code && n.LaunchState == "1" && set.Contains(n.UnderlyingInstrumentType)) .Select(n => new { n.id, n.UnderlyingCode, n.UnderlyingName, n.MarketName }) .FirstOrDefault(); if (u == null) { return JsonError("未找到该标的(不存在、未上市或类型不匹配),无法录入"); } return JsonSuccess("", new { Id = u.id, Code = u.UnderlyingCode, Name = u.UnderlyingName, 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) { if (!string.IsNullOrEmpty(req.EncryptId)) { req.id = DecryptInt(req.EncryptId); } var r = new EodPriceService(CurUser).SaveEodFuturePrice(req); return JsonSuccess("更新成功", r); } public JsonResult EodBondPriceEditJson(ChinaBondValuation req) { if (!string.IsNullOrEmpty(req.EncryptId)) { req.id = DecryptLong(req.EncryptId); } var r = new EodPriceService(CurUser).SaveBondPrice(req); return JsonSuccess("更新成功", r); } [HttpPost] public JsonResult EodStockPriceEditJson(eod_stock_price req) { if (!string.IsNullOrEmpty(req.EncryptId)) { req.id = DecryptInt(req.EncryptId); } var r = new EodPriceService(CurUser).SaveEodStockPrice(req); return JsonSuccess("更新成功", r); } [HttpPost] public JsonResult DeletEodPrice(string id) { var intid = DecryptInt(id); var r = yldb.eod_commodity_future_price.Find(intid); if (r == null) { return JsonError("找不到日终商品期货价格"); } yldb.eod_commodity_future_price.Remove(r); yldb.SaveChanges(); return JsonSuccess("删除成功"); } /// /// 导入结算价 /// public async Task UploadSettlementBill(IFormFile file) { try { if (file == null || string.IsNullOrWhiteSpace(file.FileName)) { return JsonError("未获取上传文件"); } var fileExtension = Path.GetExtension(file.FileName); if (fileExtension.ToLowerInvariant() != ".xlsx") { return JsonError("请上传xlsx格式的文件"); } using var openStream = file.OpenReadStream(); var result = new SettlementPriceImportService(CurUser).ImportxlsxDatas(openStream); var html = await _viewRenderer.RenderToStringAsync("Common/ImportResult", result); return JsonSuccess(null, html); } catch (Exception ex) { LogFactory.GetLogger("导入结算价").Error("导入结算价出错", ex); return JsonError(ex.Message); } } } }