using EntrustSettle.Common; using EntrustSettle.Common.Const; using EntrustSettle.Common.Extensions; using EntrustSettle.Common.Helper; using EntrustSettle.Controllers; using EntrustSettle.IServices; using EntrustSettle.IServices.Base; using EntrustSettle.Model; using EntrustSettle.Model.Dtos; using EntrustSettle.Model.Models; using EntrustSettle.Model.Models.BillTrace; using EntrustSettle.Model.Models.DJY; using EntrustSettle.Model.Validator; using EntrustSettle.Repository.UnitOfWorks; using FluentValidation; using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using SqlSugar; using System.Text; namespace EntrustSettle.Api.Controllers { /// /// 订单 /// public class OrderController : BaseApiController { private readonly ILogger logger; private readonly IUnitOfWorkManage unitOfWorkManage; private readonly IHYDService hydService; private readonly IOrderService orderService; private readonly IOrderAnnexService orderAnnexService; private readonly IAnnexService annexService; private readonly IOrderHistoryService orderHistoryService; private readonly IOrderFeeService orderFeeService; private readonly IQueueService queueService; private readonly IInvoiceApplyService invoiceApplyService; private readonly IBaseServices billtraceService; private readonly IBaseServices billtraceCtnService; public OrderController(IOrderService orderService, IOrderAnnexService orderFileService, ILogger logger, IUnitOfWorkManage unitOfWorkManage, IOrderHistoryService orderHistoryService, IHYDService hydService, IAnnexService annexService, IOrderFeeService orderFeeService, IQueueService queueService, IInvoiceApplyService invoiceApplyService, IBaseServices billtraceService, IBaseServices billtraceCtnService) { this.orderService = orderService; this.orderAnnexService = orderFileService; this.logger = logger; this.unitOfWorkManage = unitOfWorkManage; this.orderHistoryService = orderHistoryService; this.hydService = hydService; this.annexService = annexService; this.orderFeeService = orderFeeService; this.queueService = queueService; this.invoiceApplyService = invoiceApplyService; this.billtraceService = billtraceService; this.billtraceCtnService = billtraceCtnService; } /// /// 获取订单列表 /// [HttpGet] public async Task>> List([FromQuery] OrderListInputDto input) { if (input.QueryType == 2) { if (!App.User.CompanyName.Contains("东胜伟业") && !App.User.CompanyName.Contains("大简云")) { throw new Exception("登陆人所属公司非东胜或大简云,无法查看运营端,请联系管理员"); } } // 运踪筛选条件 List queryBilltraceGidList = null; if (input.BillTraceState != null || input.AtaStart != null || input.AtaEnd != null) { var billtraceGidPageList = await billtraceService.AsQueryable() .Where(x => x.IsOuter == true && x.CompID == App.User.CompanyId) .WhereIF(input.BillTraceState == 1, x => x.StaCangDan == "Y") .WhereIF(input.BillTraceState == 2, x => x.StaHaiGuan == "Y") .WhereIF(input.BillTraceState == 3, x => x.StaTiHuo == "Y") .WhereIF(input.BillTraceState == 4, x => x.StaFanKong == "Y") .WhereIF(input.AtaStart != null, x => x.ATA >= input.AtaStart) .WhereIF(input.AtaEnd != null, x => x.ATA <= input.AtaEnd.Value.AddDays(1)) .OrderByDescending(x => x.CreateTime) .Select(x => x.GID) .ToPageListAsyncExtension(input.pageIndex, input.pageSize); queryBilltraceGidList = billtraceGidPageList.data; } // 可以查看所有数据的用户Gid列表 var seeAllDataUserGids = AppSettings.app("Startup", "SeeAllDataUserGids"); PageModel result = await orderService.AsQueryable() .WhereIF(!seeAllDataUserGids.Contains(App.User.ID) && input.QueryType != 2, x => x.CompanyId == App.User.CompanyId) // 衣国豪的账号在客户端也可以看全部数据 .WhereIF(!string.IsNullOrWhiteSpace(input.Mblno), x => x.Mblno.Contains(input.Mblno)) .WhereIF(!string.IsNullOrWhiteSpace(input.CompanyName), x => x.CompanyName.Contains(input.CompanyName)) .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), x => x.Remark.Contains(input.Remark)) .WhereIF(input.ServiceType != null, x => x.ServiceType == input.ServiceType) .WhereIF(input.Status != null, x => x.Status == (int)input.Status) .WhereIF(input.CreateTimeStart != null, x => x.CreateTime >= input.CreateTimeStart) .WhereIF(input.CreateTimeEnd != null, x => x.CreateTime <= input.CreateTimeEnd) .WhereIF(queryBilltraceGidList != null, x => queryBilltraceGidList.Contains(x.BilltraceGid)) .Select() .OrderBy("id desc") .ToPageListAsyncExtension(input.pageIndex, input.pageSize); //var sql = orderService.AsQueryable() //.WhereIF(!seeAllDataUserGids.Contains(App.User.ID) && input.QueryType != 2, x => x.CompanyId == App.User.CompanyId).ToSqlString(); var orderIdList = result.data.Select(x => x.Id).ToList(); if (orderIdList.Count > 0) { // 为订单列表绑定发票及账单状态 var orderWithTypeList = await orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => orderIdList.Contains(o.OrderId) && (a.Type == 3 || a.Type == 4)) .Select((o, a) => new { o.OrderId, a.Type }) .Distinct() .ToListAsync(); var group = orderWithTypeList.GroupBy(x => x.OrderId).ToList(); foreach (var item in group) { var order = result.data.FirstOrDefault(x => x.Id == item.Key); if (item.Any(x => x.Type == 3)) { order.IsHasBillAnnex = true; } if (item.Any(x => x.Type == 4)) { order.IsHasInvoiceAnnex = true; } } // 查询运踪信息 var billtraceGidList = result.data.Where(x => !string.IsNullOrEmpty(x.BilltraceGid)).Select(x => x.BilltraceGid).ToList(); var billtraceList = await billtraceService.AsQueryable() .Where(x => billtraceGidList.Contains(x.GID)) .Select() .ToListAsync(); var ctnBilltraceList = await billtraceCtnService.AsQueryable() .Where(x => billtraceGidList.Contains(x.PID)) .GroupBy(x => x.PID) .Select(x => new { x.PID, numAll = SqlFunc.AggregateCount(x.GID), numTiXiang = SqlFunc.AggregateSum(SqlFunc.IIF(x.StaTiHuo == "Y", 1, 0)), numFanKong = SqlFunc.AggregateSum(SqlFunc.IIF(x.StaFanKong == "Y", 1, 0)) }).ToListAsync(); result.data.ForEach(x => { if (!string.IsNullOrWhiteSpace(x.MailBillNo)) { x.IsHasInvoiceAnnex = true; } // 绑定主要运踪 var billtrace = billtraceList.FirstOrDefault(b => b.GID == x.BilltraceGid); if (billtrace != null) { x.IsCangdan = billtrace.StaCangDan == "Y"; x.IsHaifang = billtrace.StaHaiGuan == "Y"; x.TimeHaiFang = billtrace.TimeHaiGuan; x.StaTiXiang = billtrace.StaTiHuo; x.StaFanKong = billtrace.StaFanKong; x.ATA = billtrace.ATA; } // 绑定箱信息运踪 var ctnBilltrace = ctnBilltraceList.FirstOrDefault(c => c.PID == x.BilltraceGid); if (ctnBilltrace != null) { x.CtnNumAll = ctnBilltrace.numAll; x.CtnNumTiXiang = ctnBilltrace.numTiXiang; x.CtnNumFanKong = ctnBilltrace.numFanKong; } }); } return SuccessPage(result); } /// /// 查询箱信息运踪详情 /// [HttpGet] public async Task>> GetCtnBilltraceList(long id) { var order = await orderService.QueryFirst(x => x.Id == id, x => new { x.BilltraceGid }); if (string.IsNullOrEmpty(order.BilltraceGid)) { throw new Exception("运踪未订阅"); } var ctnList = await billtraceCtnService.Query(x => x.PID == order.BilltraceGid, x => new CtnBilltraceDto() { Cntrno = x.CNTRNO, FanKongTime = x.TimeFanKong, StockpilingDays = x.StoreDays, TiXiangTime = x.TimeTiHuo, }); return Success(ctnList); } [HttpGet] [AllowAnonymous] //[ApiUser(ApiCode = "OrderSubmit")] public async Task Test() { // 查询所有待处理订单列表 var time = DateTime.Now.AddMinutes(-5); // 查询所有待处理订单列表 var pendingOrderList = await orderService.QueryTop(x => x.IsSend == false && x.CreateTime < time, 20, "Id asc"); //CustFee custFeeModel = new CustFee() //{ // SENDTYPE = 0, // SENDTIME = DateTime.Now, // CtnrInfo = string.Empty, // CtnrCount = 0, // GID = Guid.NewGuid().ToString(), //}; //string msg = "123"; //logger.LogInformation($"{msg},扣费记录内容:{{custFeeModel}}", custFeeModel.ToJson()); var a = App.User.Name; var b = App.User.ID; //await Task.CompletedTask; var c = new { a, b }; return Success(c); } /// /// 下单 /// [HttpPost] //[UseTran] public async Task>> Submit(OrderSubmitDto inputDto) { var validateResult = new OrderSubmitDtoValidator().Validate(inputDto); if (!validateResult.IsValid) { throw new ArgumentException(validateResult.ToString("、")); } // 订单信息保存 inputDto.MblnoList = inputDto.MblnoList.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToArray(); StringHelper.TrimStringProperties(inputDto); // 提单号校验重复 var existsMblnoList = await orderService.Query(x => inputDto.MblnoList.Contains(x.Mblno), x => x.Mblno); if (existsMblnoList.Any()) { throw new Exception($"下列提单号已存在,无需重复下单:{string.Join("、", existsMblnoList)}"); } // 查询税号 var custBalanceService = App.GetService>(); var taxCode = await custBalanceService.Db.Queryable().Where(x => x.CompId == inputDto.CompanyId).Select(x => x.TaxCode).FirstAsync(); var orderList = new List(inputDto.MblnoList.Length); var billtraceList = new List(inputDto.MblnoList.Length); foreach (var item in inputDto.MblnoList) { var billtraceGid = await billtraceService.QueryFirst(x => x.MBLNO == item && x.CompID == inputDto.CompanyId && x.IsOuter, x => x.GID); if (billtraceGid == null) { billtraceGid = Guid.NewGuid().ToString(); var billtrace = new OpSeaiBillTrace { GID = billtraceGid, UserID = App.User.ID, UserName = App.User.Name, CompID = inputDto.CompanyId, CompName = inputDto.CompanyName, MBLNO = item, StaCangDan = "N", StaHaiGuan = "N", StaTiHuo = "N", StaFanKong = "N", IsOuter = true, CreateTime = DateTime.Now }; billtraceList.Add(billtrace); } var order = new Order { Mblno = item, BilltraceGid = billtraceGid, CompanyId = inputDto.CompanyId, CompanyName = inputDto.CompanyName, TaxCode = taxCode, ServiceType = inputDto.ServiceType, ProjectType = inputDto.ProjectType, IsSend = false, Status = null, ContactId = inputDto.ContactId, ContactName = inputDto.ContactName, ContactTel = inputDto.ContactTel, Remark = inputDto.Remark }; orderList.Add(order); } unitOfWorkManage.BeginTran(); foreach (var item in orderList) { var id = await orderService.AsInsertable(item).ExecuteReturnSnowflakeIdAsync(); item.Id = id; } var orderIdList = orderList.Select(x => x.Id).ToList(); // 附件关联信息保存 if (inputDto.AnnexIdList?.Count > 0) { var orderFileModelList = new List(); foreach (var orderId in orderIdList) { foreach (var annexId in inputDto.AnnexIdList) { orderFileModelList.Add(new OrderAnnex() { OrderId = orderId, AnnexId = annexId }); } }; await orderAnnexService.Add(orderFileModelList); } // 状态历史保存 //var historyModelList = new List(); //foreach (var item in orderIdList) //{ // historyModelList.Add(new OrderHistory // { // Pid = item, // Status = (int)OrderStatusEnum.已下单, // StatusTime = DateTime.Now // }); //} //await orderHistoryService.Add(historyModelList); unitOfWorkManage.CommitTran(); // 保存到运踪表中 await billtraceService.AsInsertable(billtraceList).ExecuteCommandAsync(); // 查询所有待处理订单列表 var pendingOrderList = await orderService.Query(x => x.IsSend == false && orderIdList.Contains(x.Id)); var result = orderList.Select(x => new OrderSubmitResultDto() { OrderId = x.Id, Mblno = x.Mblno }).ToList(); if (pendingOrderList.Count == 0) { return Success(result); } string domainUrl = AppSettings.app(["Startup", "Domain"]); foreach (Order orderItem in pendingOrderList) { try { List annexList = await orderAnnexService.AsQueryable() .InnerJoin((o, a) => o.AnnexId == a.Id) .Where(o => o.OrderId == orderItem.Id) .Select((o, a) => a) .ToListAsync(); // 构建提交数据 string fileNameStr = string.Join(",", annexList.Select(x => x.Name)); string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/Download?key={x.Key}")); string remark = "备注:客户所选服务:"; var projects = orderItem.ProjectType.Split(","); foreach (var project in projects) { remark += project switch { "1" => "港杂费代结,", "2" => "堆存费代结,", _ => "(未维护),", }; } remark = remark.Remove(remark.Length - 1, 1); remark += Environment.NewLine; remark += "客户备注:" + orderItem.Remark; HydSubmitDto submitDto = new HydSubmitDto() { billNoList = new List() { orderItem.Mblno }, customerName = orderItem.CompanyName, tel = orderItem.ContactTel, fileName = fileNameStr, fileUrl = fileUrl, remark = remark, registerFlag = 1, invoiceApplyFlag = 0, registerUser = new HydSubmitDto.RegisterUser() { phone = orderItem.ContactTel?.Trim(), userName = orderItem.ContactName?.Trim(), enterpriseName = orderItem.CompanyName?.Trim(), sex = 1, dutyNo = orderItem.TaxCode?.Trim() ?? "" } }; // 开始提交 long bsno = await hydService.Submit(submitDto); // 更新订单状态 orderItem.Status = (int)OrderStatusEnum.已下单; orderItem.Bsno = bsno; orderItem.IsSend = true; await orderService.Update(orderItem, x => new { x.Status, x.Bsno, x.IsSend }); // 记录状态历史 await orderHistoryService.Add(new OrderHistory() { Pid = orderItem.Id, StatusTime = DateTime.Now, Status = (int)OrderStatusEnum.已下单, Remark = orderItem.Remark }); } catch (Exception ex) { logger.LogError(ex, $"提单号{orderItem.Mblno}下单时发生未知异常,继续处理下一票"); continue; } } return Success(result); } /// /// 补充订阅运踪 /// [HttpPost] public async Task SubcribeBilltrace([FromBody] long[] ids) { var billtraceList = new List(ids.Length); var orderList = await orderService.Query(x => ids.Contains(x.Id)); foreach (var item in orderList) { if (!string.IsNullOrEmpty(item.BilltraceGid) && await billtraceService.AsQueryable().AnyAsync(x => x.GID == item.BilltraceGid)) { continue; } var billtrace = new OpSeaiBillTrace { GID = Guid.NewGuid().ToString(), UserID = item.CreateId, UserName = item.CreateBy, CompID = item.CompanyId, CompName = item.CompanyName, MBLNO = item.Mblno, StaCangDan = "N", StaHaiGuan = "N", StaTiHuo = "N", StaFanKong = "N", IsOuter = true, CreateTime = DateTime.Now }; billtraceList.Add(billtrace); if (await billtraceService.AsInsertable(billtrace).ExecuteCommandAsync() > 0) { await orderService.Update(x => new Order { BilltraceGid = billtrace.GID }, x => x.Id == item.Id); } } return SuccessMsg(); } /// /// 获取订单附件信息列表 /// /// 订单Id /// 附件类型 [HttpGet] public async Task>> GetAnnexInfoList(long id, FileTypeEnum fileType) { var result = await orderAnnexService.Db.Queryable((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == id && a.Type == (int)fileType) .Select((o, a) => new AnnexDto() { Name = a.Name, Type = a.Type, Id = a.Id }) .ToListAsync(); return Success(result); } /// /// 订单状态变更 /// [HttpPost] public async Task ChangeStatus(ChangeStatusDto changeStatusDto) { var validateResult = new ChangeStatusDtoValidator().Validate(changeStatusDto); if (!validateResult.IsValid) { throw new ArgumentException(validateResult.ToString("、")); } var order = await orderService.QueryById(changeStatusDto.Id); if (order == null) { throw new Exception("未找到该订单"); } order.Status = (int)changeStatusDto.Status; decimal sumAmount = 0; bool isBeginTran = false; try { // 执行扣费 if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0) { string logMsg = $"订单Id:{changeStatusDto.Id},提单号:{order.Mblno}"; try { sumAmount = changeStatusDto.FeeList.Select(x => x.Amount).Sum(); logger.LogInformation($"{logMsg}, 手动更新状态时,需要扣费,总金额:{sumAmount}"); var custBalanceService = App.GetService>(); var balance = await custBalanceService.AsQueryable().FirstAsync(x => x.COMNAME == order.CompanyName); if (balance == null) { logger.LogInformation($"{logMsg},扣费失败:没有账户钱包!"); throw new Exception("扣费失败:没有账户钱包!"); } if (balance.Balance < sumAmount) { logger.LogInformation($"{logMsg},扣费失败:账户余额不足!{sumAmount}"); throw new Exception($"账户余额不足!{sumAmount} {order.CompanyName}"); } logger.LogInformation($"{logMsg},开始写入消费记录"); var custFeeService = App.GetService>(); var beizhu = string.Join(',', changeStatusDto.FeeList.Select(x => x.Name + ":" + x.Amount)); CustFee custFeeModel = new CustFee() { BEIZHU = beizhu, BSNO = order.Id.ToString(), COMNAME = order.CompanyName, MBLNO = order.Mblno, BSTYPE = CommonConst.WEITUOJIESUAN, CREATETIME = DateTime.Now, LURURENID = order.ContactId, LURUREN = order.ContactName, COMID = order.CompanyId, SENDUSERID = order.ContactId, SENDUSER = order.ContactName, SENDCOM = order.CompanyName, SENDTYPE = 0, SENDTIME = DateTime.Now, CtnrInfo = string.Empty, CtnrCount = 0, GID = Guid.NewGuid().ToString(), PRICE = sumAmount }; logger.LogInformation($"{logMsg},扣费记录内容:{{custFeeModel}}", custFeeModel.ToJson()); unitOfWorkManage.BeginTran(); isBeginTran = true; // 添加扣费记录 var num = await custFeeService.AsInsertable(custFeeModel).ExecuteCommandAsync(); if (num <= 0) { unitOfWorkManage.RollbackTran(); throw new Exception($"{logMsg},添加扣费记录失败!"); } else { logger.LogInformation($"{logMsg},添加扣费记录成功"); } // 更新余额 num = await custBalanceService.AsUpdateable() .SetColumns(x => x.Balance == x.Balance - sumAmount) .Where(x => x.COMNAME == order.CompanyName) .ExecuteCommandAsync(); if (num <= 0) { unitOfWorkManage.RollbackTran(); throw new Exception($"{logMsg},更新余额失败!"); } else { logger.LogInformation($"{logMsg},更新余额成功"); } } catch (Exception ex) { logger.LogError(ex, $"{logMsg},执行扣费时发生未知异常"); throw; } } if (!isBeginTran) { unitOfWorkManage.BeginTran(); } // 添加新的费用信息 if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0) { // 清除原有费用信息 //await orderFeeService.Delete(x => x.OrderId == changeStatusDto.Id); //order.Amount = order.Amount == null ? null : 0; var orderFeeModelList = changeStatusDto.FeeList.Select(x => new OrderFee() { Name = x.Name, Amount = x.Amount, OrderId = changeStatusDto.Id }).ToList(); await orderFeeService.Add(orderFeeModelList); // 查出来现有的费用记录,更新 var sumAllAmount = await orderFeeService.AsQueryable() .Where(x => x.OrderId == changeStatusDto.Id) .SumAsync(x => x.Amount); order.Amount = sumAllAmount; } await orderService.Update(order, x => new { x.Status, x.Amount }); var orderHistory = new OrderHistory { Pid = order.Id, Status = (int)changeStatusDto.Status, Remark = changeStatusDto.Remark, Amount = sumAmount, StatusTime = DateTime.Now, }; await orderHistoryService.Add(orderHistory); unitOfWorkManage.CommitTran(); } catch (Exception) { unitOfWorkManage.RollbackTran(); throw; } // 将更新后的状态及费用推送到消息队列 if (AppSettings.app("RabbitMQ", "Enabled").ObjToBool()) { _ = Task.Run(() => { string msg = $"Id:[{order.Id}],提单号:[{order.Mblno}],手动更新状态后推送队列"; try { StatusPushDto pushDto = new() { OrderId = order.Id, Mblno = order.Mblno, MessageType = 1, MessageDesc = "状态更新推送", Remark = changeStatusDto.Remark, Status = (int)changeStatusDto.Status, StatusDesc = changeStatusDto.Status.ToString() }; var feeList = orderFeeService.AsQueryable().Where(x => x.OrderId == order.Id).ToList(); if (feeList.Count > 0) { pushDto.FeeList = feeList.Select(x => new StatusPushDto.FeeDto() { FeeId = x.Id, FeeName = x.Name, FeeAmount = x.Amount }).ToList(); } var annexList = orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == order.Id && a.Type == 5) .Select((o, a) => a) .ToList(); if (annexList.Count > 0) { pushDto.FeebackAnnexList = annexList.Select(x => new StatusPushDto.FeebackAnnex() { Id = x.Id, BusinessTime = x.BusinessTime, FileName = x.Name, Remark = x.Remark }).ToList(); } //if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0) //{ // pushDto.FeeList = changeStatusDto.FeeList.Select(x => new StatusPushDto.FeeDto() // { // //Id = x. // FeeName = x.Name, // FeeAmount = x.Amount // }).ToList(); //} var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) { logger.LogError(ex, $"{msg},失败"); } }); } return SuccessMsg(); } /// /// 为订单追加附件或信息 /// /// [HttpPost] public async Task BindAnnexOrInfo(BindAnnexOrInfoDto bindDto) { var order = await orderService.QueryById(bindDto.OrderId); if (order == null) { throw new Exception("未找到该订单"); } // 反馈附件需要请求海运达接口,所以需要先判断是否反馈成功,成功后再执行后续操作 if (bindDto.OperType == FileTypeEnum.反馈附件) { if (order.Status == null) { throw new Exception("请等待具有已下单状态后再进行反馈"); } if (order.Status == (int)OrderStatusEnum.已完结) { throw new Exception("该订单已完结,无法进行反馈"); } if (string.IsNullOrWhiteSpace(bindDto.Remark) && (bindDto.AnnexIdList?.Any() ?? false) == false) { throw new Exception("无可反馈内容"); } List hydFeedbackDtoList = new List(); if (bindDto.AnnexIdList != null && bindDto.AnnexIdList.Count > 0) { string domainUrl = AppSettings.app(["Startup", "Domain"]); var annexList = await annexService.Query(x => bindDto.AnnexIdList.Contains(x.Id)); foreach (Annex item in annexList) { //string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/Download?key={x.Key}")); string fileUrl = $"{domainUrl}/api/Annex/Download?key={item.Key}"; hydFeedbackDtoList.Add(new HydFeedbackDto() { fileName = item.Name, fileUrl = fileUrl, orderNo = (long)order.Bsno, billApplyFlag = 0, remark = bindDto.Remark }); } } else { hydFeedbackDtoList.Add(new HydFeedbackDto() { orderNo = (long)order.Bsno, remark = bindDto.Remark, billApplyFlag = 0 }); } bool isSuccess = await hydService.FeedBack(hydFeedbackDtoList); if (!isSuccess) { logger.LogError($"提单号:{order.Mblno}向海运达反馈时发生异常"); throw new Exception("反馈失败,请稍后重试"); } else { logger.LogInformation($"提单号:{order.Mblno}向海运达反馈成功"); } } unitOfWorkManage.BeginTran(); if (bindDto.OperType == FileTypeEnum.反馈附件) { if (bindDto.AnnexIdList != null && bindDto.AnnexIdList.Count > 0) { // 添加要新增绑定的附件信息 var orderAnnexModelList = bindDto.AnnexIdList.Select(x => new OrderAnnex() { AnnexId = x, OrderId = bindDto.OrderId }).ToList(); await orderAnnexService.Add(orderAnnexModelList); // 将备注更新到附件表中 await annexService.AsUpdateable() .SetColumns(x => x.Remark == bindDto.Remark) .Where(x => bindDto.AnnexIdList.Contains(x.Id)) .ExecuteCommandAsync(); } else { var id = await annexService.Add(new Annex() { Remark = bindDto.Remark, Type = 2 }); await orderAnnexService.Add(new OrderAnnex() { AnnexId = id, OrderId = bindDto.OrderId }); } } // 如果操作类型为账单或发票,则先删除原有的绑定信息 else if (bindDto.OperType == FileTypeEnum.账单 || bindDto.OperType == FileTypeEnum.发票) { var oldAnnexIdList = await orderAnnexService.AsQueryable() .InnerJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == bindDto.OrderId && a.Type == (int)bindDto.OperType) .Select((o, a) => a.Id) .ToListAsync(); // 处理要删除的 var waitDelAnndexIdList = oldAnnexIdList.Except(bindDto.AnnexIdList).ToList(); if (waitDelAnndexIdList.Any()) { await orderAnnexService.Delete(x => x.OrderId == bindDto.OrderId && waitDelAnndexIdList.Contains(x.AnnexId)); await annexService.Delete(x => waitDelAnndexIdList.Contains(x.Id)); } // 处理要新增的 var waitAddAnnexIdList = bindDto.AnnexIdList.Except(oldAnnexIdList); if (waitAddAnnexIdList.Any()) { var orderAnnexModelList = waitAddAnnexIdList.Select(x => new OrderAnnex() { AnnexId = x, OrderId = bindDto.OrderId }).ToList(); await orderAnnexService.Add(orderAnnexModelList); } } orderService.Db.Tracking(order); if (bindDto.OperType == FileTypeEnum.反馈附件) { if (!string.IsNullOrWhiteSpace(bindDto.Remark)) { if (string.IsNullOrEmpty(order.Remark)) { order.Remark = bindDto.Remark; } else { order.Remark += (Environment.NewLine + bindDto.Remark); } } } else if (bindDto.OperType == FileTypeEnum.发票) { order.MailFlag = bindDto.MailFlag; order.MailBillNo = bindDto.MailBillNo; } await orderService.Db.Updateable(order).ExecuteCommandAsync(); unitOfWorkManage.CommitTran(); // 如果操作类型为发票或账单,将反馈推送到消息队列 if ((bindDto.OperType is FileTypeEnum.发票 or FileTypeEnum.账单) && AppSettings.app("RabbitMQ", "Enabled").ObjToBool()) { _ = Task.Run(() => { string msg = $"Id:[{order.Id}],提单号:[{order.Mblno}],更新账单或发票后推送队列"; try { int type = bindDto.OperType switch { FileTypeEnum.账单 => 3, FileTypeEnum.发票 => 4, _ => 0 }; var billIdList = orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == order.Id && a.Type == type) .Select((o, a) => a.Id) .ToList(); BillPushDto pushDto = new() { OrderId = order.Id, Mblno = order.Mblno, AnnexIdList = billIdList, }; if (bindDto.OperType == FileTypeEnum.账单) { pushDto.MessageType = 2; pushDto.MessageDesc = "账单附件信息推送"; } else if (bindDto.OperType == FileTypeEnum.发票) { pushDto.MessageType = 3; pushDto.MessageDesc = "发票附件信息推送"; pushDto.MailFlag = bindDto.MailFlag; pushDto.MailBillNo = bindDto.MailBillNo; } var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) { logger.LogError(ex, $"{msg},失败"); } }); //_ = Task.Run(() => //{ // string msg = $"Id:[{order.Id}],提单号:[{order.Mblno}],"; // try // { // string json = null; // if (bindDto.OperType is FileTypeEnum.账单) // { // msg += "更新账单后推送队列"; // BillPushDto pushDto = new() // { // MessageType = 2, // MessageDesc = "账单附件信息推送", // AnnexIdList = bindDto.AnnexIdList, // OrderId = order.Id, // Mblno = order.Mblno, // }; // json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() // { // NullValueHandling = NullValueHandling.Ignore // }); // } // else if (bindDto.OperType == FileTypeEnum.发票) // { // msg += "更新发票后推送队列"; // InvoicePushDto pushDto = new() // { // MessageType = 3, // MessageDesc = "发票附件信息推送", // AnnexIdList = bindDto.AnnexIdList, // OrderList = new List() // { // new InvoicePushDto.OrderInfo() // { // OrderId = order.Id, // Mblno = order.Mblno, // MailFlag = bindDto.MailFlag, // MailBillNo = bindDto.MailBillNo, // } // } // }; // json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() // { // NullValueHandling = NullValueHandling.Ignore // }); // } // queueService.Push(msg, order.CompanyId, json); // } // catch (Exception ex) // { // logger.LogError(ex, $"{msg},失败"); // } //}); } return SuccessMsg(); } /// /// 获取订单详情 /// [HttpGet] public async Task> Detail(long id) { var result = await orderService.AsQueryable() .Where(x => x.Id == id) .Select() .FirstAsync(); if (result == null) { throw new Exception("为找到该订单,请刷新后重试"); } var annexList = await orderAnnexService.Db.Queryable((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == id) .Where((o, a) => a.Type == (int)FileTypeEnum.原始附件 || a.Type == (int)FileTypeEnum.反馈附件 || a.Type == (int)FileTypeEnum.外部往来单据) .OrderByDescending((o, a) => a.CreateTime) .Select((o, a) => new AnnexDto() { Id = a.Id, Name = a.Name, Type = a.Type, Remark = a.Remark, CreateTime = a.CreateTime, CreateBy = a.CreateBy }) .ToListAsync(); result.AnnexList = annexList; return Success(result); } /// /// 获取订单费用列表 /// [HttpGet] public async Task>> FeeList(long id) { var result = await orderFeeService.AsQueryable() .Where(x => x.OrderId == id) .Select() .ToListAsync(); return Success(result); } /// /// 发票申请 /// [HttpPost] public async Task ApplyInvoice(ApplyInvoiceDto input) { var validateResult = new ApplyInvoiceValidator().Validate(input); if (!validateResult.IsValid) { throw new ArgumentException(validateResult.ToString("、")); } if (input.OrderIdList?.Any() != true) { throw new Exception("申请列表为空"); } var orderList = await orderService.AsQueryable().Where(x => input.OrderIdList.Contains(x.Id)).Select(x => new { x.Id, x.Mblno, x.CompanyName, x.ContactTel, x.ContactName, x.TaxCode, x.IsApplyInvoice, x.Status }).ToListAsync(); if (orderList.Count != input.OrderIdList.Count) { throw new Exception("待申请发票的数据中存在已删除的单据,请重新查询后重新申请"); } var noStatusOrderList = orderList.Where(x => x.Status != 3 && x.Status != 4); if (noStatusOrderList.Any()) { //throw new Exception("需要在订单具有【已缴费】或【已完结】状态时才能进行发票申请,下列订单状态不符合条件,请重新选择:" + string.Join("、", noStatusOrderList.Select(x => x.Mblno))); throw new Exception("业务尚未缴费,请先缴费"); } // 判断是否存在申请中的发票 var applyingOrderList = orderList.Where(x => x.IsApplyInvoice).ToList(); if (applyingOrderList.Count > 0) { throw new Exception("下列订单正在申请开票中,无法重复申请,请重新选择:" + string.Join("、", applyingOrderList.Select(x => x.Mblno))); } // 判断是否存在已开票的发票 var existsInvoiceOrderIdList = await orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => input.OrderIdList.Contains(o.OrderId) && a.Type == (int)FileTypeEnum.发票) .Select((o, a) => o.OrderId) .ToListAsync(); if (existsInvoiceOrderIdList.Count > 0) { throw new Exception("下列订单已存在发票,无法重复申请,请重新选择:" + string.Join("、", orderList.Where(x => existsInvoiceOrderIdList.Contains(x.Id)).Select(x => x.Mblno))); } List mblnoList = orderList.Select(x => x.Mblno).ToList(); StringBuilder builder = new(); builder.AppendLine("提单号:" + string.Join("、", mblnoList)); builder.AppendLine("单位全称:" + input.CompanyName); builder.AppendLine("税号:" + input.TaxCode); builder.AppendLine("地址:" + input.Address); builder.AppendLine("电话:" + input.Tel); builder.AppendLine("开户行:" + input.Bank); builder.AppendLine("银行账号:" + input.BankAccount); builder.AppendLine("备注:" + input.Remark); string remark = builder.ToString(); var firstOrder = orderList.First(); HydSubmitDto submitDto = new() { billNoList = mblnoList, customerName = firstOrder.CompanyName, tel = firstOrder.ContactTel, remark = remark, invoiceApplyFlag = 1, registerFlag = 1, registerUser = new HydSubmitDto.RegisterUser() { phone = firstOrder.ContactTel?.Trim(), userName = firstOrder.ContactName?.Trim(), enterpriseName = firstOrder.CompanyName?.Trim(), sex = 1, dutyNo = firstOrder.TaxCode?.Trim() ?? "" } }; long bsno = await hydService.Submit(submitDto); // 记录发票申请(用于接收到发票回推后,可以查询到关联的订单) var invoiceApplyModelList = orderList.Select(x => { var applyInfo = input.Adapt(); applyInfo.OrderId = x.Id; applyInfo.Bsno = bsno; applyInfo.Remark = input.Remark; return applyInfo; }).ToList(); await invoiceApplyService.Add(invoiceApplyModelList); // 记录订单状态历史 var orderStatusModelList = orderList.Select(x => new OrderHistory() { Pid = x.Id, StatusTime = DateTime.Now, Status = 5, Remark = remark, }).ToList(); await orderHistoryService.Add(orderStatusModelList); // 更新订单状态 await orderService.AsUpdateable() .SetColumns(x => x.IsApplyInvoice == true) .Where(x => input.OrderIdList.Contains(x.Id)) .ExecuteCommandAsync(); return SuccessMsg(); } /// /// 账单申请 /// [HttpPost] public async Task ApplyBill(ApplyBillDto input) { if (input.OrderId == 0) { throw new Exception("申请的订单为空"); } var order = await orderService.AsQueryable().Where(x => input.OrderId == x.Id).Select(x => new { x.Id, x.Mblno, x.Bsno, x.Status, x.IsApplyBill }).FirstAsync(); if (order == null) { throw new Exception("待申请账单的数据可能已删除,请重新查询后重新申请"); } if (order.Status != 4 && order.Status != 2 && order.Status != 3) { throw new Exception("业务尚未完结,无法出具账单"); } if (order.IsApplyBill) { throw new Exception("该订单正在申请账单中,请耐心等待"); } // 判断是否存账单 var existsBill = await orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => order.Id == o.OrderId && a.Type == (int)FileTypeEnum.账单) .AnyAsync(); if (existsBill) { throw new Exception("该订单已存在账单,无法重复申请"); } HydFeedbackDto feedbackDto = new() { billApplyFlag = 1, orderNo = order.Bsno, remark = "[请求账单]" }; await hydService.FeedBack([feedbackDto]); // 记录订单状态历史 await orderHistoryService.Add(new OrderHistory() { Pid = order.Id, StatusTime = DateTime.Now, Status = 6, Remark = input.Remark, }); // 更新订单状态 await orderService.AsUpdateable() .SetColumns(x => x.IsApplyBill == true) .Where(x => x.Id == order.Id) .ExecuteCommandAsync(); return SuccessMsg(); } } } // 笑脸*1:😀 // 笑脸*2:😁😂 // 笑脸*3:🤣😛😠 // 笑脸*4:😀😁😂🤣 // 笑脸*5:😄😅😆😇😈 // 笑脸*6:😉😊😋😌😍😎 // 笑脸*7:😏😐😑😒😓😔😕 // 笑脸*8:😖😗😘😙😚😛😜😝 // 笑脸*9:😞😟😠😡😢😣😤😥😦