委托结算业务

master
zhangxiaofeng 8 months ago
parent c1fcd39fd3
commit 93b22cabe6

@ -7,6 +7,7 @@ using EntrustSettle.Model.Models;
using EntrustSettle.Model.Validator; using EntrustSettle.Model.Validator;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
@ -22,12 +23,12 @@ namespace EntrustSettle.Api.Controllers
public class AnnexController : BaseApiController public class AnnexController : BaseApiController
{ {
private readonly IAnnexService annexService; private readonly IAnnexService annexService;
private readonly IOrderAnnexService orderAnnexService; private readonly IHttpContextAccessor httpContextAccessor;
public AnnexController(IAnnexService annexService, IOrderAnnexService orderAnnexService) public AnnexController(IAnnexService annexService, IHttpContextAccessor httpContextAccessor)
{ {
this.annexService = annexService; this.annexService = annexService;
this.orderAnnexService = orderAnnexService; this.httpContextAccessor = httpContextAccessor;
} }
/// <summary> /// <summary>
@ -79,24 +80,24 @@ namespace EntrustSettle.Api.Controllers
/// <summary> /// <summary>
/// 文件下载接口 /// 文件下载接口
/// </summary> /// </summary>
/// <param name="annexId">文件主键</param> /// <param name="annexId">文件记录主键</param>
[HttpGet] [HttpGet]
public async Task<IActionResult> DownloadFile([FromQuery] long annexId) public async Task<IActionResult> DownloadFile([FromQuery] long annexId)
{ {
// 如果当前登陆人非本公司,判断要下载的文件所属订单是否属于登陆人所在公司 // 如果当前登陆人非本公司,判断要下载的文件所属订单是否属于登陆人所在公司
if (!App.User.CompanyName.Contains("东胜伟业") && !App.User.CompanyName.Contains("大简云")) //if (!App.User.CompanyName.Contains("东胜伟业") && !App.User.CompanyName.Contains("大简云"))
{ //{
var compId = await orderAnnexService.AsQueryable() // var compId = await orderAnnexService.AsQueryable()
.InnerJoin<Order>((an, o) => an.OrderId == o.Id) // .InnerJoin<Order>((an, o) => an.OrderId == o.Id)
.Where(an => an.AnnexId == annexId) // .Where(an => an.AnnexId == annexId)
.Select((an, o) => o.CompanyId) // .Select((an, o) => o.CompanyId)
.FirstAsync(); // .FirstAsync();
if (compId != App.User.CompanyId) // if (compId != App.User.CompanyId)
{ // {
throw new Exception("附件所属订单与登陆人不匹配"); // throw new Exception("附件所属订单与登陆人不匹配");
} // }
} //}
var file = await annexService.QueryById(annexId); var file = await annexService.QueryById(annexId);
if (file == null) if (file == null)
{ {
@ -107,7 +108,8 @@ namespace EntrustSettle.Api.Controllers
{ {
throw new FileNotFoundException("文件不存在"); throw new FileNotFoundException("文件不存在");
} }
HttpContext.Response.Headers.TryAdd("Access-Control-Expose-Headers", "Content-Disposition");
httpContextAccessor.HttpContext.Response.Headers.TryAdd("Access-Control-Expose-Headers", "Content-Disposition");
// 读取filePath文件的内容并返回给客户端 // 读取filePath文件的内容并返回给客户端
var p = HttpUtility.UrlEncode(file.Name, System.Text.Encoding.UTF8); var p = HttpUtility.UrlEncode(file.Name, System.Text.Encoding.UTF8);
return PhysicalFile(filePath, "application/octet-stream", p); return PhysicalFile(filePath, "application/octet-stream", p);

@ -8,22 +8,61 @@ using Microsoft.AspNetCore.Mvc;
namespace EntrustSettle.Api.Controllers namespace EntrustSettle.Api.Controllers
{ {
/// <summary> /// <summary>
/// 对外接口 /// 对外提供的委托结算相关接口
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
public class OpenController : BaseApiController public class OpenController : BaseApiController
{ {
public OpenController() public OpenController()
{ {
} }
/// <summary>
/// 下单
/// </summary>
[HttpPost] [HttpPost]
[ApiUser(ApiCode = "OrderSubmit")] [ApiUser(ApiCode = "EntrustSettle")]
public async Task<MessageModel> OrderSubmit(OrderSubmitDto inputDto) public async Task<MessageModel> OrderSubmit(OrderSubmitDto inputDto)
{ {
var result = await App.GetService<OrderController>().Submit(inputDto); var result = await App.GetService<OrderController>().Submit(inputDto);
return result; return result;
} }
/// <summary>
/// 附件上传
/// </summary>
/// <param name="file">附件文件</param>
/// <param name="fileType">文件类型</param>
[HttpPost]
[ApiUser(ApiCode = "EntrustSettle")]
public async Task<MessageModel<long>> AnnexUpload([FromForm] IFormFile file, [FromForm] FileTypeEnum fileType)
{
var result = await App.GetService<AnnexController>().Upload(file, fileType);
return result;
}
/// <summary>
/// 反馈信息(为订单追加附件或信息)
/// </summary>
/// <returns></returns>
[HttpPost]
[ApiUser(ApiCode = "EntrustSettle")]
public async Task<MessageModel> BindAnnexOrInfo([FromBody] BindAnnexOrInfoDto bindDto)
{
var result = await App.GetService<OrderController>().BindAnnexOrInfo(bindDto);
return result;
}
/// <summary>
/// 获取附件
/// </summary>
/// <param name="annexId">文件记录主键</param>
[HttpGet]
[ApiUser(ApiCode = "EntrustSettle")]
public async Task<IActionResult> AnnexDownload([FromQuery] long annexId)
{
var result = await App.GetService<AnnexController>().DownloadFile(annexId);
return result;
}
} }
} }

@ -9,8 +9,12 @@ using EntrustSettle.Model.Models;
using EntrustSettle.Model.Validator; using EntrustSettle.Model.Validator;
using EntrustSettle.Repository.UnitOfWorks; using EntrustSettle.Repository.UnitOfWorks;
using FluentValidation; using FluentValidation;
using Mapster;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RabbitMQ.Client;
using System.Text;
namespace EntrustSettle.Api.Controllers namespace EntrustSettle.Api.Controllers
{ {
@ -26,6 +30,8 @@ namespace EntrustSettle.Api.Controllers
private readonly IUnitOfWorkManage unitOfWorkManage; private readonly IUnitOfWorkManage unitOfWorkManage;
private readonly IOrderHistoryService orderHistoryService; private readonly IOrderHistoryService orderHistoryService;
private readonly IHYDService hydService; private readonly IHYDService hydService;
private readonly IOrderFeeService orderFeeService;
private readonly IQueueService queueService;
public OrderController(IOrderService orderService, public OrderController(IOrderService orderService,
IOrderAnnexService orderFileService, IOrderAnnexService orderFileService,
@ -33,7 +39,9 @@ namespace EntrustSettle.Api.Controllers
IUnitOfWorkManage unitOfWorkManage, IUnitOfWorkManage unitOfWorkManage,
IOrderHistoryService orderHistoryService, IOrderHistoryService orderHistoryService,
IHYDService hydService, IHYDService hydService,
IAnnexService annexService) IAnnexService annexService,
IOrderFeeService orderFeeService,
IQueueService queueService)
{ {
this.orderService = orderService; this.orderService = orderService;
this.orderAnnexService = orderFileService; this.orderAnnexService = orderFileService;
@ -42,6 +50,8 @@ namespace EntrustSettle.Api.Controllers
this.orderHistoryService = orderHistoryService; this.orderHistoryService = orderHistoryService;
this.hydService = hydService; this.hydService = hydService;
this.annexService = annexService; this.annexService = annexService;
this.orderFeeService = orderFeeService;
this.queueService = queueService;
} }
/// <summary> /// <summary>
/// 获取订单列表 /// 获取订单列表
@ -96,8 +106,8 @@ namespace EntrustSettle.Api.Controllers
return SuccessPage(result); return SuccessPage(result);
} }
[HttpGet] [HttpGet]
[AllowAnonymous] //[AllowAnonymous]
[ApiUser(ApiCode = "OrderSubmit")] //[ApiUser(ApiCode = "OrderSubmit")]
public async Task<dynamic> Test() public async Task<dynamic> Test()
{ {
var a = App.User.Name; var a = App.User.Name;
@ -296,10 +306,27 @@ namespace EntrustSettle.Api.Controllers
throw new Exception("未找到该订单"); throw new Exception("未找到该订单");
} }
order.Status = (int)changeStatusDto.Status; order.Status = (int)changeStatusDto.Status;
order.Amount = changeStatusDto.Amount;
unitOfWorkManage.BeginTran(); unitOfWorkManage.BeginTran();
// test是否会更新UpdateTIme
// 清除原有费用信息
await orderFeeService.Delete(x => x.OrderId == changeStatusDto.Id);
order.Amount = order.Amount == null ? null : 0;
// 添加新的费用信息
if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0)
{
var orderFeeModelList = changeStatusDto.FeeList.Select(x => new OrderFee()
{
Name = x.Name,
Amount = x.Amount,
OrderId = changeStatusDto.Id
}).ToList();
await orderFeeService.Add(orderFeeModelList);
order.Amount = changeStatusDto.FeeList.Select(x => x.Amount).Sum();
}
await orderService.Update(order, x => new { x.Status, x.Amount }); await orderService.Update(order, x => new { x.Status, x.Amount });
var orderHistory = new OrderHistory var orderHistory = new OrderHistory
@ -307,21 +334,56 @@ namespace EntrustSettle.Api.Controllers
Pid = order.Id, Pid = order.Id,
Status = (int)changeStatusDto.Status, Status = (int)changeStatusDto.Status,
Remark = changeStatusDto.Remark, Remark = changeStatusDto.Remark,
Amount = changeStatusDto.Amount, Amount = order.Amount,
StatusTime = DateTime.Now, StatusTime = DateTime.Now,
}; };
await orderHistoryService.Add(orderHistory); await orderHistoryService.Add(orderHistory);
unitOfWorkManage.CommitTran(); unitOfWorkManage.CommitTran();
// 将更新后的状态及费用推送到消息队列
if (AppSettings.app("RabbitMQ", "Enabled").ObjToBool())
{
_ = Task.Run(() =>
{
string msg = $"Id[{order.Id}],提单号:[{order.Mblno}],手动更新状态后推送队列";
try
{
StatusPushDto pushDto = new()
{
MessageType = 1,
MessageDesc = "状态更新推送",
Remark = changeStatusDto.Remark,
Status = (int)changeStatusDto.Status,
StatusDesc = changeStatusDto.Status.ToString()
};
if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0)
{
pushDto.FeeList = changeStatusDto.FeeList.Select(x => new StatusPushDto.FeeDto()
{
FeeName = x.Name,
FeeAmount = x.Amount
}).ToList();
}
var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
queueService.Push(msg, json);
}
catch (Exception ex)
{
logger.LogError(ex, $"{msg},失败");
}
});
}
return SuccessMsg(); return SuccessMsg();
} }
/// <summary> /// <summary>
/// 为订单更新附件或信息 /// 为订单追加附件或信息
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<MessageModel> BindAnnexOrInfo([FromBody] BindAnnexOrInfoDto bindDto) public async Task<MessageModel> BindAnnexOrInfo(BindAnnexOrInfoDto bindDto)
{ {
var order = await orderService.QueryById(bindDto.OrderId); var order = await orderService.QueryById(bindDto.OrderId);
if (order == null) if (order == null)
@ -329,10 +391,9 @@ namespace EntrustSettle.Api.Controllers
throw new Exception("未找到该订单"); throw new Exception("未找到该订单");
} }
// 反馈附件需要请求海运达接口,所以需要先判断订单状态 // 反馈附件需要请求海运达接口,所以需要先判断是否反馈成功,成功后再执行后续操作
if (bindDto.OperType == FileTypeEnum.) if (bindDto.OperType == FileTypeEnum.)
{ {
// todo: 待放开 || order.Bsno == null
if (order.Status == null) if (order.Status == null)
{ {
throw new Exception("请等待具有已下单状态后再进行反馈"); throw new Exception("请等待具有已下单状态后再进行反馈");
@ -382,9 +443,9 @@ namespace EntrustSettle.Api.Controllers
logger.LogInformation($"提单号:{order.Mblno}向海运达反馈成功"); logger.LogInformation($"提单号:{order.Mblno}向海运达反馈成功");
} }
} }
unitOfWorkManage.BeginTran();
if (bindDto.AnnexIdList != null && bindDto.AnnexIdList.Count > 0) if (bindDto.AnnexIdList != null && bindDto.AnnexIdList.Count > 0)
{ {
unitOfWorkManage.BeginTran();
if (bindDto.OperType == FileTypeEnum. || bindDto.OperType == FileTypeEnum.) if (bindDto.OperType == FileTypeEnum. || bindDto.OperType == FileTypeEnum.)
{ {
@ -429,6 +490,41 @@ namespace EntrustSettle.Api.Controllers
await orderService.Db.Updateable(order).ExecuteCommandAsync(); await orderService.Db.Updateable(order).ExecuteCommandAsync();
unitOfWorkManage.CommitTran(); unitOfWorkManage.CommitTran();
// 如果操作类型为发票或账单,将反馈推送到消息队列
if ((bindDto.OperType is FileTypeEnum. or FileTypeEnum.)
&& AppSettings.app("RabbitMQ", "Enabled").ObjToBool())
{
_ = Task.Run(() =>
{
string msg = $"Id[{order.Id}],提单号:[{order.Mblno}],更新账单或发票后推送队列";
try
{
BillPushDto pushDto = new()
{
AnnexIdList = bindDto.AnnexIdList,
};
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, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
queueService.Push(msg, json);
}
catch (Exception ex)
{
logger.LogError(ex, $"{msg},失败");
}
});
}
return SuccessMsg(); return SuccessMsg();
} }
@ -462,5 +558,18 @@ namespace EntrustSettle.Api.Controllers
return Success(result); return Success(result);
} }
/// <summary>
/// 获取订单费用列表
/// </summary>
[HttpGet]
public async Task<MessageModel<List<OrderFeeDto>>> FeeList(long id)
{
var result = await orderFeeService.AsQueryable()
.Where(x => x.OrderId == id)
.Select<OrderFeeDto>()
.ToListAsync();
return Success(result);
}
} }
} }

