1优化重启删除redis问题

This commit is contained in:
youngq 2024-08-09 16:24:26 +08:00
parent 765d241d5b
commit d3aff3ae77
19 changed files with 561 additions and 250 deletions

View File

@ -7,6 +7,7 @@ using System.Configuration;
using System.Security.Claims; using System.Security.Claims;
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.DTOs.Login; using WGShare.Domain.DTOs.Login;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
@ -84,7 +85,7 @@ namespace WGShare.API.Controllers
btnAutn.Add(new Claim("ssid", user.ScreenShareId)); btnAutn.Add(new Claim("ssid", user.ScreenShareId));
var refreshToken = Guid.NewGuid().ToString(); var refreshToken = Guid.NewGuid().ToString();
RedisHelper.Instance.Set($@"refresh:{refreshToken}", user, TimeSpan.FromDays(30).TotalSeconds.ToInt32()); RedisHelper.Instance.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(30).TotalSeconds.ToInt32());
return Ok(new return Ok(new
{ {
@ -109,7 +110,7 @@ namespace WGShare.API.Controllers
[HttpPost("refresh"), AllowAnonymous] [HttpPost("refresh"), AllowAnonymous]
public async Task<IActionResult> Refresh([FromQuery] string refreshToken) public async Task<IActionResult> Refresh([FromQuery] string refreshToken)
{ {
var user = RedisHelper.Instance.Get<User>($@"refresh:{refreshToken}"); var user = RedisHelper.Instance.Get<User>(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
if (user == null || string.IsNullOrWhiteSpace(user.Id)) if (user == null || string.IsNullOrWhiteSpace(user.Id))
{ {
throw new FriendlyInternalException("登录已失效,请重新登录", null, 1403); throw new FriendlyInternalException("登录已失效,请重新登录", null, 1403);
@ -125,8 +126,8 @@ namespace WGShare.API.Controllers
var refreshTokenNew = Guid.NewGuid().ToString(); var refreshTokenNew = Guid.NewGuid().ToString();
RedisHelper.Instance.Del($@"refresh:{refreshToken}"); RedisHelper.Instance.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
RedisHelper.Instance.Set($@"refresh:{refreshTokenNew}", user, TimeSpan.FromDays(30).TotalSeconds.ToInt32()); RedisHelper.Instance.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(30).TotalSeconds.ToInt32());
return Ok(new return Ok(new
{ {
@ -147,7 +148,7 @@ namespace WGShare.API.Controllers
/// 匿名登录,直接进入会议室 /// 匿名登录,直接进入会议室
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost("anon-login"),Obsolete] [HttpPost("anon-login"), Obsolete]
public async Task<IActionResult> Login([FromBody] AnonymousLoginDTO loginDTO) public async Task<IActionResult> Login([FromBody] AnonymousLoginDTO loginDTO)
{ {

View File

@ -1,8 +1,14 @@
using Mapster; using Mapster;
using Masuit.Tools;
using Masuit.Tools.Security;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using MiniExcelLibs; using MiniExcelLibs;
using Newtonsoft.Json.Linq;
using SqlSugar; using SqlSugar;
using System;
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.User; using WGShare.Domain.DTOs.User;
@ -18,10 +24,13 @@ namespace WGShare.API.Controllers.Backend
public class UserController : BasicController public class UserController : BasicController
{ {
private readonly ISqlSugarClient _sqlSugar; private readonly ISqlSugarClient _sqlSugar;
private readonly OssHelper _ossHelper;
public UserController(ISqlSugarClient sqlSugar) public UserController(ISqlSugarClient sqlSugar,
OssHelper ossHelper)
{ {
_sqlSugar = sqlSugar; _sqlSugar = sqlSugar;
this._ossHelper = ossHelper;
} }
@ -58,7 +67,7 @@ namespace WGShare.API.Controllers.Backend
[HttpPost] [HttpPost]
public async Task<bool> Add([FromBody] UserInputDTO userInput) public async Task<bool> Add([FromBody] UserInputDTO userInput)
{ {
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)) if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account))
@ -119,16 +128,76 @@ namespace WGShare.API.Controllers.Backend
await _sqlSugar.Insertable(entity).ExecuteCommandAsync(); await _sqlSugar.Insertable(entity).ExecuteCommandAsync();
} }
///// <summary> /// <summary>
///// Excel 导入用户 /// Excel 导入用户
///// </summary> /// </summary>
///// <param name="file"></param> /// <param name="file"></param>
///// <returns></returns> /// <returns></returns>
//[HttpPost("import")] [HttpPost("import")]
//public async Task<bool> Import([FromForm] IFormFile file) public async Task<IActionResult> Import([FromForm] IFormFile file, [FromForm] string tenantId)
//{ {
// using var stream = file.OpenReadStream(); using var stream = file.OpenReadStream();
// MiniExcel.Query<ChannelUserInfo>(stream); var rows = stream.Query<UserExcelInputDto>().ToList();
//} if (rows.IsNullOrEmpty())
{
throw Oops.Oh("无有效数据,请检查文件数据!");
}
var accounts = rows.Select(x => x.Account.Trim());
var repeatAccount = accounts.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key).ToHashSet();
// 去除重复账号
var distinctAccount = accounts.Except(repeatAccount);
// 数据库重复账号检查
var existsAccount = await _sqlSugar.Queryable<User>()
.Where(x => distinctAccount.Contains(x.Account))
.Select(x => x.Account)
.ToListAsync();
if (!existsAccount.IsNullOrEmpty())
{
repeatAccount.UnionWith(existsAccount);
}
if (!repeatAccount.IsNullOrEmpty())
{
// 重复账号返回结果Excel
foreach (var row in rows)
{
if (repeatAccount.Contains(row.Account))
{
row.ImportResult = "账号重复";
}
else
{
row.ImportResult = "可导入";
}
}
//FileStreamResult fileStream = null;
using var memoryStream = new MemoryStream();
memoryStream.SaveAs(rows);
memoryStream.Seek(0, SeekOrigin.Begin);
var fileName = $@"excel/{Regex.Replace(file.FileName, @"\.(xlsx|xls)$", "", RegexOptions.IgnoreCase)}_验证不通过_{DateTime.UtcNow.Ticks}.xlsx";
_ossHelper.UploadWithExpireTime(fileName, memoryStream, 1);
var fileUrl = _ossHelper.GetAccessFileUrl(fileName, 1);
return Ok((isSuccess: false, url: fileUrl));
}
var users = rows.Adapt<List<User>>();
users.ForEach(x =>
{
x.Pwd = x.Pwd.MDString();
x.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
x.TenantId = tenantId;
x.RoleId = x.RoleId == "管理员" ? "1" : "2";
});
await _sqlSugar.Insertable(users).ExecuteCommandAsync();
return Ok((isSuccess: true, url: "导入成功"));
}
} }
} }

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SqlSugar.Extensions; using SqlSugar.Extensions;
using WGShare.API.Helpers;
using WGShare.Domain.Constant;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
namespace WGShare.API.Controllers.Basic namespace WGShare.API.Controllers.Basic
@ -74,5 +76,33 @@ namespace WGShare.API.Controllers.Basic
return tenant; return tenant;
} }
} }
public string ScreenShareId
{
get
{
var ssId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ssid").Value;
if (string.IsNullOrWhiteSpace(ssId))
{
throw Oops.Oh("用户信息有误,请重新登录");
}
return ssId;
}
}
public string ConnectionId
{
get
{
var connectid = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId);
if (string.IsNullOrWhiteSpace(connectid))
{
throw Oops.Oh("用户信息有误,请重新登录");
}
return connectid;
}
}
} }
} }

