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.

322 lines
14 KiB
C#

4 months ago
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;
4 months ago
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;
4 months ago
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>();
4 months ago
}
#region 扣费
/// <summary>
/// 扣费
/// </summary>
/// <param name="model">扣费请求</param>
/// <returns>返回回执</returns>
public async Task<DataResult<DJYChargeFeeResultDto>> ChargeFee(DJYChargeFeeRequestDto model)
{
/*
1URL
2
3KEY
4ID,IDID
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,请联系管理员";
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", $"当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,请联系管理员,公司:{user.TenantName}");
Logger.Log(NLog.LogLevel.Info, $"当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,请联系管理员");
4 months ago
continue;
}
var webAccountConfig = _codeThirdPartyService.GetCodeThirdPartyInfoWithCompany("DJYChargeFeeAuth").GetAwaiter().GetResult()?.Data;
//未配置公司或个人的第三方账户维护-MSK API合约请联系管理员
if (webAccountConfig == null)
{
detail.Status = "FAILURE";
detail.Message = $"未配置大简云扣费授权,请在接口账户维护";
Logger.Log(NLog.LogLevel.Info, $"未配置大简云扣费授权,请在接口账户维护");
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", $"未配置大简云扣费授权,请在接口账户维护,公司:{user.TenantName}");
4 months ago
continue;
}
string feeUserId = webAccountConfig.AppKey;
string feeUserKey = webAccountConfig.AppSecret;
1 month ago
string feeType = $"{(int)model.BSType}_{(int)model.SendType}";
1 month ago
var c = tenantDb.Queryable<DJYChargeFee>().Filter(null, true).Count(x => x.BillId == id && x.MBLNO == orderInfo.MBLNO && x.FeeType == feeType);
if (c > 0)
{
1 month ago
Logger.Log(NLog.LogLevel.Info, $"{batchId}-已存在扣费记录id{id},提单号:{orderInfo.MBLNO} feeType={feeType}");
continue;
}
4 months ago
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);
4 months ago
}
}
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);
4 months ago
}
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);
}
}
}