@ -2,18 +2,10 @@
using EntrustSettle.Common.Const; using EntrustSettle.Common.Const;
using EntrustSettle.IRepository.Base; using EntrustSettle.IRepository.Base;
using EntrustSettle.Model.Models; using EntrustSettle.Model.Models;
using EntrustSettle.Model.Models.DJY;
using EntrustSettle.Repository.Base;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace EntrustSettle.Filter namespace EntrustSettle.Filter
{ {

@ -137,7 +137,7 @@ internal class Program
//options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64)); //options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64));
}); });
builder.Services.AddRabbitMQSetup(); //builder.Services.AddRabbitMQSetup(); 未采用注入的方式而是直接在需要的地方new
builder.Services.AddKafkaSetup(builder.Configuration); builder.Services.AddKafkaSetup(builder.Configuration);
builder.Services.AddEventBusSetup(); builder.Services.AddEventBusSetup();
@ -224,7 +224,7 @@ internal class Program
app.UseAuthentication(); // 认证中间件 app.UseAuthentication(); // 认证中间件
app.UseAuthorization(); // 授权中间件 app.UseAuthorization(); // 授权中间件
// 大简云的ids4返回的token里只有用户id没有Name、公司名称等信息所以这里手动赋值一下 // Ids4服务返回的token里只有用户id没有Name、公司名称等信息所以这里手动赋值一下
app.UseSetAppUserMiddleware(); app.UseSetAppUserMiddleware();
app.MapControllers(); app.MapControllers();

