diff --git a/Myshipping.Application/Entity/BookingFeeRecord.cs b/Myshipping.Application/Entity/BookingFeeRecord.cs
new file mode 100644
index 00000000..85ce69cb
--- /dev/null
+++ b/Myshipping.Application/Entity/BookingFeeRecord.cs
@@ -0,0 +1,35 @@
+using System;
+using SqlSugar;
+using System.ComponentModel;
+using Myshipping.Core.Entity;
+namespace Myshipping.Application.Entity
+{
+ ///
+ ///
+ ///
+ [SugarTable("booking_fee_record")]
+ [Description("订舱扣费记录信息")]
+ public class BookingFeeRecord : PrimaryKeyEntity
+ {
+ ///
+ /// 单据ID
+ ///
+ public long BillId { get; set; }
+ ///
+ /// 费用类型
+ ///
+ public string Type { get; set; }
+ ///
+ /// 金额
+ ///
+ public decimal? Amount { get; set; }
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedTime { get; set; } = DateTime.Now;
+ }
+}
\ No newline at end of file
diff --git a/Myshipping.Application/Event/BookingFeeSubscriber.cs b/Myshipping.Application/Event/BookingFeeSubscriber.cs
new file mode 100644
index 00000000..9d4f7b7a
--- /dev/null
+++ b/Myshipping.Application/Event/BookingFeeSubscriber.cs
@@ -0,0 +1,166 @@
+using Furion;
+using Furion.EventBus;
+using Furion.FriendlyException;
+using Furion.JsonSerialization;
+using Furion.RemoteRequest.Extensions;
+using Google.Protobuf.WellKnownTypes;
+using Mapster;
+using Microsoft.AspNetCore.JsonPatch.Internal;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Myshipping.Application.ConfigOption;
+using Myshipping.Application.Entity;
+using Myshipping.Application.Service.BookingOrder.Dto;
+using Myshipping.Core;
+using Myshipping.Core.Entity;
+using Myshipping.Core.Helper;
+using Myshipping.Core.Service;
+using Newtonsoft.Json.Linq;
+using NPOI.SS.Formula.Functions;
+using NPOI.SS.Formula.PTG;
+using StackExchange.Profiling.Internal;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Security.Policy;
+using System.Text;
+using System.Threading.Tasks;
+using Yitter.IdGenerator;
+
+namespace Myshipping.Application.Event
+{
+ ///
+ /// 扣费
+ ///
+ public class BookingFeeSubscriber : IEventSubscriber
+ {
+ private IServiceProvider _services { get; }
+ private readonly ILogger _logger;
+
+ public BookingFeeSubscriber(IServiceProvider services
+ , ILogger logger)
+ {
+ _services = services;
+ _logger = logger;
+ }
+
+ //扣费
+ [EventSubscribe("Booking:DoFeeRecord")]
+ public async Task DoFeeRecord(EventHandlerExecutingContext context)
+ {
+ _logger.LogInformation($"收到订舱扣费请求:{context.Source.Payload}");
+
+ var paraObj = context.Source.Payload as dynamic;
+
+ int bsType = paraObj.bsType;
+ int sendType = paraObj.sendtype;
+ List idList = paraObj.idList;
+ idList = idList.Distinct().ToList();
+
+ _logger.LogInformation($"准备处理扣费,bsType:{bsType},sendType:{sendType},id列表:{string.Join(',', idList)}");
+
+ using var scope = _services.CreateScope();
+
+ var repoUser = scope.ServiceProvider.GetRequiredService>();
+ var repoBooking = scope.ServiceProvider.GetRequiredService>();
+ var repoFeeRecord = scope.ServiceProvider.GetRequiredService>();
+ var cache = scope.ServiceProvider.GetRequiredService();
+
+ var typeStr = $"{bsType}_{sendType}";
+ var dbFeeRecord = repoFeeRecord.AsQueryable().Where(x => x.Type == typeStr && idList.Contains(x.BillId)).Select(x => x.BillId).ToList();
+ var idToDo = idList.Except(dbFeeRecord).ToList();
+ var sysCfg = await cache.GetAllSysConfig();
+ var feeUrl = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiUrl");
+ var feeUserId = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiUserId");
+ var feeKey = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiKey");
+ if (feeKey == null || string.IsNullOrEmpty(feeUrl.Value)
+ || feeUserId == null || string.IsNullOrEmpty(feeUserId.Value)
+ || feeKey == null || string.IsNullOrEmpty(feeKey.Value))
+ {
+ var errMsg = "大简云扣费URL和KEY未配置";
+ _logger.LogError(errMsg);
+ DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
+ return;
+ }
+
+ foreach (var id in idToDo)
+ {
+ var order = await repoBooking.AsQueryable().FirstAsync(x => x.Id == id);
+ var iptId = string.IsNullOrEmpty(order.OPID) ? order.CreatedUserId.Value : Convert.ToInt64(order.OPID);
+ var user = await repoUser.AsQueryable().FirstAsync(x => x.Id == iptId);
+ if (user == null || string.IsNullOrEmpty(user.DjyUserId))
+ {
+ var errMsg = $"未找到{order.MBLNO}({id})的用户信息,无法调用扣费";
+ _logger.LogError(errMsg);
+ DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
+ continue;
+ }
+
+ var seconds = DateTime.Now.ToTimeStamp();
+ var runId = Guid.NewGuid().ToString();
+ var srcBeforMD5 = $"{runId}{feeKey.Value}expend{bsType}0{id}{order.MBLNO}{seconds}{feeKey.Value}";
+ var postObj = new
+ {
+ runId,
+ userId = feeUserId.Value,
+ module = "expend",//固定
+ bsType = $"{bsType}",
+ sendType = $"{sendType}",
+ timestamp = seconds,//秒级时间戳
+ md5 = srcBeforMD5.ToMd5(),// 加密字符串小写 RunId + UserId + Module + BsType + SendType+Timestamp+ Key
+ Data = new
+ {
+ BSNO = id.ToString(),
+ MBLNO = order.MBLNO,
+ CtnrInfo = "",
+ CtnrCount = 1,
+ IsCredit = 1,//是否是信用支付 1 信用支付 0不允许信用支付默认值为0,
+ LURURENID = user.DjyUserId,
+ SENDUSERID = user.DjyUserId
+ }
+ };
+
+ _logger.LogInformation($"调用扣费:{postObj.ToJsonString()}");
+ var apiRtn = await feeUrl.Value
+ .SetHttpMethod(HttpMethod.Post)
+ .SetBody(postObj)
+ .SetRetryPolicy(3, 5000)
+ .OnException((c, m, errMsg) =>
+ {
+ _logger.LogError($"扣费失败:{errMsg}");
+ DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
+ })
+ .SendAsStringAsync();
+ _logger.LogInformation($"调用扣费返回:{apiRtn}");
+ var jobjApiRtn = JObject.Parse(apiRtn);
+ var code = Convert.ToInt32(jobjApiRtn.GetValue("code").ToString());
+ 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 fr = new BookingFeeRecord();
+ fr.Id = YitIdHelper.NextId();
+ fr.BillId = id;
+ fr.Type = typeStr;
+ fr.Amount = total;
+ await repoFeeRecord.InsertAsync(fr);
+ }
+ else
+ {
+ var errMsg = jobjApiRtnData.GetValue("message").ToString();
+ _logger.LogError($"扣费失败:{errMsg}");
+ DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
+ }
+ }
+
+ _logger.LogInformation($"扣费处理完成");
+ }
+ }
+}
diff --git a/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs b/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs
index ac7f1b6d..643d78bc 100644
--- a/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs
+++ b/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs
@@ -315,7 +315,6 @@ namespace Myshipping.Application
}
else
{
- entity = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == entity.Id);
if (entity.BSSTATUS != "已录入" && entity.BSSTATUS != "已驳回")
{
throw Oops.Bah("当前状态不允许修改");
@@ -1745,6 +1744,7 @@ namespace Myshipping.Application
await CancelSubmit(new List() { custOrder.Id });
+ input.Id = custOrder.Id;
input.Adapt(custOrder);
}
else
diff --git a/Myshipping.Application/Service/DataSync/DataSyncService.cs b/Myshipping.Application/Service/DataSync/DataSyncService.cs
index 28e06e14..c069962d 100644
--- a/Myshipping.Application/Service/DataSync/DataSyncService.cs
+++ b/Myshipping.Application/Service/DataSync/DataSyncService.cs
@@ -40,6 +40,7 @@ using System.Linq.Expressions;
using Myshipping.Core.Service.Dict.Dto;
using Furion.JsonSerialization;
using Microsoft.AspNetCore.SignalR;
+using Furion.EventBus;
namespace Myshipping.Application
{
@@ -82,6 +83,8 @@ namespace Myshipping.Application
private readonly IBookingValueAddedService _bookingValueAddedService;
private readonly IHubContext _chatHubContext;
+ private readonly IEventPublisher _publisher;
+ private readonly SqlSugarRepository _tenantParamValue;
public DataSyncService(ILogger logger, ISysCacheService cache, SqlSugarRepository rep, SqlSugarRepository repCtn,
SqlSugarRepository repUser, SqlSugarRepository repTenant, SqlSugarRepository djycustomer,
@@ -93,7 +96,9 @@ namespace Myshipping.Application
SqlSugarRepository codePortRep, SqlSugarRepository codeLaneRep, ICommonDBService commonDBService, SqlSugarRepository relaPortLane,
SqlSugarRepository accountconfig, SqlSugarRepository bookingfile, IBookingOrderService bookingorderservice,
IBookingValueAddedService bookingValueAddedService,
- IHubContext chatHubContext)
+ IHubContext chatHubContext,
+ IEventPublisher publisher,
+ SqlSugarRepository tenantParamValue)
{
this._logger = logger;
this._rep = rep;
@@ -127,6 +132,9 @@ namespace Myshipping.Application
this._bookingextstate = bookingextstate;
this._bookingValueAddedService = bookingValueAddedService;
this._chatHubContext = chatHubContext;
+ this._publisher = publisher;
+ this._tenantParamValue = tenantParamValue;
+
}
@@ -1784,8 +1792,8 @@ namespace Myshipping.Application
[SqlSugarUnitOfWork]
public async Task SaveSyncVesselDate(List dto)
{
- //var infolist = _vesselinfo.AsQueryable().Filter(null, true).Where(x => x.TenantId == UserManager.TENANT_ID && x.IsDeleted == false).ToList();
- //var orderlist = await _rep.AsQueryable().Filter(null, true).Where(x => x.TenantId == UserManager.TENANT_ID && x.IsDeleted == false).ToListAsync();
+ var feeIdList = new List();
+
foreach (var item in dto)
{
//var model = infolist.Where(x => x.Vessel == item.Vessel && x.Voyno == item.Voyno).FirstOrDefault();
@@ -1811,6 +1819,15 @@ namespace Myshipping.Application
&& x.IsDeleted == false
&& x.VESSEL == item.Vessel
&& x.VOYNO == item.Voyno).ToListAsync();
+
+ //当前租户配置为实际开船后扣费
+ var paraVal = _tenantParamValue.AsQueryable().First(x => x.TenantId == UserManager.TENANT_ID && x.ParaCode == "BOOKING_FEE_METHOD");
+ //有实际开船,扣费
+ if (paraVal != null && paraVal.ItemCode == "ATD" && item.ATD.HasValue)
+ {
+ feeIdList.AddRange(orderList.Where(x => !feeIdList.Contains(x.Id)).Select(x => x.Id));
+ }
+
bool issend = false;
//批量变更业务数据
if (orderList != null)
@@ -1868,6 +1885,12 @@ namespace Myshipping.Application
//通知前端更新缓存
//await _chatHubContext.Clients.All.NotifyVesselChange();
+
+ //扣费
+ if (feeIdList.Count > 0)
+ {
+ await _publisher.PublishAsync(new ChannelEventSource($"Booking:DoFeeRecord", new { bsType = 28, sendtype = 0, idList = feeIdList }));
+ }
}
diff --git a/Myshipping.Core/Extension/DateTimeExtension.cs b/Myshipping.Core/Extension/DateTimeExtension.cs
new file mode 100644
index 00000000..c5dde888
--- /dev/null
+++ b/Myshipping.Core/Extension/DateTimeExtension.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Myshipping.Core
+{
+
+ ///
+ /// datetime数据类型拓展
+ ///
+ public static class DateTimeExtension
+ {
+
+ ///
+ ///将一个时间转换为秒级时间戳
+ ///
+ /// 时间
+ ///
+ public static long ToTimeStampSeconds(this DateTime datetime)
+ {
+ return (long)Math.Round((datetime.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
+ }
+
+ ///
+ ///将一个时间转换为毫秒级时间戳
+ ///
+ ///
+ ///
+ public static long ToTimeStampMilliSeconds(this DateTime datetime)
+ {
+
+ return (long)Math.Round((datetime.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalMilliseconds);
+ }
+
+ ///
+ /// 获取标准时间戳 秒级
+ ///
+ ///
+ ///
+ public static long ToTimeStamp(this DateTime datetime)
+ { return ToTimeStampSeconds(datetime); }
+
+ ///
+ /// 将时间转换为时间字符串编码 yyyyMMddHHmmssffff
+ ///
+ ///
+ ///
+ public static string ToTimeStr(this DateTime datetime)
+ {
+ return datetime.ToString("yyyyMMddHHmmssffff");
+ }
+
+ ///
+ /// 判断时间是否大于1970年的有效时间
+ ///
+ ///
+ ///
+ public static bool IsValidTime(this DateTime dateTime)
+ {
+ if (dateTime.Date >= DateTime.Parse("1970-1-1"))
+ return true;
+ else return false;
+ }
+ ///
+ /// 获时间一天中的开始时间
+ ///
+ ///
+ public static DateTime GetDayStartTime(this DateTime dateTime)
+ {
+ return dateTime.Date;
+ }
+ ///
+ /// 获取时间一天的结束时间
+ ///
+ ///
+ ///
+
+ public static DateTime GetDateEndTime(this DateTime dateTime)
+ {
+ return dateTime.Date.AddDays(1).AddSeconds(-1);
+ }
+
+ ///
+ /// 获取时间周的星期一的时间
+ ///
+ ///
+ ///
+ public static DateTime GetWeekStartTime(this DateTime dateTime)
+ {
+ return dateTime.GetWeekOfDayTime(1);
+ }
+
+ ///
+ /// 获取时间周的周日
+ ///
+ ///
+ ///
+ public static DateTime GetWeekEndTime(this DateTime dateTime)
+ {
+ return dateTime.GetWeekOfDayTime(7);
+ }
+
+ ///
+ /// 获取时间周的指定周几时间
+ ///
+ ///
+ /// 周几 1 2 3 4 5 6 7
+ ///
+ public static DateTime GetWeekOfDayTime(this DateTime dateTime, int Day)
+ {
+ if (Day < 1)
+ Day = 1;
+ if (Day > 7)
+ Day = (int)dateTime.DayOfWeek;
+ return dateTime.Subtract(new TimeSpan(dateTime.DayOfWeek - (DayOfWeek)Day, 0, 0, 0)).Date;
+ }
+
+ ///
+ /// 获取时间月开始时间
+ ///
+ ///
+ ///
+ public static DateTime GetMonthStartTime(this DateTime dateTime)
+ {
+ return new DateTime(dateTime.Year, dateTime.Month, 1).Date;
+ }
+ ///
+ /// 获取一个月的结束时间
+ ///
+ ///
+ ///
+ public static DateTime GetMonthEndTime(this DateTime dateTime)
+ {
+ return dateTime.GetMonthStartTime().AddMonths(1).AddDays(-1);
+
+ }
+ }
+
+}
diff --git a/Myshipping.Core/Extension/Int32Extensions.cs b/Myshipping.Core/Extension/Int32Extensions.cs
new file mode 100644
index 00000000..0d425cf3
--- /dev/null
+++ b/Myshipping.Core/Extension/Int32Extensions.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Myshipping.Core
+{
+ ///
+ /// 扩展Int32功能
+ ///
+ public static class Int32Extensions
+ {
+ ///
+ /// 向上整除
+ /// 1.当num能被divideBy整除时,结果即为num/divideBy;
+ /// 2.当num不能被divideBy整除时,结果为num/divideBy + 1;
+ ///
+ /// 被除数,大于或者等于0
+ /// 除数,大于0
+ /// 向上整除结果
+ public static int CeilingDivide(this int num, int divideBy)
+ {
+ if (num < 0 || divideBy <= 0)
+ {
+ return 0;
+ }
+
+ return (num + divideBy - 1) / divideBy;
+
+ }
+ ///
+ /// 向上整除
+ /// 1.当num能被divideBy整除时,结果即为num/divideBy;
+ /// 2.当num不能被divideBy整除时,结果为num/divideBy + 1;
+ ///
+ /// 被除数,大于或者等于0
+ /// 除数,大于0
+ /// 向上整除结果
+ public static long CeilingDivide(this long num, long divideBy)
+ {
+ if (num < 0 || divideBy <= 0)
+ {
+ return 0;
+ }
+
+ return (num + divideBy - 1) / divideBy;
+
+ }
+
+ ///
+ /// 将List 转为间隔字符串
+ ///
+ ///
+ public static string ListToString(this List strlist, char Split = ',')
+ {
+ StringBuilder str = new StringBuilder();
+ foreach (var item in strlist)
+ {
+ str.Append(item.ToString() + Split);
+ }
+ return str.ToString();
+ }
+
+ ///
+ /// 拓展 将字符串抓换为int
+ ///
+ ///
+ ///
+ public static int StrToInt(this string str)
+ {
+ if (str.Isint())
+ { return Convert.ToInt32(str); }
+ else
+ {
+ return 0;
+ }
+ }
+ ///
+ /// 拓展 将字符串数组转换成int 数组
+ ///
+ ///
+ ///
+ public static int[] strToIntArray(this string[] str)
+ {
+ return Array.ConvertAll(str, new Converter(StrToInt));
+ }
+
+ }
+}
diff --git a/Myshipping.Core/Extension/StringExtension.cs b/Myshipping.Core/Extension/StringExtension.cs
new file mode 100644
index 00000000..d152b5ce
--- /dev/null
+++ b/Myshipping.Core/Extension/StringExtension.cs
@@ -0,0 +1,480 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace Myshipping.Core
+{
+ ///
+ /// string 拓展
+ ///
+ public static class StringExtension
+ {
+
+
+ ///
+ /// 隐藏中间字符串
+ ///
+ ///
+ ///
+ public static string GetHideCentre(this string str)
+ {
+ if (str.Length > 8)
+ {
+
+ return string.Format("{0}***{1}", str.Substring(0, 4), str.Substring(str.Length - 4, 4));
+ }
+ else if (str.Length > 5)
+ {
+ return string.Format("{0}***{1}", str.Substring(0, 2), str.Substring(str.Length - 2, 2));
+
+ }
+ else if (str.Length > 4)
+ {
+ return string.Format("{0}***{1}", str.Substring(0, 1), str.Substring(str.Length - 1, 1));
+
+ }
+ else
+ {
+ return GetHideHead(str);
+ }
+ }
+
+ ///
+ /// 隐藏头部
+ ///
+ ///
+ ///
+ public static string GetHideHead(this string str)
+ {
+ var length = 1;
+ length = length > str.Length ? str.Length : length;
+ if (str.Length < 4)
+ {
+ length = 1;
+ if (str.Length == 1)
+ {
+ return str;
+ }
+
+ return "**" + str.Substring(str.Length - length, length);
+ }
+ length = 4;
+ return "****" + str.Substring(str.Length - length, length);
+
+
+ }
+
+ ///
+ /// 用于判断是否为空字符
+ ///
+ ///
+ ///
+ public static bool IsNull(this string s)
+ {
+ return s == null || (s.Trim().Length == 0);
+ }
+
+ ///
+ /// 用于判断是否为非空字符
+ ///
+ ///
+ ///
+ public static bool IsNotNull(this string s)
+ {
+ return !s.IsNull();
+ }
+
+ #region 加密算法
+
+
+ ///
+ /// DES对称加密字符串
+ ///
+ /// 待加密的字符串
+ /// 加密密钥,要求为16位
+ /// 加密成功返回加密后的字符串,失败返回源串
+ public static string DESEncrypt(this string encryptString, string key)
+ {
+ try
+ {
+ byte[] rgbKey = Encoding.UTF8.GetBytes(key);
+ //用于对称算法的初始化向量(默认值)。
+ byte[] rgbIV = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+ byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
+ Aes dCSP = Aes.Create();
+
+ MemoryStream mStream = new MemoryStream();
+ CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
+ cStream.Write(inputByteArray, 0, inputByteArray.Length);
+ cStream.FlushFinalBlock();
+ return Convert.ToBase64String(mStream.ToArray());
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ ///
+ /// DES对称解密字符串
+ ///
+ /// 待解密的字符串
+ /// 解密密钥,要求16位
+ ///
+ public static string DESDecrypt(this string decryptString, string key)
+ {
+ try
+ {
+ //用于对称算法的初始化向量(默认值)
+ byte[] Keys = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+ byte[] rgbKey = Encoding.UTF8.GetBytes(key);
+ byte[] rgbIV = Keys;
+ byte[] inputByteArray = Convert.FromBase64String(decryptString);
+ Aes DCSP = Aes.Create();
+
+ MemoryStream mStream = new MemoryStream();
+ CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
+ cStream.Write(inputByteArray, 0, inputByteArray.Length);
+ cStream.FlushFinalBlock();
+ return Encoding.UTF8.GetString(mStream.ToArray());
+ }
+ catch
+ {
+ return decryptString;
+ }
+ }
+
+ ///
+ /// 将字符串转换成MD5加密字符串
+ ///
+ ///
+ ///
+ public static string ToMd5(this string orgStr)
+ {
+ using (var md5 = MD5.Create())
+ {
+ var encoding = Encoding.UTF8;
+ var encryptedBytes = md5.ComputeHash(encoding.GetBytes(orgStr));
+ var sb = new StringBuilder(32);
+ foreach (var bt in encryptedBytes)
+ {
+ sb.Append(bt.ToString("x").PadLeft(2, '0'));
+ }
+ return sb.ToString().ToLower();
+ }
+ }
+ #endregion
+ ///
+ /// 获取扩展名
+ ///
+ ///
+ ///
+ public static string GetExt(this string s)
+ {
+ var ret = string.Empty;
+ if (!s.Contains('.')) return ret;
+ var temp = s.Split('.');
+ ret = temp[temp.Length - 1];
+
+ return ret;
+ }
+ ///
+ /// 验证QQ格式
+ ///
+ ///
+ ///
+ public static bool IsQq(this string s)
+ {
+ return s.IsNull() || Regex.IsMatch(s, @"^[1-9]\d{4,15}$");
+ }
+
+ ///
+ /// 将字符串根据分隔符转换我List
+ ///
+ ///
+ /// 分隔符
+ ///
+ public static List ToListString(this string str, char split)
+ {
+ return new List(str.Split(split));
+
+ }
+
+ ///
+ /// 判断是否为有效的Email地址
+ ///
+ ///
+ ///
+ public static bool IsEmail(this string s)
+ {
+ if (!s.IsNull())
+ {
+ //return Regex.IsMatch(s,
+ // @"^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
+ // @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$");
+ const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";
+ return Regex.IsMatch(s, pattern);
+ }
+ return false;
+ }
+ ///
+ /// 判断是否是url
+ ///
+ ///
+ ///
+ public static bool IsUrl(this string s)
+ {
+ if (!s.IsNull())
+ {
+ const string pattern = @"^(http://|https://)?((?:[A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+([A-Za-z]+)[/\?\:]?.*$";
+ return Regex.IsMatch(s, pattern);
+ }
+ return false;
+ }
+
+ ///
+ /// 验证是否是合法的电话号码
+ ///
+ ///
+ ///
+ public static bool IsPhone(this string s)
+ {
+ if (!s.IsNull())
+ {
+ return Regex.IsMatch(s, @"^\+?((\d{2,4}(-)?)|(\(\d{2,4}\)))*(\d{0,16})*$");
+ }
+ return true;
+ }
+
+ ///
+ /// 验证是否是合法的手机号码
+ ///
+ ///
+ ///
+ public static bool IsMobile(this string s)
+ {
+ if (!s.IsNull())
+ {
+ return Regex.IsMatch(s, @"^\+?\d{0,4}?[1][3-8]\d{9}$");
+ }
+ return false;
+ }
+
+ ///
+ /// 验证是否是合法的邮编
+ ///
+ ///
+ ///
+ public static bool IsZipCode(this string s)
+ {
+ if (!s.IsNull())
+ {
+ return Regex.IsMatch(s, @"[1-9]\d{5}(?!\d)");
+ }
+ return true;
+ }
+
+ ///
+ /// 验证是否是合法的传真
+ ///
+ ///
+ ///
+ public static bool IsFax(this string s)
+ {
+ if (!s.IsNull())
+ {
+ return Regex.IsMatch(s, @"(^[0-9]{3,4}\-[0-9]{7,8}$)|(^[0-9]{7,8}$)|(^\([0-9]{3,4}\)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)");
+ }
+ return true;
+ }
+
+ ///
+ /// 检查字符串是否为有效的int数字
+ ///
+ ///
+ ///
+ public static bool Isint(this string val)
+ {
+ if (IsNull(val))
+ return false;
+ int k;
+ return int.TryParse(val, out k);
+ }
+
+ ///
+ /// 字符串转数字,未转换成功返回0
+ ///
+ ///
+ ///
+ public static int ToInt(this string val)
+ {
+
+ if (IsNull(val))
+ return 0;
+ int k;
+ return int.TryParse(val, out k) ? k : 0;
+ }
+
+ ///
+ /// 将int间隔字符串抓换为list
+ ///
+ ///
+ ///
+ ///
+ public static List ToIntList(this string str, char Split = ',')
+ {
+ return str.Split(Split).strToIntArray().ToList();
+ }
+
+ ///
+ /// 判断是否是json字符串
+ ///
+ ///
+ ///
+ public static bool IsJson(this string str)
+ {
+ try
+ {
+ if (str.IsNull())
+ return false;
+
+ JsonConvert.DeserializeObject(str);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 检查字符串是否为有效的INT64数字
+ ///
+ ///
+ ///
+ public static bool IsInt64(this string val)
+ {
+ if (IsNull(val))
+ return false;
+ long k;
+ return long.TryParse(val, out k);
+ }
+
+ ///
+ /// 验证是否是身份证
+ ///
+ ///
+ ///
+ public static bool IsCardId(this string ID)
+ {
+ var r = false;
+ if (IsNull(ID))
+ r = false;
+ if (ID.Length == 15)
+ {
+
+ var date = $"19{ID.Substring(6, 2)}-{ID.Substring(8, 2)}-{ID.Substring(10, 2)}";
+ DateTime dt;
+ return DateTime.TryParse(date, out dt);
+ }
+ else if (ID.Length == 18)
+ {
+ var date = $"{ID.Substring(6, 4)}-{ID.Substring(10, 2)}-{ID.Substring(12, 2)}";
+ DateTime dt;
+ return DateTime.TryParse(date, out dt);
+ }
+ else { r = false; }
+
+ return r;
+ }
+
+ ///
+ /// 检查字符串是否为有效的double
+ ///
+ ///
+ ///
+ public static bool IsDecimal(this string val)
+ {
+ if (IsNull(val))
+ return false;
+ double d;
+ return double.TryParse(val, out d);
+ }
+
+ ///
+ ///检测字符串是否是时间类型
+ ///
+ ///
+ ///
+ public static bool IsDateTime(this string val)
+ {
+ if (IsNull(val))
+ return false;
+ DateTime d;
+ return DateTime.TryParse(val, out d);
+ }
+ ///
+ /// 字符串转时间 非时间返回空
+ ///
+ ///
+ ///
+ public static DateTime? ToDateTime(this string val)
+ {
+ if (IsDateTime(val))
+ {
+ return DateTime.Parse(val);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ ///
+ /// 将时间类型字符转时间戳
+ ///
+ ///
+ ///
+ public static long ToTimestamp(this string Val)
+ {
+ var time = Val.ToDateTime();
+ return time != null ? ((DateTime)time).ToTimeStamp() : 0;
+ }
+
+ ///
+ /// 从左边截取N个字符
+ ///
+ ///
+ ///
+ public static string GetLeftStr(this string val, int count = 0)
+ {
+ if (count > val.Length)
+ return null;
+
+ return val.Substring(0, count);
+ }
+
+ ///
+ ///从右边截取N个字符
+ ///
+ ///
+ ///
+ ///
+ public static string GetRightStr(this string val, int count = 0)
+ {
+
+ if (count > val.Length)
+ return null;
+
+ return val.Substring(val.Length - count, count);
+
+ }
+
+
+ }
+}
diff --git a/Myshipping.Core/Myshipping.Core.xml b/Myshipping.Core/Myshipping.Core.xml
index e6baa86e..d602d403 100644
--- a/Myshipping.Core/Myshipping.Core.xml
+++ b/Myshipping.Core/Myshipping.Core.xml
@@ -5701,6 +5701,95 @@
默认用户集合
+
+
+ datetime数据类型拓展
+
+
+
+
+ 将一个时间转换为秒级时间戳
+
+ 时间
+
+
+
+
+ 将一个时间转换为毫秒级时间戳
+
+
+
+
+
+
+ 获取标准时间戳 秒级
+
+
+
+
+
+
+ 将时间转换为时间字符串编码 yyyyMMddHHmmssffff
+
+
+
+
+
+
+ 判断时间是否大于1970年的有效时间
+
+
+
+
+
+
+ 获时间一天中的开始时间
+
+
+
+
+
+ 获取时间一天的结束时间
+
+
+
+
+
+
+ 获取时间周的星期一的时间
+
+
+
+
+
+
+ 获取时间周的周日
+
+
+
+
+
+
+ 获取时间周的指定周几时间
+
+
+ 周几 1 2 3 4 5 6 7
+
+
+
+
+ 获取时间月开始时间
+
+
+
+
+
+
+ 获取一个月的结束时间
+
+
+
+
字典扩展
@@ -5852,6 +5941,46 @@
排序方法,默认降序
+
+
+ 扩展Int32功能
+
+
+
+
+ 向上整除
+ 1.当num能被divideBy整除时,结果即为num/divideBy;
+ 2.当num不能被divideBy整除时,结果为num/divideBy + 1;
+
+ 被除数,大于或者等于0
+ 除数,大于0
+ 向上整除结果
+
+
+
+ 向上整除
+ 1.当num能被divideBy整除时,结果即为num/divideBy;
+ 2.当num不能被divideBy整除时,结果为num/divideBy + 1;
+
+ 被除数,大于或者等于0
+ 除数,大于0
+ 向上整除结果
+
+
+
+
+ 拓展 将字符串抓换为int
+
+
+
+
+
+
+ 拓展 将字符串数组转换成int 数组
+
+
+
+
获取JObject
@@ -6045,6 +6174,198 @@
时间戳
+
+
+ string 拓展
+
+
+
+
+ 隐藏中间字符串
+
+
+
+
+
+
+ 隐藏头部
+
+
+
+
+
+
+ 用于判断是否为空字符
+
+
+
+
+
+
+ 用于判断是否为非空字符
+
+
+
+
+
+
+ DES对称加密字符串
+
+ 待加密的字符串
+ 加密密钥,要求为16位
+ 加密成功返回加密后的字符串,失败返回源串
+
+
+
+ DES对称解密字符串
+
+ 待解密的字符串
+ 解密密钥,要求16位
+
+
+
+
+ 将字符串转换成MD5加密字符串
+
+
+
+
+
+
+ 获取扩展名
+
+
+
+
+
+
+ 验证QQ格式
+
+
+
+
+
+
+
+ 判断是否为有效的Email地址
+
+
+
+
+
+
+ 判断是否是url
+
+
+
+
+
+
+ 验证是否是合法的电话号码
+
+
+
+
+
+
+ 验证是否是合法的手机号码
+
+
+
+
+
+
+ 验证是否是合法的邮编
+
+
+
+
+
+
+ 验证是否是合法的传真
+
+
+
+
+
+
+ 检查字符串是否为有效的int数字
+
+
+
+
+
+
+ 字符串转数字,未转换成功返回0
+
+
+
+
+
+
+
+ 判断是否是json字符串
+
+
+
+
+
+
+ 检查字符串是否为有效的INT64数字
+
+
+
+
+
+
+ 验证是否是身份证
+
+
+
+
+
+
+ 检查字符串是否为有效的double
+
+
+
+
+
+
+ 检测字符串是否是时间类型
+
+
+
+
+
+
+ 字符串转时间 非时间返回空
+
+
+
+
+
+
+ 将时间类型字符转时间戳
+
+
+
+
+
+
+ 从左边截取N个字符
+
+
+
+
+
+
+ 从右边截取N个字符
+
+
+
+
+
处理文件名称
diff --git a/Myshipping.Web.Core/Startup.cs b/Myshipping.Web.Core/Startup.cs
index 9f7b827c..9e66ba39 100644
--- a/Myshipping.Web.Core/Startup.cs
+++ b/Myshipping.Web.Core/Startup.cs
@@ -138,6 +138,8 @@ public class Startup : AppStartup
{
builder.AddSubscriber();
}
+ //扣费
+ builder.AddSubscriber();
});
// 客户订舱:客户端订阅大简云公司用户信息同步
diff --git a/Myshipping.Web.Core/applicationconfig.json b/Myshipping.Web.Core/applicationconfig.json
index 607e2066..ee728dc6 100644
--- a/Myshipping.Web.Core/applicationconfig.json
+++ b/Myshipping.Web.Core/applicationconfig.json
@@ -56,7 +56,7 @@
},
"Cache": {
"CacheType": "RedisCache", // RedisCache
- "RedisConnectionString": "192.168.0.182:6379,password=,defaultDatabase=11"
+ "RedisConnectionString": "192.168.0.80:6379,password=,defaultDatabase=11"
},
"SnowId": {
"WorkerId": "1" // 取值范围0~63,默认1