|
|
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,请联系管理员";
|
|
|
|
|
|
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", $"当前操作OP={userInfo?.UserName}没有绑定大简云用户ID,请联系管理员,公司:{user.TenantName}");
|
|
|
|
|
|
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, $"未配置大简云扣费授权,请在接口账户维护");
|
|
|
|
|
|
_dingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", $"未配置大简云扣费授权,请在接口账户维护,公司:{user.TenantName}");
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
}
|