Compare commits

..

No commits in common. "master" and "feature-考勤" have entirely different histories.

54 changed files with 126 additions and 2207 deletions

View File

@ -24,23 +24,13 @@
"LinuxServerList": [ "LinuxServerList": [
{ {
"UserName": "marking", "UserName": "marking",
"Pwd": "CE09921E2AD09E56095579DF1F7C614B", "Pwd": "0610DBF49053E6779393A74BE1ED4FD2",
"Host": "47.109.67.254:10022", "Host": "47.109.67.254:10022",
"NickName": "marking001", "NickName": "marking001",
"IIsFireUrl": null, "IIsFireUrl": null,
"DockerFireUrl": "", "DockerFireUrl": "",
"WindowsServiceFireUrl": null, "WindowsServiceFireUrl": null,
"LinuxServiceFireUrl": null "LinuxServiceFireUrl": null
},
{
"UserName": "marking",
"Pwd": "CE09921E2AD09E56095579DF1F7C614B",
"Host": "47.109.193.53:10022",
"NickName": "meeting",
"IIsFireUrl": null,
"DockerFireUrl": "",
"WindowsServiceFireUrl": null,
"LinuxServiceFireUrl": null
} }
], ],
"IgnoreList": [], "IgnoreList": [],
@ -125,11 +115,11 @@
"DockerConfig": { "DockerConfig": {
"Prot": "5192:5192", "Prot": "5192:5192",
"AspNetCoreEnv": "", "AspNetCoreEnv": "",
"LastEnvName": "marking001", "LastEnvName": "29dev",
"RemoveDaysFromPublished": "10", "RemoveDaysFromPublished": "10",
"WorkDir": "", "WorkDir": "",
"Volume": "", "Volume": "",
"Other": "--name wgshare-api -e ASPNETCORE_ENVIRONMENT=Production -e TZ=Asia/Shanghai", "Other": "--name wgshare-api -e ASPNETCORE_ENVIRONMENT=Development -e TZ=Asia/Shanghai",
"EnvPairList": [ "EnvPairList": [
{ {
"EnvName": "29dev", "EnvName": "29dev",

View File

@ -32,10 +32,10 @@ namespace WGShare.API.BackgroudServices
// 离开频道消息订阅 // 离开频道消息订阅
using (RedisHelper.Instance.SubscribeList(RedisKeyConstant.PubSub.MeetingRecord, async (message) => using (RedisHelper.Instance.SubscribeList(RedisKeyConstant.PubSub.MeetingRecord, async (message) =>
{ {
_logger.LogDebug($"接受消息: {message}");
if (message == null) return; if (message == null) return;
_logger.LogDebug($"接受消息: {message}");
var body = message.ToString().FromJson<EventBody>(); var body = message.ToString().FromJson<EventBody>();
if (body == null) if (body == null)
{ {

View File

@ -12,7 +12,6 @@ using WGShare.API.Hubs;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Login; using WGShare.Domain.DTOs.Login;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
using WGShare.Domain.FriendlyException.Exceptions; using WGShare.Domain.FriendlyException.Exceptions;
@ -48,28 +47,7 @@ namespace WGShare.API.Controllers
[HttpGet("check-user"), AllowAnonymous] [HttpGet("check-user"), AllowAnonymous]
public async Task<bool> CheckUser([FromQuery] string account) public async Task<bool> CheckUser([FromQuery] string account)
{ {
return await _sqlSugar.Queryable<User>().AnyAsync(x => x.IsDelete == false && x.Account == account && x.IsAnonymous == false); return await _sqlSugar.Queryable<User>().AnyAsync(x => x.IsDelete == false && x.Account == account);
}
/// <summary>
/// 检查用户是否在线
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
[HttpGet("check-online"), AllowAnonymous]
public async Task<bool> CheckUserOnline([FromQuery] string account)
{
var user = await _sqlSugar.Queryable<User>().FirstAsync(x => x.IsDelete == false && x.Account == account && x.IsAnonymous == false);
if (user == null)
{
return false;
}
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(user.TenantId), user.Id);
if (!string.IsNullOrWhiteSpace(connectId))
{
return true;
}
return false;
} }
/// <summary> /// <summary>
@ -80,7 +58,7 @@ namespace WGShare.API.Controllers
public async Task<IActionResult> Login([FromBody] UserLoginDTO loginDTO) public async Task<IActionResult> Login([FromBody] UserLoginDTO loginDTO)
{ {
var user = await _sqlSugar.Queryable<User>() var user = await _sqlSugar.Queryable<User>()
.FirstAsync(x => x.Account == loginDTO.Account && x.IsDelete == false && x.Pwd == loginDTO.Pwd && x.IsAnonymous == false); .FirstAsync(x => x.Account == loginDTO.Account && x.IsDelete == false && x.Pwd == loginDTO.Pwd);
if (user == null) if (user == null)
{ {
throw Oops.Oh("用户名或密码不正确!"); throw Oops.Oh("用户名或密码不正确!");
@ -113,9 +91,6 @@ namespace WGShare.API.Controllers
btnAutn.Add(new Claim("account", user.Account)); btnAutn.Add(new Claim("account", user.Account));
btnAutn.Add(new Claim("uname", user.UserName)); btnAutn.Add(new Claim("uname", user.UserName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId)); btnAutn.Add(new Claim("ssid", user.ScreenShareId));
btnAutn.Add(new Claim("year", user.Year.ToString()));
btnAutn.Add(new Claim("subject", ((int)user.Subject).ToString()));
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
// 获取已登录的token // 获取已登录的token
var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(user.Id)); var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(user.Id));
@ -129,7 +104,7 @@ namespace WGShare.API.Controllers
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(tokens.RefreshToken)); pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(tokens.RefreshToken));
} }
// 设置新的刷新token // 设置新的刷新token
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(360).TotalSeconds.ToInt32()); pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
// 记录accessToken // 记录accessToken
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
{ {
@ -148,7 +123,7 @@ namespace WGShare.API.Controllers
if (!string.IsNullOrWhiteSpace(roomNum)) if (!string.IsNullOrWhiteSpace(roomNum))
{ {
await _hubContext.Clients.Group(roomNum).UserLeave(user.Id); await _hubContext.Clients.Group(roomNum).UserLeave(user.Id);
} }
await _hubContext.Clients.Client(connectId).ForceLogout("账号已在其他地方登录,您被迫下线!"); await _hubContext.Clients.Client(connectId).ForceLogout("账号已在其他地方登录,您被迫下线!");
} }
@ -163,8 +138,7 @@ namespace WGShare.API.Controllers
expire = _configuration["Jwt:Expires"].ToInt32(), expire = _configuration["Jwt:Expires"].ToInt32(),
account = user.Account, account = user.Account,
uid = user.Id, uid = user.Id,
screenShareId = user.ScreenShareId, screenShareId = user.ScreenShareId
isAnonymous = false
}); });
} }
@ -189,16 +163,13 @@ namespace WGShare.API.Controllers
btnAutn.Add(new Claim("account", user.Account)); btnAutn.Add(new Claim("account", user.Account));
btnAutn.Add(new Claim("uname", user.UserName)); btnAutn.Add(new Claim("uname", user.UserName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId)); btnAutn.Add(new Claim("ssid", user.ScreenShareId));
btnAutn.Add(new Claim("year", user.Year.ToString()));
btnAutn.Add(new Claim("subject", ((int)user.Subject).ToString()));
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn); var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
var refreshTokenNew = Guid.NewGuid().ToString(); var refreshTokenNew = Guid.NewGuid().ToString();
using (var pipe = RedisHelper.Instance.StartPipe()) using (var pipe = RedisHelper.Instance.StartPipe())
{ {
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken)); pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(360).TotalSeconds.ToInt32()); pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
{ {
AccessToken = accessToken, AccessToken = accessToken,
@ -219,12 +190,11 @@ namespace WGShare.API.Controllers
expire = _configuration["Jwt:Expires"].ToInt32(), expire = _configuration["Jwt:Expires"].ToInt32(),
account = user.Account, account = user.Account,
uid = user.Id, uid = user.Id,
screenShareId = user.ScreenShareId, screenShareId = user.ScreenShareId
isAnonymous = false
}); });
} }
/// <summary> /// <summary>
/// 登出(暂未处理任何业务逻辑) /// 登出(暂未处理任何业务逻辑)
/// </summary> /// </summary>
@ -235,76 +205,6 @@ namespace WGShare.API.Controllers
return true; return true;
} }
/// <summary>
/// 匿名登录
/// </summary>
/// <param name="loginDTO"></param>
/// <returns></returns>
[HttpPost("anon-login"), AllowAnonymous]
public async Task<IActionResult> AnonymousLogin([FromBody] AnonymousUserLoginDTO loginDTO)
{
var room = await _sqlSugar.Queryable<Room>().Where(x => x.RoomNum == loginDTO.RoomNum && x.IsDelete == false).FirstAsync();
if (room == null)
{
throw Oops.Oh("房间不存在!");
}
var user = await _sqlSugar.Queryable<User>().Where(x => x.Account == loginDTO.DeviceId).FirstAsync();
if (user == null)
{
// 用户不存在,创建
user = new User
{
Account = loginDTO.DeviceId,
IsDelete = false,
IsAnonymous = true,
Pwd = "123456",
RoleId = "2",
UserName = loginDTO.NickName,
ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(),
TenantId = "123456",
};
user.Id = (await _sqlSugar.Insertable(user).ExecuteReturnIdentityAsync()).ToString();
}
else
{
if (user.IsDelete)
{
throw Oops.Oh("该设备已禁止登录!");
}
// 修改用户名
await _sqlSugar.Updateable<User>()
.SetColumns(x => x.UserName == loginDTO.NickName)
.Where(x => x.Id == user.Id)
.ExecuteCommandHasChangeAsync();
}
var btnAutn = new List<Claim>();
btnAutn.Add(new Claim("perm", "0"));
btnAutn.Add(new Claim("roleid", "2"));
btnAutn.Add(new Claim("tenant", room.TenantId));
btnAutn.Add(new Claim("account", user.Account));
btnAutn.Add(new Claim("uname", loginDTO.NickName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
return Ok(new
{
perms = 0,
token = accessToken,
refresh_token = "",
roleId = user.RoleId,
userName = loginDTO.NickName,
tenantName = "匿名用户区域",
expire = _configuration["Jwt:Expires"].ToInt32(),
account = user.Account,
uid = user.Id,
screenShareId = user.ScreenShareId,
isAnonymous = true
});
}
#region #region

View File

@ -13,7 +13,6 @@ using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.Domain.DTOs.User; using WGShare.Domain.DTOs.User;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
using WGShare.Domain.GeneralModel; using WGShare.Domain.GeneralModel;
using Yitter.IdGenerator; using Yitter.IdGenerator;
@ -72,7 +71,7 @@ namespace WGShare.API.Controllers.Backend
var entity = userInput.Adapt<User>(); var entity = userInput.Adapt<User>();
entity.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(); entity.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.IsDelete == false)) if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account))
{ {
throw Oops.Oh("账号已存在!"); throw Oops.Oh("账号已存在!");
} }
@ -85,7 +84,7 @@ namespace WGShare.API.Controllers.Backend
{ {
var entity = inputDTO.Adapt<User>(); var entity = inputDTO.Adapt<User>();
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id && x.IsDelete == false)) if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id))
{ {
throw Oops.Oh("账号已存在!"); throw Oops.Oh("账号已存在!");
} }
@ -153,7 +152,7 @@ namespace WGShare.API.Controllers.Backend
// 数据库重复账号检查 // 数据库重复账号检查
var existsAccount = await _sqlSugar.Queryable<User>() var existsAccount = await _sqlSugar.Queryable<User>()
.Where(x => distinctAccount.Contains(x.Account) && x.IsDelete == false) .Where(x => distinctAccount.Contains(x.Account))
.Select(x => x.Account) .Select(x => x.Account)
.ToListAsync(); .ToListAsync();
if (!existsAccount.IsNullOrEmpty()) if (!existsAccount.IsNullOrEmpty())
@ -194,18 +193,7 @@ namespace WGShare.API.Controllers.Backend
x.Pwd = x.Pwd.MDString(); x.Pwd = x.Pwd.MDString();
x.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(); x.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
x.TenantId = tenantId; x.TenantId = tenantId;
x.RoleId = x.RoleId == "管理员" ? "1" : "2";
var roleId = "2";
if (x.RoleId == "管理员")
roleId = "1";
else if (x.RoleId == "房间管理员")
roleId = "3";
x.RoleId = roleId;
if (string.IsNullOrWhiteSpace(x.SubjectName))
x.Subject = SubjectType.All;
else
x.Subject = x.SubjectName.GetEnumValueFromDescription<SubjectType>();
}); });
await _sqlSugar.Insertable(users).ExecuteCommandAsync(); await _sqlSugar.Insertable(users).ExecuteCommandAsync();

View File

