// Admin.NET 项目的版æƒã€å•†æ ‡ã€ä¸“利和其他相关æƒåˆ©å‡å—ç›¸åº”æ³•å¾‹æ³•è§„çš„ä¿æŠ¤ã€‚ä½¿ç”¨æœ¬é¡¹ç›®åº”éµå®ˆç›¸å…³æ³•律法规和许å¯è¯çš„è¦æ±‚。 // // 本项目主è¦éµå¾ª MIT 许å¯è¯å’Œ Apache 许å¯è¯ï¼ˆç‰ˆæœ¬ 2.0)进行分å‘和使用。许å¯è¯ä½äºŽæºä»£ç æ ‘æ ¹ç›®å½•ä¸çš„ LICENSE-MIT å’Œ LICENSE-APACHE 文件。 // // ä¸å¾—利用本项目从事å±å®³å›½å®¶å®‰å…¨ã€æ‰°ä¹±ç¤¾ä¼šç§©åºã€ä¾µçŠ¯ä»–äººåˆæ³•æƒç›Šç‰æ³•å¾‹æ³•è§„ç¦æ¢çš„æ´»åЍï¼ä»»ä½•基于本项目二次开å‘è€Œäº§ç”Ÿçš„ä¸€åˆ‡æ³•å¾‹çº çº·å’Œè´£ä»»ï¼Œæˆ‘ä»¬ä¸æ‰¿æ‹…ä»»ä½•è´£ä»»ï¼ namespace Admin.NET.Core.Service; /// <summary> /// å¾®ä¿¡å…¬ä¼—å·æœåŠ¡ 🧩 /// </summary> [ApiDescriptionSettings(Order = 230)] public class SysWechatService : IDynamicApiController, ITransient { private readonly SqlSugarRepository<SysWechatUser> _sysWechatUserRep; private readonly SysConfigService _sysConfigService; private readonly WechatApiClientFactory _wechatApiClientFactory; private readonly WechatApiClient _wechatApiClient; private readonly SysCacheService _sysCacheService; public SysWechatService(SqlSugarRepository<SysWechatUser> sysWechatUserRep, SysConfigService sysConfigService, WechatApiClientFactory wechatApiClientFactory, SysCacheService sysCacheService) { _sysWechatUserRep = sysWechatUserRep; _sysConfigService = sysConfigService; _wechatApiClientFactory = wechatApiClientFactory; _wechatApiClient = wechatApiClientFactory.CreateWechatClient(); _sysCacheService = sysCacheService; } /// <summary> /// 生æˆç½‘页授æƒUrl 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [AllowAnonymous] [DisplayName("生æˆç½‘页授æƒUrl")] public string GenAuthUrl(GenAuthUrlInput input) { return _wechatApiClient.GenerateParameterizedUrlForConnectOAuth2Authorize(input.RedirectUrl, input.Scope, input.State); } /// <summary> /// 获å–微信用户OpenId 🔖 /// </summary> /// <param name="input"></param> [AllowAnonymous] [DisplayName("获å–微信用户OpenId")] public async Task<string> SnsOAuth2([FromQuery] WechatOAuth2Input input) { var reqOAuth2 = new SnsOAuth2AccessTokenRequest() { Code = input.Code, }; var resOAuth2 = await _wechatApiClient.ExecuteSnsOAuth2AccessTokenAsync(reqOAuth2); if (resOAuth2.ErrorCode != (int)WechatReturnCodeEnum.请求æˆåŠŸ) throw Oops.Oh(resOAuth2.ErrorMessage + " " + resOAuth2.ErrorCode); var wxUser = await _sysWechatUserRep.GetFirstAsync(p => p.OpenId == resOAuth2.OpenId); if (wxUser == null) { var reqUserInfo = new SnsUserInfoRequest() { OpenId = resOAuth2.OpenId, AccessToken = resOAuth2.AccessToken, }; var resUserInfo = await _wechatApiClient.ExecuteSnsUserInfoAsync(reqUserInfo); wxUser = resUserInfo.Adapt<SysWechatUser>(); wxUser.Avatar = resUserInfo.HeadImageUrl; wxUser.NickName = resUserInfo.Nickname; wxUser = await _sysWechatUserRep.AsInsertable(wxUser).ExecuteReturnEntityAsync(); } else { wxUser.AccessToken = resOAuth2.AccessToken; wxUser.RefreshToken = resOAuth2.RefreshToken; await _sysWechatUserRep.AsUpdateable(wxUser).IgnoreColumns(true).ExecuteCommandAsync(); } return resOAuth2.OpenId; } /// <summary> /// 微信用户登录OpenId 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [AllowAnonymous] [DisplayName("微信用户登录OpenId")] public async Task<dynamic> OpenIdLogin(WechatUserLogin input) { var wxUser = await _sysWechatUserRep.GetFirstAsync(p => p.OpenId == input.OpenId); if (wxUser == null) throw Oops.Oh("微信用户登录OpenId错误"); var tokenExpire = await _sysConfigService.GetTokenExpire(); return new { wxUser.Avatar, accessToken = JWTEncryption.Encrypt(new Dictionary<string, object> { { ClaimConst.UserId, wxUser.Id }, { ClaimConst.NickName, wxUser.NickName }, { ClaimConst.LoginMode, LoginModeEnum.APP }, }, tokenExpire) }; } /// <summary> /// 获å–é…ç½®ç¾å傿•°(wx.config) 🔖 /// </summary> /// <returns></returns> [DisplayName("获å–é…ç½®ç¾å傿•°(wx.config)")] public async Task<dynamic> GenConfigPara(SignatureInput input) { var resCgibinToken = await _wechatApiClient.ExecuteCgibinTokenAsync(new CgibinTokenRequest()); var request = new CgibinTicketGetTicketRequest() { AccessToken = resCgibinToken.AccessToken }; var response = await _wechatApiClient.ExecuteCgibinTicketGetTicketAsync(request); if (!response.IsSuccessful()) throw Oops.Oh(response.ErrorMessage); return _wechatApiClient.GenerateParametersForJSSDKConfig(response.Ticket, input.Url); } /// <summary> /// èŽ·å–æ¨¡æ¿åˆ—表 🔖 /// </summary> [DisplayName("èŽ·å–æ¨¡æ¿åˆ—表")] public async Task<dynamic> GetMessageTemplateList() { var accessToken = await GetCgibinToken(); var reqTemplate = new CgibinTemplateGetAllPrivateTemplateRequest() { AccessToken = accessToken }; var resTemplate = await _wechatApiClient.ExecuteCgibinTemplateGetAllPrivateTemplateAsync(reqTemplate); if (resTemplate.ErrorCode != (int)WechatReturnCodeEnum.请求æˆåŠŸ) throw Oops.Oh(resTemplate.ErrorMessage + " " + resTemplate.ErrorCode); return resTemplate.TemplateList; } /// <summary> /// å‘逿¨¡æ¿æ¶ˆæ¯ 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("å‘逿¨¡æ¿æ¶ˆæ¯")] public async Task<dynamic> SendTemplateMessage(MessageTemplateSendInput input) { var dataInfo = input.Data.ToDictionary(k => k.Key, k => k.Value); var messageData = new Dictionary<string, CgibinMessageTemplateSendRequest.Types.DataItem>(); foreach (var item in dataInfo) { messageData.Add(item.Key, new CgibinMessageTemplateSendRequest.Types.DataItem() { Value = "" + item.Value.Value.ToString() + "" }); } var accessToken = await GetCgibinToken(); var reqMessage = new CgibinMessageTemplateSendRequest() { AccessToken = accessToken, TemplateId = input.TemplateId, ToUserOpenId = input.ToUserOpenId, Url = input.Url, MiniProgram = new CgibinMessageTemplateSendRequest.Types.MiniProgram { AppId = _wechatApiClientFactory._wechatOptions.WxOpenAppId, PagePath = input.MiniProgramPagePath, }, Data = messageData }; var resMessage = await _wechatApiClient.ExecuteCgibinMessageTemplateSendAsync(reqMessage); return resMessage; } /// <summary> /// åˆ é™¤æ¨¡æ¿ ðŸ”– /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "DeleteMessageTemplate"), HttpPost] [DisplayName("åˆ é™¤æ¨¡æ¿")] public async Task<dynamic> DeleteMessageTemplate(DeleteMessageTemplateInput input) { var accessToken = await GetCgibinToken(); var reqMessage = new CgibinTemplateDeletePrivateTemplateRequest() { AccessToken = accessToken, TemplateId = input.TemplateId }; var resTemplate = await _wechatApiClient.ExecuteCgibinTemplateDeletePrivateTemplateAsync(reqMessage); return resTemplate; } /// <summary> /// 获å–Access_token /// </summary> [NonAction] public async Task<string> GetCgibinToken() { // 先从缓å˜ä¸å– AccessToken var wx_accessToken = _sysCacheService.Get<string>("sys_wx_accessToken"); if (!string.IsNullOrWhiteSpace(wx_accessToken)) { return wx_accessToken; } // è‹¥ç¼“å˜æ²¡æœ‰åˆ™ä»Žå¾®ä¿¡å…¬ä¼—å·é‡æ–°èŽ·å– AccessToken var reqCgibinToken = new CgibinTokenRequest(); var resCgibinToken = await _wechatApiClient.ExecuteCgibinTokenAsync(reqCgibinToken); if (resCgibinToken.ErrorCode != (int)WechatReturnCodeEnum.请求æˆåŠŸ) throw Oops.Oh(resCgibinToken.ErrorMessage + " " + resCgibinToken.ErrorCode); _sysCacheService.Set("sys_wx_accessToken", resCgibinToken.AccessToken, TimeSpan.FromSeconds(resCgibinToken.ExpiresIn)); // ç¼“å˜ AccessToken return resCgibinToken.AccessToken; } }