.gitignore
@@ -36,3 +36,4 @@ cylsg/EzJob/bin/ cylsg/EzJob/obj/ cylsg/cylsg.Application/cylsg.Application.xml cylsg/cylsg.Web.Entry/application.log cylsg/EzInitQ/Mapper.cs
@@ -14,8 +14,8 @@ { public void Register(TypeAdapterConfig config) { config.ForType<CreateTransferBatchRequest, WeChatTransferOrder>(); config.ForType<CreateTransferBatchRequest, WeChatTransferOrder>().Map(x=>x.TotalNum,x=>x.TotalNumber); config.ForType<WeChatTransferOrder,CreateTransferBatchRequest>().Map(x => x.TotalNumber, x => x.TotalNum); } } } cylsg/EzInitQ/PayServiceMessageQ.cs
@@ -8,6 +8,7 @@ using Furion; using Furion.DatabaseAccessor; using Furion.FriendlyException; using Furion.Logging; using InitQ.Abstractions; using InitQ.Attributes; using Mapster; @@ -29,14 +30,7 @@ { private IEzCoreNetRedisService _ezCoreNetRedisService; private IWecharPayServicecs _wecharPayServicecs; private IMapper _mapper; //public PayServiceMessageQ(IEzCoreNetRedisService ezCoreNetRedisService,IWecharPayServicecs wecharPayServicecs,IMapper mapper) { // _ezCoreNetRedisService = ezCoreNetRedisService; // _wecharPayServicecs = wecharPayServicecs; // _mapper = mapper; //} private IMapper _mapper; /// <summary> /// 微信转账队列处理 @@ -191,5 +185,114 @@ } [Subscribe(InitQMessages.WxTransfer)] public async void WxTransfer(string msg) { _ezCoreNetRedisService = App.GetService<IEzCoreNetRedisService>(); _wecharPayServicecs = App.GetService<IWecharPayServicecs>(); _mapper = App.GetService<IMapper>(); var WeChatTransferOrderwork = new BaseRepository<WeChatTransferOrder>(); var TransferOrder = await WeChatTransferOrderwork.AsQueryable().Includes(x => x.TransferDetailList).Where(x=>x.Id==msg.toInt()).FirstAsync(); if(TransferOrder == null) { Log.Error($"WxTransfer微信支付处理 失败,原因是没有找到TransferOrder ,传递Id为{msg}"); return; } if(!string.IsNullOrEmpty(TransferOrder.BatchStatus)) { return; } // 发起支付 var requit = _mapper.Map<CreateTransferBatchRequest>(TransferOrder); requit.AppId = App.Configuration["WechatAPP:AppId"]; requit.BatchName = "小镇临时工工资转账"; requit.BatchRemark = "川印临时工工资,操过200的多笔支付"; var ret = await _wecharPayServicecs.Transfer(requit); if (ret.IsSuccessful()) { var retdata = await WeChatTransferOrderwork.GetByIdAsync(TransferOrder.Id); retdata.BatchId = ret.BatchId; retdata.BatchStatus = ret.BatchStatus; retdata.UpDataBy = "微信付款请求之后"; retdata.UpDataTime = DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(retdata); } else { var retdata = await WeChatTransferOrderwork.GetByIdAsync(TransferOrder.Id); retdata.ErrorCode = ret.ErrorCode; retdata.ErrorMsg = ret.ErrorMessage; retdata.BatchStatus = ret.BatchStatus; retdata.UpDataBy = "微信付款请求之后"; retdata.UpDataTime = DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(retdata); Log.Error($"WxTransfer微信支付处理 失败,传递Id为{msg} 错误原因:{retdata.ErrorMsg}"); return; } } [Subscribe(InitQMessages.WxTransferAg)] public async void WxTransferAg(string msg) { _ezCoreNetRedisService = App.GetService<IEzCoreNetRedisService>(); _wecharPayServicecs = App.GetService<IWecharPayServicecs>(); _mapper = App.GetService<IMapper>(); var WeChatTransferOrderwork = new BaseRepository<WeChatTransferOrder>(); var TransferOrder = await WeChatTransferOrderwork.AsQueryable().Includes(x => x.TransferDetailList).Where(x => x.Id == msg.toInt()).FirstAsync(); if (TransferOrder == null) { Log.Error($" 再次调用WxTransfer微信支付处理 失败,原因是没有找到TransferOrder ,传递Id为{msg}"); return; } if (!string.IsNullOrEmpty(TransferOrder.BatchStatus)) { return; } // 发起支付 var requit = _mapper.Map<CreateTransferBatchRequest>(TransferOrder); requit.AppId = App.Configuration["WechatAPP:AppId"]; requit.BatchName = "小镇临时工工资转账"; requit.BatchRemark = "川印临时工工资,操过200的多笔支付"; var ret = await _wecharPayServicecs.Transfer(requit); if (ret.IsSuccessful()) { var retdata = await WeChatTransferOrderwork.GetByIdAsync(TransferOrder.Id); retdata.BatchId = ret.BatchId; retdata.BatchStatus = ret.BatchStatus; retdata.UpDataBy = "再次微信付款请求"; retdata.UpDataTime = DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(retdata); } else { var retdata = await WeChatTransferOrderwork.GetByIdAsync(TransferOrder.Id); retdata.ErrorCode = ret.ErrorCode; retdata.ErrorMsg = ret.ErrorMessage; retdata.BatchStatus = ret.BatchStatus; retdata.UpDataBy = "再微信付款请求"; retdata.UpDataTime = DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(retdata); Log.Error($"WxTransfer微信支付处理 失败,传递Id为{msg} 错误原因:{retdata.ErrorMsg}"); return; } } } } cylsg/EzInitqMessageDef/InitQMessages.cs
@@ -14,7 +14,14 @@ /// 转账 /// </summary> public const string WxTransferMSQ = "WxTransferMSQ"; /// <summary> ///微信提现只传递ID /// </summary> public const string WxTransfer = "WxTransfer"; /// <summary> ///重新支付 /// </summary> public const string WxTransferAg = "WxTransferAg"; /// <summary> /// 向堆栈中压入一个消息 /// </summary> @@ -22,7 +29,7 @@ /// <param name="MessageName"> 消息名称</param> /// <param name="msg">类型</param> /// <returns></returns> public static async Task<bool> SendMessageAsync<T>(string MessageName,T msg) public static async Task<bool> SendMessageAsync<T>(string MessageName,T msg) { var _redis= App.GetService<ICacheService>(); @@ -40,6 +47,7 @@ var _redis = App.GetService<ICacheService>(); await _redis.ListRightPushAsync(MessageName, msg); return true; } } cylsg/EzJob/ClearWorkOnDay.cs
New file @@ -0,0 +1,29 @@ using cylsg.utility; using EzCoreNet.Redis; using Furion.Schedule; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EzJob { /// <summary> /// 清除每日提现统计key /// </summary> public class ClearWorkOnDay : IJob { private readonly IEzCoreNetRedisService _redisService; public ClearWorkOnDay(IEzCoreNetRedisService ezCoreNetRedis) { _redisService = ezCoreNetRedis; } public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { await _redisService.delegateAllKeyWith(StaticStringDef.TransferMoneyManKey); } } } cylsg/EzJob/StartUpcs.cs
@@ -18,7 +18,8 @@ services.AddSchedule(options => { options.AddJob<WeChatJob>(concurrent: false, Triggers.Hourly()); // 串行 options.AddJob<WeChatJob>(concurrent: false, Triggers.PeriodMinutes(1)); // 串行Triggers.PeriodMinutes(1) options.AddJob<ClearWorkOnDay>(concurrent: false, Triggers.DailyAt(0)); }); } cylsg/EzJob/WeChatJob.cs
@@ -5,6 +5,7 @@ using Furion.FriendlyException; using Furion.Schedule; using Microsoft.AspNetCore.Http.HttpResults; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models; using System; using System.Collections.Generic; using System.Linq; @@ -32,20 +33,21 @@ } var WeChatTransferOrderRs = new BaseRepository<WeChatTransferOrder>(); var OderList = await WeChatTransferOrderRs.AsQueryable().Includes(x=>x.TransferDetailList).Where(x => (x.BatchId != null && x.BatchId != "") || x.BatchStatus == "ACCEPTED" || x.BatchStatus == "PROCESSING").ToListAsync(); var OderList = await WeChatTransferOrderRs.AsQueryable().Includes(x=>x.TransferDetailList).Where(x => (x.BatchId != null && x.BatchId != "")&&(x.BatchStatus==null|| x.BatchStatus == "ACCEPTED" || x.BatchStatus == "PROCESSING")).ToListAsync(); foreach( var o in OderList ) { var ret = await payServices.TransferBatches(new SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.GetTransferBatchByBatchIdRequest var ret = await payServices.TransferBatches(new GetTransferBatchByOutBatchNumberRequest { BatchId = o.BatchId OutBatchNumber = o.OutBatchNumber }); }); ; if(ret != null) { if(ret.IsSuccessful()) { { if (ret.TransferBatch.BatchStatus == "FINISHED") { @@ -61,28 +63,32 @@ foreach (var item in o.TransferDetailList) { var del =ret.TransferDetailList.Where(x=>x.OutDetailNumber==item.OutDetailNumber).FirstOrDefault(); item.DetailStatus = del?.DetailStatus; switch (item.DetailStatus) if (del != null) { case "FAIL": //失败,获取失败原因 var retde = await payServices.TransferBatchesDetails(new SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.GetTransferBatchDetailByDetailIdRequest { BatchId = o.BatchId, DetailId = del.DetailId, item.DetailStatus = del?.DetailStatus; switch (item.DetailStatus) { case "FAIL": //失败,获取失败原因 var retde = await payServices.TransferBatchesDetails(new SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.GetTransferBatchDetailByDetailIdRequest { BatchId = o.BatchId, DetailId = del.DetailId, }); }); item.FailReason = retde?.FailReason; break; case "SUCCESS": item.DetailStatus = "SUCCESS"; item.FailReason = retde?.FailReason; break; case "SUCCESS": item.DetailStatus = "SUCCESS"; break; break; default: item.DetailStatus = del?.DetailStatus; break; default: item.DetailStatus = del?.DetailStatus; break; } } @@ -92,7 +98,31 @@ } else if(ret.TransferBatch.BatchStatus== "PROCESSING") { o.BatchStatus = ret.TransferBatch.BatchStatus; o.UpDataBy = "ExecuteAsync"; o.UpDataTime = DateTime.Now; o.CloseReason = ret.TransferBatch.CloseReason; o.FailAmount = ret.TransferBatch.FailAmount; o.FailNum = ret.TransferBatch.FailNumber; o.SuccessNum = ret.TransferBatch.SuccessNumber; o.SuccessAmount = ret.TransferBatch.SuccessAmount; } } else { //处理失败 o.ErrorCode = ret.ErrorCode; o.ErrorMsg = ret.ErrorMessage; o.UpDataBy = "ExecuteAsync"; o.UpDataTime = DateTime.Now; } await WeChatTransferOrderRs.UpdateRangeAsync(OderList); } } } cylsg/EzWechat/EzWechat.csproj
@@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.4.0" /> <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.5.0" /> <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.7.0" /> </ItemGroup> cylsg/EzWechat/IWecharPayServicecs.cs
@@ -20,7 +20,7 @@ /// </summary> /// <param name="request"></param> /// <returns></returns> Task<GetTransferBatchByBatchIdResponse> TransferBatches(GetTransferBatchByBatchIdRequest request); Task<GetTransferBatchByOutBatchNumberResponse> TransferBatches(GetTransferBatchByOutBatchNumberRequest request); /// <summary> /// 根据Detail id 查询名单详细 /// </summary> cylsg/EzWechat/WecharPayServicecs.cs
@@ -1,5 +1,6 @@ using Furion; using Furion.DependencyInjection; using Microsoft.Extensions.FileSystemGlobbing; using SKIT.FlurlHttpClient.Wechat.TenpayV3; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings; @@ -8,6 +9,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using static SKIT.FlurlHttpClient.Wechat.Api.Events.TransferCustomerServiceReply.Types; using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinOpenApiRequestIdGetResponse.Types; namespace EzWechat @@ -40,10 +42,10 @@ } public async Task<GetTransferBatchByBatchIdResponse> TransferBatches(GetTransferBatchByBatchIdRequest request) public async Task<GetTransferBatchByOutBatchNumberResponse> TransferBatches(GetTransferBatchByOutBatchNumberRequest request) { var response = await _V3Client.ExecuteGetTransferBatchByBatchIdAsync(request); var response = await _V3Client.ExecuteGetTransferBatchByOutBatchNumberAsync(request); return response; } cylsg/cylsg.Application/LogoInController.cs
@@ -84,6 +84,9 @@ //没有用户 ,需要新建用户 var phone = await _wechatService.GetPhone(Param.Bindgetphonenumber); user = await UserRes.GetFirstAsync(x => x.ItCode == phone); if(user == null) { user = new User { @@ -94,14 +97,22 @@ ItCode = phone, PassWord = "123456", WxOpenId = opeid, CreateBy="微信注册登录", CreateTime = DateTime.UtcNow, }; user.Id = await UserRes.EzInsertReturnIdentityAsync(user); user= await UserRes.InsertReturnEntityAsync(user); } else { user.WxOpenId = opeid; await UserRes.EzUpdateAsync(user); } } var jwt = new EzJwtModel() { @@ -123,9 +134,7 @@ } } /// <summary> cylsg/cylsg.Application/Transfer/UserTransfer.cs
@@ -1,14 +1,25 @@ using cylsg.Core; using cylsg.Model.TransferOrder; using cylsg.Model.UserModel; using cylsg.utility; using cylsg.utility.Extend; using Cylsg.Filter; using EzCoreNet.Redis; using EzInitqMessageDef; using EzWechat; using Furion.LinqBuilder; using MapsterMapper; using Newtonsoft.Json; using SKIT.FlurlHttpClient.Wechat.Api.Models; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using TencentCloud.Ame.V20190916.Models; using static SKIT.FlurlHttpClient.Wechat.Api.Models.ChannelsLeadsGetLeadsInfoByComponentIdResponse.Types; namespace cylsg.Application.Transfer { @@ -21,16 +32,30 @@ public class UserTransfer { public UserTransfer() { } private readonly IEzCoreNetRedisService _redisService; private readonly IWecharPayServicecs _wecharPayServicecs; public UserTransfer(IEzCoreNetRedisService ezCoreNetRedisService,IWecharPayServicecs wecharPayServicecs) { _redisService = ezCoreNetRedisService; _wecharPayServicecs = wecharPayServicecs; } /// <summary> /// 提现 /// </summary> /// <param name="Money"></param> [LimitFilter(LimiType = Limttype.User,timespan =10,ResponseMeg ="请勿在10秒内重复请求")] public async Task GetTransferMoney( [FromQuery]decimal Money) [LimitFilter(LimiType = Limttype.User, timespan = 10, ResponseMeg = "请勿在10秒内重复请求")] public async Task GetTransferMoney([FromQuery] decimal Money) { var rs= new BaseRepository<UserWorker>(); if (Money < 0.3m) throw Oops.Oh("必须大于0.3元"); if (Money > 2000) throw Oops.Oh("每人每天最多只能提取2000元"); var rs = new BaseRepository<UserWorker>(); var UserID = App.User?.FindFirstValue("UserID"); int userid = 0; if (!string.IsNullOrEmpty(UserID)) @@ -42,17 +67,293 @@ throw Oops.Oh("没有识别到用户收入"); } var uw= await rs.GetByIdAsync(userid); if((uw.TiXianZonge-uw.YiTiXianJine)< Money) if (await _redisService.TryLock(StaticStringDef.TransferMoneyLockKey + userid.ToString(), 300)) { throw Oops.Oh("用户余额不足"); try { var UserRs = new BaseRepository<User>(); var user = await UserRs.GetByIdAsync(userid); if (user == null) { throw Oops.Oh($"没有找到用户"); } if (string.IsNullOrEmpty(user.WxOpenId)) { throw Oops.Oh($"用户微信OpenID确实"); } var uw = await rs.GetFirstAsync(x => x.UserId == userid); if (uw == null) { throw Oops.Oh("该用户没有收入"); } if ((uw.TiXianZonge - uw.YiTiXianJine) < Money) { throw Oops.Oh("用户余额不足"); } var totle = _redisService.Get<decimal>(StaticStringDef.TransferMoneyManKey + userid.ToString()); if (totle + Money > 2000) { throw Oops.Oh("提现金额不可超出2000"); } var UserTiXianDetailwork = new BaseRepository<UserTiXianDetail>(); var WeChatTransferOrderwork = new BaseRepository<WeChatTransferOrder>(); if ((uw != null) && ((uw.TiXianZonge - uw.YiTiXianJine) >= Money)) { //满足条件,发起支付 var TransferOrder = new WeChatTransferOrder { CreateBy = uw.UserId.ToString(), CreateTime = DateTime.Now, // BatchId = _redisService.Get32sn(), OutBatchNumber = _redisService.Get32sn(), Remake = "川印工资支付", TransferDetailList = new List<WeChatTransferItem>(), UserID = uw.UserId, }; try { await UserTiXianDetailwork.AsTenant().BeginTranAsync(); var moneylist = Money; var maxPayItem = Convert.ToDecimal(App.Configuration["WechartPay:PayMoneyMax"].toInt()); ; while ((moneylist > maxPayItem)) { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)maxPayItem * 100, TransferRemark = "川印工资支付", }); moneylist -= maxPayItem; } if (moneylist <= 0.3m) { //如果这里低于0.3毛,将社区预检,留下次处理 Money -= moneylist; } else { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)(moneylist * 100), TransferRemark = "川印工资支付", }); } TransferOrder.TotalAmount = (int)(Money * 100); TransferOrder.TotalNum = TransferOrder.TransferDetailList.Count(); TransferOrder = await WeChatTransferOrderwork.AsSugarClient().InsertNav(TransferOrder).Include(x => x.TransferDetailList).ExecuteReturnEntityAsync(); await UserTiXianDetailwork.InsertAsync(new UserTiXianDetail { CreateBy = uw.UserId.ToString(), CreateTime = DateTime.Now, UserId = user.Id, ZhiChuShouRu = 0, YiTiXianJine = Money, WeChatTransferOrderID = TransferOrder.Id, }); //钱包余额调整 uw.YiTiXianJine += Money; uw.UpDataBy = uw.UserId.ToString(); uw.UpDataTime = DateTime.Now; await rs.UpdateAsync(uw); await UserTiXianDetailwork.AsTenant().CommitTranAsync(); totle += Money; //设置每日提现限额 _redisService.Add(StaticStringDef.TransferMoneyManKey + userid.ToString(), totle, 60 * 60 * 24); //发起支付 await InitQMessages.SendMessageAsync(InitQMessages.WxTransfer, TransferOrder.Id.ToString()); } catch (Exception) { await UserTiXianDetailwork.AsTenant().RollbackTranAsync(); throw; } // 发起支付 } } catch (Exception) { throw; } finally { await _redisService.TryUnLock(StaticStringDef.TransferMoneyLockKey + userid.ToString()); } } var b = await InitQMessages.SendMessageAsync(InitQMessages.WxTransferMSQ, Money.ToString()); if (b) return; else throw Oops.Oh("请求失败"); else throw Oops.Oh("请不要频繁重复申请"); } /// <summary> /// 获取为支付列表 /// </summary> [AllowAnonymous] [HttpPost] [ApiExplorerSettings(IgnoreApi = true)] public async Task<TransferOderOut> GetTransferOder(SearchTransferOder param) { var WeChatTransferOrderwork = new BaseRepository<WeChatTransferOrder>(); PageModel pageModel = new PageModel { PageIndex = param.PageIndex, PageSize = param.PageSize }; Expression<Func<WeChatTransferOrder, bool>> SearchList = (x) => true; if (!string.IsNullOrEmpty(param.BatchStatus)) { SearchList= SearchList.And(x => x.BatchStatus.Contains(param.BatchStatus)); } if (!string.IsNullOrEmpty(param.NoTBatchStatus)) { var lisstring = param.NoTBatchStatus?.Split('|'); foreach (var lis in lisstring) { SearchList= SearchList.And(x => x.BatchStatus != lis); } } if (param.HasSendOk == false) SearchList= SearchList.And(x => x.BatchId == null); else SearchList= SearchList.And(x => x.BatchId != null); var data = await WeChatTransferOrderwork.GetPageListAsync(SearchList, pageModel); return new TransferOderOut { listdata = data, TotalCount=pageModel.TotalCount, }; } /// <summary> /// 重新支付 /// </summary> /// <param name="Id"> 按订单批次操作</param> /// <returns></returns> [AllowAnonymous] [HttpGet] [ApiExplorerSettings(IgnoreApi = true)] public async Task<bool> ReSendTransferOder([FromQuery] string ids) { var itmsRes = new BaseRepository<WeChatTransferOrder>(); if (string.IsNullOrEmpty(ids)) throw Oops.Oh("参数错误"); var idsr= ids.Split(',').Select(x=>x.toInt()).ToList(); foreach (var id in idsr) { if (itmsRes.GetById(id) != null) await InitQMessages.SendMessageAsync(InitQMessages.WxTransferAg, id.ToString()); } return true; } } /// <summary> /// /// </summary> public class SearchTransferOder { /// <summary> /// 搜索状态值 模糊查询 /// </summary> public string BatchStatus { get; set; } /// <summary> /// 排除搜索值状态 要排除的状态值必须是全称,多个之间用 “|”间隔 /// </summary> public string NoTBatchStatus { get; set; } /// <summary> /// 是否已经成功发起了 /// </summary> public bool HasSendOk { get; set; } = false; /// <summary> /// 当前页码 /// </summary> public int PageIndex { get; set; } /// <summary> /// 页面大小 /// </summary> public int PageSize { get; set; } } public class TransferOderOut { public List<WeChatTransferOrder> listdata { get; set; } public int TotalCount { get; set; } } } cylsg/cylsg.Model/TransferOrder/WeChartTransferOrder.cs
@@ -33,18 +33,22 @@ /// <summary> /// 获取或设置微信批次单号。 /// </summary> [SugarColumn(ColumnDescription = "获取或设置微信批次单号")] public string BatchId { get; set; } [SugarColumn(ColumnDescription = "获取或设置微信批次单号",IsNullable =true)] public string? BatchId { get; set; } /// <summary> /// 获取或设置批次状态。 /// </summary> [SugarColumn(ColumnDescription = "获取或设置批次状态")] [SugarColumn(ColumnDescription = "获取或设置批次状态",IsNullable =true)] public string? BatchStatus { get; set; } /// <summary> /// 用户ID。 /// </summary> [SugarColumn(ColumnDescription = "用户ID")] public int UserID { get; set; } @@ -130,14 +134,21 @@ /// </summary> [SugarColumn(ColumnDescription = "获取或设置转账场景标识符", IsNullable = true)] public string? TransferSceneId { get; set; } /// <summary> /// 错误消息 /// </summary> [SugarColumn(ColumnDescription = "错误消息", IsNullable = true)] public string? ErrorMsg { get; set; } /// <summary> /// 获取或设置批次中的详细转账列表。 /// </summary> [Navigate(NavigateType.OneToMany,nameof(WeChatTransferItem.WeChatTransferOrderID))] /// <summary> /// 错误标识 /// </summary> [SugarColumn(ColumnDescription = "错误标识", IsNullable = true)] public string? ErrorCode { get; set; } /// <summary> /// 获取或设置批次中的详细转账列表。 /// </summary> [Navigate(NavigateType.OneToMany,nameof(WeChatTransferItem.WeChatTransferOrderID))] public List<WeChatTransferItem> TransferDetailList { get; set; } } @@ -146,6 +157,7 @@ /// 转账单列表 /// </summary> [SugarTable(TableDescription = "转账单账详细列表模型")] [CoderFirst] public class WeChatTransferItem:BaseModel { /// <summary> cylsg/cylsg.Web.Core/Startup.cs
@@ -47,6 +47,7 @@ services.AddControllersWithViews() .AddInjectWithUnifyResult<EzCoreRESTFulResultProvider>(); services.AddFileLogging(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) cylsg/cylsg.Web.Entry/appsettings.json
@@ -5,6 +5,14 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.EntityFrameworkCore": "Information" }, "File": { "FileName": "application.log", // 日志文件完整路径或文件名,推荐 .log 作为拓展名 "Append": true, // 追加到已存在日志文件或覆盖它们 "MinimumLevel": "Information", // 最低日志记录级别 "FileSizeLimitBytes": 0, // 控制每一个日志文件最大存储大小,单位是 B,也就是 1024 才等于 1KB,默认无限制,如果指定了该值,那么日志文件大小超出了该配置就会创建新的日志文件,新创建的日志文件命名规则:文件名+[递增序号].log "MaxRollingFiles": 0 // 控制最大创建的日志文件数量,默认无限制,配合 FileSizeLimitBytes 使用,如果指定了该值,那么超出该值将从最初日志文件中从头写入覆盖 } }, "AllowedHosts": "*", @@ -39,7 +47,7 @@ "ValidateAudience": true, // 是否验证签收方,bool 类型,默认true "ValidAudience": "www.51zhengcai.com", // 签收方,string 类型 "ValidateLifetime": true, // 是否验证过期时间,bool 类型,默认true,建议true "ExpiredTime": 20, // 过期时间,long 类型,单位分钟,默认20分钟 "ExpiredTime": 1440, // 过期时间,long 类型,单位分钟,默认20分钟 "ClockSkew": 5, // 过期时间容错值,long 类型,单位秒,默认 5秒 "Algorithm": "HS256", // 加密算法,string 类型,默认 HS256 "RefreshTokenExpires": 1440 //分钟 1天 1440分钟 cylsg/cylsg.redis/EzCoreNetRedisService.cs
@@ -10,7 +10,7 @@ namespace EzCoreNet.Redis { public class EzCoreNetRedisService : IEzCoreNetRedisService,IScoped public class EzCoreNetRedisService : IEzCoreNetRedisService, IScoped { public bool Add(string key, object value, int expireSeconds) { @@ -35,9 +35,9 @@ return RedisHelper.Ttl(key); } public bool SetTtl(string key, int ttl) public bool SetTtl(string key, int ttl) { return RedisHelper.Expire(key, ttl); return RedisHelper.Expire(key, ttl); } /// <summary> @@ -70,7 +70,7 @@ { return RedisHelper.Keys(Prefix + "*"); } /// <summary> /// 后去一个缓存,如果没有,则从数据库中获取, /// </summary> @@ -102,23 +102,61 @@ public long Incrby(string key) { return RedisHelper.IncrBy(key); return RedisHelper.IncrBy(key); } public string Get32sn() { string formattedDate = DateTime.Now.ToString("yyyyMMdd"); var sn = Incrby($"CreatSnKey:{formattedDate}"); if(sn<1) if (sn < 1) { //设置有效期限为24小时 SetTtl($"CreatSnKey:{formattedDate}", 24 * 60 * 60); } string re = "Ez" + formattedDate + sn.ToString(); string re = "EZCoreCanYinLingShiGon" + formattedDate + sn.ToString(); return re; } /// <summary> /// /// </summary> /// <param name="LockKey"></param> /// <param name="expireSeconds"></param> /// <param name="value"></param> /// <returns></returns> public async Task<bool> TryLock(string LockKey, int expireSeconds = 600, string value = "Lock") { if (await RedisHelper.SetNxAsync(LockKey, value) == true) { if( await RedisHelper.ExpireAsync(LockKey, expireSeconds)==false) return false; return true; } else return false; } /// <summary> /// /// </summary> /// <param name="LockKey"></param> /// <returns></returns> public async Task<bool > TryUnLock(string LockKey) { var b= await RedisHelper.DelAsync(LockKey); if(b>0) return true; else return false; } } } cylsg/cylsg.redis/IEzCoreNetRedisService.cs
@@ -86,6 +86,21 @@ /// 获取32位sn /// </summary> string Get32sn(); /// <summary> /// 设置锁 /// </summary> /// <param name="LockKey"> 锁Key</param> /// <param name="value"> 值 默认lock</param> /// <param name="expireSeconds"> 最长锁定时间 默认600</param> /// <returns></returns> Task<bool> TryLock(string LockKey, int expireSeconds = 600,string value = "Lock"); /// <summary> /// 解锁 /// </summary> /// <param name="LockKey"></param> /// <returns></returns> Task<bool> TryUnLock(string LockKey); } } cylsg/cylsg.utility/StaticStringDef.cs
New file @@ -0,0 +1,24 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace cylsg.utility { /// <summary> /// 常用字符串定义 /// </summary> public static class StaticStringDef { /// <summary> /// 提现自锁KeY /// </summary> public static string TransferMoneyLockKey = "TransferMoneyLockKey:"; /// <summary> /// 提现统计累计锁 /// </summary> public static string TransferMoneyManKey = "TransferMoneyManKey:"; } }