@ -243,12 +243,17 @@
"ConnectionString": "127.0.0.1:6379,defaultDatabase=3", "ConnectionString": "127.0.0.1:6379,defaultDatabase=3",
"InstanceName": "" //Key "InstanceName": "" //Key
}, },
"EventBus": {
"Enabled": false,
"SubscriptionClientName": "EntrustSettle"
},
"RabbitMQ": { "RabbitMQ": {
"Enabled": true, "Enabled": true,
"Connection": "60.209.125.238:40101/audit_booking", "ConnectionString": "amqp://entrust_settle_user:djy^2024@60.209.125.238:40101/entrust_settle"
"UserName": "audit_booking_user", //"Connection": "60.209.125.238:40101/audit_booking",
"Password": "djy^2024", //"UserName": "audit_booking_user",
"RetryCount": 3 //"Password": "djy^2024",
//"RetryCount": 3
}, },
"Kafka": { "Kafka": {
"Enabled": false, "Enabled": false,
@ -256,9 +261,5 @@
"Topic": "entrustsettle", "Topic": "entrustsettle",
"GroupId": "entrustsettle-consumer", "GroupId": "entrustsettle-consumer",
"NumPartitions": 3 // "NumPartitions": 3 //
},
"EventBus": {
"Enabled": false,
"SubscriptionClientName": "EntrustSettle"
} }
} }