@ -58,12 +58,12 @@ namespace WGShare.API.Controllers.Basic
{ {
get get
{ {
var roleId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value; var roleId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "roleid").Value;
if (string.IsNullOrWhiteSpace(roleId) || !int.TryParse(roleId, out int role) || role == 0) if (string.IsNullOrWhiteSpace(roleId) || !int.TryParse(roleId, out int role) || role == 0)
{ {
throw Oops.Oh("用户信息有误,请重新登录"); throw Oops.Oh("用户信息有误,请重新登录");
} }
return (RoleEnums)role; return (RoleEnums)role;
} }
} }
@ -72,7 +72,7 @@ namespace WGShare.API.Controllers.Basic
{ {
get get
{ {
var tenant = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var tenant = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "tenant").Value;
if (string.IsNullOrWhiteSpace(tenant)) if (string.IsNullOrWhiteSpace(tenant))
{ {
throw Oops.Oh("用户信息有误,请重新登录"); throw Oops.Oh("用户信息有误,请重新登录");
@ -85,7 +85,7 @@ namespace WGShare.API.Controllers.Basic
{ {
get get
{ {
var ssId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; var ssId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ssid").Value;
if (string.IsNullOrWhiteSpace(ssId)) if (string.IsNullOrWhiteSpace(ssId))
{ {
throw Oops.Oh("用户信息有误,请重新登录"); throw Oops.Oh("用户信息有误,请重新登录");
@ -111,63 +111,6 @@ namespace WGShare.API.Controllers.Basic
} }
} }
private int year = -1;
public int Year
{
get
{
if (year >= 0)
{
return year;
}
var year_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "year")?.Value;
if (string.IsNullOrWhiteSpace(year_str) || !int.TryParse(year_str, out year))
{
throw Oops.Oh("用户信息有误,请重新登录");
}
return year;
}
}
private int subject = -1;
public SubjectType Subject
{
get
{
if (subject >= 0)
{
return (SubjectType)subject;
}
var subject_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "subject")?.Value;
if (string.IsNullOrWhiteSpace(subject_str) || !int.TryParse(subject_str, out subject))
{
throw Oops.Oh("用户信息有误,请重新登录");
}
return (SubjectType)subject;
}
}
/// <summary>
/// 匿名用户
/// </summary>
public bool IsAnonymous
{
get
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
return true;
}
var anonymous_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "anonymous")?.Value;
if (string.IsNullOrWhiteSpace(anonymous_str) || !int.TryParse(anonymous_str, out int anonymous))
{
return false;
}
return anonymous == 1;
}
}
} }
} }

View File

@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using SharpCompress; using SharpCompress;
using SqlSugar; using SqlSugar;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Net.Http; using System.Net.Http;
using WGShare.API.Controllers.Basic; using WGShare.API.Controllers.Basic;
@ -33,23 +32,17 @@ namespace WGShare.API.Controllers.Frontend
private readonly ILogger<AgoraCallbackController> _logger; private readonly ILogger<AgoraCallbackController> _logger;
private readonly AgoraHelper _agoraHelper; private readonly AgoraHelper _agoraHelper;
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly ISqlSugarClient _sqlSugarClient;
private readonly IHostEnvironment _hostEnvironment;
public AgoraCallbackController( public AgoraCallbackController(
ILogger<AgoraCallbackController> logger, ILogger<AgoraCallbackController> logger,
AgoraHelper agoraHelper, AgoraHelper agoraHelper,
IConfiguration configuration, IConfiguration configuration)
ISqlSugarClient sqlSugarClient,
IHostEnvironment hostEnvironment)
{ {
this._logger = logger; this._logger = logger;
this._agoraHelper = agoraHelper; this._agoraHelper = agoraHelper;
this._configuration = configuration; this._configuration = configuration;
this._sqlSugarClient = sqlSugarClient;
this._hostEnvironment = hostEnvironment;
} }
[HttpPost("event")] [HttpPost("event")]
public async Task Event() public async Task Event()
@ -91,14 +84,12 @@ namespace WGShare.API.Controllers.Frontend
switch (body.eventType) switch (body.eventType)
{ {
case Domain.Enums.EventType.channel_create: case Domain.Enums.EventType.channel_create:
await CreateChannel(body);
break; break;
case Domain.Enums.EventType.channel_destroy: case Domain.Enums.EventType.channel_destroy:
await DestroyChannel(body);
break; break;
case Domain.Enums.EventType.broadcaster_join_channel: case Domain.Enums.EventType.broadcaster_join_channel:
case Domain.Enums.EventType.audience_join_channel: case Domain.Enums.EventType.audience_join_channel:
JoinChannelEvent(bodyString, body); JoinChannelEvent(bodyString);
break; break;
case Domain.Enums.EventType.broadcaster_leave_channel: case Domain.Enums.EventType.broadcaster_leave_channel:
case Domain.Enums.EventType.audience_leave_channel: case Domain.Enums.EventType.audience_leave_channel:
@ -112,7 +103,7 @@ namespace WGShare.API.Controllers.Frontend
await ExceptionNotice.SendAsync(new Exception("声网事件未知类型"), "声网回调异常"); await ExceptionNotice.SendAsync(new Exception("声网事件未知类型"), "声网回调异常");
break; break;
} }
} }
@ -120,9 +111,10 @@ namespace WGShare.API.Controllers.Frontend
/// 加入频道 /// 加入频道
/// </summary> /// </summary>
[NonAction] [NonAction]
private void JoinChannelEvent(string bodyString, EventBody eventBody) private void JoinChannelEvent(string bodyString)
{ {
_logger.LogDebug($"Agora回调内容 加入频道:{bodyString}"); _logger.LogDebug($"Agora回调内容 加入频道:{bodyString}");
RedisHelper.Instance.LPush(RedisKeyConstant.PubSub.MeetingRecord, bodyString); RedisHelper.Instance.LPush(RedisKeyConstant.PubSub.MeetingRecord, bodyString);
} }
@ -139,61 +131,6 @@ namespace WGShare.API.Controllers.Frontend
} }
static List<string> excludeChannel = new();
static ConcurrentDictionary<string, int> existsChannel = new();
/// <summary>
/// 创建频道
/// </summary>
[NonAction]
private async Task CreateChannel(EventBody eventBody)
{
if (_hostEnvironment.IsDevelopment())
{
_logger.LogDebug($"测试环境不通知创建频道");
return;
}
if (excludeChannel.IsNullOrEmpty())
{
// 缓存测试区域房间
excludeChannel = await _sqlSugarClient.Queryable<Room>().Where(x => x.TenantId == "559167236182085")
.Select(x => x.RoomNum).ToListAsync();
}
if (excludeChannel.Any(x => x == eventBody.payload.channelName))
{
_logger.LogDebug($"正式环境的测试区域不通知创建频道");
return;
}
if (existsChannel.TryAdd(eventBody.payload.channelName, 0))
{
var roomInfo = await _sqlSugarClient.Queryable<Room>()
.LeftJoin<Tenant>((r, t) => r.TenantId == t.Id)
.Where((r, t) => r.RoomNum == eventBody.payload.channelName)
.Select((r, t) => new Room
{
Id = r.Id.SelectAll(),
TenantName = t.TenantName
})
.FirstAsync();
ExceptionNotice.JoinAsync(eventBody, roomInfo);
}
}
/// <summary>
/// 销毁频道
/// </summary>
[NonAction]
private async Task DestroyChannel(EventBody eventBody)
{
if (_hostEnvironment.IsDevelopment())
return;
existsChannel.TryRemove(eventBody.payload.channelName, out _);
}
} }

View File

@ -1,22 +1,15 @@
using AgoraIO.Media; using AgoraIO.Media;
using AgoraIO.Rtm; using AgoraIO.Rtm;
using Azure;
using Mapster; using Mapster;
using Masuit.Tools; using Masuit.Tools;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs; using MiniExcelLibs;
using MiniExcelLibs.Attributes;
using MiniExcelLibs.OpenXml;
using SqlSugar; using SqlSugar;
using SqlSugar.Extensions;
using System.IO; using System.IO;
using System.Net.Http.Headers;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using WGShare.API.Controllers.Basic; using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Home;
using WGShare.Domain.DTOs.MiniProgram;
using WGShare.Domain.DTOs.Room; using WGShare.Domain.DTOs.Room;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums; using WGShare.Domain.Enums;
@ -40,7 +33,6 @@ namespace WGShare.API.Controllers.Frontend
private readonly AgoraHelper _agoraHelper; private readonly AgoraHelper _agoraHelper;
private readonly ILogger<HomeController> _logger; private readonly ILogger<HomeController> _logger;
private readonly OssHelper _ossHelper; private readonly OssHelper _ossHelper;
private readonly MiniProgramHelper _miniProgramHelper;
public HomeController( public HomeController(
ISqlSugarClient sqlSugar, ISqlSugarClient sqlSugar,
@ -48,8 +40,7 @@ namespace WGShare.API.Controllers.Frontend
IHttpClientFactory httpClientFactory, IHttpClientFactory httpClientFactory,
AgoraHelper agoraHelper, AgoraHelper agoraHelper,
ILogger<HomeController> logger, ILogger<HomeController> logger,
OssHelper ossHelper, OssHelper ossHelper)
MiniProgramHelper miniProgramHelper)
{ {
_sqlSugar = sqlSugar; _sqlSugar = sqlSugar;
this._configuration = configuration; this._configuration = configuration;
@ -57,7 +48,6 @@ namespace WGShare.API.Controllers.Frontend
this._agoraHelper = agoraHelper; this._agoraHelper = agoraHelper;
this._logger = logger; this._logger = logger;
this._ossHelper = ossHelper; this._ossHelper = ossHelper;
this._miniProgramHelper = miniProgramHelper;
} }
@ -73,8 +63,6 @@ namespace WGShare.API.Controllers.Frontend
var list = await _sqlSugar.Queryable<Room>() var list = await _sqlSugar.Queryable<Room>()
.Where(x => x.TenantId == TenantId && x.IsDelete == false) .Where(x => x.TenantId == TenantId && x.IsDelete == false)
.WhereIF(Year > 0 && RoleId == RoleEnums.User, x => x.Year == Year || x.Year == 0)
.WhereIF(Subject > 0 && RoleId == RoleEnums.User, x => x.Subject == Subject || x.Subject == 0)
.OrderBy(x => x.Id, OrderByType.Desc) .OrderBy(x => x.Id, OrderByType.Desc)
.ToPageListAsync(dto.PageIndex, dto.PageSize, total); .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
@ -91,7 +79,7 @@ namespace WGShare.API.Controllers.Frontend
//} //}
} }
return PagedResult<RoomOutputDTO>.Create(result, total.Value, dto.PageSize); return PagedResult<RoomOutputDTO>.Create(result, total.Value);
} }
/// <summary> /// <summary>
@ -111,9 +99,7 @@ namespace WGShare.API.Controllers.Frontend
entity.Id = YitIdHelper.NextId().ToString(); entity.Id = YitIdHelper.NextId().ToString();
entity.TenantId = TenantId; entity.TenantId = TenantId;
if (await _sqlSugar.Queryable<Room>().AnyAsync(x => x.RoomNum == inputDTO.RoomNum))
var room = await _sqlSugar.Queryable<Room>().FirstAsync(x => x.RoomNum == inputDTO.RoomNum);
if (room != null)
{ {
throw Oops.Oh("无效会议号,请重新输入"); throw Oops.Oh("无效会议号,请重新输入");
} }
@ -121,19 +107,6 @@ namespace WGShare.API.Controllers.Frontend
return await _sqlSugar.Insertable(entity).ExecuteCommandAsync() > 0; return await _sqlSugar.Insertable(entity).ExecuteCommandAsync() > 0;
} }
/// <summary>
/// 更新会议室信息
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HttpPut("room-info")]
public async Task<bool> ModifyRoom([FromBody] RoomInfoInputDTO inputDTO)
{
var entity = inputDTO.Adapt<Room>();
return await _sqlSugar.Updateable(entity)
.UpdateColumns(x => new { x.Year, x.Subject, x.RoomName, x.AllowAnonymous })
.ExecuteCommandHasChangeAsync();
}
/// <summary> /// <summary>
/// 删除会议室 /// 删除会议室
@ -215,19 +188,15 @@ namespace WGShare.API.Controllers.Frontend
var groupByUser = recordList.GroupBy(x => x.uid).ToList(); var groupByUser = recordList.GroupBy(x => x.uid).ToList();
var beginDatetime = DateTimeUtils.FromJavaScriptTimestampToLocal(beginTimestamp);
var endDaetime = DateTimeUtils.FromJavaScriptTimestampToLocal(endTimestamp);
var value = new RoomMettingRecordExportDTO var value = new RoomMettingRecordExportDTO
{ {
RoomName = room.RoomName, RoomName = room.RoomName,
RoomNum = room.RoomNum, RoomNum = room.RoomNum,
BeginTime = beginDatetime.ToString("yyyy-MM-dd HH:mm:ss"), BeginTime = DateTimeUtils.FromJavaScriptTimestampToLocal(beginTimestamp).ToString("yyyy-MM-dd HH:mm:ss"),
EndTime = endDaetime.ToString("yyyy-MM-dd HH:mm:ss"), EndTime = DateTimeUtils.FromJavaScriptTimestampToLocal(endTimestamp).ToString("yyyy-MM-dd HH:mm:ss"),
Users = new List<UserBehavior>(), Users = new List<UserBehavior>()
Signin = new List<SignInListRecordExcelDto>()
}; };
#region
foreach (var userRecord in groupByUser) foreach (var userRecord in groupByUser)
{ {
if (userRecord.IsNullOrEmpty()) if (userRecord.IsNullOrEmpty())
@ -238,25 +207,14 @@ namespace WGShare.API.Controllers.Frontend
var orderedRecord = userRecord.OrderBy(x => x.ts).ToList(); var orderedRecord = userRecord.OrderBy(x => x.ts).ToList();
// 获取第一次进入房间的事件记录 // 获取第一次进入房间的事件记录
var firstJoinTimeRecord = orderedRecord var firstJoinTime = orderedRecord
.FirstOrDefault(x => x.EventType == EventType.broadcaster_join_channel .FirstOrDefault(x => x.EventType == EventType.broadcaster_join_channel
|| x.EventType == EventType.audience_join_channel); || x.EventType == EventType.audience_join_channel);
string firstJoinTime = "暂无记录";
if (firstJoinTimeRecord != null)
{
firstJoinTime = DateTimeUtils.FromJavaScriptTimestampToLocal(firstJoinTimeRecord.ts).ToString("yyyy-MM-dd HH:mm:ss");
}
// 获取最后一次离开房间的事件记录 // 获取最后一次离开房间的事件记录
var lastLeaveTimeRecord = orderedRecord var lastLeaveTime = orderedRecord
.LastOrDefault(x => x.EventType == EventType.broadcaster_leave_channel .LastOrDefault(x => x.EventType == EventType.broadcaster_leave_channel
|| x.EventType == EventType.audience_leave_channel); || x.EventType == EventType.audience_leave_channel);
string lastLeaveTime = "暂无记录";
if (lastLeaveTimeRecord != null)
{
lastLeaveTime = DateTimeUtils.FromJavaScriptTimestampToLocal(lastLeaveTimeRecord.ts).ToString("yyyy-MM-dd HH:mm:ss");
}
// 计算入会次数 // 计算入会次数
var joinCount = orderedRecord.Count(x => x.EventType == EventType.broadcaster_join_channel var joinCount = orderedRecord.Count(x => x.EventType == EventType.broadcaster_join_channel
@ -268,120 +226,22 @@ namespace WGShare.API.Controllers.Frontend
value.Users.Add(new UserBehavior value.Users.Add(new UserBehavior
{ {
Account = userRecord.FirstOrDefault().UserAccount, Account = userRecord.FirstOrDefault().UserAccount,
FirstJoinTime = firstJoinTime, FirstJoinTime = DateTimeUtils.FromJavaScriptTimestampToLocal(firstJoinTime.ts).ToString("yyyy-MM-dd HH:mm:ss"),
LastExitTime = lastLeaveTime, LastExitTime = DateTimeUtils.FromJavaScriptTimestampToLocal(lastLeaveTime.ts).ToString("yyyy-MM-dd HH:mm:ss"),
JoinCount = joinCount, JoinCount = joinCount,
Role = userRecord.FirstOrDefault().RoleName, Role = userRecord.FirstOrDefault().RoleName,
UserName = userRecord.FirstOrDefault().userName, UserName = userRecord.FirstOrDefault().userName,
SumTime = sumTime, SumTime = sumTime,
}); });
} }
#endregion
#region
var signins = await _sqlSugar.Queryable<UserSignInRecord>()
.InnerJoin<User>((u, us) => u.UId == us.Id)
.Where((u, us) => u.RoomNum == roomNum && u.CreateTime >= beginDatetime && u.CreateTime <= endDaetime)
.Select((u, us) => new SignInListRecordExcelDto
{
Account = us.Account,
SignInTime = u.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
UserName = us.UserName,
SignInName = u.SignInName
})
.ToListAsync();
value.Signin.AddRange(signins);
#endregion
using var stream = new MemoryStream(); using var stream = new MemoryStream();
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}meetingRecordTemplate.xlsx", value); await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}meetingRecordTemplate.xlsx", value);
stream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin);
var fileName = $@"excel/{room.RoomName}-参会记录-{beginDatetime.ToString("yyyyMMddHHmmss")}至{endDaetime.ToString("yyyyMMddHHmmss")}.xlsx"; var fileName = $@"excel/{room.RoomName}-参会记录.xlsx";
_ossHelper.UploadWithExpireTime(fileName, stream, 10); _ossHelper.UploadWithExpireTime(fileName, stream, 10);
return _ossHelper.GetAccessFileUrl(fileName, 5); 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);
imgStr = QrCodeOptimizerHelper.CompressImage(imgStr, 50);
RedisHelper.Instance.Set(RedisKeyConstant.WxMiniProgram.GetRoomQrCode(roomNum, env), imgStr, TimeSpan.FromDays(1));
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("二维码生成失败");
}
/// <summary>
/// 反馈打分
/// </summary>
/// <returns></returns>
[HttpPost("feedback")]
public async Task FeedbackScoring([FromBody] FeedBackRequset requset)
{
var entity = requset.Adapt<FeedbackIssue>();
entity.UID = UId.ToInt64();
entity.Types = string.Join(",", requset.Types);
await _sqlSugar.Insertable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 记录用户当前用户版本
/// </summary>
/// <returns></returns>
[HttpPost("ver-log")]
public async Task RecordVersionLog([FromBody] UserVersionLogDto userVersionLog)
{
var uvl = userVersionLog.Adapt<UserVersionLog>();
uvl.UserId = UId.ToInt64();
await _sqlSugar.Insertable(uvl).ExecuteCommandAsync();
}
} }
} }

