新增小程序扫描打开接口

This commit is contained in:
youngq 2024-11-29 16:24:32 +08:00
parent e55edf4c63
commit 82aede3b9d
8 changed files with 191 additions and 1 deletions

View File

@ -1,5 +1,6 @@
using AgoraIO.Media;
using AgoraIO.Rtm;
using Azure;
using Mapster;
using Masuit.Tools;
using Microsoft.AspNetCore.Mvc;
@ -8,10 +9,12 @@ using MiniExcelLibs.Attributes;
using MiniExcelLibs.OpenXml;
using SqlSugar;
using System.IO;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers;
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.MiniProgram;
using WGShare.Domain.DTOs.Room;
using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
@ -35,6 +38,7 @@ namespace WGShare.API.Controllers.Frontend
private readonly AgoraHelper _agoraHelper;
private readonly ILogger<HomeController> _logger;
private readonly OssHelper _ossHelper;
private readonly MiniProgramHelper _miniProgramHelper;
public HomeController(
ISqlSugarClient sqlSugar,
@ -42,7 +46,8 @@ namespace WGShare.API.Controllers.Frontend
IHttpClientFactory httpClientFactory,
AgoraHelper agoraHelper,
ILogger<HomeController> logger,
OssHelper ossHelper)
OssHelper ossHelper,
MiniProgramHelper miniProgramHelper)
{
_sqlSugar = sqlSugar;
this._configuration = configuration;
@ -50,6 +55,7 @@ namespace WGShare.API.Controllers.Frontend
this._agoraHelper = agoraHelper;
this._logger = logger;
this._ossHelper = ossHelper;
this._miniProgramHelper = miniProgramHelper;
}
@ -291,5 +297,58 @@ namespace WGShare.API.Controllers.Frontend
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
return _ossHelper.GetAccessFileUrl(fileName, 5);
}
/// <summary>
/// 获取房间二维码缓存10mins
/// </summary>
/// <param name="roomNum"></param>
/// <returns></returns>
[HttpGet("r-qrcode")]
public async Task<string> GetMiniProgramQrCode([FromQuery] string roomNum, [FromQuery] string env = "release")
{
var img = RedisHelper.Instance.Get(RedisKeyConstant.WxMiniProgram.GetRoomQrCode(roomNum, env));
if (!string.IsNullOrWhiteSpace(img))
{
return img;
}
var httpClient = _httpClientFactory.CreateClient();
var accessToken = await _miniProgramHelper.GetAccessToken();
var result = await httpClient.PostAsync($@"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={accessToken}", new StringContent(new wxacodeunlimitBody
{
page = "pages/form/index",
scene = ("r=" + roomNum),
check_path = true,
env_version = env,
width = 280
}.ToJsonString()));
if (result == null || !result.IsSuccessStatusCode)
{
_logger.LogError($@"二维码生成失败,statusCode:{(int)result.StatusCode},content:{await result.Content.ReadAsStringAsync()}");
throw Oops.Oh("二维码生成失败!");
}
var contentType = result.Content.Headers.ContentType?.MediaType;
// 如果是图片类型
if (contentType != null && contentType.StartsWith("image/"))
{
// 处理图片数据
var imageArr = await result.Content.ReadAsByteArrayAsync();
var imgStr = Convert.ToBase64String(imageArr);
RedisHelper.Instance.Set(RedisKeyConstant.WxMiniProgram.GetRoomQrCode(roomNum, env), imgStr, TimeSpan.FromMinutes(10));
return imgStr;
}
else if (contentType != null && contentType.Contains("json"))
{
var apiResult = await result.Content.ReadFromJsonAsync<WxMiniProgramBaseApiResult>();
if (apiResult != null)
{
_logger.LogError($"二维码生成失败,errorCode:{apiResult.errorcode},errmsg:{apiResult.errmsg}");
throw Oops.Oh("二维码生成失败");
}
}
_logger.LogError("返回 ContentType 未命中");
throw Oops.Oh("二维码生成失败");
}
}
}

View File

