// using System.Text.RegularExpressions; namespace SafeCampus.System; /// public class UserCenterService : DbRepository, IUserCenterService { private readonly ISysUserService _userService; private readonly IRelationService _relationService; private readonly IResourceService _resourceService; private readonly IMenuService _menuService; private readonly IConfigService _configService; private readonly ISysOrgService _sysOrgService; private readonly IMessageService _messageService; public UserCenterService(ISysUserService userService, IRelationService relationService, IResourceService resourceService, IMenuService menuService, IConfigService configService, ISysOrgService sysOrgService, IMessageService messageService) { _userService = userService; _relationService = relationService; _resourceService = resourceService; _menuService = menuService; _configService = configService; _sysOrgService = sysOrgService; _messageService = messageService; } #region 查询 /// public async Task> GetLoginMenu(BaseIdInput input) { var result = new List(); //获取用户信息 var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId); if (userInfo != null) { //定义菜单ID列表 var menuIdList = new HashSet();//获取所有的菜单和模块以及单页面列表,并按分类和排序码排序 var allModuleAndMenuAndSpaList = await _resourceService.GetMenuAndSpaListByModuleId(input.Id); //通过 App.GetOptions 获取选项 var settings = App.GetOptions(); //如果设置了超级管理员可以看到全部 if (settings.SuperAdminViewAllData && UserManager.SuperAdmin) { menuIdList = allModuleAndMenuAndSpaList.Select(it => it.Id).ToHashSet(); } else { //获取用户所拥有的资源集合 var resourceList = await _relationService.GetRelationListByObjectIdAndCategory(userInfo.Id, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE); if (resourceList.Count == 0)//如果没有就获取角色的 //获取角色所拥有的资源集合 resourceList = await _relationService.GetRelationListByObjectIdListAndCategory(userInfo.RoleIdList, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE); //获取菜单Id集合 menuIdList.AddRange(resourceList.Select(r => r.TargetId.ToLong()).ToList()); } var allMenuList = new List();//菜单列表 var allSpaList = new List();//单页列表 //遍历菜单集合 allModuleAndMenuAndSpaList.ForEach(it => { switch (it.Category) { case CateGoryConst.RESOURCE_MENU://菜单 allMenuList.Add(it);//添加到菜单列表 break; case CateGoryConst.RESOURCE_SPA://单页 allSpaList.Add(it);//添加到单页列表 break; } }); //获取我的菜单列表,只显示启用的 var myMenus = allMenuList.Where(it => menuIdList.Contains(it.Id) && it.Status == CommonStatusConst.ENABLE).ToList(); // 对获取到的角色对应的菜单列表进行处理,获取父列表 var parentList = GetMyParentMenus(allMenuList, myMenus); myMenus.AddRange(parentList);//合并列表 // 遍历单页列表 allSpaList.ForEach(it => { it.ParentId = SafeCampusConst.ZERO; }); myMenus.AddRange(allSpaList);//单页添加到菜单 //构建meta ConstructMeta(myMenus); //构建菜单树 result = _menuService.ConstructMenuTrees(myMenus); } return result; } /// public async Task GetLoginWorkbench() { //获取个人工作台信息 var sysRelation = await _relationService.GetWorkbench(UserManager.UserId); if (sysRelation != null) { //如果有数据直接返回个人工作台 return sysRelation.ExtJson.ToLower(); } //如果没数据去系统配置里取默认的工作台 var devConfig = await _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_BASE, SysConfigConst.SYS_DEFAULT_WORKBENCH_DATA); if (devConfig != null) { return devConfig.ConfigValue.ToLower();//返回工作台信息 } return ""; } /// public async Task> LoginOrgTree() { var orgList = await _sysOrgService.GetListAsync();//获取全部机构 var parentOrgList = _sysOrgService.GetOrgParents(orgList, UserManager.OrgId);//获取父节点列表 var topOrg = parentOrgList.Where(it => it.ParentId == SafeCampusConst.ZERO).FirstOrDefault();//获取顶级节点 if (topOrg != null) { var orgChildList = await _sysOrgService.GetChildListById(topOrg.Id);//获取下级 var orgTree = ConstrucOrgTrees(orgChildList, 0, UserManager.OrgId);//获取组织架构 return orgTree; } return new List(); } /// public async Task> LoginMessagePage(MessagePageInput input) { var messages = await _messageService.MyMessagePage(input, UserManager.UserId);//分页查询 return messages; } /// public async Task LoginMessageDetail(BaseIdInput input) { return await _messageService.Detail(input, true);//返回详情,不带用户列表 } /// public async Task UnReadCount() { return await _messageService.UnReadCount(UserManager.UserId); } /// public async Task> ShortcutTree() { var sysResourceList = await _resourceService.GetAllModuleAndMenuAndSpaList();//获取模块和菜单和单页列表 var userInfo = await _userService.GetUserById(UserManager.UserId); var hasResourcesList = new HashSet();//拥有的资源列表 var hasModuleList = new HashSet();//拥有的资源列表 var userResourceList = (await _relationService.GetRelationListByObjectIdAndCategory(UserManager.UserId, CateGoryConst.RELATION_SYS_USER_HAS_RESOURCE)) .Select(it => it.TargetId.ToLong()).ToList();//获取用户资源id列表 var userModuleList = (await _relationService.GetRelationListByObjectIdAndCategory(UserManager.UserId, CateGoryConst.RELATION_SYS_USER_HAS_MODULE)) .Select(it => it.TargetId.ToLong()).ToList();//获取用户模块id列表 if (userResourceList.Count > 0)//如果用户资源列表大于0就以用户为主 { hasResourcesList.AddRange(userResourceList); hasResourcesList.AddRange(userModuleList); } else { var roleIds = userInfo.RoleIdList;//获取角色ID列表 var roleResourceList = (await _relationService.GetRelationListByObjectIdListAndCategory(roleIds, CateGoryConst.RELATION_SYS_ROLE_HAS_RESOURCE)) .Select(it => it.TargetId.ToLong()).ToList();//获取角色资源id列表 var roleModuleList = (await _relationService.GetRelationListByObjectIdListAndCategory(roleIds, CateGoryConst.RELATION_SYS_ROLE_HAS_MODULE)) .Select(it => it.TargetId.ToLong()).ToList();//获取角色模块id列表 hasResourcesList.AddRange(roleResourceList); hasResourcesList.AddRange(roleModuleList); } // 获取目录 var catalogList = sysResourceList.Where(it => it.MenuType == SysResourceConst.CATALOG).ToList(); //过滤出拥有的资源列表 sysResourceList = sysResourceList.Where(it => hasResourcesList.Contains(it.Id) || it.Category == CateGoryConst.RESOURCE_SPA) .ToList();//获取拥有的资源列表 var parentIds = sysResourceList.Select(it => it.ParentId).Distinct().ToList();//获取父ID列表 var parentList = catalogList.Where(it => parentIds.Contains(it.Id)).ToList();//获取所拥有的父级目录 sysResourceList.AddRange(parentList);//添加到列表 return await _menuService.ShortcutTree(sysResourceList); } #endregion 查询 #region 编辑 /// public async Task UpdateUserInfo(UpdateInfoInput input) { //如果手机号不是空 if (!string.IsNullOrEmpty(input.Phone)) { if (!input.Phone.MatchPhoneNumber())//判断是否是手机号格式 throw Oops.Bah("手机号码格式错误"); input.Phone = CryptogramUtil.Sm4Encrypt(input.Phone); var any = await IsAnyAsync(it => it.Phone == input.Phone && it.Id != UserManager.UserId);//判断是否有重复的 if (any) throw Oops.Bah("系统已存在该手机号"); } if (!string.IsNullOrEmpty(input.Email)) { var match = input.Email.MatchEmail(); if (!match.isMatch) throw Oops.Bah("邮箱格式错误"); } //更新指定字段 var result = await UpdateSetColumnsTrueAsync(it => new SysUser { Name = input.Name, Email = input.Email, Phone = input.Phone, Nickname = input.Nickname, Gender = input.Gender, Birthday = input.Birthday }, it => it.Id == UserManager.UserId); if (result) _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 } /// public async Task UpdateSignature(UpdateSignatureInput input) { var signatureArray = input.Signature.Split(",");//分割 // var base64String = signatureArray[1];//根据逗号分割取到base64字符串 // var image = base64String.GetSkBitmapFromBase64();//转成图片 // var resizeImage = image.ResizeImage(100, 50);//重新裁剪 // var newBase64String = resizeImage.ImgToBase64String();//重新转为base64 // var newSignature = signatureArray[0] + "," + newBase64String;//赋值新的签名 //更新签名 var result = await UpdateSetColumnsTrueAsync(it => new SysUser { Signature = input.Signature }, it => it.Id == UserManager.UserId); if (result) _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 } /// public async Task UpdateWorkbench(UpdateWorkbenchInput input) { //关系表保存个人工作台 await _relationService.SaveRelation(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA, UserManager.UserId, null, input.WorkbenchData, true); } /// public async Task DeleteMyMessage(BaseIdInput input) { await _messageService.DeleteMyMessage(input, UserManager.UserId); } /// public async Task UpdatePassword(UpdatePasswordInput input) { //获取用户信息 var userInfo = await _userService.GetUserById(UserManager.UserId); var password = CryptogramUtil.Sm2Decrypt(input.Password);//SM2解密 if (userInfo.Password != password) throw Oops.Bah("原密码错误"); var newPassword = CryptogramUtil.Sm2Decrypt(input.NewPassword);//sm2解密 var loginPolicy = await _configService.GetConfigsByCategory(CateGoryConst.CONFIG_PWD_POLICY);//获取密码策略 var containNumber = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_NUM).ConfigValue.ToBoolean();//是否包含数字 var containLower = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_LOWER).ConfigValue.ToBoolean();//是否包含小写 var containUpper = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_UPPER).ConfigValue.ToBoolean();//是否包含大写 var containChar = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_CONTAIN_CHARACTER).ConfigValue.ToBoolean();//是否包含特殊字符 var minLength = loginPolicy.First(it => it.ConfigKey == SysConfigConst.PWD_MIN_LENGTH).ConfigValue.ToInt();//最小长度 if (minLength > newPassword.Length) throw Oops.Bah($"密码长度不能小于{minLength}"); if (containNumber && !Regex.IsMatch(newPassword, "[0-9]")) throw Oops.Bah("密码必须包含数字"); if (containLower && !Regex.IsMatch(newPassword, "[a-z]")) throw Oops.Bah("密码必须包含小写字母"); if (containUpper && !Regex.IsMatch(newPassword, "[A-Z]")) throw Oops.Bah("密码必须包含大写字母"); if (containChar && !Regex.IsMatch(newPassword, "[~!@#$%^&*()_+`\\-={}|\\[\\]:\";'<>?,./]")) throw Oops.Bah("密码必须包含特殊字符"); // var similarity = PwdUtil.Similarity(password, newPassword); // if (similarity > 80) // throw Oops.Bah($"新密码请勿与旧密码过于相似"); newPassword = CryptogramUtil.Sm4Encrypt(newPassword);//SM4加密 userInfo.Password = newPassword; await UpdateSetColumnsTrueAsync(it => new SysUser() { Password = newPassword }, it => it.Id == userInfo.Id);//更新密码 _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 } /// public async Task UpdateAvatar(BaseFileInput input) { var userInfo = await _userService.GetUserById(UserManager.UserId); var file = input.File; using var fileStream = file.OpenReadStream();//获取文件流 var bytes = new byte[fileStream.Length]; fileStream.Read(bytes, 0, bytes.Length); fileStream.Close(); var base64String = Convert.ToBase64String(bytes);//转base64 var avatar = base64String.ToImageBase64();//转图片 await UpdateSetColumnsTrueAsync(it => new SysUser() { Avatar = avatar }, it => it.Id == userInfo.Id);// 更新头像 _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 return avatar; } /// public async Task SetDefaultModule(SetDefaultModuleInput input) { //获取用户信息 var userInfo = await _userService.GetUserById(UserManager.UserId); //如果是默认模块 if (input.IfDefault) userInfo.DefaultModule = input.Id; else userInfo.DefaultModule = null; await Context.Updateable(userInfo).UpdateColumns(it => new { it.DefaultModule }).ExecuteCommandAsync();//修改默认模块 _userService.DeleteUserFromRedis(UserManager.UserId);//redis删除用户数据 } #endregion 编辑 #region 方法 /// /// 获取父菜单集合 /// /// 所有菜单列表 /// 我的菜单列表 /// private List GetMyParentMenus(List allMenuList, List myMenus) { var parentList = new List(); myMenus.ForEach(it => { var parents = _resourceService.GetResourceParent(allMenuList, it.ParentId.Value);//获取父级 parents.ForEach(parent => { // 如果父级菜单存在,并且父级菜单状态为启用,并不在父级列表中,则添加到父级列表 if (parent != null && parent.Status == CommonStatusConst.ENABLE && !parentList.Contains(parent) && !myMenus.Contains(parent)) { parentList.Add(parent);//添加到父列表 } }); }); return parentList; } /// /// 构建Meta /// /// 我的菜单集合 private void ConstructMeta(List myMenus) { myMenus.ForEach(it => { //定义meta var meta = new Meta { Icon = it.Icon, Title = it.Title, IsAffix = it.IsAffix, IsHide = it.IsHide, IsKeepAlive = it.IsKeepAlive, IsFull = it.IsFull, ActiveMenu = it.ActiveMenu, IsLink = it.Category == SysResourceConst.LINK ? it.Path : "" }; it.Meta = meta; }); } /// /// 构建机构树 /// /// 机构列表 /// 父ID /// 用户ID /// public List ConstrucOrgTrees(List orgList, long parentId, long orgId) { //找下级字典ID列表 var orgParents = orgList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode).ToList(); if (orgParents.Count > 0)//如果数量大于0 { var data = new List(); foreach (var item in orgParents)//遍历字典 { var loginOrg = new LoginOrgTreeOutput { Children = ConstrucOrgTrees(orgList, item.Id, orgId),//添加子节点 Id = item.Id, Label = item.Name, Pid = item.ParentId, Style = orgId != item.Id ? null : new LoginOrgTreeOutput.MyStyle() }; data.Add(loginOrg);//添加到列表 } return data;//返回结果 } return new List(); } #endregion 方法 }