View File

@ -3,7 +3,6 @@ using Hangfire.MemoryStorage.Database;
using Mapster; using Mapster;
using Masuit.Tools; using Masuit.Tools;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -63,11 +62,10 @@ namespace WGShare.API.Controllers.Frontend
[HttpPost("manager")] [HttpPost("manager")]
public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO) public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO)
{ {
inputDTO.SettingUserId = UId;
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum)); var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 20) if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 12)
{ {
throw Oops.Oh("当前房间已达最大发言人数!"); throw Oops.Oh("房间已达到12个发言人限制。请移除一位发言人");
} }
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId); var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
if (user == null) if (user == null)
@ -75,13 +73,11 @@ namespace WGShare.API.Controllers.Frontend
throw Oops.Oh("用户已不在房间内!"); throw Oops.Oh("用户已不在房间内!");
} }
await _hubContext.Clients.User(inputDTO.UserId).SetSpeaker(inputDTO); user.IsRoomManager = true;
//user.IsRoomManager = true; RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
//RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user); await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
//await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
} }
/// <summary> /// <summary>
@ -99,35 +95,21 @@ namespace WGShare.API.Controllers.Frontend
} }
user.IsRoomManager = false; user.IsRoomManager = false;
user.EnableCamera = false;
user.EnableMicr = false;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
// 判断是否显示用户 // 判断是否显示用户
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum); var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum);
if (showUserId == inputDTO.UserId || showUserId == user.ScreenShareId) if (showUserId == inputDTO.UserId)
{ {
if (UId == inputDTO.UserId) // 取消显示用户,设置显示管理员
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString());
if (showUser != null)
{ {
// 表示自己取消自己的发言权限 RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, showUser.UID);
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum)); await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString());
if (showUser != null)
{
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, showUser.UID);
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
}
else
{
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, 0);
}
}
else
{
// 取消显示用户,设置显示当前操作的管理员
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, UId);
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(UId, UserName, string.Empty, string.Empty);
} }
} }
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId); await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
@ -206,34 +188,7 @@ namespace WGShare.API.Controllers.Frontend
[HttpGet("checkout"), AllowAnonymous] [HttpGet("checkout"), AllowAnonymous]
public async Task<bool> ExistsRoom([FromQuery] string roomNum) public async Task<bool> ExistsRoom([FromQuery] string roomNum)
{ {
if (IsAnonymous) return await _sqlSugar.Queryable<Room>().AnyAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
{
// 匿名用户
var room = await _sqlSugar.Queryable<Room>().FirstAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
if (room == null)
{
return false;
}
if (!room.AllowAnonymous)
{
throw Oops.Oh("房间不允许匿名用户进入");
}
return true;
}
else
{
// 非匿名用户
var room = await _sqlSugar.Queryable<Room>()
.WhereIF(Year > 0 && RoleId == RoleEnums.User, x => x.Year == Year || x.Year == 0)
.WhereIF(Subject > 0 && RoleId == RoleEnums.User, x => x.Subject == Subject || x.Subject == 0)
.FirstAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
if (room == null)
{
return false;
}
return true;
}
} }
/// <summary> /// <summary>
@ -342,7 +297,7 @@ namespace WGShare.API.Controllers.Frontend
userInfo.EnableMicr = enableMicr; userInfo.EnableMicr = enableMicr;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
//_logger.LogInformation($@"开闭麦克分,推送一次,roomNum:{roomNum},enableMicr:{enableMicr},uid:{uid}"); _logger.LogInformation($@"开闭麦克分,推送一次,roomNum:{roomNum},enableMicr:{enableMicr},uid:{uid}");
// 通知所有人该用户麦克风状态 // 通知所有人该用户麦克风状态
await _hubContext.Clients.Group(roomNum).OperMicr(userInfo, UId); await _hubContext.Clients.Group(roomNum).OperMicr(userInfo, UId);
} }
@ -383,25 +338,13 @@ namespace WGShare.API.Controllers.Frontend
} }
// 获取全部用户 // 获取全部用户
var userInfos = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum)); var uids = RedisHelper.Instance.HKeys(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (userInfos.IsNullOrEmpty()) if (uids.IsNullOrEmpty())
{ {
throw Oops.Oh("无效会议号!"); throw Oops.Oh("无效会议号!");
} }
var managers = userInfos.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString()); return uids.FirstOrDefault();
if (managers.IsNullOrEmpty())
{
return userInfos.FirstOrDefault().UID;
}
var user = managers.FirstOrDefault(x => x.EnableCamera = true);
if (user == null)
{
return managers.FirstOrDefault().UID;
}
return user.UID;
} }
/// <summary> /// <summary>
@ -411,13 +354,6 @@ namespace WGShare.API.Controllers.Frontend
[HttpPost("show-user")] [HttpPost("show-user")]
public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string uid, [FromQuery] string uname) public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string uid, [FromQuery] string uname)
{ {
if (RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum) == uid)
{
// 如果已经是全员观看他了, 直接通知其他房间用户
await _hubContext.Clients.Group(roomNum).ShowUser(uid, uname, UId, UserName);
return;
}
// 设置房间全员观看用户 // 设置房间全员观看用户
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, uid); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, uid);
@ -431,16 +367,15 @@ namespace WGShare.API.Controllers.Frontend
} }
/// <summary> /// <summary>
/// 加入频道 /// 加入频道
/// </summary> /// </summary>
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
/// <param name="enableMicr"></param> /// <param name="enableMicr"></param>
/// <param name="enableCamera"></param> /// <param name="enableCamera"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("join"), Obsolete("废弃请使用Socker接口 JoinChannel")] [HttpGet("join")]
public async Task JoinChannel([FromQuery] string roomNum, [FromQuery] bool enableMicr = false, [FromQuery] bool enableCamera = false) public async Task JoinChannel([FromQuery] string roomNum, [FromQuery] bool enableMicr = false, [FromQuery] bool enableCamera = false)
{ {
//throw Oops.("接口已废弃");
//var isRoomManager = await _sqlSugar.Queryable<RoomManager>() //var isRoomManager = await _sqlSugar.Queryable<RoomManager>()
// .InnerJoin<Room>((rm, r) => r.Id == rm.RoomId) // .InnerJoin<Room>((rm, r) => r.Id == rm.RoomId)
// .Where((rm, r) => r.RoomNum == roomNum && rm.UserId == UId) // .Where((rm, r) => r.RoomNum == roomNum && rm.UserId == UId)
@ -498,10 +433,9 @@ namespace WGShare.API.Controllers.Frontend
/// </summary> /// </summary>
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("leave"), Obsolete("废弃请使用Socker接口 leavelChannel")] [HttpGet("leave")]
public async Task LevelChannel([FromQuery] string roomNum) public async Task LevelChannel([FromQuery] string roomNum)
{ {
using (var pipe = RedisHelper.Instance.StartPipe()) using (var pipe = RedisHelper.Instance.StartPipe())
{ {
// 判断如果有全员看ta则删除 // 判断如果有全员看ta则删除
@ -628,78 +562,10 @@ namespace WGShare.API.Controllers.Frontend
if (connectionIds.Any()) if (connectionIds.Any())
{ {
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId); await _hubContext.Clients.Clients(connectionIds).ApplyToSpeak(UId, UserName);
var userName = UserName;
if (userInfo != null)
{
userName = userInfo.UserName;
}
await _hubContext.Clients.Clients(connectionIds).ApplyToSpeak(UId, userName);
} }
} }
/// <summary>
/// 获取共享屏幕
/// </summary>
/// <returns></returns>
[HttpGet("shared-screen")]
public async Task<string> GetSharedScreen([FromQuery] string roomNum)
{
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum);
if (!string.IsNullOrWhiteSpace(showUserId) && showUserId.Length == 9)
{
// 全员观看userid =9 表示共享屏幕
return showUserId;
}
return string.Empty;
}
/// <summary>
/// 设置共享屏幕
/// </summary>
/// <returns></returns>
[HttpPost("shared-screen")]
public async Task SharedScreen([FromQuery] string roomNum)
{
//var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum);
//if (showUserId.Length == 9)
//{
// var user = await _sqlSugar.Queryable<User>().FirstAsync(x => x.ScreenShareId == showUserId);
// if (user != null)
// {
// //
// await _hubContext.Clients.User(user.Id).ExitSharedScreen();
// }
//}
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId);
// 通知其他所有共享屏幕用户退出
await _hubContext.Clients.GroupExcept(roomNum, connectId).ExitSharedScreen();
// 设置新的共享屏幕
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, ScreenShareId);
// 通知全员观看新的共享屏幕
await _hubContext.Clients.Group(roomNum).ShowUser(UId, UserName, string.Empty, string.Empty);
}
/// <summary>
/// 共享人取消共享屏幕
/// </summary>
/// <returns></returns>
[HttpPost("stop-shared-screen")]
public async Task StopedSharedScreen([FromQuery] string roomNum)
{
if (RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum) != ScreenShareId)
{
// 不是共享屏幕的人,不做处理
return;
}
// 设置新的共享屏幕
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, UId);
await _hubContext.Clients.Group(roomNum).StopedSharedScreen(ScreenShareId);
}
#region #region
/// <summary> /// <summary>
@ -788,49 +654,5 @@ namespace WGShare.API.Controllers.Frontend
return _ossHelper.GetAccessFileUrl(fileUrl); return _ossHelper.GetAccessFileUrl(fileUrl);
} }
#endregion #endregion
/// <summary>
/// 获取签到列表
/// </summary>
/// <returns></returns>
[HttpGet("sign-in")]
public async Task<List<UserSignInListDto>> GetSignInList()
{
var list = await _sqlSugar.Queryable<UserSignInList>()
.Where(x => x.UId == UId)
.ToListAsync();
return list.Adapt<List<UserSignInListDto>>();
}
/// <summary>
/// 提交签到
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
[HttpPost("sign-in")]
public async Task SignIn([FromBody] List<UserSignInRecordDto> list)
{
var entitys = list.Adapt<List<UserSignInRecord>>();
entitys.ForEach(x => x.UId = UId);
await _sqlSugar.Insertable(entitys).ExecuteCommandAsync();
}
/// <summary>
/// 修改昵称
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPut("alter-uname")]
public async Task ModifyNickName([FromBody] UserModifyNickNameDto dto)
{
var user = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, dto.RoomNum), dto.UId.ToString());
user.UserName = dto.NickName;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, dto.RoomNum), dto.UId.ToString(), user);
await _hubContext.Clients.Group(dto.RoomNum).ModifyNickName(dto.UId, dto.NickName);
}
} }
} }

