|
- using BPA.Kitchen.Core;
- using BPA.KitChen.GroupMealOrder.Core.CacheOption;
- using BPA.KitChen.WeChat.WechatServer.Dtos;
- using BPA.KitChen.WeChat.WechatServer.Service;
- using Furion;
- using Furion.DependencyInjection;
- using Furion.FriendlyException;
- using Furion.JsonSerialization;
- using Furion.RemoteRequest.Extensions;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Caching.Distributed;
- using Microsoft.Extensions.Caching.Memory;
- using System.Text;
-
- namespace Black_B_Project.Application.WechatServer.Service
- {
- /// <summary>
- /// 微信小程序服务端方法
- /// </summary>
- public class WechatService : IWechatService, ITransient
- {
- private readonly IMemoryCache _memoryCache;
- private readonly IHttpContextAccessor _httpContextAccessor;
- private readonly IDistributedCache _redisClient;
- public WechatService(IMemoryCache memoryCache, IHttpContextAccessor httpContextAccessor, IDistributedCache redisClient)
- {
- _memoryCache = memoryCache;
- _httpContextAccessor = httpContextAccessor;
- _redisClient = redisClient;
- }
- /// <summary>
- /// 解密获取用户完整信息
- /// </summary>
- /// <returns></returns>
- public WeChatUserInfo Decryptuserinfo(DecryptVM decryptVM)
- {
- WeChatUserInfo info = new();
- try
- {
- AESHelper.AesKey = decryptVM.session_key;
- AESHelper.AesIV = decryptVM.aesiv;
- string decrstr = AESHelper.AESDecrypt(decryptVM.encryptedData);
- info = JSON.Deserialize<WeChatUserInfo>(decrstr);
- }
- catch (Exception)
- {
- //BPALog.WriteLog("解析用户信息失败", LogEnum.Error, param: info);
- throw Oops.Oh("解析失败,session_key已过期");
- }
- return info;
- }
-
-
- /// <summary>
- /// 用户登录,获取openid
- /// </summary>
- /// <param name="vm"></param>
- /// <returns></returns>
- public WeChatUserInfo WxLogin(DecryptVM vm)
- {
- var appid = _httpContextAccessor.HttpContext.Request.Headers["AppId"].ToString();
- var config = ApolloApplication.Configs.Find(x => x.Key == appid);
- if (config == null)
- {
- throw Oops.Oh("AppId不能为空!");
- }
- WeChatUserInfo userinfo = new();
- if (!string.IsNullOrEmpty(vm.code))
- {
- var opt = config.WechatConfig;
- var apiUrl = $"https://api.weixin.qq.com/sns/jscode2session?appid={opt.Appid}&secret={opt.AppSecret}&js_code={vm.code}&grant_type=authorization_code";
- var response = apiUrl.GetAsStringAsync().Result;
- //todo 记录openID进入数据库
- var loginData = JSON.Deserialize<WeChatLoginModel>(response);
- if (loginData.session_key == null)
- {
- throw Oops.Oh($"登录失败,请重试!{response}");
- }
- vm.session_key = loginData.session_key;
- vm.openId = loginData.openid;
- userinfo.openId = loginData.openid;
- userinfo.session_key = loginData.session_key;
- userinfo.TmplIds.Add(config.WechatConfig.AppMessagetTakeAway);
- return userinfo;
- }
- else
- {
- throw Oops.Oh($"登录失败,请重试!");
- }
- }
- /// <summary>
- /// 获取微信token
- /// </summary>
- /// <returns></returns>
- [AllowAnonymous]
- public async Task<string> AccessToken(string appid)
- {
- var config = ApolloApplication.Configs.Find(x => x.Key == appid);
- //过期时间
- string tokenExpiresName = $"{appid}_TokenExpires";
- //数据
- string accessTokenName = $"{appid}_AccessToken";
- var expiresTimeout = await _redisClient.GetStringAsync(tokenExpiresName);
- //判断是否存在缓存
- if (expiresTimeout == null)
- {
- var opt = config.WechatConfig;
- var response = await $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={opt.Appid}&secret={opt.AppSecret}".GetAsStringAsync();
- WechatToken res = JSON.Deserialize<WechatToken>(response);
- if (!string.IsNullOrEmpty(res.access_token))
- {
- DistributedCacheEntryOptions distributedCacheEntryOptions = new();
- //Token
- await _redisClient.SetStringAsync(accessTokenName, res.access_token, distributedCacheEntryOptions);
- //存入当前时间
- var currtime = DateTime.Now;
- await _redisClient.SetStringAsync(tokenExpiresName, currtime.ToString(), distributedCacheEntryOptions);
- return res.access_token;
- }
- }
- //存在对比是否过期
- TimeSpan ts = DateTime.Now - Convert.ToDateTime(expiresTimeout);
- //如果总秒数大于6500秒,那么视为过期,重新获取
- if (ts.TotalSeconds >= 6500)
- {
- var opt = config.WechatConfig;
- var response = await $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={opt.Appid}&secret={opt.AppSecret}".GetAsStringAsync();
- WechatToken res = JSON.Deserialize<WechatToken>(response);
- if (!string.IsNullOrEmpty(res.access_token))
- {
- DistributedCacheEntryOptions distributedCacheEntryOptions = new();
- //Token
- await _redisClient.SetStringAsync(accessTokenName, res.access_token, distributedCacheEntryOptions);
- //存入当前时间
- var currtime = DateTime.Now;
- await _redisClient.SetStringAsync(tokenExpiresName, currtime.ToString(), distributedCacheEntryOptions);
- return res.access_token;
- }
- }
- else
- {
- //没过期就取
- var wechatToken = await _redisClient.GetStringAsync(accessTokenName);
- return wechatToken;
- }
- return null;
- }
- /// <summary>
- /// 发送预定通知
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- public async Task<bool> SendReserveMessage(ReserveInput input)
- {
- var config = ApolloApplication.Configs.Find(x => x.Key == input.AppId);
- try
- {
- var param = new
- {
- touser = input.OpenId,
- template_id = config.WechatConfig.AppMessagetTakeAway,
- page = "pages/homeNew/homeNew",
- data = new
- {
- time1 = new { value = input.ReserveTime },
- thing2 = new { value = input.ReserveWarning },
- }
- };
- var access_token = await AccessToken(input.AppId);
- var res = JSON.Serialize(param);
- var response = await $"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}".SetBody(res).PostAsStringAsync();
- }
- catch (Exception ex)
- {
- return false;
- }
- return true;
- }
- /// <summary>
- /// 获取手机号
- /// </summary>
- /// <param name="code"></param>
- /// <returns></returns>
- public async Task<WechatPhoneMsg> WxPhone(string code)
- {
- var appid = _httpContextAccessor.HttpContext.Request.Headers["AppId"].ToString();
- if (string.IsNullOrEmpty(code))
- {
- throw Oops.Bah("code不能为空");
- }
- if (string.IsNullOrEmpty(appid))
- {
- throw Oops.Bah("appid不能为空");
- }
- var access_token = await AccessToken(appid);
- var respones = await $"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={access_token}".SetBody(new
- {
- code
- }).PostAsStringAsync();
- WechatPhoneMsg wechatPhone = JSON.Deserialize<WechatPhoneMsg>(respones);
- return wechatPhone;
- }
- /// <summary>
- /// 发送服务号
- /// </summary>
- /// <returns></returns>
- public async Task<string> Uniform_send()
- {
-
- var token = _memoryCache.Get("weToken");
- if (token == null)
- {
- await GetWechatTokenAsync();
- token = _memoryCache.Get("weToken");
- }
- var response = await $"https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token={token.ToString()}".PostAsStreamAsync();
-
- StreamReader readStream = new StreamReader(response.Stream, Encoding.UTF8);
- var data = readStream.ReadToEnd();
- return data;
- }
- /// <summary>
- /// 获取微信token
- /// </summary>
- /// <returns></returns>
- public async Task<string> GetWechatTokenAsync()
- {
- var opt = App.GetOptions<WechatConfigOptions>();
- var response = await $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={opt.Appid}&secret={opt.AppSecret}".GetAsStreamAsync();
- StreamReader readStream = new StreamReader(response.Stream, Encoding.UTF8);
- var data = readStream.ReadToEnd();
- var res = JSON.Deserialize<WeChatTokenModel>(data);
- _memoryCache.Set("weToken", res.access_token);
- return _memoryCache.Get("weToken").ToString();
- }
- /// <summary>
- /// 用户支付完成后,获取该用户的 UnionId,无需用户授权。本接口支持第三方平台代理查询。
- /// </summary>
- /// <param name="token"></param>
- /// <param name="openid"></param>
- /// <returns></returns>
- public async Task<string> GetPaidunionid(string token, string openid)
- {
- var response = await $"https://api.weixin.qq.com/wxa/getpaidunionid?access_token={token}&openid={openid}".GetAsStreamAsync();
- StreamReader readStream = new StreamReader(response.Stream, Encoding.UTF8);
- return readStream.ReadToEnd();
- }
-
-
-
- }
- }
|