View File

@ -15,8 +15,10 @@ using WGShare.API.Hubs;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.File; using WGShare.Domain.DTOs.File;
using WGShare.Domain.DTOs.Room; using WGShare.Domain.DTOs.Room;
using WGShare.Domain.DTOs.Tenant;
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;
@ -52,33 +54,27 @@ namespace WGShare.API.Controllers.Frontend
this._logger = logger; this._logger = logger;
} }
///// <summary>
///// 获取会议室管理员
///// </summary>
///// <returns></returns>
//[HttpGet("manager")]
//public async Task<List<string>> GetRoomManager([FromQuery] string roomId)
//{
// return await _sqlSugar.Queryable<RoomManager>()
// .Where(x => x.RoomId == roomId)
// .Select(x => x.UserId)
// .ToListAsync();
//}
/// <summary> /// <summary>
/// 设置房间管理员 /// 设置房间管理员
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost("manager")] [HttpPost("manager")]
public async Task<bool> SetRoomManager([FromQuery] string roomId, [FromBody] List<string> userIds) public async Task SetRoomManager([FromQuery] string roomId, [FromQuery] string roomNum, [FromBody] string userId)
{ {
var entities = userIds.ConvertAll(x => new RoomManager var entities = new RoomManager
{ {
RoomId = roomId, RoomId = roomId,
UserId = x UserId = userId
}); };
return await _sqlSugar.Insertable(entities).ExecuteCommandAsync() > 0; var user = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), userId);
user.IsRoomManager = true;
await _sqlSugar.Insertable(entities).ExecuteCommandAsync();
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), userId, user);
await _hubContext.Clients.Group(roomNum).ManagerRefresh(user);
} }
/// <summary> /// <summary>
@ -86,54 +82,33 @@ namespace WGShare.API.Controllers.Frontend
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpDelete("manager")] [HttpDelete("manager")]
public async Task<bool> DelRoomManager([FromQuery] string roomId, [FromBody] List<string> userIds) public async Task DelRoomManager([FromQuery] string roomId, [FromQuery] string roomNum, [FromBody] string userId)
{ {
return await _sqlSugar.Deleteable<RoomManager>() await _sqlSugar.Deleteable<RoomManager>()
.Where(x => x.RoomId == roomId && userIds.Contains(x.UserId)) .Where(x => x.RoomId == roomId && x.UserId == userId)
.ExecuteCommandAsync() > 0; .ExecuteCommandAsync();
var user = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), userId);
user.IsRoomManager = false;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), userId, user);
await _hubContext.Clients.Group(roomNum).ManagerRefresh(user);
} }
/// <summary> /// <summary>
/// 查询用户信息 /// 查询房间中所有用户信息
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("user")] [HttpGet("user")]
public async Task<List<UserOutputDTO>> GetUsers([FromQuery] string roomNum) public async Task<IEnumerable<ChannelUserInfo>> GetUsers([FromQuery] string roomNum)
{ {
var channelUsers = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum)); var channelUsers = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (channelUsers.IsNullOrEmpty()) if (channelUsers.IsNullOrEmpty())
{ {
return new List<UserOutputDTO>(); return new List<ChannelUserInfo>();
} }
var uids = channelUsers.Select(x => x.UID); return channelUsers;
var users = await _sqlSugar.Queryable<User>()
.Where(x => uids.Contains(x.Id))
.ToListAsync();
var managerIds = await _sqlSugar.Queryable<RoomManager>()
.InnerJoin<Room>((rm, r) => r.Id == rm.RoomId)
.Where((rm, r) => r.RoomNum == roomNum)
.Select((rm, r) => rm.UserId)
.ToListAsync();
var result = users.Adapt<List<UserOutputDTO>>();
result.ForEach(x =>
{
x.IsManager = (x.RoleId == "1" || managerIds.Contains(x.Id));
var info = channelUsers.FirstOrDefault(q => q.UID == x.Id);
if (info != null)
{
x.EnableMicr = info.EnableMicr;
x.EnableCamera = info.EnableCamera;
}
});
return result;
#region #region
//var data = await _agoraHelper.GetChannelUserList(roomNum); //var data = await _agoraHelper.GetChannelUserList(roomNum);
@ -244,33 +219,39 @@ namespace WGShare.API.Controllers.Frontend
} }
/// <summary> /// <summary>
/// 开闭麦 /// 全部人开闭麦
/// </summary>
/// <returns></returns>
[HttpGet("mute-all")]
public async Task MuteAll([FromQuery] string roomNum, [FromQuery] bool enableMicr)
{
// 全员静音
var allUsers = RedisHelper.Instance.HGetAll<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (!allUsers.Any())
{
return;
}
allUsers.ForEach(x =>
{
// 排除自己
if (x.Key != UId)
{
x.Value.EnableMicr = enableMicr;
}
});
RedisHelper.Instance.HMSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), allUsers);
// 通知其他人
await _hubContext.Clients.GroupExcept(roomNum, allUsers[UId].ConnectId).OperAllMicr(enableMicr);
}
/// <summary>
/// 单用户开闭麦
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("oper-micr")] [HttpGet("oper-micr")]
public async Task Mute([FromQuery] string roomNum, [FromQuery] bool enableMicr, [FromQuery] string? uid, [FromQuery] bool? isAll = false) public async Task Mute([FromQuery] string roomNum, [FromQuery] bool enableMicr, [FromQuery] string uid)
{ {
if (isAll.HasValue && isAll.Value)
{
// 全员静音
var allUsers = RedisHelper.Instance.HGetAll<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (!allUsers.Any())
{
return;
}
allUsers.ForEach(x =>
{
if (x.Key != uid)
{
x.Value.EnableMicr = enableMicr;
}
});
RedisHelper.Instance.HMSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), allUsers);
await _hubContext.Clients.GroupExcept(roomNum, allUsers[uid].ConnectId).OperMicr(enableMicr);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
return;
}
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid); var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid);
if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId)) if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId))
@ -282,8 +263,8 @@ 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);
await _hubContext.Clients.Clients(userInfo.ConnectId).OperMicr(enableMicr); // 通知所有人该用户麦克风状态
await _hubContext.Clients.Group(roomNum).RefreshUserList(); await _hubContext.Clients.Group(roomNum).OperMicr(userInfo);
} }
/// <summary> /// <summary>
@ -291,33 +272,8 @@ namespace WGShare.API.Controllers.Frontend
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("oper-camera")] [HttpGet("oper-camera")]
public async Task CloseCamera([FromQuery] string roomNum, [FromQuery] bool enableCamera, [FromQuery] string? uid, [FromQuery] bool? isAll = false) public async Task CloseCamera([FromQuery] string roomNum, [FromQuery] bool enableCamera, [FromQuery] string uid)
{ {
if (isAll.HasValue && isAll.Value)
{
var allUsers = RedisHelper.Instance.HGetAll<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (!allUsers.Any())
{
return;
}
allUsers.ForEach(x =>
{
if (x.Key != uid)
{
x.Value.EnableCamera = enableCamera;
}
});
//allUsers.ForEach(x => x.Value.EnableCamera = enableCamera);
RedisHelper.Instance.HMSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), allUsers);
// 全员开关闭摄像头
await _hubContext.Clients.GroupExcept(roomNum, allUsers[uid].ConnectId).OperCamera(enableCamera);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
return;
}
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid); var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid);
if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId)) if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId))
{ {
@ -328,8 +284,8 @@ namespace WGShare.API.Controllers.Frontend
userInfo.EnableCamera = enableCamera; userInfo.EnableCamera = enableCamera;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
await _hubContext.Clients.Clients(userInfo.ConnectId).OperCamera(enableCamera); // 通知所有人该用户麦克风状态
await _hubContext.Clients.Group(roomNum).RefreshUserList(); await _hubContext.Clients.Group(roomNum).OperCamera(userInfo);
} }
/// <summary> /// <summary>
@ -358,7 +314,7 @@ namespace WGShare.API.Controllers.Frontend
} }
// 获取全员观看用户 // 获取全员观看用户
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.RoomManager.GetChannelShowUserKey(TenantId), roomNum); var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum);
if (!string.IsNullOrWhiteSpace(showUserId)) if (!string.IsNullOrWhiteSpace(showUserId))
{ {
return showUserId; return showUserId;
@ -372,10 +328,10 @@ namespace WGShare.API.Controllers.Frontend
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost("show-user")] [HttpPost("show-user")]
public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string uid) public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string? uid)
{ {
// 设置房间全员观看用户 // 设置房间全员观看用户
RedisHelper.Instance.HSet(RedisKeyConstant.RoomManager.GetChannelShowUserKey(TenantId), roomNum, uid); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, uid);
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId); var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId);
if (!string.IsNullOrWhiteSpace(connectId)) if (!string.IsNullOrWhiteSpace(connectId))
@ -384,6 +340,69 @@ namespace WGShare.API.Controllers.Frontend
} }
} }
/// <summary>
/// 加入频道
/// </summary>
/// <param name="roomNum"></param>
/// <param name="enableMicr"></param>
/// <param name="enableCamera"></param>
/// <returns></returns>
[HttpGet("join")]
public async Task JoinChannel([FromQuery] string roomNum, [FromQuery] bool enableMicr = false, [FromQuery] bool enableCamera = false)
{
var isManager = await _sqlSugar.Queryable<RoomManager>()
.InnerJoin<Room>((rm, r) => r.Id == rm.RoomId)
.Where((rm, r) => r.RoomNum == roomNum && rm.UserId == UId)
.AnyAsync();
var userInfo = new ChannelUserInfo
{
UID = UId,
UserName = UserName,
EnableCamera = enableCamera,
EnableMicr = enableMicr,
ConnectId = ConnectionId,
Account = Account,
ScreenShareId = ScreenShareId,
RoleId = RoleId,
RoleName = ((RoleEnums)RoleId.ToInt32()).GetDescription(),
IsRoomManager = isManager
};
using (var pipe = RedisHelper.Instance.StartPipe())
{
pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId, userInfo.ToJsonString());
pipe.HSet(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId), roomNum, 1);
pipe.EndPipe();
}
await _hubContext.Groups.AddToGroupAsync(ConnectionId, roomNum);
await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserJoined(userInfo);
}
/// <summary>
/// 离开频道
/// </summary>
/// <param name="roomNum"></param>
/// <returns></returns>
[HttpGet("leave")]
public async Task LevelChannel([FromQuery] string roomNum)
{
using (var pipe = RedisHelper.Instance.StartPipe())
{
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(TenantId)], roomNum, UId, ScreenShareId);
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId);
pipe.HDel(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId), roomNum);
pipe.EndPipe();
}
await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserLeave(UId);
await _hubContext.Groups.RemoveFromGroupAsync(ConnectionId, roomNum);
}
#region #region
/// <summary> /// <summary>
/// 分享上传文件 /// 分享上传文件