@ -4,5 +4,10 @@
{ {
public const string API_USER_HEADER_KEY = "USER_KEY"; public const string API_USER_HEADER_KEY = "USER_KEY";
public const string API_USER_HEADER_SECRET = "USER_SECRET"; public const string API_USER_HEADER_SECRET = "USER_SECRET";
/// <summary>
/// AFR申报代码名称为“AFR申报”
/// </summary>
public const int AFR_REPORT = 27;
} }
} }

@ -26,7 +26,9 @@
<PackageReference Include="RestSharp" Version="110.2.0" /> <PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="RSAExtensions" Version="1.1.1" /> <PackageReference Include="RSAExtensions" Version="1.1.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" /> <PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.2.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.2.0" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -0,0 +1,53 @@
using ICSharpCode.SharpZipLib.BZip2;
using System;
using System.IO;
using System.Text;
namespace EntrustSettle.Common
{
public class SharpZipLib
{
/// <summary>
/// 数据压缩
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string Compress(string input)
{
string result = string.Empty;
byte[] buffer = Encoding.UTF8.GetBytes(input);
using (MemoryStream outputStream = new MemoryStream())
{
using (BZip2OutputStream zipStream = new BZip2OutputStream(outputStream))
{
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Close();
}
return Convert.ToBase64String(outputStream.ToArray());
}
}
/// <summary>
/// 数据解压缩
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string Decompress(string input)
{
string result = string.Empty;
byte[] buffer = Convert.FromBase64String(input);
using (Stream inputStream = new MemoryStream(buffer))
{
BZip2InputStream zipStream = new BZip2InputStream(inputStream);
using (StreamReader reader = new StreamReader(zipStream, Encoding.UTF8))
{
//输出
result = reader.ReadToEnd();
}
}
return result;
}
}
}

