namespace ZhiYi.Core.Application.Services.Implements { public class GroupAppService : IGroupAppService { private readonly IMapper _mapper; private readonly SqlSugarClient _client; private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly IDatabase _redis; private readonly IConnectionClientManagerService _connectionClientManager; private readonly SubscribeAndPublishService _subscribeAndPublishService; public GroupAppService( IMapper mapper, IConfiguration configuration, ILogger logger, IConnectionMultiplexer redis, IConnectionClientManagerService connectionClientManager, SubscribeAndPublishService subscribeAndPublishService ) { _mapper = mapper; _configuration = configuration; string connStr = _configuration.GetSection("ConnectionStrings:SqlConnection").Value; if (_client == null) { _client = SugarClientInit.Instance.GetDdClient(connStr); } _logger = logger; _redis = redis.GetDatabase(); _connectionClientManager = connectionClientManager; _subscribeAndPublishService = subscribeAndPublishService; } /// /// 创建组 /// /// public async Task CreateAsync(GroupCreationDto input) { var group = _mapper.Map(input); group.Id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); group.CreateTime = DateTime.Now; try { //清空对应用户的组缓存 await _redis.KeyDeleteAsync($"group:{input.UserId}"); await _client.Insertable(group).ExecuteCommandAsync(); } catch(Exception ex) { _logger.LogError("创建失败:{message}", ex.Message); throw new Exception("创建失败"); } } /// /// 批量导入分组关系(分组ID导入) /// /// /// public async Task CreateBatchAsync(GroupCreationBatchDto input) { try { //分组去重 保留未导入过的分组 var originalGroupIds = await _client.Queryable() .Where(x => x.Owner == input.UserId && input.Ids.Contains(x.Original_GroupId)) .Select(x => x.Original_GroupId) .Distinct() .ToArrayAsync(); if (originalGroupIds.Any()) { var ids = input.Ids.ToList(); var idsNewList = new List(); ids.ForEach(x => { if (!originalGroupIds.Contains(x)) idsNewList.Add(x); }); input.Ids = idsNewList.ToArray(); } if (input.Ids.Any()) { //当前分组列表 /*var groupList = await _client.Queryable() .Where(x => input.Ids.Contains(x.Id)) .ToListAsync();*/ await _client.BeginTranAsync(); var groupRelationList = new List(); //导入目标分组列表 input.Ids.ToList().ForEach(x => { //分组关系建立 var groupRelation = new ZhiYi_Group_Relation { Id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Original_GroupId = x, Owner = input.UserId }; //新分组ID 其他基本信息同步 /*x.Id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); x.CreateTime = DateTime.Now; x.CreateType = "shared"; x.UserId = input.UserId;*/ groupRelationList.Add(groupRelation); }); //await _client.Insertable(groupList).ExecuteCommandAsync(); if (groupRelationList.Count > 0) await _client.Insertable(groupRelationList).ExecuteCommandAsync(); else throw new Exception("分组关系已存在,请勿重复导入"); //当前分组列表对应服务器列表 /* var serverList = await _client.Queryable() .Where(x => input.Ids.Contains(x.GroupId)) .ToListAsync(); var serverRelationList = new List(); //导入目标服务器列表 serverList.ForEach(x => { //服务器关系建立 var serverRelation = new Zhiyi_Server_Relation { Id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Original_ServerId = x.Id }; //新服务器ID 其他基本信息同步 x.Id = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); serverRelation.Current_ServerId = x.Id; x.CreateTime = DateTime.Now; x.CreateType = "shared"; }); await _client.Insertable(serverList).ExecuteCommandAsync(); if (serverRelationList.Count > 0) await _client.Insertable(serverRelationList).ExecuteCommandAsync(); */ //目标分组和目标服务器缓存清空 await _redis.KeyDeleteAsync($"group:{input.UserId}"); foreach (var id in input.Ids) await _redis.KeyDeleteAsync($"server:{id}"); await _client.CommitTranAsync(); } } catch(Exception ex) { await _client.RollbackTranAsync(); _logger.LogError("批量导入分组失败:{message}", ex.Message); throw new Exception("批量导入分组失败"); } finally { _client.Dispose(); } } /// /// 删除组 /// /// /// public async Task DeleteAsync(GroupDeleteDto input) { try { await _client.BeginTranAsync(); //验证是否为创建人 var exists = await _client.Queryable().AnyAsync(x => x.CreateBy == input.UserId && x.Id == input.Id); if (!exists) throw new Exception("仅能删除自己的分组"); //清空对应用户的分组缓存 await _redis.KeyDeleteAsync($"group:{input.UserId}"); //删除对应用户的分组 await _client.Deleteable().Where(x => x.Id == input.Id).ExecuteCommandAsync(); var groupRelationList = await _client.Queryable() .Where(x => x.Original_GroupId == input.Id) .ToListAsync(); if(groupRelationList.Count > 0) { //清空分享出去对应用户的分组缓存 var userIds = groupRelationList.Select(x => x.Owner).Distinct().ToList(); userIds.ForEach(async x => { await _redis.KeyDeleteAsync($"group:{x}"); }); //删除分组对应关系 await _client.Deleteable(groupRelationList).ExecuteCommandAsync(); /*var newGroupIds = groupRelationList.Select(x => x.Current_GroupId).ToArray(); //删除分享出去对应用户的分组 await _client.Deleteable().Where(x => newGroupIds.Contains(x.Id)).ExecuteCommandAsync();*/ //删除后,通知使用分享码导入的人员已删除,接收通知后刷新分组列表 _ = Task.Run(() => { groupRelationList.ForEach(x => { //await _connectionClientManager.SendAsync(x.Owner.ToString(), JsonConvert.SerializeObject(new MessageDto { Type = "通知", Content = "分组列表已删除" })); _subscribeAndPublishService.Publish(JsonConvert.SerializeObject(new MessageDto { Type = "通知", Content = "分组列表已删除" }), x.Owner.ToString()); }); }); } await _client.CommitTranAsync(); } catch(Exception ex) { await _client.RollbackTranAsync(); _logger.LogError("删除分组失败:{message}", ex.Message); throw new Exception("删除分组失败"); } finally { _client.Dispose(); } } /// /// 获取组列表 /// /// 账号ID /// public async Task>> GetListAsync(long userid) { //缓存获取 var groupValue = await _redis.StringGetAsync($"group:{userid}"); if (groupValue.HasValue) { var groupDto = JsonConvert.DeserializeObject>(groupValue.ToString()); return new AppResponse> { Code = 200, Data = groupDto }; } try { //数据库读 //个人分组 var originalGroupQueryable = _client.Queryable() .Where(x => x.UserId == userid); //分享列表分组 var sharedGroupQueryable = _client.Queryable((a, b) => a.Original_GroupId == b.Id) .Where((a, b) => a.Owner == userid) .Select((a, b) => b); var groupList = await _client.UnionAll(originalGroupQueryable, sharedGroupQueryable).ToListAsync(); await _redis.StringSetAsync($"group:{userid}", JsonConvert.SerializeObject(groupList)); return new AppResponse> { Code = 200, Data = groupList }; } catch(Exception ex) { _logger.LogError("查询组列表失败:{message}", ex.Message); throw new Exception("查询组列表失败"); } } /// /// 更改组名 /// /// /// public async Task UpdateAsync(GroupUpdationDto input) { input.TrimStringFields(); //验证是否为创建人 var exists = await _client.Queryable().AnyAsync(x => x.CreateBy == input.UserId && x.Id == input.Id); if (!exists) throw new Exception("仅能修改自己的分组"); try { await _client.BeginTranAsync(); //清空对应用户的分组缓存 await _redis.KeyDeleteAsync($"group:{input.UserId}"); /*//指定行跟踪 var group = await _client.Queryable().FirstAsync(x => x.Id == input.Id); _client.Tracking(group); //更新实体列 CustomerAppService.ConditionalMap(input, group);*/ var group = _mapper.Map(input); await _client.Updateable(group) .SetColumns(x => x.GroupName == group.GroupName) .Where(x => x.Id == group.Id) .ExecuteCommandAsync(); var groupRelationList = await _client.Queryable() .Where(x => x.Original_GroupId == input.Id) .ToListAsync(); if(groupRelationList.Count > 0) { //清空分享出去对应用户的分组缓存 var userIds = groupRelationList.Select(x => x.Owner).Distinct().ToList(); userIds.ForEach(async x => { await _redis.KeyDeleteAsync($"group:{x}"); }); /*var newGroupIds = groupRelationList.Select(x => x.Current_GroupId).ToArray(); await _client.Updateable() .SetColumns(x => x.GroupName == group.GroupName) .Where(x => newGroupIds.Contains(x.Id)) .ExecuteCommandAsync();*/ //更新后,通知使用分享码导入的人员已更新,接收通知后刷新分组列表 _ = Task.Run(() => { groupRelationList.ForEach( x => { /*await _connectionClientManager.SendAsync(x.Owner.ToString(), JsonConvert.SerializeObject(new MessageDto { Type = "通知", Content = $"分组{input.GroupName}更新为{group.GroupName}" }));*/ _subscribeAndPublishService.Publish(JsonConvert.SerializeObject(new MessageDto { Type = "通知", Content = $"分组{input.GroupName}更新为{group.GroupName}" }), x.Owner.ToString()); }); }); } await _client.CommitTranAsync(); } catch(Exception ex) { await _client.RollbackTranAsync(); _logger.LogError("修改分组信息失败:{message}", ex.Message); throw new Exception("修改分组信息失败"); } finally { _client.Dispose(); } } } }