View File

@ -1,12 +1,15 @@
using Masuit.Tools; using Masuit.Tools;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using SqlSugar; using SqlSugar;
using System.Configuration; using System.Configuration;
using System.Security.Claims; using System.Security.Claims;
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.User;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.FriendlyException; using WGShare.Domain.FriendlyException;
@ -34,6 +37,6 @@ namespace WGShare.API.Controllers
public async Task<List<Role>> GetDropDownList() public async Task<List<Role>> GetDropDownList()
{ {
return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync(); return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync();
} }
} }
} }

View File

@ -0,0 +1,14 @@
using System.ComponentModel;
namespace WGShare.API.Helpers
{
public static class EnumExtensions
{
public static string GetDescription(this Enum val)
{
var field = val.GetType().GetField(val.ToString());
var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
}
}
}

View File

@ -69,16 +69,16 @@ namespace WGShare.API.Helpers
}; };
} }
public string GetAccessFileUrl(string path) public string GetAccessFileUrl(string path, int expireInMinutes = 1)
{ {
if (string.IsNullOrWhiteSpace(path) ) if (string.IsNullOrWhiteSpace(path))
{ {
throw Oops.Oh("路径不能为空!"); throw Oops.Oh("路径不能为空!");
} }
var urlRequest = new GeneratePresignedUriRequest(_bucketName, path) var urlRequest = new GeneratePresignedUriRequest(_bucketName, path)
{ {
Expiration = DateTimeOffset.Now.AddMinutes(1).LocalDateTime Expiration = DateTimeOffset.Now.AddMinutes(expireInMinutes).LocalDateTime
}; };
return _ossClient.GeneratePresignedUri(urlRequest).ToString(); return _ossClient.GeneratePresignedUri(urlRequest).ToString();
@ -95,5 +95,24 @@ namespace WGShare.API.Helpers
return result.HttpStatusCode == System.Net.HttpStatusCode.OK; return result.HttpStatusCode == System.Net.HttpStatusCode.OK;
} }
/// <summary>
/// 流上传文件
/// </summary>
/// <param name="objectName"></param>
/// <param name="stream"></param>
public void UploadWithExpireTime(string objectName, MemoryStream stream, int expireTimeInMinutes)
{
if (expireTimeInMinutes <= 0)
{
throw Oops.Oh("过期时间不能小于0");
}
_ossClient.PutObject(_bucketName, objectName, stream, new ObjectMetadata
{
ExpirationTime = DateTimeOffset.Now.AddMinutes(expireTimeInMinutes).DateTime,
});
}
} }
} }