@ -1,7 +1,6 @@
using EntrustSettle.Common.Const; using EntrustSettle.Common.Const;
using EntrustSettle.Common.Swagger; using EntrustSettle.Common.Swagger;
using EntrustSettle.Model; using EntrustSettle.Model;
using EntrustSettle.Model.Models.DJY;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using SqlSugar; using SqlSugar;
using System; using System;
@ -15,17 +14,11 @@ namespace EntrustSettle.Common.HttpContextUser
public class DJYUser : IUser public class DJYUser : IUser
{ {
private readonly IHttpContextAccessor _accessor; private readonly IHttpContextAccessor _accessor;
//private User _djyuser;
public DJYUser(IHttpContextAccessor accessor) public DJYUser(IHttpContextAccessor accessor)
{ {
_accessor = accessor; _accessor = accessor;
} }
//public string ID => _djyuser?.GID ?? GetClaimValueByType("loginid").FirstOrDefault() ?? string.Empty;
//public string Name => _djyuser?.SHOWNAME ?? string.Empty;
//public string CompanyId => _djyuser?.CompId ?? string.Empty;
//public string CompanyName => _djyuser?.COMNAME ?? string.Empty;
//public string Mobile => _djyuser?.Mobile ?? string.Empty;
public string ID => GetClaimValueByType(ClaimConst.LOGIN_ID).FirstOrDefault() ?? string.Empty; public string ID => GetClaimValueByType(ClaimConst.LOGIN_ID).FirstOrDefault() ?? string.Empty;
public string Name => GetClaimValueByType(ClaimConst.LOGIN_NAME).FirstOrDefault() ?? string.Empty; public string Name => GetClaimValueByType(ClaimConst.LOGIN_NAME).FirstOrDefault() ?? string.Empty;
@ -33,13 +26,6 @@ namespace EntrustSettle.Common.HttpContextUser
public string CompanyName => GetClaimValueByType(ClaimConst.LOGIN_COMPANYNAME).FirstOrDefault() ?? string.Empty; public string CompanyName => GetClaimValueByType(ClaimConst.LOGIN_COMPANYNAME).FirstOrDefault() ?? string.Empty;
public string Mobile => GetClaimValueByType(ClaimConst.LOGIN_MOBILE).FirstOrDefault() ?? string.Empty; public string Mobile => GetClaimValueByType(ClaimConst.LOGIN_MOBILE).FirstOrDefault() ?? string.Empty;
//public bool IsSetUser => _djyuser != null;
//public void SetUser(object user)
//{
// _djyuser = user as User;
//}
public bool IsAuthenticated() public bool IsAuthenticated()
{ {
return _accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; return _accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false;

@ -11,8 +11,6 @@ namespace EntrustSettle.Common.HttpContextUser
string CompanyId { get; } string CompanyId { get; }
string CompanyName { get; } string CompanyName { get; }
string Mobile { get; } string Mobile { get; }
//bool IsSetUser { get; }
//void SetUser(object user);
bool IsAuthenticated(); bool IsAuthenticated();

@ -16,7 +16,6 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Polly" Version="8.2.1" /> <PackageReference Include="Polly" Version="8.2.1" />
<PackageReference Include="protobuf-net" Version="3.2.30" /> <PackageReference Include="protobuf-net" Version="3.2.30" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup> </ItemGroup>

@ -27,8 +27,6 @@ namespace EntrustSettle.Extensions.Middlewares
{ {
var userId = App.User?.ID; var userId = App.User?.ID;
// 如果是ApiUser类型的对外接口ApiUserFilter中已经设置了用户信息这里不再重复设置不会进到if中
//if (!string.IsNullOrEmpty(userId) && !App.User.IsSetUser)
if (!string.IsNullOrEmpty(userId)) if (!string.IsNullOrEmpty(userId))
{ {
var user = _caching.Get<User>(CacheConst.KeyUserInfoCache + userId); var user = _caching.Get<User>(CacheConst.KeyUserInfoCache + userId);
@ -43,8 +41,6 @@ namespace EntrustSettle.Extensions.Middlewares
identity.AddClaim(new Claim(type: ClaimConst.LOGIN_MOBILE, value: user.Mobile)); identity.AddClaim(new Claim(type: ClaimConst.LOGIN_MOBILE, value: user.Mobile));
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity); ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
context.User = claimsPrincipal; context.User = claimsPrincipal;
//App.User.SetUser(user);
} }
else else
{ {
@ -65,8 +61,6 @@ namespace EntrustSettle.Extensions.Middlewares
identity.AddClaim(new Claim(type: ClaimConst.LOGIN_MOBILE, value: user.Mobile)); identity.AddClaim(new Claim(type: ClaimConst.LOGIN_MOBILE, value: user.Mobile));
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity); ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
context.User = claimsPrincipal; context.User = claimsPrincipal;
//App.User.SetUser(user);
} }
} }
} }

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntrustSettle.IServices
{
public interface IFinanceService
{
}
}

@ -0,0 +1,7 @@
using EntrustSettle.IServices.Base;
using EntrustSettle.Model.Models;
namespace EntrustSettle.IServices
{
public interface IOrderFeeService : IBaseServices<OrderFee> { }
}

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntrustSettle.IServices
{
public interface IQueueService
{
void Push(string opType, string data);
}
}