View File

@ -15,9 +15,6 @@ using WGShare.Domain.Entities;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
using WGShare.Domain.GeneralModel; using WGShare.Domain.GeneralModel;
using Yitter.IdGenerator; using Yitter.IdGenerator;
using WGShare.Domain.Enums;
using Microsoft.AspNetCore.Routing.Template;
using MiniExcelLibs.OpenXml;
namespace WGShare.API.Controllers.Frontend namespace WGShare.API.Controllers.Frontend
{ {
@ -52,7 +49,7 @@ namespace WGShare.API.Controllers.Frontend
var list = await _sqlSugar.Queryable<User>() var list = await _sqlSugar.Queryable<User>()
.InnerJoin<Role>((u, r) => u.RoleId == r.Id) .InnerJoin<Role>((u, r) => u.RoleId == r.Id)
.Where((u, r) => u.IsDelete == false && u.TenantId == TenantId && u.IsAnonymous == false) .Where((u, r) => u.IsDelete == false && u.TenantId == TenantId)
.WhereIF(!string.IsNullOrWhiteSpace(searchKeywod), (u, r) => u.UserName.Contains(searchKeywod) || u.Account.Contains(searchKeywod)) .WhereIF(!string.IsNullOrWhiteSpace(searchKeywod), (u, r) => u.UserName.Contains(searchKeywod) || u.Account.Contains(searchKeywod))
.WhereIF(isOnline.HasValue && isOnline.Value == true, (u, r) => onlineUid.Contains(u.Id)) .WhereIF(isOnline.HasValue && isOnline.Value == true, (u, r) => onlineUid.Contains(u.Id))
.WhereIF(isOnline.HasValue && isOnline.Value == false, (u, r) => !onlineUid.Contains(u.Id)) .WhereIF(isOnline.HasValue && isOnline.Value == false, (u, r) => !onlineUid.Contains(u.Id))
@ -64,9 +61,7 @@ namespace WGShare.API.Controllers.Frontend
Account = u.Account, Account = u.Account,
RoleId = r.Id, RoleId = r.Id,
RoleName = r.RoleName, RoleName = r.RoleName,
ScreenShareId = u.ScreenShareId, ScreenShareId = u.ScreenShareId
Subject = u.Subject,
Year = u.Year,
}) })
.ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total); .ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total);
@ -90,7 +85,7 @@ namespace WGShare.API.Controllers.Frontend
user.TenantId = TenantId; user.TenantId = TenantId;
user.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(); user.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == user.Account && x.IsDelete == false)) if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == user.Account))
{ {
throw Oops.Oh("账号已存在!"); throw Oops.Oh("账号已存在!");
} }
@ -108,52 +103,13 @@ namespace WGShare.API.Controllers.Frontend
{ {
var entity = inputDTO.Adapt<User>(); var entity = inputDTO.Adapt<User>();
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id && x.IsDelete == false)) if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id))
{ {
throw Oops.Oh("账号已存在!"); throw Oops.Oh("账号已存在!");
} }
return await _sqlSugar.Updateable(entity) return await _sqlSugar.Updateable(entity)
.UpdateColumns(x => new { x.Account, x.UserName, x.RoleId, x.Year, x.Subject }).ExecuteCommandAsync() > 0; .UpdateColumns(x => new { x.Account, x.UserName, x.RoleId }).ExecuteCommandAsync() > 0;
}
/// <summary>
/// 获取用户签到名单列表
/// </summary>
/// <param name="uid"></param>
/// <returns></returns>
[HttpGet("signs")]
public async Task<List<UserSignInListDto>> GetUserSignInList([FromQuery] string uid)
{
var list = await _sqlSugar.Queryable<UserSignInList>().Where(x => x.UId == uid)
.ToListAsync();
return list.Adapt<List<UserSignInListDto>>();
}
/// <summary>
/// 修改用户签到列表
/// </summary>
/// <returns></returns>
[HttpPut("signs")]
public async Task ModifySignList([FromQuery] string uid, [FromBody] List<UserSignInListDto> signInList)
{
var entities = signInList.Adapt<List<UserSignInList>>();
using (var tran = _sqlSugar.AsTenant().UseTran())
{
await _sqlSugar.Deleteable<UserSignInList>().Where(x => x.UId == uid).ExecuteCommandAsync();
if (!entities.IsNullOrEmpty())
{
var stor = await _sqlSugar.Storageable(entities).ToStorageAsync();
await stor.AsInsertable.ExecuteCommandAsync(); //不存在插入
await stor.AsUpdateable.UpdateColumns(x => x.SignInName).ExecuteCommandAsync(); //存在更新
}
tran.CommitTran();
}
} }
/// <summary> /// <summary>
@ -170,21 +126,6 @@ namespace WGShare.API.Controllers.Frontend
.UpdateColumns(x => new { x.Pwd }).ExecuteCommandAsync() > 0; .UpdateColumns(x => new { x.Pwd }).ExecuteCommandAsync() > 0;
} }
/// <summary>
/// 批量修改用户信息
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HttpPut("bth")]
public async Task<bool> BatchModifyUsers([FromBody] List<UserBatchUpdateDTO> updateDTOs)
{
var entity = updateDTOs.Adapt<List<User>>();
return await _sqlSugar.Updateable(entity)
.UpdateColumns(x => new { x.Subject, x.Year }).ExecuteCommandAsync() > 0;
}
/// <summary> /// <summary>
/// 删除用户 /// 删除用户
/// </summary> /// </summary>
@ -224,7 +165,7 @@ namespace WGShare.API.Controllers.Frontend
// 数据库重复账号检查 // 数据库重复账号检查
var existsAccount = await _sqlSugar.Queryable<User>() var existsAccount = await _sqlSugar.Queryable<User>()
.Where(x => distinctAccount.Contains(x.Account) && x.IsDelete == false) .Where(x => distinctAccount.Contains(x.Account))
.Select(x => x.Account) .Select(x => x.Account)
.ToListAsync(); .ToListAsync();
if (!existsAccount.IsNullOrEmpty()) if (!existsAccount.IsNullOrEmpty())
@ -273,11 +214,6 @@ namespace WGShare.API.Controllers.Frontend
roleId = "3"; roleId = "3";
x.RoleId = roleId; x.RoleId = roleId;
if (string.IsNullOrWhiteSpace(x.SubjectName))
x.Subject = SubjectType.All;
else
x.Subject = x.SubjectName.GetEnumValueFromDescription<SubjectType>();
}); });
await _sqlSugar.Insertable(users).ExecuteCommandAsync(); await _sqlSugar.Insertable(users).ExecuteCommandAsync();
@ -285,80 +221,5 @@ namespace WGShare.API.Controllers.Frontend
return Ok((isSuccess: true, url: "", msg: "导入成功")); return Ok((isSuccess: true, url: "", msg: "导入成功"));
} }
/// <summary>
/// 获取签到绑定列表
/// </summary>
/// <returns></returns>
[HttpGet("signin-list")]
public async Task<string> GetSignInBinding()
{
var userWithSign = await _sqlSugar.Queryable<User>()
.InnerJoin<Role>((u, r) => u.RoleId == r.Id)
.LeftJoin<UserSignInList>((u, r, s) => u.Id == s.UId)
.Where((u, r, s) => u.IsDelete == false && TenantId == u.TenantId)
.Select((u, r, s) => new SignInListExcelDto
{
UId = u.Id,
Account = u.Account,
RoleId = u.RoleId,
RoleName = r.RoleName,
SignInName = s.SignInName,
UserName = u.UserName,
}).ToListAsync();
var value = new Dictionary<string, object>()
{
["Users"] = userWithSign
};
using var stream = new MemoryStream();
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}signInListImportTemplate.xlsx", value);
stream.Seek(0, SeekOrigin.Begin);
var fileName = $@"excel/签到绑定导入-{DateTime.Now.ToString("MMddHHmmss")}.xlsx";
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
return _ossHelper.GetAccessFileUrl(fileName, 5);
}
[HttpPost("import/signin-list")]
public async Task<IActionResult> ImportSigninList([FromForm] IFormFile file)
{
using var stream = file.OpenReadStream();
var rows = stream.Query<SignInListExcelDto>().ToList();
rows.RemoveAll(x => x == null || string.IsNullOrWhiteSpace(x.Account) || string.IsNullOrWhiteSpace(x.UId));
if (rows.IsNullOrEmpty())
{
throw Oops.Oh("无有效数据,请检查文件数据!");
}
// 获取已存在用户Id
var existsUIds = await _sqlSugar.Queryable<User>()
.Where(x => x.IsDelete == false).Select(x => x.Id).ToListAsync();
// 去除不存在用户Id
rows.RemoveAll(x => !existsUIds.Contains(x.UId));
var delUids = rows.Select(x => x.UId).Distinct().ToList();
var entities = rows.Where(x => !string.IsNullOrWhiteSpace(x.SignInName)).Adapt<List<UserSignInList>>();
using (var tran = _sqlSugar.AsTenant().UseTran())
{
await _sqlSugar.Deleteable<UserSignInList>().Where(x => delUids.Contains(x.UId)).ExecuteCommandAsync();
var store = await _sqlSugar.Storageable(entities)
.WhereColumns(x => new { x.UId, x.SignInName })
.ToStorageAsync();
await store.AsInsertable.ExecuteCommandAsync();
await store.AsUpdateable.UpdateColumns(x => x.SignInName).ExecuteCommandHasChangeAsync();
tran.CommitTran();
}
return Ok((isSuccess: true, url: "", msg: "导入成功"));
}
} }
} }

View File

@ -3,18 +3,14 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs; using MiniExcelLibs;
using SqlSugar; using SqlSugar;
using System.ComponentModel;
using System.Configuration; using System.Configuration;
using System.Reflection;
using System.Security.Claims; using System.Security.Claims;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using WGShare.API.Controllers.Basic; using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.Domain.DTOs.Login; using WGShare.Domain.DTOs.Login;
using WGShare.Domain.DTOs.MiniProgram;
using WGShare.Domain.DTOs.User; using WGShare.Domain.DTOs.User;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
namespace WGShare.API.Controllers namespace WGShare.API.Controllers
@ -27,19 +23,10 @@ namespace WGShare.API.Controllers
public class PublicController : BasicController public class PublicController : BasicController
{ {
private readonly ISqlSugarClient _sqlSugar; private readonly ISqlSugarClient _sqlSugar;
private readonly IHttpClientFactory _httpClientFactory;
private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;
private readonly ILogger<PublicController> _logger;
public PublicController(ISqlSugarClient sqlSugar, public PublicController(ISqlSugarClient sqlSugar)
IHttpClientFactory httpClientFactory,
Microsoft.Extensions.Configuration.IConfiguration configuration,
ILogger<PublicController> logger)
{ {
_sqlSugar = sqlSugar; _sqlSugar = sqlSugar;
this._httpClientFactory = httpClientFactory;
this._configuration = configuration;
this._logger = logger;
} }
/// <summary> /// <summary>
@ -51,54 +38,5 @@ namespace WGShare.API.Controllers
{ {
return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync(); return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync();
} }
/// <summary>
/// 科目列表下拉框
/// </summary>
/// <returns></returns>
[HttpGet("sub-dp-list"), AllowAnonymous]
public async Task<List<SubjectInfo>> GetSubjectDropDownList()
{
var list = new List<SubjectInfo>();
foreach (SubjectType subject in Enum.GetValues(typeof(SubjectType)))
{
var description = GetEnumDescription(subject);
list.Add(new SubjectInfo { Value = (int)subject, Name = description });
}
return list;
}
[NonAction]
private string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
/// <summary>
/// 获取小程序openid
/// </summary>
/// <returns></returns>
[HttpGet("mini-openid"), AllowAnonymous]
public async Task<string> GetOpenId(string js_code)
{
var queryString = $@"appid={_configuration["miniProgram:appId"]}&secret={_configuration["miniProgram:appSecret"]}&js_code={js_code}&grant_type=authorization_code";
var httpclient = _httpClientFactory.CreateClient();
var result = await httpclient.GetFromJsonAsync<JsCode2SessionApiResult>($@"https://api.weixin.qq.com/sns/jscode2session?{queryString}");
if (result == null || result.errorcode != 0 || string.IsNullOrWhiteSpace(result.openid))
{
_logger.LogError($"获取openid失败错误码{result?.errorcode},错误信息:{result?.errmsg}");
throw Oops.Oh("小程序登录失败");
}
return result.openid;
}
} }
} }

