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