@ -38,7 +38,7 @@ namespace EntrustSettle.Model.Dtos
public string MailBillNo { get; set; } public string MailBillNo { get; set; }
/// <summary> /// <summary>
/// 反馈操作时的追加信息(如果操作反馈) /// 反馈操作时的追加信息(如果操作反馈)
/// </summary> /// </summary>
public string Remark { get; set; } public string Remark { get; set; }
} }

@ -1,4 +1,6 @@
namespace EntrustSettle.Model.Dtos using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
{ {
/// <summary> /// <summary>
/// 订单状态变更入参Dto /// 订单状态变更入参Dto
@ -17,9 +19,15 @@
/// 状态备注 /// 状态备注
/// </summary> /// </summary>
public string Remark { get; set; } public string Remark { get; set; }
///// <summary>
///// 缴费总金额
///// </summary>
//public decimal? Amount { get; set; }
/// <summary> /// <summary>
/// 缴费金额 /// 费用列表
/// </summary> /// </summary>
public decimal? Amount { get; set; } public List<OrderFeeDto> FeeList { get; set; }
} }
} }

@ -36,7 +36,7 @@ namespace EntrustSettle.Model.Dtos
/// </summary> /// </summary>
public int ServiceType { get; set; } public int ServiceType { get; set; }
/// <summary> /// <summary>
/// 费用项目列表(使用,连接) 1:港杂费 2:堆存费 /// 费用项目列表(将编码使用,连接) 1:港杂费 2:堆存费
/// </summary> /// </summary>
public string ProjectType { get; set; } public string ProjectType { get; set; }
/// <summary> /// <summary>

@ -0,0 +1,8 @@
namespace EntrustSettle.Model.Dtos
{
public class OrderFeeDto
{
public string Name { get; set; }
public decimal Amount { get; set; }
}
}

@ -0,0 +1,20 @@
using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
{
/// <summary>
/// 委托结算消息队列推送Dto - 基类
/// </summary>
public class BasePushDto
{
/// <summary>
/// 消息类型 1:状态更新推送(手动或自动更新订单状态后,推送状态及费用列表) 2:账单附件信息推送 3:发票附件信息推送
/// </summary>
public int MessageType { get; set; }
/// <summary>
/// 消息类型说明
/// </summary>
public string MessageDesc { get; set; }
}
}

@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
{
/// <summary>
/// 委托结算消息队列推送Dto - 发票账单
/// </summary>
public class BillPushDto : BasePushDto
{
/// <summary>
/// 账单或发票附件的Id列表用于获取账单或发票
/// </summary>
public List<long> AnnexIdList { get; set; }
/// <summary>
/// 是否邮寄(如果推送类型为发票推送)
/// </summary>
public bool? MailFlag { get; set; }
/// <summary>
/// 快递单号(如果推送类型为发票推送
/// </summary>
public string MailBillNo { get; set; }
}
}