View File

@ -1,7 +1,4 @@
using System.ComponentModel; using System.ComponentModel;
using System.Reflection;
using WGShare.Domain.DTOs.User;
using WGShare.Domain.Enums;
namespace WGShare.API.Helpers namespace WGShare.API.Helpers
{ {
@ -13,38 +10,5 @@ namespace WGShare.API.Helpers
var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)); var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description; return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
} }
/// <summary>
/// 根据描述获取枚举
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="description"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static T GetEnumValueFromDescription<T>(this string description) where T : Enum
{
description = description.Trim();
foreach (var field in typeof(T).GetFields())
{
if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
{
if (attribute.Description == description)
{
return (T)field.GetValue(null);
}
}
else
{
if (field.Name == description)
{
return (T)field.GetValue(null);
}
}
}
throw new ArgumentException($"No matching enum value found for description: {description}", nameof(description));
}
} }
} }

View File

@ -1,59 +0,0 @@
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

@ -1,36 +0,0 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using System.Drawing.Imaging;
namespace WGShare.API.Helpers
{
public class QrCodeOptimizerHelper
{
public static string CompressImage(string base64String, int quality)
{
// 将 Base64 字符串转换为字节数组
byte[] imageBytes = Convert.FromBase64String(base64String);
// 使用 ImageSharp 加载图像
using (Image image = Image.Load(imageBytes))
{
// 设置压缩参数
JpegEncoder jpegEncoder = new JpegEncoder
{
Quality = quality
};
// 创建一个新的内存流来保存压缩后的图像
using (MemoryStream compressedMs = new MemoryStream())
{
image.Save(compressedMs, jpegEncoder);
// 将压缩后的图像转换回 Base64 字符串
byte[] compressedImageBytes = compressedMs.ToArray();
return Convert.ToBase64String(compressedImageBytes);
}
}
}
}
}

View File

@ -1,6 +1,4 @@
using SignalRSwaggerGen.Attributes; using WGShare.Domain.DTOs.User;
using WGShare.Domain.DTOs.Room;
using WGShare.Domain.DTOs.User;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
namespace WGShare.API.Hubs namespace WGShare.API.Hubs
@ -8,7 +6,6 @@ namespace WGShare.API.Hubs
/// <summary> /// <summary>
/// 客户端消息 /// 客户端消息
/// </summary> /// </summary>
[SignalRHub]
public interface IMessageClient public interface IMessageClient
{ {
/// <summary> /// <summary>
@ -47,7 +44,7 @@ namespace WGShare.API.Hubs
/// </summary> /// </summary>
/// <param name="type"></param> /// <param name="type"></param>
/// <returns></returns> /// <returns></returns>
Task Operation(string contentString); Task Operation(int type);
/// <summary> /// <summary>
/// 更新视图 /// 更新视图
@ -61,12 +58,6 @@ namespace WGShare.API.Hubs
/// <returns></returns> /// <returns></returns>
Task ShowUser(string uid, string uname, string operUid, string operUserName); Task ShowUser(string uid, string uname, string operUid, string operUserName);
/// <summary>
/// 共享人取消共享屏幕
/// </summary>
/// <returns></returns>
Task StopedSharedScreen(string ScreenShareId);
/// <summary> /// <summary>
/// 用户加入频道回调 /// 用户加入频道回调
/// </summary> /// </summary>
@ -153,37 +144,5 @@ namespace WGShare.API.Hubs
/// <param name="driversJsonString"></param> /// <param name="driversJsonString"></param>
/// <returns></returns> /// <returns></returns>
Task ShowDriverList(string driversJsonString); Task ShowDriverList(string driversJsonString);
/// <summary>
/// 修改昵称
/// </summary>
/// <param name="UId"></param>
/// <param name="NickName"></param>
/// <returns></returns>
Task ModifyNickName(long UId, string NickName);
/// <summary>
/// 退出共享屏幕
/// </summary>
/// <returns></returns>
Task ExitSharedScreen();
/// <summary>
/// 加入频道回调
/// </summary>
Task JoinChannelCallback(bool isSuccess);
/// <summary>
/// 发送设置发言人指令
/// </summary>
/// <returns></returns>
Task SetSpeaker(RoomManagerInputDTO inputDTO);
/// <summary>
/// 客户端接收到消息
/// </summary>
/// <param name="contentString"></param>
/// <returns></returns>
Task ReceivedOperation(string contentString);
} }
} }

View File

@ -2,22 +2,16 @@
using Masuit.Tools.DateTimeExt; using Masuit.Tools.DateTimeExt;
using Masuit.Tools.Maths; using Masuit.Tools.Maths;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using SqlSugar; using SqlSugar;
using SqlSugar.Extensions;
using System; using System;
using System.Globalization; using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography;
using System.Text; using System.Text;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Room;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums; using WGShare.Domain.Enums;
using WGShare.Domain.FriendlyException;
using ZstdSharp.Unsafe; using ZstdSharp.Unsafe;
namespace WGShare.API.Hubs namespace WGShare.API.Hubs
@ -35,22 +29,13 @@ namespace WGShare.API.Hubs
public async override Task OnConnectedAsync() public async override Task OnConnectedAsync()
{ {
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value; var uid = Context.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value; var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value;
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
Context.Items.Add("tenant", tenant); Console.WriteLine($"{DateTime.Now}连接成功 当前租户:{tenant} account{account} uid:{uid} connectId:{Context.ConnectionId}");
Context.Items.Add("uid", uid);
Context.Items.Add("account", account);
Context.Items.Add("ssid", ssid);
Context.Items.Add("uname", uname);
Context.Items.Add("roleid", roleId);
_logger.LogInformation($"{DateTime.Now}连接成功 当前租户:{tenant} account{account} uid:{uid} connectId:{Context.ConnectionId}"); await ClearUserChannel(uid, tenant, account, ssid, false);
//await ClearUserChannel(uid, tenant, account, ssid, false);
// 存储在线信息 // 存储在线信息
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid, Context.ConnectionId); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid, Context.ConnectionId);
} }
@ -63,11 +48,11 @@ namespace WGShare.API.Hubs
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
_logger.LogInformation($"{DateTime.Now}断开连接 当前租户:{tenant} account{account} uid:{uid} connectId:{Context.ConnectionId} exception:{exception?.Message} "); Console.WriteLine($"{DateTime.Now}断开连接 当前租户:{tenant} account{account} uid:{uid} connectId:{Context.ConnectionId} exception:{exception?.Message} ");
if (Context.ConnectionId == RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid)) if (Context.ConnectionId == RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid))
{ {
_logger.LogInformation($"{DateTime.Now}断开连接 未重连,开始删除用户频道信息"); Console.WriteLine($"{DateTime.Now}断开连接 未重连,开始删除用户频道信息");
// 断开后未重连则清退频道 // 断开后未重连则清退频道
await ClearUserChannel(uid, tenant, account, ssid, true); await ClearUserChannel(uid, tenant, account, ssid, true);
@ -77,14 +62,17 @@ namespace WGShare.API.Hubs
private async Task ClearUserChannel(string uid, string tenant, string account, string ssid, bool isclose) private async Task ClearUserChannel(string uid, string tenant, string account, string ssid, bool isclose)
{ {
_logger.LogInformation($"{DateTime.Now} 执行删除开始"); Console.WriteLine($"{DateTime.Now} 执行删除开始");
// 获取用户参加得频道 // 获取用户参加得频道
var roomNum = RedisHelper.Instance.Get(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid)); var roomNum = RedisHelper.Instance.Get(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
using (var pipe = RedisHelper.Instance.StartPipe()) using (var pipe = RedisHelper.Instance.StartPipe())
{ {
_logger.LogInformation($@"{DateTime.Now} account:{account} 退出以下频道:{string.Join(',', roomNum)}"); Console.WriteLine($@"{DateTime.Now} account:{account} 退出以下频道:{string.Join(',', roomNum)}");
if (!string.IsNullOrEmpty(roomNum)) if (!string.IsNullOrEmpty(roomNum))
{ {
// 所有房间移除该用户
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
// 判断是否全员看他,是则移除 // 判断是否全员看他,是则移除
var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1]) var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1])
if value == ARGV[2] or value == ARGV[3] then if value == ARGV[2] or value == ARGV[3] then
@ -92,9 +80,6 @@ namespace WGShare.API.Hubs
else return -1 end"; else return -1 end";
// 执行 eval 命令 // 执行 eval 命令
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid); pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
// 房间移除该用户
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
} }
// 删除用户在线状态 // 删除用户在线状态
@ -103,31 +88,14 @@ namespace WGShare.API.Hubs
// 删除用户已加入频道信息 // 删除用户已加入频道信息
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid)); pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
var result = pipe.EndPipe(); pipe.EndPipe();
if (!result.IsNullOrEmpty() && result[0].ObjToInt() != -1)
{
// 如果离开的是全员看ta则重新设置管理员为全员看ta
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum));
var showUsers = users.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString()).ToList();
if (!showUsers.IsNullOrEmpty())
{
var showUser = showUsers.FirstOrDefault(x => x.EnableCamera == true);
if (showUser == null)
{
showUser = showUsers.FirstOrDefault();
}
// 通知全员看ta
await Clients.Group(roomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
}
}
} }
if (!string.IsNullOrEmpty(roomNum)) if (!string.IsNullOrEmpty(roomNum))
// 通知房间其他用户,该用户退出 // 通知房间其他用户,该用户退出
await Clients.Group(roomNum).UserLeave(uid); await Clients.Group(roomNum).UserLeave(uid);
_logger.LogInformation($"{DateTime.Now} 执行删除完成"); Console.WriteLine($"{DateTime.Now} 执行删除完成");
} }
/// <summary> /// <summary>
@ -136,8 +104,8 @@ namespace WGShare.API.Hubs
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
/// <param name="enableMicr">是否关闭麦克风,默认是</param> /// <param name="enableMicr">是否关闭麦克风,默认是</param>
/// <param name="enableCamera">是否关闭摄像头,默认是</param> /// <param name="enableCamera">是否关闭摄像头,默认是</param>
[HubMethodName("joinChannel")] [HubMethodName("joinChannel"), Obsolete("废弃请使用Api接口 JoinChannel")]
public async Task JoinChannel(string roomNum, bool enableMicr = false, bool enableCamera = false, bool isRoomManager = false) public async Task JoinChannel(string roomNum, bool enableMicr = true, bool enableCamera = true)
{ {
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
@ -145,74 +113,18 @@ namespace WGShare.API.Hubs
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value; var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value; var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
try
{
_logger.LogInformation($"{DateTime.Now}加入频道 会议号:" + roomNum);
_logger.LogInformation($"{DateTime.Now}加入频道 account" + account);
_logger.LogInformation($"{DateTime.Now}加入频道 tenant" + tenant);
var userInfo = new ChannelUserInfo
{
UID = uid,
UserName = uname,
EnableCamera = enableCamera,
EnableMicr = enableMicr,
ConnectId = Context.ConnectionId,
Account = account,
ScreenShareId = ssid,
RoleId = roleId,
RoleName = ((RoleEnums)roleId.ToInt32()).GetDescription(),
IsRoomManager = isRoomManager
};
using (var pipe = RedisHelper.Instance.StartPipe())
{
if (((RoleEnums)roleId.ToInt32()) == RoleEnums.Admin || ((RoleEnums)roleId.ToInt32()) == RoleEnums.RoomManager) Console.WriteLine($"{DateTime.Now}加入频道 会议号:" + roomNum);
{ Console.WriteLine($"{DateTime.Now}加入频道 account" + account);
// 管理员进房如果没有全员看ta则设置 Console.WriteLine($"{DateTime.Now}加入频道 tenant" + tenant);
var script = @"local hashKey = KEYS[1]
local field = ARGV[1]
local value = ARGV[2]
if redis.call('HEXISTS', hashKey, field) == 0 then
redis.call('HSET', hashKey, field, value)
return 1
else
return 0
end";
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid);
}
// 记录频道得用户信息
pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid, userInfo);
// 记录用户已参与频道
pipe.Set(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum);
var results = pipe.EndPipe();
// 判断如果有全员看ta则通知
if ((((RoleEnums)roleId.ToInt32()) == RoleEnums.Admin || ((RoleEnums)roleId.ToInt32()) == RoleEnums.RoomManager) && !results.IsNullOrEmpty() && results[0].ObjToInt() == 1)
await Clients.Group(roomNum).ShowUser(uid, uname, string.Empty, string.Empty);
}
await Groups.AddToGroupAsync(Context.ConnectionId, roomNum);
await Clients.GroupExcept(roomNum, Context.ConnectionId).UserJoined(userInfo);
await Clients.Caller.JoinChannelCallback(true);
}
catch (Exception ex)
{
await Clients.Caller.JoinChannelCallback(false);
_logger.LogError(ex, $@"加入频道异常,tenant:{tenant},uid:{uid},ssid:{ssid},uname:{uname} {Environment.NewLine}{ex.Message}");
await ExceptionNotice.SendAsync(ex, $@"加入频道异常,tenant:{tenant},uid:{uid},ssid:{ssid},uname:{uname} ");
}
} }
/// <summary> /// <summary>
/// 离开频道 /// 离开频道
/// </summary> /// </summary>
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
[HubMethodName("levelChannel")] [HubMethodName("levelChannel"), Obsolete("废弃请使用Api接口 LevelChannel")]
public async Task LevelChannel(string roomNum) public async Task LevelChannel(string roomNum)
{ {
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
@ -223,45 +135,9 @@ namespace WGShare.API.Hubs
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value; var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
_logger.LogInformation($" {DateTime.Now}离开频道 会议号:" + roomNum); Console.WriteLine($" {DateTime.Now}离开频道 会议号:" + roomNum);
_logger.LogInformation($" {DateTime.Now}离开频道 account" + account); Console.WriteLine($" {DateTime.Now}离开频道 account" + account);
_logger.LogInformation($" {DateTime.Now}离开频道 tenant" + tenant); Console.WriteLine($" {DateTime.Now}离开频道 tenant" + tenant);
using (var pipe = RedisHelper.Instance.StartPipe())
{
// 判断如果有全员看ta则删除
var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1])
if value == ARGV[2] or value == ARGV[3] then
return redis.call('HDEL', KEYS[1], ARGV[1])
else return -1 end";
// 执行 eval 命令
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
// 删除频道中得该用户
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
// 删除用户已参与频道
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
var result = pipe.EndPipe();
if (!result.IsNullOrEmpty() && result[0].ObjToInt() != -1)
{
// 如果离开的是全员看ta则重新设置管理员为全员看ta
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum));
var showUsers = users.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString()).ToList();
if (!showUsers.IsNullOrEmpty())
{
var showUser = showUsers.FirstOrDefault(x => x.EnableCamera == true);
if (showUser == null)
{
showUser = showUsers.FirstOrDefault();
}
// 通知全员看ta
await Clients.Group(roomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
}
}
}
await Clients.GroupExcept(roomNum, Context.ConnectionId).UserLeave(uid);
await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomNum);
} }
/// <summary> /// <summary>
@ -274,18 +150,12 @@ namespace WGShare.API.Hubs
{ {
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value; var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
var tenant = Context.Items["tenant"].ToString();
_logger.LogInformation($" {DateTime.Now} 发送消息 uname{uname} roomNum{rooNum} msg{msg}");
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, rooNum), uid); Console.WriteLine($" {DateTime.Now}发送消息 uname" + uname);
var userName = uname; Console.WriteLine($" {DateTime.Now}发送消息 roomNum" + rooNum);
if (userInfo != null) Console.WriteLine($" {DateTime.Now}发送消息 msg" + msg);
{
userName = userInfo.UserName;
}
await Clients.OthersInGroup(rooNum).ReceiveMessage(uid, userName, msg, DateTime.Now.GetTotalMilliseconds()); //await Clients.GroupExcept(rooNum, Context.ConnectionId).ReceiveMessage(uid, uname, msg); await Clients.OthersInGroup(rooNum).ReceiveMessage(uid, uname, msg, DateTime.Now.GetTotalMilliseconds()); //await Clients.GroupExcept(rooNum, Context.ConnectionId).ReceiveMessage(uid, uname, msg);
} }
/// <summary> /// <summary>
@ -293,21 +163,9 @@ namespace WGShare.API.Hubs
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HubMethodName("sendOper")] [HubMethodName("sendOper")]
public async Task SendOperation(string roomNum, string contentString) public async Task SendOperation(string roomNum, int type)
{ {
await Clients.Group(roomNum).Operation(contentString); await Clients.Group(roomNum).Operation(type);
}
/// <summary>
/// 发送客户端指令到指定用户
/// </summary>
/// <param name="uid"></param>
/// <param name="contentString"></param>
/// <returns></returns>
[HubMethodName("sendOper2User")]
public async Task SendOperationToUser(string uid, string contentString)
{
await Clients.User(uid).ReceivedOperation(contentString);
} }
/// <summary> /// <summary>
@ -345,32 +203,5 @@ namespace WGShare.API.Hubs
{ {
await Clients.User(uid).SaveDriver(driversJsonString); await Clients.User(uid).SaveDriver(driversJsonString);
} }
/// <summary>
/// 发言人设置成功回调
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HubMethodName("setSpeakerCallback")]
public async Task SetSpeakerCallback(RoomManagerInputDTO inputDTO)
{
var tenantId = Context.Items["tenant"].ToString();
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenantId, inputDTO.RoomNum));
//if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 20)
//{
// throw Oops.Oh("房间已达到20个发言人限制。请移除一位发言人");
//}
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
if (user == null)
{
throw Oops.Oh("用户已不在房间内!");
}
user.IsRoomManager = true;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenantId, inputDTO.RoomNum), inputDTO.UserId, user);
await Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, inputDTO.SettingUserId);
}
} }
} }

