添加项目文件。
This commit is contained in:
@@ -0,0 +1,461 @@
|
||||
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
|
||||
//
|
||||
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
|
||||
// 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
|
||||
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
|
||||
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
|
||||
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
|
||||
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
|
||||
|
||||
using NewLife;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <inheritdoc cref="IUserCenterService"/>
|
||||
public class UserCenterService : DbRepository<SysUser>, 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 查询
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<SysResource>> GetLoginMenu(BaseIdInput input)
|
||||
{
|
||||
var result = new List<SysResource>();
|
||||
//获取用户信息
|
||||
var userInfo = await _userService.GetUserByAccount(UserManager.UserAccount, UserManager.TenantId);
|
||||
if (userInfo != null)
|
||||
{
|
||||
//定义菜单ID列表
|
||||
var menuIdList = new HashSet<long>();//获取所有的菜单和模块以及单页面列表,并按分类和排序码排序
|
||||
var allModuleAndMenuAndSpaList = await _resourceService.GetMenuAndSpaListByModuleId(input.Id);
|
||||
//通过 App.GetOptions<TOptions> 获取选项
|
||||
var settings = App.GetOptions<SystemSettingsOptions>();
|
||||
//如果设置了超级管理员可以看到全部
|
||||
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<SysResource>();//菜单列表
|
||||
var allSpaList = new List<SysResource>();//单页列表
|
||||
//遍历菜单集合
|
||||
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 = SimpleAdminConst.ZERO;
|
||||
});
|
||||
myMenus.AddRange(allSpaList);//单页添加到菜单
|
||||
//构建meta
|
||||
ConstructMeta(myMenus);
|
||||
//构建菜单树
|
||||
result = _menuService.ConstructMenuTrees(myMenus);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> 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 "";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<LoginOrgTreeOutput>> LoginOrgTree()
|
||||
{
|
||||
var orgList = await _sysOrgService.GetListAsync();//获取全部机构
|
||||
var parentOrgList = _sysOrgService.GetOrgParents(orgList, UserManager.OrgId);//获取父节点列表
|
||||
var topOrg = parentOrgList.Where(it => it.ParentId == SimpleAdminConst.ZERO).FirstOrDefault();//获取顶级节点
|
||||
if (topOrg != null)
|
||||
{
|
||||
var orgChildList = await _sysOrgService.GetChildListById(topOrg.Id);//获取下级
|
||||
var orgTree = ConstrucOrgTrees(orgChildList, 0, UserManager.OrgId);//获取组织架构
|
||||
return orgTree;
|
||||
}
|
||||
return new List<LoginOrgTreeOutput>();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<SysResource>> ShortcutTree()
|
||||
{
|
||||
var sysResourceList = await _resourceService.GetAllModuleAndMenuAndSpaList();//获取模块和菜单和单页列表
|
||||
var userInfo = await _userService.GetUserById(UserManager.UserId);
|
||||
var hasResourcesList = new HashSet<long>();//拥有的资源列表
|
||||
var hasModuleList = new HashSet<long>();//拥有的资源列表
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SqlSugarPagedList<SysMessage>> LoginMessagePage(MessagePageInput input)
|
||||
{
|
||||
var messages = await _messageService.MyMessagePage(input, UserManager.UserId);//分页查询
|
||||
return messages;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SysMessage> LoginMessageDetail(MessageDetailInput input)
|
||||
{
|
||||
return await _messageService.Detail(input);//返回详情,不带用户列表
|
||||
}
|
||||
|
||||
#endregion 查询
|
||||
|
||||
#region 编辑
|
||||
|
||||
/// <inheritdoc />
|
||||
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删除用户数据
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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删除用户数据
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task UpdateWorkbench(UpdateWorkbenchInput input)
|
||||
{
|
||||
//关系表保存个人工作台
|
||||
await _relationService.SaveRelation(CateGoryConst.RELATION_SYS_USER_WORKBENCH_DATA, UserManager.UserId, null, input.WorkbenchData,
|
||||
true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task DeleteMyMessage(BaseIdInput input)
|
||||
{
|
||||
await _messageService.DeleteMyMessage(input, UserManager.UserId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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删除用户数据
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> 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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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 我的消息
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SqlSugarPagedList<SysMessage>> MyMessagePage(MessagePageInput input)
|
||||
{
|
||||
var messages = await _messageService.MyMessagePage(input, UserManager.UserId);//分页查询
|
||||
return messages;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<SysMessage> MyMessageDetail(BaseIdInput input)
|
||||
{
|
||||
return await _messageService.Detail(new MessageDetailInput { Id = input.Id, Read = true });//返回详情,不带用户列表
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<MessageUnReadOutPut>> UnReadCount()
|
||||
{
|
||||
return await _messageService.UnReadCount(UserManager.UserId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<List<SysMessage>> NewUnRead()
|
||||
{
|
||||
return await _messageService.NewUnRead(UserManager.UserId);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> SetRead(MessageReadInput input)
|
||||
{
|
||||
return await _messageService.SetRead(input);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> SetDelete(MessageReadInput input)
|
||||
{
|
||||
return await _messageService.SetDelete(input);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取父菜单集合
|
||||
/// </summary>
|
||||
/// <param name="allMenuList">所有菜单列表</param>
|
||||
/// <param name="myMenus">我的菜单列表</param>
|
||||
/// <returns></returns>
|
||||
private List<SysResource> GetMyParentMenus(List<SysResource> allMenuList, List<SysResource> myMenus)
|
||||
{
|
||||
var parentList = new List<SysResource>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建Meta
|
||||
/// </summary>
|
||||
/// <param name="myMenus">我的菜单集合</param>
|
||||
private void ConstructMeta(List<SysResource> 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.IsLink
|
||||
};
|
||||
it.Meta = meta;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建机构树
|
||||
/// </summary>
|
||||
/// <param name="orgList">机构列表</param>
|
||||
/// <param name="parentId">父ID</param>
|
||||
/// <param name="orgId">用户ID</param>
|
||||
/// <returns></returns>
|
||||
public List<LoginOrgTreeOutput> ConstrucOrgTrees(List<SysOrg> 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<LoginOrgTreeOutput>();
|
||||
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<LoginOrgTreeOutput>();
|
||||
}
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
Reference in New Issue
Block a user