@ -0,0 +1,46 @@
using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
{
/// <summary>
/// 委托结算消息队列推送Dto - 手动或自动更新状态后推送状态信息及或费用
/// </summary>
public class StatusPushDto : BasePushDto
{
/// <summary>
/// 状态编码 已下单=0 已接单=1 待缴费=2 已缴费=3 已完结=4
/// </summary>
public int Status { get; set; }
/// <summary>
/// 状态说明 已下单=0 已接单=1 待缴费=2 已缴费=3 已完结=4
/// </summary>
public string StatusDesc { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 费用列表
/// </summary>
public List<FeeDto> FeeList { get; set; }
/// <summary>
/// 费用总金额
/// </summary>
//public decimal AllAmount { get; set; }
public class FeeDto
{
/// <summary>
/// 费用名称
/// </summary>
public string FeeName { get; set; }
/// <summary>
/// 费用金额
/// </summary>
public decimal FeeAmount { get; set; }
}
}
}

@ -0,0 +1,15 @@
using SqlSugar;
namespace EntrustSettle.Model.Models.DJY
{
[Tenant(DBConst.PingTai)]
public class CustBalance
{
[SugarColumn(IsPrimaryKey = true)]
public string GID { get; set; }
public decimal? Balance { get; set; }
public string COMNAME { get; set; }
}
}

@ -0,0 +1,113 @@
using SqlSugar;
using System;
namespace EntrustSettle.Model.Models.DJY
{
[Tenant(DBConst.PingTai)]
public class CustFee
{
[SugarColumn(IsPrimaryKey = true)]
public string GID { get; set; } = Guid.NewGuid().ToString().ToUpper();
public string BEIZHU { get; set; }
public string BEIZHU2 { get; set; }
/// <summary>
/// 一般是业务Gid
/// </summary>
public string BSNO { get; set; }
/// <summary>
///业务订单编号
/// </summary>
public string MBLNO { get; set; }
public string BSSTATUS { get; set; }
/// <summary>
/// 业务类型 />
/// </summary>
public int? BSTYPE { get; set; }
public string CANGKU { get; set; }
public string CARRIER { get; set; }
public decimal? CBM { get; set; }
/// <summary>
/// 录入人公司ID
/// </summary>
public string COMID { get; set; }
/// <summary>
/// 录入人公司
/// </summary>
public string COMNAME { get; set; }
public DateTime? CREATETIME { get; set; }
public string DESCRIPTION { get; set; }
public string DESTINATION { get; set; }
public DateTime? ETD { get; set; }
public string FORWARDER { get; set; }
public string HBLNO { get; set; }
public decimal? KGS { get; set; }
public string KINDPKGS { get; set; }
/// <summary>
/// 录入人
/// </summary>
public string LURUREN { get; set; }
/// <summary>
/// 录入人ID
/// </summary>
public string LURURENID { get; set; }
public string MARKS { get; set; }
public decimal? PKGS { get; set; }
public string PORTDISCHARGE { get; set; }
public decimal? PRICE { get; set; }
/// <summary>
/// 发送公司
/// </summary>
public string SENDCOM { get; set; }
public DateTime? SENDTIME { get; set; }
/// <summary>
/// 0新增发送或原始重发 1修改发送 5删除发送
/// </summary>
public int? SENDTYPE { get; set; }
/// <summary>
/// 发送人名
/// </summary>
public string SENDUSER { get; set; }
/// <summary>
/// 发送人ID
/// </summary>
public string SENDUSERID { get; set; }
public string VESSEL { get; set; }
public string VOYNO { get; set; }
/// <summary>
///箱量 根据 CtnrInfo计算
/// </summary>
public int CtnrCount { get; set; }
/// <summary>
///箱型箱量明细 尺寸*数量 多个逗号间隔
/// </summary>
public string CtnrInfo { get; set; }
}
}

@ -0,0 +1,49 @@
using Newtonsoft.Json;
using SqlSugar;
using System;
namespace EntrustSettle.Model.Models.DJY
{
[Tenant(DBConst.PingTai)]
public class CustPrice
{
[SugarColumn(IsPrimaryKey = true)]
public string GID { get; set; }
public int? BSTYPE { get; set; }
public string COMID { get; set; }
public string COMNAME { get; set; }
/// <summary>
/// 騰箇岱띨
/// </summary>
public decimal? GiftBalance { get; set; }
/// <summary>
/// 데송(寮데)
/// </summary>
public decimal? PRICE { get; set; }
/// <summary>
/// 데송(롸데)
/// </summary>
public decimal PRICEF { get; set; } = 0M;
/// <summary>
/// 데송(행멍寮데)
/// </summary>
public decimal PRICEFQG { get; set; } = 0M;
/// <summary>
/// 데송(행멍롸데)
/// </summary>
public decimal PRICEQG { get; set; } = 0M;
[JsonProperty]
public int? SENDTYPE { get; set; }
public DateTime? UPDATETIME { get; set; }
}
}

@ -0,0 +1,16 @@
using SqlSugar;
namespace EntrustSettle.Model.Models
{
///<summary>
///订单费用表
///</summary>
[SugarTable("order_fee")]
public class OrderFee : BaseEntity
{
public long OrderId { get; set; }
public string Name { get; set; }
public decimal Amount { get; set; }
}
}

@ -0,0 +1,13 @@
using EntrustSettle.IServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntrustSettle.Services
{
public class FinanceService : IFinanceService
{
}
}

@ -0,0 +1,10 @@
using EntrustSettle.IServices;
using EntrustSettle.Model.Models;
using EntrustSettle.Services.Base;
namespace EntrustSettle.Services
{
public class OrderFeeService : BaseServices<OrderFee>, IOrderFeeService
{
}
}

@ -0,0 +1,58 @@
using EntrustSettle.Common;
using EntrustSettle.IServices;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
using System;
using System.Text;
namespace EntrustSettle.Services
{
public class QueueService : IQueueService
{
private readonly ILogger<QueueService> logger;
public QueueService(ILogger<QueueService> logger)
{
this.logger = logger;
}
public void Push(string opType, string data)
{
var mqUrl = AppSettings.app("RabbitMQ", "ConnectionString");
try
{
const string MqActionExchangeName = "amq.direct";
const string MqActionQueueName = "feedback.output";
ConnectionFactory factory = new ConnectionFactory();
factory.Uri = new Uri(mqUrl);
using (IConnection conn = factory.CreateConnection())
using (IModel mqModel = conn.CreateModel())
{
mqModel.ExchangeDeclare(MqActionExchangeName, ExchangeType.Direct, true);
//var queueName = $"{MqActionQueueName}.{model.TenantId}";
var queueName = $"{MqActionQueueName}";
mqModel.QueueDeclare(queueName, false, false, false, null);
mqModel.QueueBind(queueName, MqActionExchangeName, queueName, null);
IBasicProperties props = mqModel.CreateBasicProperties();
props.DeliveryMode = 2;
byte[] messageBodyBytes = Encoding.UTF8.GetBytes(SharpZipLib.Compress(data));
mqModel.BasicPublish(MqActionExchangeName, queueName, props, messageBodyBytes);
conn.Close();
logger.LogInformation($"{opType},已发送数据到消息队列,数据内容:【{data}】");
}
}
catch (Exception)
{
throw;
}
}
}
}

@ -1,11 +1,15 @@
using EntrustSettle.IServices; using EntrustSettle.Common;
using EntrustSettle.IServices;
using EntrustSettle.Model; using EntrustSettle.Model;
using EntrustSettle.Model.Dtos; using EntrustSettle.Model.Dtos;
using EntrustSettle.Model.Models; using EntrustSettle.Model.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz; using Quartz;
//using StackExchange.Redis;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
@ -20,12 +24,16 @@ namespace EntrustSettle.Tasks
private readonly IHYDService hydService; private readonly IHYDService hydService;
private readonly IOrderService orderService; private readonly IOrderService orderService;
private readonly IOrderHistoryService orderHistoryService; private readonly IOrderHistoryService orderHistoryService;
private readonly IQueueService queueService;
private readonly IOrderFeeService orderFeeService;
public JobHydStatusQuartz(ILogger<JobHydStatusQuartz> logger, public JobHydStatusQuartz(ILogger<JobHydStatusQuartz> logger,
ITasksQzServices tasksQzServices, ITasksQzServices tasksQzServices,
ITasksLogServices tasksLogServices, ITasksLogServices tasksLogServices,
IHYDService hydService, IHYDService hydService,
IOrderService orderService, IOrderService orderService,
IOrderHistoryService orderHistoryService) IOrderHistoryService orderHistoryService,
IQueueService queueService,
IOrderFeeService orderFeeService)
: base(tasksQzServices, tasksLogServices) : base(tasksQzServices, tasksLogServices)
{ {
_tasksQzServices = tasksQzServices; _tasksQzServices = tasksQzServices;
@ -33,6 +41,8 @@ namespace EntrustSettle.Tasks
this.hydService = hydService; this.hydService = hydService;
this.orderService = orderService; this.orderService = orderService;
this.orderHistoryService = orderHistoryService; this.orderHistoryService = orderHistoryService;
this.queueService = queueService;
this.orderFeeService = orderFeeService;
} }
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
{ {
@ -76,19 +86,64 @@ namespace EntrustSettle.Tasks
_logger.LogInformation($"提单号{orderItem.Mblno}接收到回推后根据bsno查询到多个本地订单"); _logger.LogInformation($"提单号{orderItem.Mblno}接收到回推后根据bsno查询到多个本地订单");
continue; continue;
} }
if (orderList[0].Status != item.status) var order = orderList[0];
if (order.Status != item.status)
{ {
orderList[0].Status = item.status; order.Status = item.status;
var updateSuccess = await orderService.Update(orderList[0], x => new { x.Status }); var updateSuccess = await orderService.Update(order, x => new { x.Status });
_logger.LogInformation($"提单号{orderItem.Mblno}状态更新{(updateSuccess ? "" : "")}status:{item.status}"); _logger.LogInformation($"提单号{orderItem.Mblno}状态更新{(updateSuccess ? "" : "")}status:{item.status}");
// 记录订单状态变更历史 // 记录订单状态变更历史
await orderHistoryService.Add(new OrderHistory() await orderHistoryService.Add(new OrderHistory()
{ {
Pid = orderList[0].Id, Pid = order.Id,
Status = item.status, Status = item.status,
StatusTime = DateTime.Now StatusTime = DateTime.Now
}); });
// 将更新后的状态及费用推送到消息队列
if (AppSettings.app("RabbitMQ", "Enabled").ObjToBool())
{
_ = Task.Run(async () =>
{
string msg = $"Id[{order.Id}],提单号:[{order.Mblno}],手动更新状态后推送队列";
try
{
StatusPushDto pushDto = new()
{
MessageType = 1,
MessageDesc = "状态更新推送",
Remark = "",
Status = item.status,
StatusDesc = item.status switch
{
0 => "已下单",
1 => "已接单",
2 => "待缴费",
3 => "已缴费",
4 => "已完结",
_ => "未知状态",
}
};
var feeList = await orderFeeService.Query(x => x.OrderId == order.Id);
if (feeList.Count > 0)
{
pushDto.FeeList = feeList.Select(x => new StatusPushDto.FeeDto()
{
FeeName = x.Name,
FeeAmount = x.Amount
}).ToList();
}
var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
queueService.Push(msg, json);
}
catch (Exception ex)
{
_logger.LogError(ex, $"{msg},失败");
}
});
}
} }
else else
{ {

Loading…
Cancel
Save