View File

@ -1,4 +1,6 @@
namespace WGShare.API.Helpers using WGShare.Domain.Constant;
namespace WGShare.API.Helpers
{ {
public class UserShareIdHelper public class UserShareIdHelper
{ {
@ -16,10 +18,10 @@
{ {
long ticks = DateTime.UtcNow.Ticks; long ticks = DateTime.UtcNow.Ticks;
var randomPart = random.Next(1000, 10000).ToString(); // 随机生成4位数字 var randomPart = random.Next(1000, 10000).ToString(); // 随机生成4位数字
uniqueNumber = randomPart + (ticks % 10000).ToString("D4"); // 拼接成8位数字 uniqueNumber = randomPart + (ticks % 10000).ToString("D5"); // 拼接成8位数字
} while (RedisHelper.Instance.SIsMember("screen_share_id", uniqueNumber)); } while (RedisHelper.Instance.SIsMember(RedisKeyConstant.Data.GetScreenShareIdKey, uniqueNumber));
RedisHelper.Instance.SAdd("screen_share_id", uniqueNumber); RedisHelper.Instance.SAdd(RedisKeyConstant.Data.GetScreenShareIdKey, uniqueNumber);
return uniqueNumber; return uniqueNumber;
} }
} }

View File

@ -1,4 +1,7 @@
namespace WGShare.API.Hubs using WGShare.Domain.DTOs.User;
using WGShare.Domain.Entities;
namespace WGShare.API.Hubs
{ {
/// <summary> /// <summary>
/// 客户端消息 /// 客户端消息
@ -30,20 +33,6 @@
/// <returns></returns> /// <returns></returns>
Task ForceExitRoom(string roomNum); Task ForceExitRoom(string roomNum);
/// <summary>
/// 用户开闭麦
/// </summary>
/// <param name="enableMicr"></param>
/// <returns></returns>
Task OperMicr(bool enableMicr);
/// <summary>
/// 用户开启关闭摄像头
/// </summary>
/// <param name="enableCamera"></param>
/// <returns></returns>
Task OperCamera(bool enableCamera);
/// <summary> /// <summary>
/// 刷新用户列表 /// 刷新用户列表
/// </summary> /// </summary>
@ -68,5 +57,45 @@
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task ShowUser(); Task ShowUser();
/// <summary>
/// 用户加入频道回调
/// </summary>
/// <returns></returns>
Task UserJoined(ChannelUserInfo user);
/// <summary>
/// 用户退出频道回调
/// </summary>
/// <returns></returns>
Task UserLeave(string uid);
/// <summary>
/// 所有用户开闭麦
/// </summary>
/// <param name="enableMicr"></param>
/// <returns></returns>
Task OperAllMicr(bool enableMicr);
/// <summary>
/// 用户关闭开启麦克风
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
Task OperMicr(ChannelUserInfo user);
/// <summary>
/// 用户开启关闭摄像头
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
Task OperCamera(ChannelUserInfo user);
/// <summary>
/// 管理员用户信息刷新
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
Task ManagerRefresh(ChannelUserInfo user);
} }
} }