View File

@ -59,13 +59,12 @@ namespace WGShare.API
}); });
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwagger(); builder.Services.AddSwagger();
builder.Services.AddSignalR(); builder.Services.AddSignalR();
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
builder.Services.ConfigureHangfire(); builder.Services.ConfigureHangfire();
builder.Services.AddSingleton(new JwtHelper(configuration)); builder.Services.AddSingleton(new JwtHelper(configuration));
builder.Services.AddSingleton(new AgoraHelper(configuration)); builder.Services.AddSingleton(new AgoraHelper(configuration));
builder.Services.AddSingleton(new MiniProgramHelper(configuration));
builder.Services.AddSingleton(new OssHelper(configuration)); builder.Services.AddSingleton(new OssHelper(configuration));
builder.Services.AddHostedService<AgoraCallbackComsuerService>(); builder.Services.AddHostedService<AgoraCallbackComsuerService>();
builder.Services.AddAuth(configuration["Jwt:Issuer"], builder.Services.AddAuth(configuration["Jwt:Issuer"],
@ -99,6 +98,7 @@ namespace WGShare.API
options.SwaggerEndpoint($"/swagger/frontend/swagger.json", "ǰ¶Ë"); options.SwaggerEndpoint($"/swagger/frontend/swagger.json", "ǰ¶Ë");
options.SwaggerEndpoint($"/swagger/backend/swagger.json", "ºó¶Ë"); options.SwaggerEndpoint($"/swagger/backend/swagger.json", "ºó¶Ë");
options.SwaggerEndpoint($"/swagger/public/swagger.json", "¹«¹²½Ó¿Ú"); options.SwaggerEndpoint($"/swagger/public/swagger.json", "¹«¹²½Ó¿Ú");
}); });
app.UseCustomCors(); app.UseCustomCors();
} }

View File

