//
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 方法
}