View File

@ -7,6 +7,7 @@ using System.Text;
using WGShare.API.Helpers; using WGShare.API.Helpers;
using WGShare.Domain.Constant; using WGShare.Domain.Constant;
using WGShare.Domain.Entities; using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
namespace WGShare.API.Hubs namespace WGShare.API.Hubs
{ {
@ -79,7 +80,7 @@ namespace WGShare.API.Hubs
return redis.call('HDEL', KEYS[1], ARGV[1]) return redis.call('HDEL', KEYS[1], ARGV[1])
else return -1 end"; else return -1 end";
// 执行 eval 命令 // 执行 eval 命令
pipe.Eval(script, [RedisKeyConstant.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid, ssid); pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
}); });
} }
@ -101,62 +102,79 @@ 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 = true, bool enableCamera = true) 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 == "uid")?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.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 == "role")?.Value;
Console.WriteLine($"{DateTime.Now}加入频道 会议号:" + roomNum); Console.WriteLine($"{DateTime.Now}加入频道 会议号:" + roomNum);
Console.WriteLine($"{DateTime.Now}加入频道 account" + account); Console.WriteLine($"{DateTime.Now}加入频道 account" + account);
Console.WriteLine($"{DateTime.Now}加入频道 tenant" + tenant); Console.WriteLine($"{DateTime.Now}加入频道 tenant" + tenant);
using (var pipe = RedisHelper.Instance.StartPipe()) //using (var pipe = RedisHelper.Instance.StartPipe())
{ //{
var userInfo = new ChannelUserInfo(uid, Context.ConnectionId, enableMicr, enableCamera, account, ssid); // var userInfo = new ChannelUserInfo(uid, Context.ConnectionId, enableMicr, enableCamera, account, ssid);
pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid, userInfo.ToJsonString()); // pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid, userInfo.ToJsonString());
//pipe.HIncrBy(RedisKeyConstant.SessionManage.GetChannelUserCountKey(tenant), roomNum, 1); // //pipe.HIncrBy(RedisKeyConstant.SessionManage.GetChannelUserCountKey(tenant), roomNum, 1);
pipe.HSet(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum, 1); // pipe.HSet(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum, 1);
pipe.EndPipe(); // pipe.EndPipe();
} //}
await Groups.AddToGroupAsync(Context.ConnectionId, roomNum); //await Groups.AddToGroupAsync(Context.ConnectionId, roomNum);
//await Clients.GroupExcept(roomNum, Context.ConnectionId).UserJoined(new Domain.DTOs.User.UserOutputDTO
//{
// Id = uid,
// UserName = uname,
// Account = account,
// RoleId = roleId,
// RoleName = ((RoleEnums)roleId.ToInt32()).GetDescription(),
// EnableCamera = enableCamera,
// EnableMicr = enableMicr,
// ScreenShareId = ssid,
// IsOnline = true,
//});
} }
/// <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;
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.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 == "role")?.Value;
Console.WriteLine($" {DateTime.Now}离开频道 会议号:" + roomNum); Console.WriteLine($" {DateTime.Now}离开频道 会议号:" + roomNum);
Console.WriteLine($" {DateTime.Now}离开频道 account" + account); Console.WriteLine($" {DateTime.Now}离开频道 account" + account);
Console.WriteLine($" {DateTime.Now}离开频道 tenant" + tenant); Console.WriteLine($" {DateTime.Now}离开频道 tenant" + tenant);
using (var pipe = RedisHelper.Instance.StartPipe()) //using (var pipe = RedisHelper.Instance.StartPipe())
{ //{
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
return redis.call('HDEL', KEYS[1], ARGV[1]) // return redis.call('HDEL', KEYS[1], ARGV[1])
else return -1 end"; // else return -1 end";
// 执行 eval 命令 // // 执行 eval 命令
pipe.Eval(script, [RedisKeyConstant.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid, ssid); // pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid); // pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
pipe.HDel(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum); // pipe.HDel(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum);
pipe.EndPipe(); // pipe.EndPipe();
} //}
await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomNum); //await Clients.GroupExcept(roomNum, Context.ConnectionId).UserLeave(uid);
//await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomNum);
} }
/// <summary> /// <summary>