@ -22,7 +22,6 @@ namespace WGShare.API.ServiceConfigs
{ {
services.AddSwaggerGen(w => services.AddSwaggerGen(w =>
{ {
w.AddSignalRSwaggerGen();
w.SwaggerDoc("frontend", new OpenApiInfo { Title = "前端", Version = "frontend" }); w.SwaggerDoc("frontend", new OpenApiInfo { Title = "前端", Version = "frontend" });
w.SwaggerDoc("backend", new OpenApiInfo { Title = "后端", Version = "backend" }); w.SwaggerDoc("backend", new OpenApiInfo { Title = "后端", Version = "backend" });
w.SwaggerDoc("public", new OpenApiInfo { Title = "公共接口", Version = "public" }); w.SwaggerDoc("public", new OpenApiInfo { Title = "公共接口", Version = "public" });

View File

@ -15,7 +15,6 @@
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
<PackageReference Include="Hangfire.Core" Version="1.8.14" /> <PackageReference Include="Hangfire.Core" Version="1.8.14" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.8.1.1" /> <PackageReference Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
<PackageReference Include="SignalRSwaggerGen" Version="4.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>
@ -36,9 +35,6 @@
<None Update="Reference\AgoraIO.dll"> <None Update="Reference\AgoraIO.dll">
<CopyToOutputDirectory>Never</CopyToOutputDirectory> <CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None> </None>
<None Update="signInListImportTemplate.xlsx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="WGShare.API.xml"> <None Update="WGShare.API.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

View File

@ -11,13 +11,6 @@
<param name="account"></param> <param name="account"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.AuthController.CheckUserOnline(System.String)">
<summary>
检查用户是否在线
</summary>
<param name="account"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.AuthController.Login(WGShare.Domain.DTOs.Login.UserLoginDTO)"> <member name="M:WGShare.API.Controllers.AuthController.Login(WGShare.Domain.DTOs.Login.UserLoginDTO)">
<summary> <summary>
正常账号登录 正常账号登录
@ -37,13 +30,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.AuthController.AnonymousLogin(WGShare.Domain.DTOs.Login.AnonymousUserLoginDTO)">
<summary>
匿名登录
</summary>
<param name="loginDTO"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.AuthController.LoginForAdmin(WGShare.Domain.DTOs.Login.UserLoginDTO)"> <member name="M:WGShare.API.Controllers.AuthController.LoginForAdmin(WGShare.Domain.DTOs.Login.UserLoginDTO)">
<summary> <summary>
管理员登录 管理员登录
@ -75,17 +61,12 @@
<param name="file"></param> <param name="file"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="P:WGShare.API.Controllers.Basic.BasicController.IsAnonymous">
<summary>
匿名用户
</summary>
</member>
<member name="T:WGShare.API.Controllers.Frontend.AgoraCallbackController"> <member name="T:WGShare.API.Controllers.Frontend.AgoraCallbackController">
<summary> <summary>
Agora接口 Agora接口
</summary> </summary>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.JoinChannelEvent(System.String,WGShare.Domain.DTOs.AgoraCallback.EventBody)"> <member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.JoinChannelEvent(System.String)">
<summary> <summary>
加入频道 加入频道
</summary> </summary>
@ -95,16 +76,6 @@
离开频道 离开频道
</summary> </summary>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.CreateChannel(WGShare.Domain.DTOs.AgoraCallback.EventBody)">
<summary>
创建频道
</summary>
</member>
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.DestroyChannel(WGShare.Domain.DTOs.AgoraCallback.EventBody)">
<summary>
销毁频道
</summary>
</member>
<member name="T:WGShare.API.Controllers.Frontend.HomeController"> <member name="T:WGShare.API.Controllers.Frontend.HomeController">
<summary> <summary>
首页接口 首页接口
@ -124,13 +95,6 @@
<param name="inputDTO"></param> <param name="inputDTO"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.ModifyRoom(WGShare.Domain.DTOs.Room.RoomInfoInputDTO)">
<summary>
更新会议室信息
</summary>
<param name="inputDTO"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.DeleteRoom(System.String)"> <member name="M:WGShare.API.Controllers.Frontend.HomeController.DeleteRoom(System.String)">
<summary> <summary>
删除会议室 删除会议室
@ -156,25 +120,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.GetMiniProgramQrCode(System.String,System.String)">
<summary>
获取房间二维码缓存10mins
</summary>
<param name="roomNum"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.FeedbackScoring(WGShare.Domain.DTOs.Home.FeedBackRequset)">
<summary>
反馈打分
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.HomeController.RecordVersionLog(WGShare.Domain.DTOs.Home.UserVersionLogDto)">
<summary>
记录用户当前用户版本
</summary>
<returns></returns>
</member>
<member name="T:WGShare.API.Controllers.Frontend.RoomController"> <member name="T:WGShare.API.Controllers.Frontend.RoomController">
<summary> <summary>
会议室接口 会议室接口
@ -266,7 +211,7 @@
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.JoinChannel(System.String,System.Boolean,System.Boolean)"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.JoinChannel(System.String,System.Boolean,System.Boolean)">
<summary> <summary>
加入频道 加入频道
</summary> </summary>
<param name="roomNum"></param> <param name="roomNum"></param>
<param name="enableMicr"></param> <param name="enableMicr"></param>
@ -299,24 +244,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.GetSharedScreen(System.String)">
<summary>
获取共享屏幕
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.SharedScreen(System.String)">
<summary>
设置共享屏幕
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.StopedSharedScreen(System.String)">
<summary>
共享人取消共享屏幕
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.AddFile(WGShare.Domain.DTOs.File.ShareFileInputDTO)"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.AddFile(WGShare.Domain.DTOs.File.ShareFileInputDTO)">
<summary> <summary>
分享上传文件 分享上传文件
@ -352,26 +279,6 @@
<param name="fileId">文件Id</param> <param name="fileId">文件Id</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.GetSignInList">
<summary>
获取签到列表
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.SignIn(System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserSignInRecordDto})">
<summary>
提交签到
</summary>
<param name="list"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.ModifyNickName(WGShare.Domain.DTOs.User.UserModifyNickNameDto)">
<summary>
修改昵称
</summary>
<param name="dto"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserList(System.String,System.Nullable{System.Boolean},WGShare.Domain.GeneralModel.PagedBaseDto)"> <member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserList(System.String,System.Nullable{System.Boolean},WGShare.Domain.GeneralModel.PagedBaseDto)">
<summary> <summary>
获取用户列表 获取用户列表
@ -394,19 +301,6 @@
<param name="inputDTO"></param> <param name="inputDTO"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserSignInList(System.String)">
<summary>
获取用户签到名单列表
</summary>
<param name="uid"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.ModifySignList(System.String,System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserSignInListDto})">
<summary>
修改用户签到列表
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.ModifyPassword(WGShare.Domain.DTOs.User.UserChangePwdDTO)"> <member name="M:WGShare.API.Controllers.Frontend.UserController.ModifyPassword(WGShare.Domain.DTOs.User.UserChangePwdDTO)">
<summary> <summary>
更改密码 更改密码
@ -414,13 +308,6 @@
<param name="inputDTO"></param> <param name="inputDTO"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.BatchModifyUsers(System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserBatchUpdateDTO})">
<summary>
批量修改用户信息
</summary>
<param name="inputDTO"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.Delete(System.String[])"> <member name="M:WGShare.API.Controllers.Frontend.UserController.Delete(System.String[])">
<summary> <summary>
删除用户 删除用户
@ -435,12 +322,6 @@
<param name="file"></param> <param name="file"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetSignInBinding">
<summary>
获取签到绑定列表
</summary>
<returns></returns>
</member>
<member name="T:WGShare.API.Controllers.PublicController"> <member name="T:WGShare.API.Controllers.PublicController">
<summary> <summary>
前后端共用接口 前后端共用接口
@ -452,18 +333,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.PublicController.GetSubjectDropDownList">
<summary>
科目列表下拉框
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.PublicController.GetOpenId(System.String)">
<summary>
获取小程序openid
</summary>
<returns></returns>
</member>
<member name="F:WGShare.API.Helpers.AgoraHelper.Constant.REDIS_CHANNEL_USERCOUNT"> <member name="F:WGShare.API.Helpers.AgoraHelper.Constant.REDIS_CHANNEL_USERCOUNT">
<summary> <summary>
Redis 键hash ,每个频道用户数量 Redis 键hash ,每个频道用户数量
@ -518,26 +387,6 @@
<param name="jsTimestamp">JavaScript 时间戳(以秒为单位)。</param> <param name="jsTimestamp">JavaScript 时间戳(以秒为单位)。</param>
<returns>对应的本地时间的 DateTime 对象。</returns> <returns>对应的本地时间的 DateTime 对象。</returns>
</member> </member>
<member name="M:WGShare.API.Helpers.EnumExtensions.GetEnumValueFromDescription``1(System.String)">
<summary>
根据描述获取枚举
</summary>
<typeparam name="T"></typeparam>
<param name="description"></param>
<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)"> <member name="M:WGShare.API.Helpers.OssHelper.GetUploadUrl(System.String,System.String,System.UInt32)">
<summary> <summary>
获取上传url 获取上传url
@ -619,7 +468,7 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.Operation(System.String)"> <member name="M:WGShare.API.Hubs.IMessageClient.Operation(System.Int32)">
<summary> <summary>
客户端操作 客户端操作
</summary> </summary>
@ -638,12 +487,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.StopedSharedScreen(System.String)">
<summary>
共享人取消共享屏幕
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.UserJoined(WGShare.Domain.Entities.ChannelUserInfo)"> <member name="M:WGShare.API.Hubs.IMessageClient.UserJoined(WGShare.Domain.Entities.ChannelUserInfo)">
<summary> <summary>
用户加入频道回调 用户加入频道回调
@ -731,39 +574,7 @@
<param name="driversJsonString"></param> <param name="driversJsonString"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.ModifyNickName(System.Int64,System.String)"> <member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)">
<summary>
修改昵称
</summary>
<param name="UId"></param>
<param name="NickName"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.ExitSharedScreen">
<summary>
退出共享屏幕
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.JoinChannelCallback(System.Boolean)">
<summary>
加入频道回调
</summary>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.SetSpeaker(WGShare.Domain.DTOs.Room.RoomManagerInputDTO)">
<summary>
发送设置发言人指令
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.ReceivedOperation(System.String)">
<summary>
客户端接收到消息
</summary>
<param name="contentString"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean,System.Boolean)">
<summary> <summary>
加入频道 加入频道
</summary> </summary>
@ -784,20 +595,12 @@
<param name="rooNum"></param> <param name="rooNum"></param>
<param name="msg"></param> <param name="msg"></param>
</member> </member>
<member name="M:WGShare.API.Hubs.SessionManageHub.SendOperation(System.String,System.String)"> <member name="M:WGShare.API.Hubs.SessionManageHub.SendOperation(System.String,System.Int32)">
<summary> <summary>
发送客户端指令 发送客户端指令
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.SessionManageHub.SendOperationToUser(System.String,System.String)">
<summary>
发送客户端指令到指定用户
</summary>
<param name="uid"></param>
<param name="contentString"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.SessionManageHub.GetDriversList(System.String)"> <member name="M:WGShare.API.Hubs.SessionManageHub.GetDriversList(System.String)">
<summary> <summary>
获取设备列表 获取设备列表
@ -820,13 +623,6 @@
<param name="driversJsonString"></param> <param name="driversJsonString"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.SessionManageHub.SetSpeakerCallback(WGShare.Domain.DTOs.Room.RoomManagerInputDTO)">
<summary>
发言人设置成功回调
</summary>
<param name="inputDTO"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Program.ResetRedisKey"> <member name="M:WGShare.API.Program.ResetRedisKey">
<summary> <summary>
程序启动前删除redis中得数据 程序启动前删除redis中得数据

View File

@ -36,12 +36,12 @@
"Issuer": "WGshareApi", "Issuer": "WGshareApi",
"Audience": "WGshareClient", "Audience": "WGshareClient",
// //
"Expires": 600000 "Expires": 86400
}, },
"Agora": { "Agora": {
"appId": "4a4f7be64fa1404ebda74784fe9ac381", "appId": "4a4f7be64fa1404ebda74784fe9ac381",
"appSecret": "255e05d96c794251b282a0de84242355", "appSecret": "255e05d96c794251b282a0de84242355",
"tokenExpireTimeInSecond": 86400, "tokenExpireTimeInSecond": 7200,
"apiPrefix": "https://api.sd-rtn.com/", "apiPrefix": "https://api.sd-rtn.com/",
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4", "clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
"clientSecret": "8323581d4d464114b1f324b26cc62e09", "clientSecret": "8323581d4d464114b1f324b26cc62e09",

View File

@ -10,37 +10,33 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Jwt": { "Jwt": {
"SecretKey": "apDbztyqjSNuvWnezhbdUxduhDidZbF897t2uTJs53RMdY9Cai7eexavBhka3HN6mcTe9oohjFg6bNffRRkcfMqnVKNBnmyPzkRgNopHGJAL7KMwkeZdZ7BaWnT57jCi11", "SecretKey": "apDbztyqjSNuvWnezhbdUxduhDidZbF897t2uTJs53RMdY9Cai7eexavBhka3HN6mcTe9oohjFg6bNffRRkcfMqnVKNBnmyPzkRgNopHGJAL7KMwkeZdZ7BaWnT57jCi",
"Issuer": "WGshareApi", "Issuer": "WGshareApi",
"Audience": "WGshareClient", "Audience": "WGshareClient",
// 360 //
"Expires": 31104000 "Expires": 86400
}, },
"ConnectionStrings": { "ConnectionStrings": {
"metting": "Database=metting;Server=rds-external.23544.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;", "metting": "Database=metting;Server=rds-proxy-internal.rwlb.cn-chengdu.rds.aliyuncs.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;",
"usercenter": "Database=usercenter;Server=rds-external.23544.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;" "usercenter": "Database=usercenter;Server=rds-proxy-internal.rwlb.cn-chengdu.rds.aliyuncs.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;"
}, },
"Redis": { "Redis": {
"master": "redis-internal.23544.com:16379,password=poiuyt)(*&^%,defaultDatabase=6,prefix=wgshare:" "master": "172.29.33.83:16379,password=poiuyt)(*&^%,defaultDatabase=6,prefix=wgshare:"
}, },
"Agora": { "Agora": {
"appId": "dcfc466a6ecb4a1f972630065dfb1e75", "appId": "dcfc466a6ecb4a1f972630065dfb1e75",
"appSecret": "fc77000e329b4be7a0e26fa789e20d00", "appSecret": "fc77000e329b4be7a0e26fa789e20d00",
"tokenExpireTimeInSecond": 72000, "tokenExpireTimeInSecond": 7200,
"apiPrefix": "https://api.sd-rtn.com/", "apiPrefix": "https://api.sd-rtn.com/",
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4", "clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
"clientSecret": "8323581d4d464114b1f324b26cc62e09", "clientSecret": "8323581d4d464114b1f324b26cc62e09"
"eventSecret": "dgi7oUiuT"
}, },
"OSS": { "OSS": {
"AccessKeyID": "LTAI5tQYVQHkkXxXTmjwiSDv", "AccessKeyID": "LTAI5tQYVQHkkXxXTmjwiSDv",
"AccessKeySecret": "FKFNYRdS53FwA5ME2wM1585qX5eVEd", "AccessKeySecret": "FKFNYRdS53FwA5ME2wM1585qX5eVEd",
"Endpoint": "oss-cn-chengdu.aliyuncs.com", "Endpoint": "oss-cn-chengdu.aliyuncs.com",
"Host": "https://wgshare.oss-cn-chengdu.aliyuncs.com/", "Host": "https://wgshare.oss-cn-chengdu.aliyuncs.com/",
"BucketName": "wgshare" "BucketName": "wgshare",
}, "eventSecret": ""
"miniProgram": {
"appId": "wx99885b1c181cda72",
"appSecret": "edd9cdb04c3f59fe70f2a70c396e5b0d"
} }
} }

View File

@ -86,12 +86,5 @@ namespace WGShare.Domain.Constant
{ {
public static string MeetingRecord => "meeting_record"; 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

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WGShare.Domain.Enums;
namespace WGShare.Domain.DTOs.Home
{
public class FeedBackRequset
{
/// <summary>
/// 分值
/// </summary>
public double Score { get; set; }
/// <summary>
/// 反馈内容
/// </summary>
public string OtherContent { get; set; }
/// <summary>
/// 反馈类型
/// </summary>
public List<int> Types { get; set; }
}
}

View File

@ -1,29 +0,0 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace WGShare.Domain.DTOs.Home
{
public class UserVersionLogDto
{
/// <summary>
/// 使用版本
///</summary>
public string Version { get; set; }
/// <summary>
/// 平台类型 1:PC 2:微信小程序
///</summary>
public int PlatformType { get; set; }
/// <summary>
/// 房间号
///</summary>
public string RoomNum { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.Login
{
/// <summary>
/// 匿名用户登录
/// </summary>
public class AnonymousUserLoginDTO
{
public string DeviceId { get; set; }
public string NickName { get; set; }
public string RoomNum { get; set; }
}
}

View File

@ -1,14 +0,0 @@
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

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

View File

@ -1,14 +0,0 @@
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

@ -1,18 +0,0 @@
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; }
}
}

View File

@ -4,54 +4,21 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WGShare.Domain.Enums;
using Yitter.IdGenerator; using Yitter.IdGenerator;
namespace WGShare.Domain.DTOs.Room namespace WGShare.Domain.DTOs.Room
{ {
public class RoomInputDTO : RoomInfoInputDTO public class RoomInputDTO
{ {
/// <summary> /// <summary>
/// 会议室名称 /// 会议室名称
///</summary> ///</summary>
[SugarColumn(ColumnName = "room_name")]
public string RoomName { get; set; } public string RoomName { get; set; }
/// <summary> /// <summary>
/// 会议号 /// 会议号
///</summary> ///</summary>
[SugarColumn(ColumnName = "room_num")]
public string RoomNum { get; set; } public string RoomNum { get; set; }
/// <summary>
/// 届
///</summary>
public int Year { get; set; }
/// <summary>
/// 科目
///</summary>
public SubjectType Subject { get; set; }
}
public class RoomInfoInputDTO
{
public string Id { get; set; }
/// <summary>
/// 届
///</summary>
public int Year { get; set; }
/// <summary>
/// 科目
///</summary>
public SubjectType Subject { get; set; }
/// <summary>
/// 会议室名称
/// </summary>
public string RoomName { get; set; }
/// <summary>
/// 是否允许匿名
/// </summary>
public bool AllowAnonymous { get; set; } = true;
} }
} }

View File

@ -12,9 +12,5 @@ namespace WGShare.Domain.DTOs.Room
public string RoomId { get; set; } public string RoomId { get; set; }
public string RoomNum { get; set; } public string RoomNum { get; set; }
public string UserId { get; set; } public string UserId { get; set; }
/// <summary>
/// 设置人Id
/// </summary>
public string SettingUserId { get; set; }
} }
} }

View File

@ -1,5 +1,4 @@
using MiniExcelLibs.Attributes; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -16,8 +15,6 @@ namespace WGShare.Domain.DTOs.Room
public string EndTime { get; set; } public string EndTime { get; set; }
public List<UserBehavior> Users { get; set; } public List<UserBehavior> Users { get; set; }
public List<SignInListRecordExcelDto> Signin { get; set; }
} }
public class UserBehavior public class UserBehavior
@ -30,15 +27,4 @@ namespace WGShare.Domain.DTOs.Room
public int JoinCount { get; set; } public int JoinCount { get; set; }
public int SumTime { get; set; } public int SumTime { get; set; }
} }
public class SignInListRecordExcelDto
{
public string Account { get; set; }
public string UserName { get; set; }
public string SignInTime { get; set; }
public string SignInName { get; set; }
}
} }

View File

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WGShare.Domain.Enums;
using Yitter.IdGenerator; using Yitter.IdGenerator;
namespace WGShare.Domain.DTOs.Room namespace WGShare.Domain.DTOs.Room
@ -25,16 +24,5 @@ namespace WGShare.Domain.DTOs.Room
/// 在线人数 /// 在线人数
/// </summary> /// </summary>
public long OnlineUserCount { get; set; } public long OnlineUserCount { get; set; }
}
/// <summary>
/// 届
///</summary>
public int Year { get; set; }
/// <summary>
/// 科目
///</summary>
public SubjectType Subject { get; set; }
public bool AllowAnonymous { get; set; }
}
} }

View File

