From bc77b85686ddd497d457e626347e28a4e5d1b1c3 Mon Sep 17 00:00:00 2001 From: youngq Date: Wed, 7 Aug 2024 16:22:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=85=B1=E4=BA=AB=E5=B1=8F?= =?UTF-8?q?=E5=B9=95id=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Backend/UserController.cs | 24 +++++++++++------ .../Controllers/Frontend/RoomController.cs | 8 +++++- .../Controllers/Frontend/UserController.cs | 15 +++++------ WGShare.API/Helpers/UserShareIdHelper.cs | 26 +++++++++++++++++++ WGShare.API/Hubs/IMessageClient.cs | 6 +++++ WGShare.API/Hubs/SessionManageHub.cs | 23 +++++++++++----- WGShare.API/WGShare.API.csproj | 1 + WGShare.API/WGShare.API.xml | 12 +++++++++ WGShare.Domain/DTOs/User/UserOutputDTO.cs | 4 +++ 9 files changed, 94 insertions(+), 25 deletions(-) create mode 100644 WGShare.API/Helpers/UserShareIdHelper.cs diff --git a/WGShare.API/Controllers/Backend/UserController.cs b/WGShare.API/Controllers/Backend/UserController.cs index c842263..ebfcbdd 100644 --- a/WGShare.API/Controllers/Backend/UserController.cs +++ b/WGShare.API/Controllers/Backend/UserController.cs @@ -1,8 +1,10 @@ using Mapster; using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; using SqlSugar; using WGShare.API.Controllers.Basic; +using WGShare.API.Helpers; using WGShare.Domain.DTOs.User; using WGShare.Domain.Entities; using WGShare.Domain.FriendlyException; @@ -56,14 +58,8 @@ namespace WGShare.API.Controllers.Backend [HttpPost] public async Task Add([FromBody] UserInputDTO userInput) { - var entity = userInput.Adapt(); - - // 获取当前时间的Unix时间戳(以毫秒为单位) - long unixTimeMilliseconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - // 将Unix时间戳转换为字符串并截取最后7位 - string last7Digits = unixTimeMilliseconds.ToString().Substring(unixTimeMilliseconds.ToString().Length - 7); - - entity.ScreenShareId = $@"{last7Digits}{new Random().Next(10, 100)}"; + var entity = userInput.Adapt(); + entity.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(); if (await _sqlSugar.Queryable().AnyAsync(x => x.Account == entity.Account)) { @@ -122,5 +118,17 @@ namespace WGShare.API.Controllers.Backend await _sqlSugar.Insertable(entity).ExecuteCommandAsync(); } + + ///// + ///// Excel 导入用户 + ///// + ///// + ///// + //[HttpPost("import")] + //public async Task Import([FromForm] IFormFile file) + //{ + // using var stream = file.OpenReadStream(); + // MiniExcel.Query(stream); + //} } } diff --git a/WGShare.API/Controllers/Frontend/RoomController.cs b/WGShare.API/Controllers/Frontend/RoomController.cs index b57b060..f28216b 100644 --- a/WGShare.API/Controllers/Frontend/RoomController.cs +++ b/WGShare.API/Controllers/Frontend/RoomController.cs @@ -359,7 +359,7 @@ namespace WGShare.API.Controllers.Frontend // 获取全员观看用户 var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.RoomManager.GetChannelShowUserKey(TenantId), roomNum); - if (!string.IsNullOrWhiteSpace(showUserId) && channelUsers.Any(x => x.Value.UID == showUserId)) + if (!string.IsNullOrWhiteSpace(showUserId)) { return showUserId; } @@ -376,6 +376,12 @@ namespace WGShare.API.Controllers.Frontend { // 设置房间全员观看用户 RedisHelper.Instance.HSet(RedisKeyConstant.RoomManager.GetChannelShowUserKey(TenantId), roomNum, uid); + + var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId); + if (!string.IsNullOrWhiteSpace(connectId)) + { + await _hubContext.Clients.GroupExcept(roomNum, connectId).ShowUser(); + } } #region 文件分享 diff --git a/WGShare.API/Controllers/Frontend/UserController.cs b/WGShare.API/Controllers/Frontend/UserController.cs index 67d25cd..dfcbbd9 100644 --- a/WGShare.API/Controllers/Frontend/UserController.cs +++ b/WGShare.API/Controllers/Frontend/UserController.cs @@ -1,6 +1,7 @@ using Mapster; using Microsoft.AspNetCore.Mvc; using SqlSugar; +using System; using WGShare.API.Controllers.Basic; using WGShare.API.Helpers; using WGShare.Domain.Constant; @@ -51,7 +52,8 @@ namespace WGShare.API.Controllers.Frontend UserName = u.UserName, Account = u.Account, RoleId = r.Id, - RoleName = r.RoleName + RoleName = r.RoleName, + ScreenShareId = u.ScreenShareId }) .ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total); @@ -72,14 +74,8 @@ namespace WGShare.API.Controllers.Frontend { var user = inputDTO.Adapt(); //user.Id = YitIdHelper.NextId().ToString(); - user.TenantId = TenantId; - - // 获取当前时间的Unix时间戳(以毫秒为单位) - long unixTimeMilliseconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - // 将Unix时间戳转换为字符串并截取最后7位 - string last7Digits = unixTimeMilliseconds.ToString().Substring(unixTimeMilliseconds.ToString().Length - 7); - - user.ScreenShareId = $@"{last7Digits}{new Random().Next(10, 100)}"; + user.TenantId = TenantId; + user.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(); if (await _sqlSugar.Queryable().AnyAsync(x => x.Account == user.Account)) { @@ -134,5 +130,6 @@ namespace WGShare.API.Controllers.Frontend .SetColumns(x => x.IsDelete == true) .Where(x => ids.Contains(x.Id)).ExecuteCommandHasChangeAsync(); } + } } diff --git a/WGShare.API/Helpers/UserShareIdHelper.cs b/WGShare.API/Helpers/UserShareIdHelper.cs new file mode 100644 index 0000000..73f9bf6 --- /dev/null +++ b/WGShare.API/Helpers/UserShareIdHelper.cs @@ -0,0 +1,26 @@ +namespace WGShare.API.Helpers +{ + public class UserShareIdHelper + { + + /// + /// 生成用户共享ID 8位数字 + /// + /// + public static string GenerateUnique8DigitNumber() + { + int uniqueNumber; + Random random = new Random(); + // 确保生成的数字不会重复 + do + { + long ticks = DateTime.UtcNow.Ticks; + int randomPart = random.Next(1000, 10000); // 随机生成4位数字 + uniqueNumber = int.Parse((ticks % 10000).ToString("D4") + randomPart.ToString("D4")); // 拼接成8位数字 + } while (RedisHelper.Instance.SIsMember("screen_share_id", uniqueNumber)); + + RedisHelper.Instance.SAdd("screen_share_id", uniqueNumber); + return uniqueNumber.ToString(); + } + } +} diff --git a/WGShare.API/Hubs/IMessageClient.cs b/WGShare.API/Hubs/IMessageClient.cs index 7d6911b..ab922bb 100644 --- a/WGShare.API/Hubs/IMessageClient.cs +++ b/WGShare.API/Hubs/IMessageClient.cs @@ -62,5 +62,11 @@ /// /// Task RefreshView(string type); + + /// + /// 全员观看 + /// + /// + Task ShowUser(); } } diff --git a/WGShare.API/Hubs/SessionManageHub.cs b/WGShare.API/Hubs/SessionManageHub.cs index ee22c93..426a597 100644 --- a/WGShare.API/Hubs/SessionManageHub.cs +++ b/WGShare.API/Hubs/SessionManageHub.cs @@ -25,13 +25,14 @@ namespace WGShare.API.Hubs var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.Value; var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value; + var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; Console.WriteLine($"{DateTime.Now}连接成功 当前租户:" + tenant); Console.WriteLine($"{DateTime.Now} 连接成功 account:" + account); Console.WriteLine($"{DateTime.Now} 连接成功 uid:" + uid); Console.WriteLine($"{DateTime.Now}连接成功 connectId:" + Context.ConnectionId); - await ClearUserChannel(uid, tenant, account); + await ClearUserChannel(uid, tenant, account, ssid); // 存储在线信息 RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid, Context.ConnectionId); } @@ -41,6 +42,7 @@ namespace WGShare.API.Hubs var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.Value; var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value; + var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; Console.WriteLine($"{DateTime.Now}断开连接 当前租户:" + tenant); Console.WriteLine($"{DateTime.Now}断开连接 account:" + account); @@ -51,13 +53,13 @@ namespace WGShare.API.Hubs { Console.WriteLine($"{DateTime.Now}断开连接 未重连,开始删除用户频道信息"); // 断开后未重连则清退频道 - await ClearUserChannel(uid, tenant, account); + await ClearUserChannel(uid, tenant, account, ssid); } } - private async Task ClearUserChannel(string uid, string tenant, string account) + private async Task ClearUserChannel(string uid, string tenant, string account, string ssid) { Console.WriteLine($"{DateTime.Now} 执行删除开始"); // 获取用户参加得频道 @@ -72,9 +74,12 @@ namespace WGShare.API.Hubs { pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid); - var script = $@"if (redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2]) then return redis.call('HDEL', KEYS[1], ARGV[1]) else return -1 end"; + 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.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid); + pipe.Eval(script, [RedisKeyConstant.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid, ssid); }); } @@ -131,6 +136,7 @@ namespace WGShare.API.Hubs var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value; var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == "uid")?.Value; var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value; + var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value; Console.WriteLine($" {DateTime.Now}离开频道 会议号:" + roomNum); @@ -139,9 +145,12 @@ namespace WGShare.API.Hubs using (var pipe = RedisHelper.Instance.StartPipe()) { - var script = $@"if (redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2]) then return redis.call('HDEL', KEYS[1], ARGV[1]) else return -1 end"; + 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.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid); + pipe.Eval(script, [RedisKeyConstant.RoomManager.GetChannelShowUserKey(tenant)], roomNum, uid, ssid); pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid); pipe.HDel(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum); pipe.EndPipe(); diff --git a/WGShare.API/WGShare.API.csproj b/WGShare.API/WGShare.API.csproj index cbe3796..4ba7a54 100644 --- a/WGShare.API/WGShare.API.csproj +++ b/WGShare.API/WGShare.API.csproj @@ -15,6 +15,7 @@ + diff --git a/WGShare.API/WGShare.API.xml b/WGShare.API/WGShare.API.xml index 571d373..1166f47 100644 --- a/WGShare.API/WGShare.API.xml +++ b/WGShare.API/WGShare.API.xml @@ -309,6 +309,12 @@ 最大秒数 + + + 生成用户共享ID 8位数字 + + + 客户端消息 @@ -371,6 +377,12 @@ + + + 全员观看 + + + 加入频道 diff --git a/WGShare.Domain/DTOs/User/UserOutputDTO.cs b/WGShare.Domain/DTOs/User/UserOutputDTO.cs index e3ff39d..86fc925 100644 --- a/WGShare.Domain/DTOs/User/UserOutputDTO.cs +++ b/WGShare.Domain/DTOs/User/UserOutputDTO.cs @@ -40,5 +40,9 @@ namespace WGShare.Domain.DTOs.User /// 是否在线 /// public bool IsOnline { get; set; } + /// + /// 共享屏幕ID + /// + public string ScreenShareId { get; set; } } }