You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
14 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Op.Interface;
using DS.WMS.Core.Sys.Entity;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using NLog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DS.Module.Core.Extensions;
using LogicExtensions;
using DS.Module.Core.Helpers;
using Newtonsoft.Json.Linq;
using DS.Module.Core.Data;
using DS.WMS.Core.Sys.Interface;
using DS.WMS.Core.Code.Method;
using DS.WMS.Core.Code.Interface;
using DS.WMS.Core.Utils;
using NPOI.SS.Formula.PTG;
namespace DS.WMS.Core.Op.Method
{
public class DJYChargeFeeService: IDJYChargeFeeService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
private readonly IConfigService _configService;
private readonly ICodeThirdPartyService _codeThirdPartyService;
private readonly IDingTalkGroupHelper _dingTalkGroupHelper;
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
public DJYChargeFeeService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_configService = serviceProvider.GetRequiredService<IConfigService>();
_codeThirdPartyService = serviceProvider.GetRequiredService<ICodeThirdPartyService>();
_dingTalkGroupHelper = serviceProvider.GetRequiredService<IDingTalkGroupHelper>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
user = _serviceProvider.GetRequiredService<IUser>();
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
}
#region 扣费
/// <summary>
/// 扣费
/// </summary>
/// <param name="model">扣费请求</param>
/// <returns>返回回执</returns>
public async Task<DataResult<DJYChargeFeeResultDto>> ChargeFee(DJYChargeFeeRequestDto model)
{
/*
1、先获取扣费URL
2、根据业务主键取所有订单信息
3、获取扣费KEY和密钥通过接口账户维护
4、提取订单操作相关的账户如果绑定了大简云用户ID,默认用大简云用户ID否则就用系统参数设置的大简云用户ID
5、组织扣费报文并发送
6、接收回执写入记录表
*/
Logger.Log(NLog.LogLevel.Info, $"收到订舱扣费请求,{JsonConvert.SerializeObject(model)}");
var batchId = DateTime.Now.Ticks.ToString();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear<IOrgId>();
//提取扣费URL
var feeUrl = db.Queryable<SysConfig>().Filter(null, true)
.Where(x => x.Code == "djyFeeApiUrl" && x.TenantId == 1288018625843826688).Select(x => x.Value).First();
if(string.IsNullOrWhiteSpace(feeUrl))
{
Logger.Log(NLog.LogLevel.Info, $"未配置大简云扣费接口地址,请联系管理员");
return DataResult<DJYChargeFeeResultDto>.Failed("未配置大简云扣费接口地址,请联系管理员");
}
var orderList = tenantDb.Queryable<SeaExport>().Filter(null, true).Where(a => model.BusinessIdList.Contains(a.Id)).ToList();
DateTime nowDate = DateTime.Now;
DJYChargeFeeResultDto resultDto = new DJYChargeFeeResultDto
{
ExcuteDate = nowDate,
ExcuteDetail = new List<DJYChargeFeeResultDetailDto>()
};
foreach (var id in model.BusinessIdList)
{
DJYChargeFeeResultDetailDto detail = new DJYChargeFeeResultDetailDto {
BillId = id,
};
var orderInfo = orderList.FirstOrDefault(a => a.Id == id);
var userInfo = db.Queryable<SysUser>().Filter(null, true).First(x => x.Id == orderInfo.OperatorId && x.TenantId == long.Parse(user.TenantId));
string djyUserId = userInfo?.DjyUserId;
if (string.IsNullOrWhiteSpace(djyUserId))
{
var defaultDJYUserId = _configService.GetConfig("DJY_CHARGE_FEE_DEFAULT_USERID", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
djyUserId = defaultDJYUserId;
Logger.Log(NLog.LogLevel.Info, $"批次号={batchId}-调用扣费,当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,试用系统默认的大简云用户ID={defaultDJYUserId}");
}
if (string.IsNullOrWhiteSpace(djyUserId))
{
detail.Status = "FAILURE";
detail.Message = $"当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,请联系管理员";
Logger.Log(NLog.LogLevel.Info, $"当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,请联系管理员");
continue;
}
var webAccountConfig = _codeThirdPartyService.GetCodeThirdPartyInfoWithCompany("DJYChargeFeeAuth").GetAwaiter().GetResult()?.Data;
//未配置公司或个人的第三方账户维护-MSK API合约请联系管理员
if (webAccountConfig == null)
{
detail.Status = "FAILURE";
detail.Message = $"未配置大简云扣费授权,请在接口账户维护";
Logger.Log(NLog.LogLevel.Info, $"未配置大简云扣费授权,请在接口账户维护");
continue;
}
string feeUserId = webAccountConfig.AppKey;
string feeUserKey = webAccountConfig.AppSecret;
string feeType = $"{(int)model.BSType}_{(int)model.SendType}";
var c = tenantDb.Queryable<DJYChargeFee>().Filter(null, true).Count(x => x.BillId == id && x.MBLNO == orderInfo.MBLNO && x.FeeType == feeType);
if (c > 0)
{
Logger.Log(NLog.LogLevel.Info, $"{batchId}-已存在扣费记录id{id},提单号:{orderInfo.MBLNO} feeType={feeType}");
continue;
}
var runId = Guid.NewGuid().ToString();
var seconds = DateTime.Now.ToTimestamp();
var srcBeforMD5 = $"{runId}{feeUserId}expend{(int)model.BSType}{(int)model.SendType}{id}{orderInfo.MBLNO}{seconds}{feeUserKey}";
var md5 = MD5Helper.Encrypt(srcBeforMD5);
var reqModel = new DJYChargeFeeBaseDto
{
runId = runId,
userId = feeUserId,
module = "expend",//固定
bsType = ((int)model.BSType).ToString(),
sendType = ((int)model.SendType).ToString(),
timestamp = seconds,//秒级时间戳
md5 = md5,// 加密字符串小写 RunId + UserId + Module + BsType + SendType+Timestamp+ Key
Data = new DJYChargeFeeDataDto {
BSNO = orderInfo.Id.ToString(),
MBLNO = orderInfo.MBLNO,
HBLNO = orderInfo.HBLNO,
CtnrInfo = "",
CtnrCount = 1,
IsCredit = 1,//是否是信用支付 1 信用支付 0不允许信用支付默认值为0,
LURURENID = djyUserId,
SENDUSERID = djyUserId,
VESSEL = orderInfo.Vessel,
VOYNO = orderInfo.InnerVoyno,
ETD = orderInfo.ATD,
CARRIER = orderInfo.Carrier
}
};
Logger.Log(NLog.LogLevel.Info, $"批次号={batchId}-调用扣费,请求报文:{JsonConvert.SerializeObject(reqModel)}");
var record = new DJYChargeFee
{
BillId = id,
BatchNo = batchId,
BSType = model.BSType.ToString(),
SendType = model.SendType.ToString(),
FeeType = $"{(int)model.BSType}_{(int)model.SendType}",
MBLNO = orderInfo.MBLNO,
};
try
{
var jsonBody = JsonConvert.SerializeObject(reqModel);
var res = RequestHelper.Post(jsonBody, feeUrl);
Logger.Log(NLog.LogLevel.Info, $"批次号={batchId}-调用扣费,返回结果:{res}");
var jobjApiRtn = JObject.Parse(res);
var code = jobjApiRtn.GetIntValue("code");
var jobjApiRtnData = jobjApiRtn.GetValue("data") as JObject;
if (code == 200 || code == 450)
{
var jobjApiRtnDataPayInfo = jobjApiRtnData.GetValue("payInfo") as JObject;
var price = Convert.ToDecimal(jobjApiRtnDataPayInfo.GetValue("price").ToString());
var total = Convert.ToDecimal(jobjApiRtnDataPayInfo.GetValue("total").ToString());
var msg = jobjApiRtn.GetValue("message").ToString();
record.Amount = total;
record.Price = price;
record.ResultNote = msg;
record.Status = "SUCC";
detail.Status = "SUCC";
tenantDb.Insertable<DJYChargeFee>(record).ExecuteCommand();
}
else
{
var msg = jobjApiRtn.GetValue("message").ToString();
record.ResultNote = msg;
record.Status = "FAILURE";
detail.Status = "FAILURE";
detail.Message = msg;
tenantDb.Insertable<DJYChargeFee>(record).ExecuteCommand();
Logger.Log(NLog.LogLevel.Info, $"批次号={batchId}-扣费失败,原因:{msg}");
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", msg);
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"批次号={batchId}-扣费异常,原因:{ex.Message}");
record.ResultNote = ex.Message.Length > 200? ex.Message.Substring(0,200): ex.Message;
record.Status = "EXCEPTION";
detail.Status = "EXCEPTION";
detail.Message = ex.Message;
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", record.ResultNote);
}
resultDto.ExcuteDetail.Add(detail);
}
return DataResult<DJYChargeFeeResultDto>.Success(resultDto);
}
#endregion
/// <summary>
/// 扣费前校验
/// </summary>
/// <param name="model">扣费请求</param>
/// <returns>返回回执</returns>
public async Task<DataResult<string>> CheckChargeFee(DJYChargeFeeRequestDto model)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
tenantDb.QueryFilter.Clear<IOrgId>();
//提取扣费URL
var feeUrl = db.Queryable<SysConfig>().Filter(null, true)
.Where(x => x.Code == "djyFeeApiUrl" && x.TenantId == 1288018625843826688).Select(x => x.Value).First();
if (string.IsNullOrWhiteSpace(feeUrl))
{
Logger.Log(NLog.LogLevel.Info, $"未配置大简云扣费接口地址,请联系管理员");
return DataResult<string>.Failed("未配置大简云扣费接口地址,请联系管理员");
}
var orderList = tenantDb.Queryable<SeaExport>().Filter(null,true).Where(a => model.BusinessIdList.Contains(a.Id)).ToList();
List<long> opUserIdList = orderList.Select(a => a.OperatorId).Distinct().ToList();
var userList = db.Queryable<SysUser>().Filter(null, true).Where(x => opUserIdList.Contains(x.Id) && x.TenantId == long.Parse(user.TenantId)).ToList();
var defaultDJYUserId = _configService.GetConfig("DJY_CHARGE_FEE_DEFAULT_USERID", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
//校验是否有大简云账户
if (userList.Any(a=> string.IsNullOrWhiteSpace(a.DjyUserId)) && string.IsNullOrWhiteSpace(defaultDJYUserId))
{
return DataResult<string>.Failed($"操作={string.Join(",", userList.Where(a => string.IsNullOrWhiteSpace(a.DjyUserId)).Select(a => a.UserName).ToArray())}未绑定大简云账户ID,请联系管理员");
}
Dictionary<long, Tuple<string, string>> dict = new Dictionary<long, Tuple<string, string>>();
//校验是否已有扣费记录
foreach (var order in orderList)
{
var record = tenantDb.Queryable<DJYChargeFee>().Filter(null, true)
.First(a => a.BillId == order.Id && a.FeeType == $"{(int)model.BSType}_{(int)model.SendType}" && a.Deleted == false);
if (record != null)
{
dict.Add(order.Id, new Tuple<string, string>(!string.IsNullOrWhiteSpace(order.MBLNO) ? $"提单号:{order.MBLNO}" : $"委托编号:{order.CustomerNo}", "已有扣费记录"));
}
}
if (dict.Count > 0)
{
return DataResult<string>.Failed($"{string.Join(",", dict.Select(a => a.Value.Item1).ToArray())} 已有扣费记录");
}
return DataResult<string>.Success(string.Empty);
}
}
}