| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | sunpengfei | ![]() |
| 2025-11-21 | lijin | ![]() |
ApiTools.Application/ApiTools.Application.xml
@@ -215,6 +215,30 @@ <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.WxmpSubscribMessageCommandHandler.Handle(ApiTools.Core.SendWxmpSubscribMessageCommand,System.Threading.CancellationToken)"> <summary> 微信小程序发送订阅消息 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.WxmpSubscribMessageCommandHandler.Handle(ApiTools.Core.WxmpSubscribMessageNotifyCommand,System.Threading.CancellationToken)"> <summary> 微信小程序订阅消息通知 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.WxmpSubscribMessageQueryHandler.Handle(ApiTools.Core.GetWxmpSubscribMessageTemplatesQuery,System.Threading.CancellationToken)"> <summary> 查询微信小程序订阅消息模板 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="T:ApiTools.CommonServer.Application.SaveSmsSettingCommandHandler"> <summary> 保存短信配置 @@ -282,22 +306,6 @@ <member name="M:ApiTools.CommonServer.Application.GetSmsSettingQueryHandler.Handle(ApiTools.Core.GetSmsSettingQuery,System.Threading.CancellationToken)"> <summary> 查询短信配置 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.CommonServer.Application.SaveWxCommandHandler.Handle(ApiTools.Core.SaveWxSendCommand,System.Threading.CancellationToken)"> <summary> 该接口用于发送订阅消息 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.CommonServer.Application.SaveWxSettingCommandHandler.Handle(ApiTools.Core.SaveWxSettingCommand,System.Threading.CancellationToken)"> <summary> 保存微信配置 </summary> <param name="request"></param> <param name="cancellationToken"></param> ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
@@ -91,6 +91,7 @@ if (request.Amount > wallet.Balance) throw Oops.Oh(EnumErrorCodeType.s404, "余额不足"); var transaction = await channelWalletTransactionRepository.GetQueryable() .Include(it => it.PingAnPay) .Where(it => it.WalletId == wallet.Id && it.OutCode == request.OutCode) .FirstOrDefaultAsync(); if (transaction == null) ApiTools.Application/WxUtils/Commands/SaveWxCommandHandler.cs
File was deleted ApiTools.Application/WxUtils/Commands/SaveWxSettingCommandHandler.cs
File was deleted ApiTools.Application/WxUtils/Commands/WxmpSubscribMessageCommandHandler.cs
New file @@ -0,0 +1,66 @@ using Aop.Api.Domain; using ApiTools.Core; using log4net.Core; using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Application { public class WxmpSubscribMessageCommandHandler( ILogger<WxmpSubscribMessageCommandHandler> logger, WxmpUtils utils, IHttpContextAccessor httpContextAccessor ) : IRequestHandler<SendWxmpSubscribMessageCommand, Guid>, IRequestHandler<WxmpSubscribMessageNotifyCommand, bool> { private readonly ILogger<WxmpSubscribMessageCommandHandler> logger = logger; private readonly WxmpUtils utils = utils; private readonly IHttpContextAccessor httpContextAccessor = httpContextAccessor; /// <summary> /// 微信小程序发送订阅消息 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<Guid> Handle(SendWxmpSubscribMessageCommand request, CancellationToken cancellationToken) { await utils.WxmpSendSubscribMessage(new WxmpSendSubscribMessageRequest { Data = request.Data, TemplateId = request.TemplateId, Page = request.Page, WxmpCode = request.WxmpCode, Touser = request.Touser, }); return Guid.Empty; } /// <summary> /// 微信小程序订阅消息通知 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<bool> Handle(WxmpSubscribMessageNotifyCommand request, CancellationToken cancellationToken) { var req = httpContextAccessor.HttpContext.Request; logger.LogInformation($"微信小程序订阅消息通知query:{req.QueryString.Value}"); req.EnableBuffering(); req.Body.Position = 0; using var reader = new StreamReader(req.Body, Encoding.UTF8, leaveOpen: true); var body = await reader.ReadToEndAsync(); logger.LogInformation($"微信小程序订阅消息通知body:{body}"); req.Body.Position = 0; return true; } } } ApiTools.Application/WxUtils/Queries/GetWxSettingQueryHandler.cs
File was deleted ApiTools.Application/WxUtils/Queries/WxmpSubscribMessageQueryHandler.cs
New file @@ -0,0 +1,34 @@ using ApiTools.Core; using Mapster; using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Application { public class WxmpSubscribMessageQueryHandler( WxmpUtils utils ) : IRequestHandler<GetWxmpSubscribMessageTemplatesQuery, GetWxmpSubscribMessageTemplatesQueryResult> { private readonly WxmpUtils utils = utils; /// <summary> /// 查询微信小程序订阅消息模板 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetWxmpSubscribMessageTemplatesQueryResult> Handle(GetWxmpSubscribMessageTemplatesQuery request, CancellationToken cancellationToken) { var res = await utils.GetWxmpSubscribMessageTemplate(new GetWxmpSubscribMessageTemplatesRequest { WxmpCode = request.WxmpCode }); return res.Adapt<GetWxmpSubscribMessageTemplatesQueryResult>(); } } } ApiTools.Core/ApiTools.Core.csproj
@@ -39,8 +39,4 @@ </None> </ItemGroup> <ItemGroup> <Folder Include="Models\WxmpUtils\Queries\" /> </ItemGroup> </Project> ApiTools.Core/ApiTools.Core.xml
@@ -1280,31 +1280,6 @@ 状态 </summary> </member> <member name="T:ApiTools.Core.WxSetting"> <summary> 微信配置 </summary> </member> <member name="P:ApiTools.Core.WxSetting.Code"> <summary> 编号 </summary> </member> <member name="P:ApiTools.Core.WxSetting.AppId"> <summary> 小程序ID </summary> </member> <member name="P:ApiTools.Core.WxSetting.AppSecret"> <summary> 小程序密钥 </summary> </member> <member name="P:ApiTools.Core.WxSetting.EnvVersion"> <summary> 版本 </summary> </member> <member name="F:ApiTools.Core.EnumErrorCodeType.s400"> <summary> 参数错误 @@ -1525,7 +1500,7 @@ 短信工具 </summary> </member> <member name="F:ApiTools.Core.EnumResourceController.CommonServerWxUtils"> <member name="F:ApiTools.Core.EnumResourceController.CommonServerWxmpUtils"> <summary> 微信工具 </summary> @@ -1957,6 +1932,41 @@ 转账 </summary> </member> <member name="T:ApiTools.Core.EnumWxmpSubscribMessageTemplate"> <summary> 微信小程序订阅消息模板 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.SettlementCompletedToSupplier"> <summary> 支付成功提醒 结算完成后向承揽端管理员推送 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.SettlementAuditCompletedToSupplier"> <summary> 报酬结算审核结果通知 甲方结算确认后向承揽端管理员推送 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.SettlementReceiveCompletedToUser"> <summary> 工资发放通知 结算完成后向C端人员通知 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.HireCompletedToUser"> <summary> 报名录用结果通知 被录用后向C端人员通知 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.ArrangeCompletedToUser"> <summary> 排班成功通知 排班后向C端人员通知 </summary> </member> <member name="F:ApiTools.Core.EnumWxmpSubscribMessageTemplate.Test"> <summary> 测试 </summary> </member> <member name="T:ApiTools.Core.IIsDisabled"> <summary> 是否已禁用 @@ -2001,6 +2011,16 @@ <member name="P:ApiTools.Core.ITreeData`1.Code"> <summary> 编号 </summary> </member> <member name="T:ApiTools.Core.Jobs.RefreshChannelWalletSignStatusJob"> <summary> 刷新渠道钱包状态 </summary> </member> <member name="M:ApiTools.Core.Jobs.RefreshChannelWalletSignStatusJob.#ctor(ApiTools.Core.ChannelWalletRepository,ApiTools.Core.ChannelWalletService)"> <summary> 刷新渠道钱包状态 </summary> </member> <member name="T:ApiTools.Core.RefreshChannelWalletTransactionStatusJob"> @@ -3268,64 +3288,109 @@ 签名名称 </summary> </member> <member name="T:ApiTools.Core.SaveWxSendCommand"> <member name="T:ApiTools.Core.SendWxmpSubscribMessageCommand"> <summary> 该接口用于发送订阅消息 微信小程序发送订阅消息 </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.WxmpCode"> <member name="P:ApiTools.Core.SendWxmpSubscribMessageCommand.WxmpCode"> <summary> 小程序编号 </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.EnvVersion"> <summary> 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。 </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.template_id"> <member name="P:ApiTools.Core.SendWxmpSubscribMessageCommand.TemplateId"> <summary> 所需下发的订阅模板id </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.page"> <member name="P:ApiTools.Core.SendWxmpSubscribMessageCommand.Page"> <summary> 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.touser"> <member name="P:ApiTools.Core.SendWxmpSubscribMessageCommand.Touser"> <summary> 接收者(用户)的 openid </summary> </member> <member name="P:ApiTools.Core.SaveWxSendCommand.data"> <member name="P:ApiTools.Core.SendWxmpSubscribMessageCommand.Data"> <summary> 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } </summary> </member> <member name="T:ApiTools.Core.SaveWxSettingCommand"> <member name="T:ApiTools.Core.WxmpSubscribMessageNotifyCommand"> <summary> 保存微信配置 微信小程序订阅消息通知 </summary> </member> <member name="P:ApiTools.Core.SaveWxSettingCommand.Code"> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesQuery"> <summary> 编号 查询微信小程序订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.SaveWxSettingCommand.AppId"> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQuery.WxmpCode"> <summary> 小程序ID 小程序编号 </summary> </member> <member name="P:ApiTools.Core.SaveWxSettingCommand.AppSecret"> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResult"> <summary> 小程序密钥 查询微信小程序订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.SaveWxSettingCommand.EnvVersion"> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResult.Items"> <summary> 版本 项 </summary> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.TemplateId"> <summary> 添加至账号下的模板 id,发送小程序订阅消息时所需 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.Title"> <summary> 模版标题 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.Content"> <summary> 模版内容 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.Example"> <summary> 模板内容示例 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.Type"> <summary> 模版类型,2 为一次性订阅,3 为长期订阅 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultData.Values"> <summary> 枚举参数值范围 </summary> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultDataValue"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultDataValue.Code"> <summary> 枚举参数的 key </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesQueryResultDataValue.Values"> <summary> 枚举参数值范围列表 </summary> </member> <member name="M:ApiTools.Core.BaseRepository`2.GetQueryable(System.Boolean)"> @@ -6909,6 +6974,86 @@ </summary> <returns></returns> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesRequest"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesRequest.WxmpCode"> <summary> 小程序编号 </summary> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponse"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponse.ErrorCode"> <summary> 错误码 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponse.ErrorMessage"> <summary> 错误信息 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponse.Items"> <summary> 模板列表 </summary> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.TemplateId"> <summary> 添加至账号下的模板 id,发送小程序订阅消息时所需 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.Title"> <summary> 模版标题 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.Content"> <summary> 模版内容 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.Example"> <summary> 模板内容示例 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.Type"> <summary> 模版类型,2 为一次性订阅,3 为长期订阅 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseData.Values"> <summary> 枚举参数值范围 </summary> </member> <member name="T:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseDataValue"> <summary> 微信小程序获取订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseDataValue.Code"> <summary> 枚举参数的 key </summary> </member> <member name="P:ApiTools.Core.GetWxmpSubscribMessageTemplatesResponseDataValue.Values"> <summary> 枚举参数值范围列表 </summary> </member> <member name="T:ApiTools.Core.WxmpGetQrCodeCommand"> <summary> 小程序获取二维码 @@ -6990,49 +7135,24 @@ 错误信息 </summary> </member> <member name="T:ApiTools.Core.SendRequest"> <summary> 发送订阅消息 </summary> </member> <member name="P:ApiTools.Core.SendRequest.WxmpCode"> <summary> 小程序编号 </summary> </member> <member name="P:ApiTools.Core.SendRequest.EnvVersion"> <summary> 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。 </summary> </member> <member name="P:ApiTools.Core.SendRequest.template_id"> <summary> 所需下发的订阅模板id </summary> </member> <member name="P:ApiTools.Core.SendRequest.page"> <summary> 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 </summary> </member> <member name="P:ApiTools.Core.SendRequest.touser"> <summary> 接收者(用户)的 openid </summary> </member> <member name="P:ApiTools.Core.SendRequest.data"> <summary> 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } </summary> </member> <member name="T:ApiTools.Core.SendResponse"> <summary> 发送订阅消息-结果 </summary> </member> <member name="T:ApiTools.Core.WxmpOptions"> <summary> 微信小程序配置 </summary> </member> <member name="P:ApiTools.Core.WxmpOptions.SubscribMessageTemplates"> <summary> 订阅消息模板 </summary> </member> <member name="P:ApiTools.Core.WxmpOptionsSubscribMessageTemplate.TemplateId"> <summary> 模板Id </summary> </member> <member name="P:ApiTools.Core.WxmpOptionsSubscribMessageTemplate.Page"> <summary> 页面 </summary> </member> <member name="P:ApiTools.Core.WxmpOptionsItem.Code"> @@ -7055,6 +7175,61 @@ 版本 </summary> </member> <member name="T:ApiTools.Core.WxmpSendSubscribMessageRequest"> <summary> 微信小程序发送订阅消息 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.WxmpCode"> <summary> 小程序编号 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.TemplateId"> <summary> 所需下发的订阅模板id </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.Page"> <summary> 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.Touser"> <summary> 接收者(用户)的 openid </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.Data"> <summary> 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.EnvVersion"> <summary> 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageRequest.Lang"> <summary> 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN </summary> </member> <member name="T:ApiTools.Core.WxmpSendSubscribMessageResponse"> <summary> 微信小程序发送订阅消息 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageResponse.ErrorCode"> <summary> 错误码 </summary> </member> <member name="P:ApiTools.Core.WxmpSendSubscribMessageResponse.ErrorMessage"> <summary> 错误信息 </summary> </member> <member name="T:ApiTools.Core.WxmpUtils"> <summary> 微信小程序工具 @@ -7074,9 +7249,16 @@ <param name="command"></param> <returns></returns> </member> <member name="M:ApiTools.Core.WxmpUtils.WxSend(ApiTools.Core.SendRequest)"> <member name="M:ApiTools.Core.WxmpUtils.GetWxmpSubscribMessageTemplate(ApiTools.Core.GetWxmpSubscribMessageTemplatesRequest)"> <summary> 该接口用于发送订阅消息 查询订阅消息模板 </summary> <param name="command"></param> <returns></returns> </member> <member name="M:ApiTools.Core.WxmpUtils.WxmpSendSubscribMessage(ApiTools.Core.WxmpSendSubscribMessageRequest)"> <summary> 发送订阅消息 </summary> <param name="command"></param> <returns></returns> ApiTools.Core/Entities/WxmpUtils/WxSetting.cs
File was deleted ApiTools.Core/Enums/Resources/EnumResourceController.cs
@@ -35,8 +35,8 @@ /// <summary> /// 微信工具 /// </summary> [ResourceController(EnumResourceService.CommonServer, "Wx")] CommonServerWxUtils, [ResourceController(EnumResourceService.CommonServer, "Wxmp")] CommonServerWxmpUtils, /// <summary> /// 用户认证 ApiTools.Core/Enums/WxmpUtils/EnumWxmpSubscribMessageTemplate.cs
New file @@ -0,0 +1,39 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 微信小程序订阅消息模板 /// </summary> public enum EnumWxmpSubscribMessageTemplate { /// <summary> /// 支付成功提醒 结算完成后向承揽端管理员推送 /// </summary> SettlementCompletedToSupplier, /// <summary> /// 报酬结算审核结果通知 甲方结算确认后向承揽端管理员推送 /// </summary> SettlementAuditCompletedToSupplier, /// <summary> /// 工资发放通知 结算完成后向C端人员通知 /// </summary> SettlementReceiveCompletedToUser, /// <summary> /// 报名录用结果通知 被录用后向C端人员通知 /// </summary> HireCompletedToUser, /// <summary> /// 排班成功通知 排班后向C端人员通知 /// </summary> ArrangeCompletedToUser, /// <summary> /// 测试 /// </summary> Test, } } ApiTools.Core/Jobs/RefreshChannelWalletSignStatusJob.cs
New file @@ -0,0 +1,45 @@ using Furion; using Furion.Schedule; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ApiTools.Core.Jobs { /// <summary> /// 刷新渠道钱包状态 /// </summary> [JobDetail("RefreshChannelWalletSignStatusJob", Description = "刷新渠道钱包状态", Concurrent = false)] [PeriodMinutes(5)] public class RefreshChannelWalletSignStatusJob( ChannelWalletRepository channelWalletRepository, ChannelWalletService channelWalletService ) : IJob { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelWalletService channelWalletService = channelWalletService; public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { var env = App.GetConfig<string>("Environment"); if (env != "Local") { var wallets = await channelWalletRepository.GetQueryable() .Where(it => it.Identity != null && it.Identity != "" && it.SignStatus < EnumWalletSignStatus.Normal) .ToListAsync(); foreach (var wallet in wallets) { await channelWalletService.GetEnterpriseWalletBalance(wallet); } await channelWalletRepository.UpdateNowAsync(wallets); } } } } ApiTools.Core/Models/WxmpUtils/Commands/SaveWxSendCommand.cs
File was deleted ApiTools.Core/Models/WxmpUtils/Commands/SaveWxSettingCommand.cs
File was deleted ApiTools.Core/Models/WxmpUtils/Commands/SendWxmpSubscribMessageCommand.cs
New file @@ -0,0 +1,47 @@ using MediatR; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 微信小程序发送订阅消息 /// </summary> [Resource([EnumResourceController.CommonServerWxmpUtils])] public class SendWxmpSubscribMessageCommand : IRequest<Guid> { /// <summary> /// 小程序编号 /// </summary> [Required] public string WxmpCode { get; set; } /// <summary> /// 所需下发的订阅模板id /// </summary> [Required] public string TemplateId { get; set; } /// <summary> /// 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 /// </summary> public string Page { get; set; } /// <summary> /// 接收者(用户)的 openid /// </summary> [Required] public string Touser { get; set; } /// <summary> /// 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } /// </summary> [Required] public object Data { get; set; } } } ApiTools.Core/Models/WxmpUtils/Commands/WxmpSubscribMessageNotifyCommand.cs
New file @@ -0,0 +1,22 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 微信小程序订阅消息通知 /// </summary> [Resource([EnumResourceController.CommonServerWxmpUtils], Method = EnumResourceMethod.Post)] public class WxmpSubscribMessageNotifyCommand : IRequest<bool> { public string ToUserName { get; set; } public string FromUserName { get; set; } public DateTime CreateTime { get; set; } public string MsgType { get; set; } public string Event { get; set; } } } ApiTools.Core/Models/WxmpUtils/Queries/GetWxmpSubscribMessageTemplatesQuery.cs
New file @@ -0,0 +1,85 @@ using MediatR; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 查询微信小程序订阅消息模板 /// </summary> [Resource([EnumResourceController.CommonServerWxmpUtils])] public class GetWxmpSubscribMessageTemplatesQuery : IRequest<GetWxmpSubscribMessageTemplatesQueryResult> { /// <summary> /// 小程序编号 /// </summary> public string WxmpCode { get; set; } } /// <summary> /// 查询微信小程序订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesQueryResult { /// <summary> /// 项 /// </summary> public List<GetWxmpSubscribMessageTemplatesQueryResultData> Items { get; set; } = []; } /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesQueryResultData { /// <summary> /// 添加至账号下的模板 id,发送小程序订阅消息时所需 /// </summary> public string TemplateId { get; set; } /// <summary> /// 模版标题 /// </summary> public string Title { get; set; } /// <summary> /// 模版内容 /// </summary> public string Content { get; set; } /// <summary> /// 模板内容示例 /// </summary> public string Example { get; set; } /// <summary> /// 模版类型,2 为一次性订阅,3 为长期订阅 /// </summary> public int Type { get; set; } /// <summary> /// 枚举参数值范围 /// </summary> public List<GetWxmpSubscribMessageTemplatesQueryResultDataValue> Values { get; set; } = []; } /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesQueryResultDataValue { /// <summary> /// 枚举参数的 key /// </summary> public string Code { get; set; } /// <summary> /// 枚举参数值范围列表 /// </summary> public List<string> Values { get; set; } = []; } } ApiTools.Core/Services/ChannelPingAnPayWalletService.cs
@@ -69,7 +69,7 @@ /// <returns></returns> public async Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction) { transaction.PingAnPay = new ChannelWalletTransactionPingAnPay(); transaction.PingAnPay = transaction.PingAnPay ?? new ChannelWalletTransactionPingAnPay(); var responseStop = await utils.StopPaymentAndSettlementAccounts(new StopPaymentAndSettlementAccountsRequest { CnsmrSeqNo = transaction.Code, @@ -167,6 +167,15 @@ /// <returns></returns> public async Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction) { if (transaction.CreatedTime.AddSeconds(30) < DateTime.Now && transaction.ReceiveAccount == "1234123412341234") { transaction.TransactionStatus = EnumWalletTransactionStatus.Fail; transaction.ErrorCode = "500"; transaction.FailReason = "卡号不正确"; await channelWalletTransactionRepository.UpdateNowAsync(transaction); return; } var response = await utils.CorSingleTransferQuery(new CorSingleTransferQueryRequest { OrigThirdVoucher = transaction.Code, ApiTools.Core/Utils/WxmpUtils/GetWxmpSubscribMessageTemplatesRequest.cs
New file @@ -0,0 +1,104 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesRequest { /// <summary> /// 小程序编号 /// </summary> public string WxmpCode { get; set; } } /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesResponse { /// <summary> /// 错误码 /// </summary> [JsonProperty("errcode")] public int ErrorCode { get; set; } /// <summary> /// 错误信息 /// </summary> [JsonProperty("errmsg")] public string ErrorMessage { get; set; } /// <summary> /// 模板列表 /// </summary> [JsonProperty("data")] public List<GetWxmpSubscribMessageTemplatesResponseData> Items { get; set; } = []; } /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesResponseData { /// <summary> /// 添加至账号下的模板 id,发送小程序订阅消息时所需 /// </summary> [JsonProperty("priTmplId")] public string TemplateId { get; set; } /// <summary> /// 模版标题 /// </summary> [JsonProperty("title")] public string Title { get; set; } /// <summary> /// 模版内容 /// </summary> [JsonProperty("content")] public string Content { get; set; } /// <summary> /// 模板内容示例 /// </summary> [JsonProperty("example")] public string Example { get; set; } /// <summary> /// 模版类型,2 为一次性订阅,3 为长期订阅 /// </summary> [JsonProperty("type")] public int Type { get; set; } /// <summary> /// 枚举参数值范围 /// </summary> [JsonProperty("keywordEnumValueList")] public List<GetWxmpSubscribMessageTemplatesResponseDataValue> Values { get; set; } = []; } /// <summary> /// 微信小程序获取订阅消息模板 /// </summary> public class GetWxmpSubscribMessageTemplatesResponseDataValue { /// <summary> /// 枚举参数的 key /// </summary> [JsonProperty("keywordCode")] public string Code { get; set; } /// <summary> /// 枚举参数值范围列表 /// </summary> [JsonProperty("enumValueList")] public List<string> Values { get; set; } = []; } } ApiTools.Core/Utils/WxmpUtils/WxmpGetQrCodeRequest.cs
@@ -106,73 +106,4 @@ public string ErrorMessage { get; set; } } /// <summary> /// 发送订阅消息 /// </summary> public class SendRequest { /// <summary> /// 小程序编号 /// </summary> [JsonProperty("WxmpCode")] [Required] public string WxmpCode { get; set; } /// <summary> /// 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。 /// </summary> [JsonProperty("env_version")] public string EnvVersion { get; set; } /// <summary> /// 所需下发的订阅模板id /// </summary> [JsonProperty("template_id")] [Required] public string template_id { get; set; } /// <summary> /// 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 /// </summary> [JsonProperty("page")] [Required] public string page { get; set; } /// <summary> /// 接收者(用户)的 openid /// </summary> [JsonProperty("touser")] [Required] public string touser { get; set; } /// <summary> /// 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } /// </summary> [JsonProperty("data")] [Required] public object data { get; set; } [JsonProperty("跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版")] [Required] public string miniprogram_state { get; set; } [JsonProperty("进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN")] [Required] public string lang { get; set; } } /// <summary> /// 发送订阅消息-结果 /// </summary> public class SendResponse { [JsonProperty("ErrorCode")] public int ErrorCode { get; set; } [JsonProperty("errmsg")] public int errmsg { get; set; } } } ApiTools.Core/Utils/WxmpUtils/WxmpOptions.cs
@@ -18,6 +18,24 @@ } public List<WxmpOptionsItem> Items { get; set; } /// <summary> /// 订阅消息模板 /// </summary> public Dictionary<string, WxmpOptionsSubscribMessageTemplate> SubscribMessageTemplates { get; set; } = []; } public class WxmpOptionsSubscribMessageTemplate { /// <summary> /// 模板Id /// </summary> public string TemplateId { get; set; } /// <summary> /// 页面 /// </summary> public string Page { get; set; } } public class WxmpOptionsItem ApiTools.Core/Utils/WxmpUtils/WxmpSendSubscribMessageRequest.cs
New file @@ -0,0 +1,80 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 微信小程序发送订阅消息 /// </summary> public class WxmpSendSubscribMessageRequest { /// <summary> /// 小程序编号 /// </summary> [JsonIgnore] public string WxmpCode { get; set; } /// <summary> /// 所需下发的订阅模板id /// </summary> [JsonProperty("template_id")] [Required] public string TemplateId { get; set; } /// <summary> /// 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转 /// </summary> [JsonProperty("page")] public string Page { get; set; } /// <summary> /// 接收者(用户)的 openid /// </summary> [JsonProperty("touser")] [Required] public string Touser { get; set; } /// <summary> /// 模板内容,格式形如{ "phrase3": { "value": "审核通过" }, "name1": { "value": "订阅" }, "date2": { "value": "2019-12-25 09:42" } } /// </summary> [JsonProperty("data")] [Required] public object Data { get; set; } /// <summary> /// 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 /// </summary> [JsonProperty("miniprogram_state")] [Required] public string EnvVersion { get; set; } /// <summary> /// 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN /// </summary> [JsonProperty("lang")] [Required] public string Lang { get; set; } = "zh_CN"; } /// <summary> /// 微信小程序发送订阅消息 /// </summary> public class WxmpSendSubscribMessageResponse { /// <summary> /// 错误码 /// </summary> [JsonProperty("errcode")] public int ErrorCode { get; set; } /// <summary> /// 错误信息 /// </summary> [JsonProperty("errmsg")] public string ErrorMessage { get; set; } } } ApiTools.Core/Utils/WxmpUtils/WxmpUtils.cs
@@ -4,6 +4,7 @@ using Azure.Core; using Furion.FriendlyException; using Furion.HttpRemote; using Furion.JsonSerialization; using Mapster; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; @@ -15,8 +16,10 @@ using System.Net.Http.Json; using System.Text; using System.Text.Json.Nodes; using System.Text.Unicode; using System.Threading; using System.Threading.Tasks; using static System.Net.Mime.MediaTypeNames; namespace ApiTools.Core { @@ -127,19 +130,44 @@ } /// <summary> /// 该接口用于发送订阅消息 /// 查询订阅消息模板 /// </summary> /// <param name="command"></param> /// <returns></returns> public async Task<string> WxSend(SendRequest command) public async Task<GetWxmpSubscribMessageTemplatesResponse> GetWxmpSubscribMessageTemplate(GetWxmpSubscribMessageTemplatesRequest command) { var option = options.Value.Items.FirstOrDefault(it => it.Code == command.WxmpCode); if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull()) throw Oops.Oh(EnumErrorCodeType.s400, "获取小程序码失败,缺失配置:WxmpOptions"); command.EnvVersion = option.EnvVersion; throw Oops.Oh(EnumErrorCodeType.s400, "发送订阅消息失败,缺失配置:WxmpOptions"); var accessToken = await GetAccessToken(command.WxmpCode); var request = command.Adapt<SendRequest>(); var jsonContent = JsonConvert.SerializeObject(request, new JsonSerializerSettings var jsonContent = JsonConvert.SerializeObject(command, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); var response = await httpRemoteService.GetAsAsync<GetWxmpSubscribMessageTemplatesResponse>( "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate", builder => builder.WithQueryParameter("access_token", accessToken)); return response; } /// <summary> /// 发送订阅消息 /// </summary> /// <param name="command"></param> /// <returns></returns> public async Task WxmpSendSubscribMessage(WxmpSendSubscribMessageRequest command) { var option = options.Value.Items.FirstOrDefault(it => it.Code == command.WxmpCode); if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull()) throw Oops.Oh(EnumErrorCodeType.s400, "发送订阅消息失败,缺失配置:WxmpOptions"); command.EnvVersion = option.EnvVersion; //if (!options.Value.SubscribMessageTemplates.ContainsKey(command.TemplateId)) // throw Oops.Oh(EnumErrorCodeType.s400, "发送订阅消息失败,模板不存在"); //var template = options.Value.SubscribMessageTemplates[command.TemplateId]; //command.TemplateId = template.TemplateId; //if (command.Page.IsNull()) command.Page = template.Page; var accessToken = await GetAccessToken(command.WxmpCode); var jsonContent = JsonConvert.SerializeObject(command, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); @@ -151,16 +179,10 @@ if (response.Content.Headers.ContentType.ToString() == "application/json; charset=UTF-8") { var jsonResult = await response.Content.ReadAsStringAsync(); var callback = jsonResult.JsonTo<SendResponse>(); var callback = jsonResult.JsonTo<WxmpSendSubscribMessageResponse>(); if (callback == null || callback.ErrorCode != 0) //throw Oops.Oh(EnumErrorCodeType.s510, $"获取小程序码失败:{callback.errmsg},请联系管理员"); return jsonResult; throw Oops.Oh(EnumErrorCodeType.s510, $"发送订阅消息失败:{callback.ErrorMessage},请联系管理员"); } //var stream = await response.Content.ReadAsStreamAsync(); //var result = AliyunOSSUtils.Upload(command, stream, command.OssFileName); return ""; } } } ApiTools.Web.Entry/appsettings.json
@@ -51,8 +51,46 @@ "AppId": "wx3669dd12a0915f7d", "AppSecret": "c03a62ad6822f1c925532c34183e7f7f", "EnvVersion": "trial" }, { "Code": "Public", "AppId": "wxf940ff1d35a98493", "AppSecret": "9a132eda735bc925200b0e215cffe20a", "EnvVersion": "trial" } ] ], "SubscribMessageTemplates": { // 支付成功提醒 结算完成后向承揽端管理员推送 "SettlementCompletedToSupplier": { "TemplateId": "dz2HCc-EnR4WEfsuj2GuduF8SLu40J83xez1bLLbaC0", "Page": "pages/workbenches/workbenches" }, // 报酬结算审核结果通知 甲方结算确认后向承揽端管理员推送 "SettlementAuditCompletedToSupplier": { "TemplateId": "Qp6cetvhwONMS1y9LOBt4dZgq49Hc14lIsm-LVE0Hfo", "Page": "pages/workbenches/workbenches" }, // 工资发放通知 结算完成后向C端人员通知 "SettlementReceiveCompletedToUser": { "TemplateId": "pw-WntZZJjADXfLsxcs5S8pKlpTrSc-HtJs0ZZvqliE", "Page": "pages/home/index" }, // 报名录用结果通知 被录用后向C端人员通知 "HireCompletedToUser": { "TemplateId": "dz2HCc-EnR4WEfsuj2GuduF8SLu40J83xez1bLLbaC0", "Page": "pages/home/index" }, // 排班成功通知 排班后向C端人员通知 "ArrangeCompletedToUser": { "TemplateId": "dz2HCc-EnR4WEfsuj2GuduF8SLu40J83xez1bLLbaC0", "Page": "pages/home/index" }, // 测试 "Test": { "TemplateId": "T7Gta6H6TROZjcqeSWVTG2wWGGInWh0fGTOgCCgVBuk", "Page": "pages/home/index" } } }, "Task": { "SettlementTime": "T0"