@ -0,0 +1,59 @@
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.MiniProgram;
using WGShare.Domain.FriendlyException;
namespace WGShare.API.Helpers
{
/// <summary>
/// 小程序帮助类
/// </summary>
public class MiniProgramHelper
{
private readonly IConfiguration _configuration;
public MiniProgramHelper(IConfiguration configuration)
{
this._configuration = configuration;
}
/// <summary>
/// 获取access_token
/// </summary>
/// <returns></returns>
public async Task<string> GetAccessToken()
{
var accessToken = RedisHelper.Instance.Get<string>(RedisKeyConstant.WxMiniProgram.AccessTokenKey);
if (!string.IsNullOrWhiteSpace(accessToken) )
{
return accessToken;
}
var appId = _configuration["miniProgram:appId"];
var secret = _configuration["miniProgram:appSecret"];
using var httpClient = new HttpClient();
var result = await httpClient.GetAsync($@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}");
if (result == null || !result.IsSuccessStatusCode)
{
Console.WriteLine($@"微信服务器授权失败,{result.StatusCode},{await result.Content.ReadAsStringAsync()}");
throw Oops.Oh("微信服务器授权失败");
}
var apiResult = await result.Content.ReadFromJsonAsync<AccessTokenApiResult>();
if (apiResult == null)
{
Console.WriteLine($@"微信服务器授权失败,接口返回数据解析失败");
throw Oops.Oh("微信服务器授权失败");
}
if (apiResult.errorcode != 0)
{
Console.WriteLine($@"微信服务器授权失败,errorCode:{apiResult.errorcode},errmsg:{apiResult.errmsg}");
throw Oops.Oh("微信服务器授权失败");
}
RedisHelper.Instance.Set(RedisKeyConstant.WxMiniProgram.AccessTokenKey, apiResult.access_token, TimeSpan.FromSeconds(apiResult.expires_in - 60));
return apiResult.access_token;
}
}
}

View File

@ -65,6 +65,7 @@ namespace WGShare.API
builder.Services.ConfigureHangfire();
builder.Services.AddSingleton(new JwtHelper(configuration));
builder.Services.AddSingleton(new AgoraHelper(configuration));
builder.Services.AddSingleton(new MiniProgramHelper(configuration));
builder.Services.AddSingleton(new OssHelper(configuration));
builder.Services.AddHostedService<AgoraCallbackComsuerService>();
builder.Services.AddAuth(configuration["Jwt:Issuer"],

View File

@ -144,6 +144,13 @@
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.GetMiniProgramQrCode(System.String,System.String)">
<summary>
获取房间二维码
</summary>
<param name="roomNum"></param>
<returns></returns>
</member>
<member name="T:WGShare.API.Controllers.Frontend.RoomController">
<summary>
会议室接口
@ -471,6 +478,17 @@
<returns></returns>
<exception cref="T:System.ArgumentException"></exception>
</member>
<member name="T:WGShare.API.Helpers.MiniProgramHelper">
<summary>
小程序帮助类
</summary>
</member>
<member name="M:WGShare.API.Helpers.MiniProgramHelper.GetAccessToken">
<summary>
获取access_token
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Helpers.OssHelper.GetUploadUrl(System.String,System.String,System.UInt32)">
<summary>
获取上传url

View File

@ -86,5 +86,12 @@ namespace WGShare.Domain.Constant
{
public static string MeetingRecord => "meeting_record";
}
public class WxMiniProgram
{
public static string AccessTokenKey => $@"wx_mini_program:accessToken";
public static string GetRoomQrCode(string roomNum, string env) => $@"wx_mini_program:room_qrcode:{env}:{roomNum}";
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.MiniProgram
{
public class AccessTokenApiResult : WxMiniProgramBaseApiResult
{
public string access_token { get; set; }
public int expires_in { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.MiniProgram
{
public class WxMiniProgramBaseApiResult
{
public int errorcode { get; set; }
public string errmsg { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.MiniProgram
{
public class wxacodeunlimitBody
{
public string scene { get; set; }
public string page { get; set; }
public bool check_path { get; set; }
public string env_version { get; set; }
public int width { get; set; }
}
}