using YLErp.BLL.Eod; using YLErp.BLL.MarginCalculation; using YLErp.DBModels.Consts; using YLErp.Enums; using YLErp.Model.Enum; using YLErp.Models.Tag; using YLErp.Modules.CalculationModule; using YLErp.Modules.EodModule; using YLErp.Modules.SalesModule; using YLErp.Modules.TagModule; using YLErp.Modules.TradeModule; using YLErp.Modules.TradeModule.DealModule; using YLErp.Modules.TradeModule.ForwardModule; namespace YLErp.Web.Controllers { public class ForwardTradeController : OtcTradeControllerBase { private readonly YLContext db = new YLContext(); private readonly ErpBaseContext sysdb = new ErpBaseContext(); private static readonly object _LockBatchGenerateSettleBill = new object(); readonly IViewRenderService _viewRenderer; public ForwardTradeController(IViewRenderService viewRenderer) { _viewRenderer = viewRenderer; } public ActionResult Index() { return View("TradeList"); } [MyAuthorize("交易管理-远期交易")] public ActionResult TradeList(int? tabIndex, string settleDate = null) { if (tabIndex <= 0 || tabIndex == null) { ViewBag.TabIndex = (int)TradeTabIndexEnum.场外衍生品交易; } else { ViewBag.TabIndex = tabIndex; } ViewBag.settleDate = settleDate; return View(); } public ActionResult TradeEditV2(string enid, bool isUseApproval = false) { OtcTradeForward td = null; var isAdd = string.IsNullOrEmpty(enid) || enid == "0"; var model = new ForwardTradeEditModel(CurUser); if (isAdd) { if (!CurUser.交易管理_交易新增) { throw new Exception("没有新增权限"); } td = new OtcTradeForward() { TradeType = "远期", Notional = 1, ExerciseMode = "European", TradeDate = valuedateBLL.ValueDate, TraderId = UserId, TraderName = UserName, UnderlyingInstrumentType = "CommodityFutures", OptionType = "看涨", NoRiskRate = 0, BuySell = "卖出", Lots = 0, TradeAmount = 0, StructureType = "远期", MarginTemplateName = "系统默认", OpponentRole = "乙方" }; } else { var intid = DataProtectHelper.DecryptInt(enid); td = new TradeForwardService(CurUser).GetDetail(intid); if (td == null) { throw new ServiceException("找不到交易数据"); } if (ConsTrade.审批中 != td.TradeStatus) { if (!CurUser.交易管理_交易编辑 && !(ConsTrade.已拒绝 == td.TradeStatus && td.TraderId == CurUser.UserId)) { throw new Exception("没有编辑权限"); } } var tradeCheck = db.trade_check.FirstOrDefault(t => t.TradeId == td.id && t.ValidState != "InValid"); if (tradeCheck != null) { var reviewTrade = tradeCheck.TradeModel; var saveTrade = TradeConverter.ConvertForward(td); model.DiffList = TradeCheckUtil.GetDiffs(saveTrade, reviewTrade); } td.SalesCommission = new SalesCommissionDataService(CurUser).GetTradeCommissionInfo(td.id); if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1") {//计提法只支持百分比; if (td.SalesCommission.Commission.Normalize() == 0) { td.SalesCommission.Commission = 1; td.SalesCommission.CommissionFixed = false; } else { td.SalesCommission.Commission = td.SalesCommission.Commission * td.SalesCommission.SalesIds.Count(); } } td.OpponentRole = td.OpponentRole == null ? "乙方" : td.OpponentRole; using (var tagService = new TagService(CurUser)) { model.Tags = tagService.GetTagByTradeId(intid); } } model.Trade = td; ViewBag.isUseApproval = isUseApproval; using (var tagService = new TagService(CurUser)) { ViewBag.TagList = tagService.GetTagListByType(TagTypeEnum.Trade); } return View(model); } [HttpPost] public JsonResult TradeEditJson(OtcTradeForward req) { if (req == null) { return JsonError("数据不能为空"); } var r = new TradeForwardService(CurUser).SaveData(req); return JsonSuccess("更新成功", new { r.EncryptId }); } #region 远期交易复核 public ActionResult TradeCheck2(int? enid) { var trade = new TradeCheckModel(); if (enid > 0) { trade = new TradeForwardService(CurUser).GetCheckTrade(enid); if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD) { if (!trade.Trade.BasisUnderlyingCode.IsNullOrWhiteSpace()) { ViewBag.Underlying2 = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.Trade.BasisUnderlyingCode); } } using (var tagService = new TagService(CurUser)) { ViewBag.HasTags = tagService.GetTagByTradeId(trade.Trade.id); } } return View(trade); } [HttpPost] public JsonResult CheckTrade(trade req, string additionalProcessing) { if (req == null) { return JsonError("数据不能为空"); } if (string.IsNullOrEmpty(req.EncryptId)) { return JsonError("获取交易ID参数失败!"); } req.NoRiskRate /= 100; if (req.trade_forward != null) { req.trade_forward.AnnualMarginRate /= 100; } req.id = DataProtectHelper.DecryptInt(req.EncryptId); var result = new TradeCheckService(CurUser).TradeCheck(req, additionalProcessing); result.message = result.message.TrimToNull(); if (result.success) { return JsonSuccess(result.specialOperateForTrade ? string.Empty : result.message ?? "复核审批成功!", result); } return JsonError(result.message ?? "交易复核失败!", result); } [HttpPost] public JsonResult TradeReject(trade req) { if (req == null) { return JsonError("数据不能为空"); } if (req.EncryptId.IsNullOrWhiteSpace()) { return JsonError("拒绝失败!"); } var id = DataProtectHelper.DecryptInt(req.EncryptId); new TradeRejectService(CurUser).ForwardTradeReject(req, id); return JsonSuccess("拒绝成功!"); } #endregion [HttpPost] public JsonResult TradeQuery(TradeReq req) { var service = new TradeForwardService(CurUser); req.TradeType = "远期"; if (!string.IsNullOrWhiteSpace(req.OptionType)) { req.OptionType = req.OptionType == "多头" ? "看涨" : "看跌"; } req.AssetIdList = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIdList).ToList(); req.UserAssets = CurUser.GetAssetUnitIds(); req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); var sList = service.SearchList(req); var tradeids = sList.rows.Select(r => r.id).ToList(); var cashTrades = db.trade_cash.Where(t => t.ValidState != ConsGlobal.InValid && tradeids.Contains(t.TradeId) && !t.IsDeleted).ToList(); var cashTradesExercise = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_行权费).ToList(); var cashTradesUnwind = cashTrades.Where(t => t.Action == ClientCashInCashOut.系统操作_平仓费).ToList(); var realtimerisk = realtime_trade_riskBLL.GetAllrealtime_trade_valueModel(); var tradeContractCodeList = (from tradeContractR in db.trade_contract_r where tradeids.Contains(tradeContractR.TradeId) && ContractTypeEnum.Trade == tradeContractR.Type && tradeContractR.IsValid select tradeContractR).ToList(); Dictionary> tradeTagList = null; if (sList != null && sList.rows != null && sList.rows.Any()) { using (var tagService = new TagService(CurUser)) { tradeTagList = tagService.GetTagByTradeIds(sList.rows.Select(p => p.id).Distinct().ToList()); } } if (tradeTagList == null) { tradeTagList = new Dictionary>(); } foreach (var r in sList.rows) { r.Amount = cashTradesExercise.FirstOrDefault(t => t.TradeId == r.id)?.Amount; //r.UnwindAmount = !cashTradesUnwind.Where(t => t.TradeId == r.id).Any() ? null : cashTradesUnwind.Where(t => t.TradeId == r.id).Sum(t => t.Amount); r.FinalPrice = cashTradesExercise.FirstOrDefault(t => t.TradeId == r.id)?.FinalPrice; r.LotsNewInfo = TradeLotsCalc.GetLots(r.UnderlyingCode, r.Notional); var pv = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair(t.VolType, t.Pv)).ToList(); var roundedPv = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair(t.VolType, t.RoundedPv)).ToList(); var positionPnl = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair(t.VolType, t.PositionPnl)).ToList(); var roundedPositionPnl = realtimerisk.Where(t => t.TradeId == r.id).Select(t => new KeyValuePair(t.VolType, t.RoundedPositionPnl)).ToList(); if (PS.Config.IsPVRounded) { if (roundedPv != null && roundedPv.Count > 0) { r.PV = roundedPv.ToJson(); } if (roundedPositionPnl != null && roundedPositionPnl.Count > 0) { r.PositionPnl = roundedPositionPnl.ToJson(); } } else { if (pv != null && pv.Count > 0) { r.PV = pv.ToJson(); } if (positionPnl != null && positionPnl.Count > 0) { r.PositionPnl = positionPnl.ToJson(); } } var un = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode); if (un != null) { r.UnderlyingPrice = un.Price; } r.RealizedPnl = cashTradesExercise.Where(x => x.TradeId == r.id).Sum(x => x.Amount) - r.TradePrice * cashTradesExercise.Where(x => x.TradeId == r.id).Sum(x => x.UnwindPercentRate) * ((r.BuySell == "卖出") ? -1 : 1) + cashTradesUnwind.Where(x => x.TradeId == r.id).Sum(x => x.Amount) - r.TradePrice * cashTradesUnwind.Where(x => x.TradeId == r.id).Sum(x => x.UnwindPercentRate) * ((r.BuySell == "卖出") ? -1 : 1); r.TradeOriginalAmount = r.OriginalNotional / un.CountRatio; var tradeContractCode = tradeContractCodeList.FirstOrDefault(t => t.TradeId == r.id); r.ContractCode = tradeContractCode?.ContractCode; r.trade_forward = db.trade_forward.FirstOrDefault(x => x.TradeId == r.id); //拼装标签值 if (tradeTagList.ContainsKey(r.id)) { r.Tags = tradeTagList[r.id]; r.OutputTags = TagService.GetOutputTagsStr(r.Tags); } } return Json(sList); } [MyAuthorize("交易管理-远期交易")] public ActionResult TradeConfirmList(int tabIndex = (int)TradeTabIndexEnum.今日成交) { ViewBag.TabIndex = tabIndex; return View(); } /// /// 当日成交查询。 /// 查询在当前交易日成交,或在当前交易日被修改过状态的交易 /// [HttpPost] public JsonResult tradeOnValueDateQuery(TdTradeQueryModel req) { req.AssetIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIds).ToList(); req.UserAssets = CurUser.GetAssetUnitIds(); req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); req.OtcTradeType = DBModels.Enums.OtcTradeType.Forward; var sList = new TodayTradeQueryService(CurUser).GetConfirmList(req); return Json(sList); } /// /// 当日成交而几个tab的交易总数。 /// [HttpPost] public JsonResult tradeCountsOnValueDateQuery() { var userAssets = CurUser.GetAssetUnitIds(); var userClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); var sum = new TodayTradeQueryService(CurUser).GetTdTradesCountSum(userAssets, userClients, DBModels.Enums.OtcTradeType.Forward); var countDic = new Dictionary { {(int)TradeTabIndexEnum.今日到期,sum.TdExerciseCount }, {(int)TradeTabIndexEnum.今日终止,sum.TdEarlyStoppedCount }, {(int)TradeTabIndexEnum.明日到期,sum.TmExerciseCount }, {(int)TradeTabIndexEnum.今日成交,sum.TdCreatedCount }, }; return Json(countDic); } [MyAuthorize("交易管理-远期交易")] public ActionResult TradePreEndList() { return View(); } [HttpPost] public JsonResult InValidTrade(string id) { var intid = DataProtectHelper.DecryptInt(id); new TradeForwardService(CurUser).InValidTrade(intid); return JsonSuccess("无效成功", "已无效"); } public ActionResult TradeUnwind(string enid, bool isUseApproval = false) { var intid = DataProtectHelper.DecryptInt(enid); var result = new TradeForwardUnwindService(CurUser).PrepareUnwind(intid, isUseApproval); //需要审批或者复核的交易都会显示行权审核提交按钮 ViewBag.IsShowReCheckClose = ((valuedateBLL.SystemDate.CloseReCheck == 1) || (valuedateBLL.SystemDate.CloseReApprove == 1 && result.HasProcess)) && result.Trade.TradeStatus != ConsTrade.平仓待复核; ViewBag.isUseApproval = isUseApproval; return View(result); } #region 确认交易 public JsonResult tradeConfirm(IEnumerable tradeIds, string additionalProcessing) { if (tradeIds is null || !tradeIds.Any()) { return JsonError("参数错误:" + nameof(tradeIds)); } var config = valuedateBLL.SystemDate; var ignoreMoneyCheck = tradeIds.Count() == 1 && (config.TradeTrial || (!config.TradeTrial && config.SpecialOperateForTrade == 1)) && additionalProcessing == tradeBLL.LackOfMoney; var result = new TradeConfirmService(CurUser).tradeConfirm(tradeIds, ignoreMoneyCheck, false); //如果客户缺少资金而操作者有交易特批权限 if (!ignoreMoneyCheck && result.LackOfMoney) { return JsonSuccessData(new { proccessType = "AdditionalProcessing", type = PS.Config.ErpElement.Company == Configuration.CompanyEnum.天风 || config.SpecialOperateForTrade == 1 ? tradeBLL.LackOfMoney : "", TrialDataId = result.TrialDataId, message = result.errorMsg, typecode = result.type }); } //生成交易确认书 if (PS.Config.IsAutoGenerateContracts && result.confirmedTradeIds?.Count > 0) { new TradeContractGenerateService(CurUser).GenerateContractsAsync(result.confirmedTradeIds, "确认书"); } if (!string.IsNullOrEmpty(result.errorMsg)) { if (result.changeConfirmPaths?.Count > 0) { return JsonError("确认成交失败,原因:\r\n" + result.errorMsg, new { generateChangeSuccess = true, url = result.changeConfirmPaths }); } return JsonError("确认成交失败,原因:\r\n" + result.errorMsg); } else { if (result.changeConfirmPaths?.Count > 0) { return JsonSuccess("操作完成", new { generateChangeSuccess = true, url = result.changeConfirmPaths }); } return JsonSuccess("操作完成"); } } #endregion #region 生成远期交易确认书 /// /// 生成远期交易确认书 /// /// /// contractType为确认书的话,表示生成交易确认书;否则则生成提前终止确认书或者到期结算单 /// public Result GenerateContracts(List tradeIds, int userId, string userName, string contractType = "其它") { Result result = null; try { if (contractType == "确认书") { var tradeConfirmBookController = new TradeConfirmBookController(_viewRenderer); var JsonResult = tradeConfirmBookController.GJGenerateConfirmBook(tradeIds, "PDF", userId, userName, null, null); result = JsonResult.Value as Result; if (result.success) { result.msg = "生成确认书成功"; } return result; } var tradeController = new tradeController(); var unwindReportInputModels = new List(); var clearingTradeIds = new List(); using (var context = new YLContext()) { var tradeCashes = context.trade_cash.Where(tc => tradeIds.Contains(tc.TradeId) && !tc.IsDeleted) .ToLookup(tc => tc.TradeId).Select(l => l.OrderByDescending(m => m.id).First()).ToList(); tradeCashes.ForEach(tc => { if (tc.Action == ClientCashInCashOut.系统操作_平仓费 || (tc.Action == ClientCashInCashOut.系统操作_行权费 && tc.ExerciseWay == TradeCashExerciseWayEnum.提前终止行权)) { unwindReportInputModels.Add( new UnwindReportInputModel { TradeId = tc.TradeId, TradeCashId = tc.id }); } else if (tc.Action == ClientCashInCashOut.系统操作_行权费) { clearingTradeIds.Add(tc.TradeId); } }); } if (unwindReportInputModels.Count > 0) { var JsonResult = tradeController.GJGenerateUnwindReport(unwindReportInputModels, "PDF", userId, userName); result = JsonResult.Value as Result; if (result.success) { result.msg = "生成提前终止确认书成功"; } } if (clearingTradeIds.Count > 0) { var JsonResult = tradeController.GJGenerateSettleBill(clearingTradeIds, "PDF", userId, userName); var tempResult = JsonResult.Value as Result; if (tempResult.success) { tempResult.msg = "生成到期结算单成功"; } if (result != null) { if (result.success && tempResult.success) { result.msg = "生成到期结算单或提前终止确认书成功"; } else { result.msg = $"{((!result.success) ? result.msg + "
" : string.Empty)}{((!tempResult.success) ? tempResult.msg + "" : string.Empty)}"; } result.success = result.success && tempResult.success; } else { result = tempResult; } } return result; } catch (Exception ex) { LogFactory.GetLogger().Error("GenerateContracts异常", ex); return null; } } #endregion #region 执行到期 /// /// 将单个交易标记为到期(并增加一条收益为零的trade_cash记录,直接到期的交易记录期末价格为0) /// public JsonResult tradeExpireConfirm(string enid) { var id = DataProtectHelper.DecryptInt(enid); var result = new TradeExpireConfirmService(CurUser).TradeExpireConfirm(id); if (result.Success) { return JsonSuccess(result.Message, result.Trade); } return JsonError(result.Message, result.Trade); } #endregion #region 预付金占用成本 [HttpGet] public ActionResult TradeMarginCost(string enid, string tradenum) { var intid = DataProtectHelper.DecryptInt(enid); ViewBag.tradeId = enid; if (db.eod_forward_margin.Any(x => x.TradeId == intid)) { var sum = db.eod_forward_margin.Where(x => x.TradeId == intid) .OrderByDescending(x => x.ValueDate).Select(x => x.MarginSum).FirstOrDefault(); ViewBag.MarginCostTotal = sum.ToString("f2"); } else { ViewBag.MarginCostTotal = "0.00"; } ViewBag.TradeNum = tradenum; return View(); } public JsonResult SingleMarginCost(Eod_forward_marginReq req) { if (string.IsNullOrWhiteSpace(req.sidx)) { req.sidx = "ValueDate"; req.sord = "desc"; } var list = new EodForwardMarginQueryService(CurUser).GetPagedList(req); var tradeId = DataProtectHelper.DecryptInt(req.enid); var code = db.trade.Where(O => O.id == tradeId).Select(O => O.UnderlyingCode).FirstOrDefault(); var un = DataCacheProvider.GetUnderlyingDataSource().GetData(code); var eodList = new List(); foreach (var item in list.rows) { var eod = new eod_forward_marginDto(); YLAutoMapper.Map(item, eod); if (un != null) { eod.TradeAmount = eod.Notional / un.CountRatio; } eodList.Add(eod); } var ret = eodList.AsQueryable().ToSearchList(req); return Json(ret); } /// /// 财务结算-远期预付金成本 /// public ActionResult MarginCostList() { ViewBag.valueDate = EodOperationBase .GetLastSettlementDate(valuedateBLL.ValueDate).ToString("yyyy-MM-dd"); return View(); } /// /// 财务结算-远期预付金成本 /// public JsonResult MarginCostListQuery(MarginCostReq req) { req.AssetIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.AssetIds).ToList(); req.UserAssets = CurUser.GetAssetUnitIds(); req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); var forward_marginQuery = db.eod_forward_margin.AsQueryable(); var tradeQuery = db.trade.AsQueryable(); if (req.UserAssets != null && req.UserClients != null) { tradeQuery = tradeQuery.Where(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId)); } var tl = from efm in forward_marginQuery where efm.ValueDate == req.ValueDate join t in db.trade on efm.TradeId equals t.id where t.TradeType == "远期" && t.ValidState != "InValid" join tf in db.trade_forward on t.id equals tf.TradeId select new MarginCostDto { TradeId = t.id, TradeNumber = t.TradeNumber, TradeDate = efm.ValueDate, TotalMarginCost = efm.MarginSum, ExerciseDate = t.ExerciseDate, BuySell = t.BuySell, OptionType = t.OptionType, UnderlyingCode = t.UnderlyingCode, Strike = t.Strike ?? 0, TradeAmount = t.TradeAmount, StockEqvNotional = t.StockEqvNotional, ClientName = t.ClientName, AssetBookName = t.AssetBookName, TraderName = t.TraderName, TraderId = t.TraderId, AssetId = t.AssetId, ClientId = t.ClientId, TradeStatus = t.TradeStatus }; if (req.ClientId != 0) { tl = tl.Where(x => x.ClientId == req.ClientId); } if (req.AssetIds.Any()) { tl = tl.Where(x => req.AssetIds.Contains(x.AssetId)); } if (req.TraderId != 0) { tl = tl.Where(x => x.TraderId == req.TraderId); } tl = tl.OrderByDescending(d => d.TradeDate); var retListResult = tl.ToSearchList(req); if(retListResult.rows !=null && retListResult.rows.Any()) { foreach (var item in retListResult.rows) { item.CountRatio = Modules.DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode).CountRatio; } } return Json(retListResult); } #endregion #region 计算初始保证 public JsonResult AjaxGetInitialMargin_Forward(OtcTradeForward trade) { if (trade is null) { throw new ArgumentNullException(nameof(trade)); } try { var tdConv = TradeConverter.ConvertForward(trade); tdConv.OptId = UserId; tdConv.VolType = "报价Bid"; tdConv.TradeCloseVolatility = null;//不设置为null会影响计算结果 if (!tdConv.TTMDays.HasValue) { var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tdConv.UnderlyingCode); tdConv.TTMDays = TradeCalcHelper.CalculateTTMDays(tdConv.TradeDate.Value, tdConv.ExerciseDate.Value, underlying?.UnderlyingTypeId ?? 0, PS.Config.ErpElement.PrecisionOfMinuteInQuote); } var initialMargin = MarginDefault.GetInitialMargin(tdConv, trade.id, true); return JsonSuccessData(initialMargin); } catch (Exception ex) { LogFactory.GetLogger("AjaxGetInitialMargin_Forward").Error(ex); return JsonError("获取初始预付金失败:" + ex.Message); } } #endregion #region 多次了结 public ActionResult MultiCloseList() { return View(); } public JsonResult AjaxGetMultiCloseList(TradeMultiCloseQueryModel queryModel) { queryModel.PageIndex = queryModel.page; queryModel.PageSize = queryModel.rows; if (!string.IsNullOrEmpty(queryModel.sidx)) { queryModel.SortExpression = queryModel.sidx + " " + queryModel.sord; } if (queryModel.PageSize == 0) { queryModel.PageIndex = 1; queryModel.PageSize = 10000; } queryModel.UserAssets = CurUser.GetAssetUnitIds(); queryModel.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); queryModel.LoginUserId = CurUser.UserId; queryModel.CurUserTradeIds = CurUser.GetTradeIdsByCurUser(); var datas = new ForwardMultiCloseService(CurUser).GetPagedDatas(queryModel); return JsonForJqGrid(datas); } public ActionResult MultiCloseListExport(TradeMultiCloseQueryModel queryModel) { queryModel.UserAssets = CurUser.GetAssetUnitIds(); queryModel.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易); var filecontent = new ForwardMultiCloseService(CurUser).ExportExcel2007(queryModel); return File(filecontent, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"远期多次了结{DateTime.Today:yyyyMMdd}.xlsx"); } #endregion #region 远期交易导入 public ActionResult TradeUpload() { return View(); } /// /// 导入Excel /// [MyAuthorize("交易管理-远期交易")] public ActionResult UploadTradeExcel(string TypeName) { if (Request.Form.Files.Count == 0) { return JsonError("上传文件不存在"); } var file = Request.Form.Files[0]; if (!Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase)) { return JsonError("请上传Excel(.xlsx)格式文件"); } using var stream = file.OpenReadStream(); new ForwardTradeImportService(CurUser).ImportFromExcel(stream, TypeName, out var TotalNum, out var SuccessNum); return Json(new { success = true, totalNum = TotalNum, successNum = SuccessNum, }); } #endregion } }