View File

@ -1,5 +1,6 @@
using Hangfire; using Hangfire;
using Masuit.Tools; using Masuit.Tools;
using Microsoft.AspNetCore.Http.Features;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
@ -29,6 +30,13 @@ namespace WGShare.API
}); });
ResetRedisKey(); ResetRedisKey();
builder.Services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = long.MaxValue; // If we are multipart
options.MemoryBufferThreshold = int.MaxValue;
});
builder.Services.AddControllers(options => builder.Services.AddControllers(options =>
{ {
// 全局异常捕获,无需在代码中 写 try catch // 全局异常捕获,无需在代码中 写 try catch
@ -122,7 +130,7 @@ namespace WGShare.API
} }
while (nextCursor != 0); while (nextCursor != 0);
var keysArr = keys.ConvertAll(x => x.Replace("wgshare:", "")).Where(x => !x.StartsWith("refresh")).Distinct().ToArray(); var keysArr = keys.ConvertAll(x => x.Replace("wgshare:", "")).Where(x => x.StartsWith("SessionManage")).Distinct().ToArray();
if (!keysArr.IsNullOrEmpty()) if (!keysArr.IsNullOrEmpty())
{ {
Console.WriteLine($@"删除键值:{Environment.NewLine}{string.Join(Environment.NewLine, keysArr)}"); Console.WriteLine($@"删除键值:{Environment.NewLine}{string.Join(Environment.NewLine, keysArr)}");

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="MiniExcel" Version="1.34.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>

View File

@ -60,6 +60,13 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Backend.UserController.Import(Microsoft.AspNetCore.Http.IFormFile,System.String)">
<summary>
Excel 导入用户
</summary>
<param name="file"></param>
<returns></returns>
</member>
<member name="T:WGShare.API.Controllers.Frontend.HomeController"> <member name="T:WGShare.API.Controllers.Frontend.HomeController">
<summary> <summary>
首页接口 首页接口
@ -90,13 +97,13 @@
会议室接口 会议室接口
</summary> </summary>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.SetRoomManager(System.String,System.Collections.Generic.List{System.String})"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.SetRoomManager(System.String,System.String,System.String)">
<summary> <summary>
设置房间管理员 设置房间管理员
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.DelRoomManager(System.String,System.Collections.Generic.List{System.String})"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.DelRoomManager(System.String,System.String,System.String)">
<summary> <summary>
取消房间管理员 取消房间管理员
</summary> </summary>
@ -104,7 +111,7 @@
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.GetUsers(System.String)"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.GetUsers(System.String)">
<summary> <summary>
查询用户信息 查询房间中所有用户信息
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
@ -138,13 +145,19 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.Mute(System.String,System.Boolean,System.String,System.Nullable{System.Boolean})"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.MuteAll(System.String,System.Boolean)">
<summary> <summary>
开闭麦 全部人开闭麦
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.CloseCamera(System.String,System.Boolean,System.String,System.Nullable{System.Boolean})"> <member name="M:WGShare.API.Controllers.Frontend.RoomController.Mute(System.String,System.Boolean,System.String)">
<summary>
单用户开闭麦
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.CloseCamera(System.String,System.Boolean,System.String)">
<summary> <summary>
开关闭摄像头 开关闭摄像头
</summary> </summary>
@ -169,6 +182,22 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.JoinChannel(System.String,System.Boolean,System.Boolean)">
<summary>
加入频道
</summary>
<param name="roomNum"></param>
<param name="enableMicr"></param>
<param name="enableCamera"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Controllers.Frontend.RoomController.LevelChannel(System.String)">
<summary>
离开频道
</summary>
<param name="roomNum"></param>
<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>
分享上传文件 分享上传文件
@ -285,6 +314,13 @@
<param name="expireInSecond">过期时间 秒</param> <param name="expireInSecond">过期时间 秒</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Helpers.OssHelper.UploadWithExpireTime(System.String,System.IO.MemoryStream,System.Int32)">
<summary>
流上传文件
</summary>
<param name="objectName"></param>
<param name="stream"></param>
</member>
<member name="T:WGShare.API.Helpers.RedisHelper"> <member name="T:WGShare.API.Helpers.RedisHelper">
<summary> <summary>
redis静态访问类 redis静态访问类
@ -344,20 +380,6 @@
<param name="roomNum">会议号</param> <param name="roomNum">会议号</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.OperMicr(System.Boolean)">
<summary>
用户开闭麦
</summary>
<param name="enableMicr"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.OperCamera(System.Boolean)">
<summary>
用户开启关闭摄像头
</summary>
<param name="enableCamera"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.RefreshUserList"> <member name="M:WGShare.API.Hubs.IMessageClient.RefreshUserList">
<summary> <summary>
刷新用户列表 刷新用户列表
@ -383,6 +405,46 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.UserJoined(WGShare.Domain.Entities.ChannelUserInfo)">
<summary>
用户加入频道回调
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.UserLeave(System.String)">
<summary>
用户退出频道回调
</summary>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.OperAllMicr(System.Boolean)">
<summary>
所有用户开闭麦
</summary>
<param name="enableMicr"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.OperMicr(WGShare.Domain.Entities.ChannelUserInfo)">
<summary>
用户关闭开启麦克风
</summary>
<param name="user"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.OperCamera(WGShare.Domain.Entities.ChannelUserInfo)">
<summary>
用户开启关闭摄像头
</summary>
<param name="user"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.IMessageClient.ManagerRefresh(WGShare.Domain.Entities.ChannelUserInfo)">
<summary>
管理员用户信息刷新
</summary>
<param name="user"></param>
<returns></returns>
</member>
<member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)"> <member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)">
<summary> <summary>
加入频道 加入频道

View File

@ -19,7 +19,7 @@ namespace WGShare.Domain.Constant
/// <summary> /// <summary>
/// 在线人数 /// 在线人数
/// </summary> /// </summary>
public static string GetOnlineUserKey(string tenantId) => $@"te_{tenantId}:OnlieUser"; public static string GetOnlineUserKey(string tenantId) => $@"SessionManage:te_{tenantId}:OnlieUser";
/// <summary> /// <summary>
/// 频道用户 /// 频道用户
@ -27,36 +27,41 @@ namespace WGShare.Domain.Constant
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
/// <returns></returns> /// <returns></returns>
public static string GetChannelUserKey(string tenantId, string roomNum) => $@"te_{tenantId}:ch_{roomNum}"; public static string GetChannelUserKey(string tenantId, string roomNum) => $@"SessionManage:te_{tenantId}:ch_{roomNum}";
/// <summary> /// <summary>
/// 用户参与频道 /// 用户参与频道
/// </summary> /// </summary>
/// <param name="uid"></param> /// <param name="uid"></param>
/// <returns></returns> /// <returns></returns>
public static string GetUserJoinChannelKey(string uid) => $@"u_{uid}_join"; public static string GetUserJoinChannelKey(string uid) => $@"SessionManage:u_{uid}_join";
/// <summary>
/// 频道用户数
/// </summary>
/// <param name="tenantId"></param>
/// <returns></returns>
[Obsolete("废弃")]
public static string GetChannelUserCountKey(string tenantId) => $@"te_{tenantId}:ChannelUserCount";
}
/// <summary>
/// 房间管理
/// </summary>
public class RoomManager
{
/// <summary> /// <summary>
/// 获取频道全员观看对象 /// 获取频道全员观看对象
/// </summary> /// </summary>
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="roomNum"></param> /// <param name="roomNum"></param>
/// <returns></returns> /// <returns></returns>
public static string GetChannelShowUserKey(string tenantId) => $@"te_{tenantId}:room_show_user"; public static string GetChannelShowUserKey(string tenantId) => $@"SessionManage:te_{tenantId}:room_show_user";
} }
/// <summary>
/// 持久化数据
/// </summary>
public class Data
{
/// <summary>
/// 获取token
/// </summary>
/// <param name="refreshToken"></param>
/// <returns></returns>
public static string GetRefreshTokenKey(string refreshToken) => $@"data:refresh:{refreshToken}";
public static string GetScreenShareIdKey => $@"data:screen_share_id";
}
} }
} }