@ -1,33 +0,0 @@
using MiniExcelLibs.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.User
{
/// <summary>
/// 导出账号签到用户列表
/// </summary>
public class SignInListExcelDto
{
[ExcelColumnName("UId")]
public string UId { get; set; }
[ExcelColumnName("账号")]
public string Account { get; set; }
[ExcelColumnName("账号名称")]
public string UserName{ get; set; }
public string RoleId { get; set; }
[ExcelColumnName("角色")]
public string RoleName { get; set; }
[ExcelColumnName("绑定签到人姓名")]
public string SignInName { get; set; }
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.User
{
public class SubjectInfo
{
public int Value { get; set; }
public string Name { get; set; }
}
}

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
namespace WGShare.Domain.DTOs.User
{
/// <summary>
/// 用户批量修改信息
/// </summary>
public class UserBatchUpdateDTO
{
public string Id { get; set; }
public int Year { get; set; }
public SubjectType Subject { get; set; }
}
}

View File

@ -29,16 +29,6 @@ namespace WGShare.Domain.DTOs.User
///</summary> ///</summary>
[ExcelColumnName("角色")] [ExcelColumnName("角色")]
public string RoleId{ get; set; } public string RoleId{ get; set; }
/// <summary>
///
///</summary>
[ExcelColumnName("届")]
public int Year { get; set; }
/// <summary>
///
///</summary>
[ExcelColumnName("科目")]
public string SubjectName { get; set; }
[ExcelColumnName("导入结果")] [ExcelColumnName("导入结果")]

View File

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WGShare.Domain.Enums;
namespace WGShare.Domain.DTOs.User namespace WGShare.Domain.DTOs.User
{ {
@ -32,15 +31,5 @@ namespace WGShare.Domain.DTOs.User
/// 租户id /// 租户id
///</summary> ///</summary>
public string? TenantId { get; set; } public string? TenantId { get; set; }
/// <summary>
/// 届
/// </summary>
public int Year { get; set; }
/// <summary>
/// 科目
/// </summary>
public SubjectType Subject { get; set; }
} }
} }

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.User
{
public class UserModifyNickNameDto
{
public string RoomNum { get; set; }
public string NickName { get; set; }
public long UId { get; set; }
}
}

View File

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WGShare.Domain.Enums;
namespace WGShare.Domain.DTOs.User namespace WGShare.Domain.DTOs.User
{ {
@ -30,15 +29,5 @@ namespace WGShare.Domain.DTOs.User
/// 共享屏幕ID /// 共享屏幕ID
/// </summary> /// </summary>
public string ScreenShareId { get; set; } public string ScreenShareId { get; set; }
/// <summary>
/// 届
/// </summary>
public int Year { get; set; }
/// <summary>
/// 科目
/// </summary>
public SubjectType Subject { get; set; }
} }
} }

View File

@ -1,19 +0,0 @@
using MiniExcelLibs.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.User
{
public class UserSignInListDto
{
public string Id { get; set; }
public string UId { get; set; }
public string SignInName { get; set; }
}
}

View File

@ -1,18 +0,0 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.DTOs.User
{
public class UserSignInRecordDto
{
public string SignInName { get; set; }
public string RoomNum { get; set; }
}
}

View File

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
using WGShare.Domain.Enums;
using Yitter.IdGenerator;
namespace WGShare.Domain.Entities
{
/// <summary>
/// 反馈问题表
///</summary>
[SugarTable("feedback_issue")]
public class FeedbackIssue
{
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "id", IsPrimaryKey = true)]
public string Id { get; set; } = YitIdHelper.NextId().ToString();
/// <summary>
/// 创建时间
/// 默认值: CURRENT_TIMESTAMP
///</summary>
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public DateTime CreateTime { get; set; }
/// <summary>
/// 用户id
///</summary>
[SugarColumn(ColumnName = "uid")]
public long UID { get; set; }
/// <summary>
/// 分值
///</summary>
[SugarColumn(ColumnName = "score")]
public double Score { get; set; }
/// <summary>
/// 反馈其他
///</summary>
[SugarColumn(ColumnName = "other_content")]
public string OtherContent { get; set; }
/// <summary>
/// 反馈其他
///</summary>
[SugarColumn(ColumnName = "types")]
public string Types { get; set; }
}
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using SqlSugar; using SqlSugar;
using WGShare.Domain.Enums;
using Yitter.IdGenerator; using Yitter.IdGenerator;
namespace WGShare.Domain.Entities namespace WGShare.Domain.Entities
{ {
@ -50,30 +49,5 @@ namespace WGShare.Domain.Entities
///</summary> ///</summary>
[SugarColumn(ColumnName = "room_num")] [SugarColumn(ColumnName = "room_num")]
public string RoomNum { get; set; } public string RoomNum { get; set; }
/// <summary>
/// 届
///</summary>
[SugarColumn(ColumnName = "year")]
public int Year { get; set; }
/// <summary>
/// 科目
///</summary>
[SugarColumn(ColumnName = "subject")]
public SubjectType Subject { get; set; }
/// <summary>
/// 是否允许匿名
///</summary>
[SugarColumn(ColumnName = "allow_anonymous")]
public bool AllowAnonymous { get; set; } = true;
/// <summary>
/// 租户名称
/// </summary>
[SugarColumn(IsIgnore = true)]
public string TenantName { get; set; }
} }
} }

View File

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using SqlSugar; using SqlSugar;
using WGShare.Domain.Enums;
using Yitter.IdGenerator; using Yitter.IdGenerator;
namespace WGShare.Domain.Entities namespace WGShare.Domain.Entities
{ {
@ -60,32 +59,11 @@ namespace WGShare.Domain.Entities
[SugarColumn(ColumnName = "tenant_id")] [SugarColumn(ColumnName = "tenant_id")]
public string TenantId { get; set; } public string TenantId { get; set; }
/// <summary> /// <summary>
/// 是否匿名登录用户
///</summary>
[SugarColumn(ColumnName = "is_anonymous")]
public bool IsAnonymous { get; set; }
/// <summary>
/// 共享屏幕Id /// 共享屏幕Id
///</summary> ///</summary>
[SugarColumn(ColumnName = "screen_share_id", IsOnlyIgnoreUpdate = true)] [SugarColumn(ColumnName = "screen_share_id", IsOnlyIgnoreUpdate = true)]
public string ScreenShareId { get; set; } public string ScreenShareId { get; set; }
/// <summary>
/// 届
///</summary>
[SugarColumn(ColumnName = "year")]
public int Year { get; set; }
/// <summary>
/// 科目
///</summary>
[SugarColumn(ColumnName = "subject")]
public SubjectType Subject { get; set; }
/// <summary>
/// 科目名称
///</summary>
[SugarColumn(IsIgnore = true)]
public string SubjectName { get; set; }
[SugarColumn(IsIgnore = true)] [SugarColumn(IsIgnore = true)]
public string RoleName { get; set; } public string RoleName { get; set; }

View File

@ -1,48 +0,0 @@
using AngleSharp.Text;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.Entities
{
/// <summary>
/// 签到名单
///</summary>
[SugarTable("user_signin_list")]
public class UserSignInList
{
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
public string Id { get; set; }
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "uid")]
public string UId { get; set; }
[SugarColumn(ColumnName = "signin_name")]
public string SignInName { get; set; }
/// <summary>
/// 创建时间
/// 默认值: CURRENT_TIMESTAMP
///</summary>
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public DateTime CreateTime { get; set; }
/// <summary>
/// 修改时间
///</summary>
[SugarColumn(ColumnName = "modify_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public DateTime ModifyTime { get; set; }
}
}

View File

@ -1,44 +0,0 @@
using AngleSharp.Text;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.Entities
{
/// <summary>
/// 签到名单记录
///</summary>
[SugarTable("user_signin_record")]
public class UserSignInRecord
{
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
public string Id { get; set; }
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "uid")]
public string UId { get; set; }
[SugarColumn(ColumnName = "signin_name")]
public string SignInName { get; set; }
[SugarColumn(ColumnName = "room_num")]
public string RoomNum { get; set; }
/// <summary>
/// 创建时间
/// 默认值: CURRENT_TIMESTAMP
///</summary>
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public DateTime CreateTime { get; set; }
}
}

View File

@ -1,52 +0,0 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace WGShare.Domain.Entities
{
/// <summary>
/// 用户版本记录表
/// </summary>
[SugarTable("user_version_log")]
public class UserVersionLog
{
/// <summary>
///
///</summary>
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
public string Id { get; set; } = YitIdHelper.NextId().ToString();
/// <summary>
/// 用户Id
///</summary>
[SugarColumn(ColumnName = "user_id")]
public long UserId { get; set; }
/// <summary>
/// 使用版本
///</summary>
[SugarColumn(ColumnName = "version")]
public string Version { get; set; }
/// <summary>
/// 平台类型
///</summary>
[SugarColumn(ColumnName = "platform_type")]
public int PlatformType { get; set; }
/// <summary>
/// 房间号
///</summary>
[SugarColumn(ColumnName = "room_num")]
public string RoomNum { get; set; }
/// <summary>
/// 进房时间
///</summary>
[SugarColumn(ColumnName = "join_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public DateTime JoinTime { get; set; }
}
}

View File

@ -1,48 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.Enums
{
/// <summary>
/// 反馈问题枚举
/// </summary>
public enum FeedbackIssueEnums
{
/// <summary>
/// 其他
/// </summary>
Other = 1,
/// <summary>
/// 软件卡顿
/// </summary>
SoftwareLag = 2,
/// <summary>
/// 设计不合理
/// </summary>
UnreasonableDesign = 3,
/// <summary>
/// 功能太少
/// </summary>
TooLittleFeatures = 4,
/// <summary>
/// 通话不流畅
/// </summary>
CallIsNotSmooth = 5,
/// <summary>
/// 视频卡顿
/// </summary>
VideoLag = 6,
/// <summary>
/// 操作麻烦
/// </summary>
OperationTrouble
}
}

View File

@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WGShare.Domain.Enums
{
/// <summary>
///
/// </summary>
public enum SubjectType
{
/// <summary>
/// 全部科目
/// </summary>
[Description("全部科目")]
All = 0,
/// <summary>
/// 语文
/// </summary>
[Description("语文")]
Chinese = 1,
/// <summary>
/// 数学
/// </summary>
[Description("数学")]
Math = 2,
/// <summary>
/// 英语
/// </summary>
[Description("英语")]
English = 3,
/// <summary>
/// 物理
/// </summary>
[Description("物理")]
Physical = 4,
/// <summary>
/// 化学
/// </summary>
[Description("化学")]
Chemical = 5,
/// <summary>
/// 生物
/// </summary>
[Description("生物")]
Biological = 6,
/// <summary>
/// 政治
/// </summary>
[Description("政治")]
Political = 7,
/// <summary>
/// 历史
/// </summary>
[Description("历史")]
History = 8,
/// <summary>
/// 地理
/// </summary>
[Description("地理")]
Geographic = 9
}
}

View File

@ -1,6 +1,4 @@
using System.Net.Http.Json; using System.Net.Http.Json;
using WGShare.Domain.DTOs.AgoraCallback;
using WGShare.Domain.Entities;
namespace WGShare.Domain.FriendlyException namespace WGShare.Domain.FriendlyException
{ {
@ -41,39 +39,6 @@ namespace WGShare.Domain.FriendlyException
return reponse.IsSuccessStatusCode; return reponse.IsSuccessStatusCode;
} }
public static async Task JoinAsync(EventBody eventBody, Room roomInfo)
{
// 获取当前的日期
DateTime today = DateTime.Today;
// 定义东八区的时区信息
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
// 创建东八区今天00:00:01的DateTime对象
DateTime startOfDayLocal = new DateTime(today.Year, today.Month, today.Day, 0, 0, 1, DateTimeKind.Unspecified);
// 创建东八区今天23:59:00的DateTime对象
DateTime endOfDayLocal = new DateTime(today.Year, today.Month, today.Day, 23, 59, 0, DateTimeKind.Unspecified);
// 将时间转换为UTC
DateTimeOffset startOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(startOfDayLocal, timeZoneInfo);
DateTimeOffset endOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(endOfDayLocal, timeZoneInfo);
// 获取Unix时间戳
long startTimestamp = startOfDayUtc.ToUnixTimeSeconds();
long endTimestamp = endOfDayUtc.ToUnixTimeSeconds();
var reponse = await httpClient.PostAsync(string.Empty, JsonContent.Create(new
{
msgtype = "markdown",
markdown = new
{
title = "有人入会通知",
text = $"有人进入会议室了,学校:{roomInfo.TenantName},会议室名称:{roomInfo.RoomName},会议号:{eventBody.payload.channelName}. \r\n 点击查看https://analytics-lab.agora.io/analytics/call/search?projectId=0tOpVUrmf&fromTs={startTimestamp}&toTs={endTimestamp}"
},
}));
}
} }
} }

View File

@ -11,7 +11,7 @@ namespace WGShare.Domain.GeneralModel
public class PagedResult<TEntity> public class PagedResult<TEntity>
{ {
public PagedResult() { } public PagedResult() { }
public PagedResult(IEnumerable<TEntity> list, int total, int pageSize = 10) public PagedResult(IEnumerable<TEntity> list, int total)
{ {
Total = total; Total = total;
Items = list; Items = list;
@ -20,19 +20,9 @@ namespace WGShare.Domain.GeneralModel
public int Total { get; set; } public int Total { get; set; }
public IEnumerable<TEntity> Items { get; private set; } public IEnumerable<TEntity> Items { get; private set; }
private int pageSize = 10; public static PagedResult<TEntity> Create(IEnumerable<TEntity> list, int total)
public int TotalPage
{ {
get return new PagedResult<TEntity>(list, total);
{
return (int)Math.Ceiling(Total / (double)pageSize);
}
}
public static PagedResult<TEntity> Create(IEnumerable<TEntity> list, int total, int pageSize = 10)
{
return new PagedResult<TEntity>(list, total, pageSize);
} }
} }
} }