View File

@ -0,0 +1,37 @@
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 UserExcelInputDto
{
/// <summary>
/// 用户名称
///</summary>
[ExcelColumnName("用户名称")]
public string UserName { get; set; }
/// <summary>
/// 账号
///</summary>
[ExcelColumnName("登录账号")]
public string Account { get; set; }
/// <summary>
/// 密码
///</summary>
[ExcelColumnName("登录密码")]
public string? Pwd { get; set; }
/// <summary>
///
///</summary>
[ExcelColumnName("角色")]
public string RoleId{ get; set; }
[ExcelColumnName("导入结果")]
public string ImportResult { get; set; } = string.Empty;
}
}

View File

@ -20,22 +20,7 @@ namespace WGShare.Domain.DTOs.User
public string Account { get; set; } public string Account { get; set; }
public string RoleId { get; set; } public string RoleId { get; set; }
public string RoleName { get; set; } public string RoleName { get; set; }
/// <summary>
/// 是否管理员
/// </summary>
public bool IsManager { get; set; }
/// <summary>
/// 是否关闭麦克风
/// </summary>
public bool EnableMicr { get; set; }
/// <summary>
/// 是否关闭摄像头
/// </summary>
public bool EnableCamera { get; set; }
/// <summary> /// <summary>
/// 是否在线 /// 是否在线
/// </summary> /// </summary>

View File

@ -10,27 +10,8 @@ namespace WGShare.Domain.Entities
/// 用户在频道中的状态 /// 用户在频道中的状态
/// </summary> /// </summary>
public class ChannelUserInfo public class ChannelUserInfo
{ {
public ChannelUserInfo()
{
}
/// <summary>
///
/// </summary>
/// <param name="uid"></param>
/// <param name="connectId"></param>
/// <param name="isMute">是否关闭麦克风,默认关</param>
/// <param name="enableCamera">是否关闭摄像头,默认关</param>
public ChannelUserInfo(string uid, string connectId, bool enableMicr, bool enableCamera, string account, string screenShareId)
{
this.UID = uid;
this.ConnectId = connectId;
this.EnableMicr = enableMicr;
this.EnableCamera = enableCamera;
this.Account = account;
this.ScreenShareId = screenShareId;
}
public string UID { get; set; } public string UID { get; set; }
@ -49,5 +30,13 @@ namespace WGShare.Domain.Entities
public bool EnableCamera { get; set; } public bool EnableCamera { get; set; }
public string ScreenShareId { get; set; } public string ScreenShareId { get; set; }
public string UserName { get; set; }
public string RoleId { get; set; }
public string RoleName { get; set; }
/// <summary>
/// 是否房间管理员
/// </summary>
public bool IsRoomManager { get; set; }
} }
} }

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WGShare.Domain.Entities;
namespace WGShare.Domain.Enums
{
/// <summary>
/// 角色枚举
/// </summary>
public enum RoleEnums
{
[Description("管理员")]
Admin = 1,
[Description("普通用户")]
User = 2,
}
}

View File

@ -12,6 +12,7 @@
<PackageReference Include="Masuit.Tools.Core" Version="2024.3.4" /> <PackageReference Include="Masuit.Tools.Core" Version="2024.3.4" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" />
<PackageReference Include="MiniExcel" Version="1.34.0" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.158" /> <PackageReference Include="SqlSugarCore" Version="5.1.4.158" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup> </ItemGroup>