Merge branch 'master' into features/UserManger

This commit is contained in:
2021-06-29 09:35:57 +08:00
64 changed files with 2464 additions and 1221 deletions

View File

@@ -120,7 +120,7 @@ WHERE HC.Id=@HouseCodeId", new { houseTask.HouseCodeId }
var houseEntity = await _houseInfoRep.DetachedEntities.FirstOrDefaultAsync(h => h.HouseCodeId == input.houseCode.Id);
//建档审核通过的房屋数据修改时对应的建档任务Task不处理
if (houseEntity.State != 6)
if (houseEntity == null || houseEntity.State != 6)
{
var houseTask = input.PatrolInfo.Adapt<BsHouseTask>();
houseTask.HouseCodeId = input.houseCode.Id;

View File

@@ -13,6 +13,7 @@ using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
namespace Ewide.Application.Service
{
@@ -108,10 +109,10 @@ WHERE 1=1";
var users = await _dapperRepository.QueryPageData<UserOutput>(sql, input, param);
foreach (var user in users.Items)
{
user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
}
//foreach (var user in users.Items)
//{
// user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
//}
return PageDataResult<UserOutput>.PageResult(users);
}
@@ -170,7 +171,10 @@ WHERE 1=1";
[UnitOfWork]
public async Task DeleteUser(DeleteUserInput input)
{
// 片区监管员在本片区已有安全员的情况下无法删除
/*
* 未处理逻辑
* 片区监管员在本片区已有安全员的情况下无法删除
*/
await _sysUserService.DeleteUser(input);
}
@@ -185,6 +189,7 @@ WHERE 1=1";
public async Task UpdateUser(UpdateUserInput input)
{
/*
* 未处理逻辑
* 如果移动组织架构,会产生以下几种逻辑
* 片区1监管员(无安全员或有其他监管员)=>片区2,直接成功
* 片区1监管员(有安全员并且无其他监管员)=>片区2,无法移动
@@ -203,7 +208,30 @@ WHERE 1=1";
[HttpGet("/houseMember/detail")]
public async Task<dynamic> GetUser([FromQuery] QueryUserInput input)
{
return await _sysUserService.GetUser(input);
var sql = @"SELECT
SU.*,
SO.Name OrgName,
SUR.RoleName,
SUR.RoleCode
FROM sys_user SU
LEFT JOIN sys_emp SE ON SU.Id = SE.Id
LEFT JOIN sys_org SO ON SE.OrgId = SO.Id
LEFT JOIN (
SELECT
SUR.SysUserId,
GROUP_CONCAT(SR.Name) RoleName,
GROUP_CONCAT(SR.Code) RoleCode
FROM sys_user_role SUR
LEFT JOIN sys_role SR ON SUR.SysRoleId = SR.Id
GROUP BY SUR.SysUserId
) SUR ON SU.Id = SUR.SysUserId
WHERE SU.Id=@Id";
var user = (await _dapperRepository.QueryAsync<UserOutput>(sql, new { input.Id })).SingleOrDefault();
if (user != null)
{
user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
}
return user;
}
/// <summary>
@@ -254,7 +282,7 @@ WHERE 1=1";
var _sysOrgRep = Db.GetRepository<SysOrg>();
var org = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == orgId);
// 如果当前组织为街道, 则直接返回安全员
if (org == null || org.Type <= 30)
if (org == null || org.Type <= (int)OrgType.)
{
return roles.LastOrDefault();
}
@@ -265,7 +293,7 @@ WHERE 1=1";
var roleIds = await _sysUserRoleRep.DetachedEntities.Where(p => userIds.Contains(p.SysUserId)).Select(p => p.SysRoleId).ToListAsync();
var _sysRoleRep = Db.GetRepository<SysRole>();
var isExistZoneManager = await _sysRoleRep.DetachedEntities.AnyAsync(p => roleIds.Contains(p.Id) && p.Code == System.Enum.GetName(HouseManagerRole.ZoneManager).ToUnderScoreCase());
var isExistZoneManager = await _sysRoleRep.DetachedEntities.AnyAsync(p => roleIds.Contains(p.Id) && p.Code == Enum.GetName(HouseManagerRole.ZoneManager).ToUnderScoreCase());
// 存在片区监管员,返回安全员, 否则返回监管员
if (isExistZoneManager)
{
@@ -282,7 +310,10 @@ WHERE 1=1";
[NonAction]
private async Task<List<SysRole>> GetRoleRange()
{
var codes = System.Enum.GetNames(typeof(HouseManagerRole)).Select(p => p.ToUnderScoreCase());
var codes = (new[] {
Enum.GetName(HouseManagerRole.ZoneManager),
Enum.GetName(HouseManagerRole.HouseSecurityManager),
}).Select(p => p.ToUnderScoreCase());
var _sysRoleRep = Db.GetRepository<SysRole>();
var roles = await _sysRoleRep.DetachedEntities.Where(p => codes.Contains(p.Code)).ToListAsync();

View File

@@ -20,9 +20,9 @@ namespace Ewide.Core
MENU = 1,
/// <summary>
/// 按钮
/// 功能
/// </summary>
[Description("按钮")]
BTN = 2
[Description("功能")]
FUNCTION = 2
}
}

View File

@@ -2417,9 +2417,9 @@
菜单
</summary>
</member>
<member name="F:Ewide.Core.MenuType.BTN">
<member name="F:Ewide.Core.MenuType.FUNCTION">
<summary>
按钮
功能
</summary>
</member>
<member name="T:Ewide.Core.MenuWeight">
@@ -4933,7 +4933,7 @@
路由元信息(路由附带扩展信息)
</summary>
</member>
<member name="P:Ewide.Core.Service.AntDesignTreeNode.Path">
<member name="P:Ewide.Core.Service.AntDesignTreeNode.Link">
<summary>
路径
</summary>
@@ -4943,6 +4943,11 @@
控制路由和子路由是否显示在 sidebar
</summary>
</member>
<member name="P:Ewide.Core.Service.AntDesignTreeNode.OpenType">
<summary>
打开方式
</summary>
</member>
<member name="T:Ewide.Core.Service.Meta">
<summary>
路由元信息内部类
@@ -5068,6 +5073,11 @@
菜单类型(字典 0目录 1菜单 2按钮
</summary>
</member>
<member name="P:Ewide.Core.Service.AddMenuInput.OpenType">
<summary>
打开方式(字典 0无 1组件 2内链 3外链
</summary>
</member>
<member name="P:Ewide.Core.Service.DeleteMenuInput.Id">
<summary>
菜单Id

View File

@@ -8,6 +8,8 @@ using System.Diagnostics;
using System.Security.Claims;
using System.Threading.Tasks;
using UAParser;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Ewide.Core
{
@@ -34,12 +36,29 @@ namespace Ewide.Core
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var descAtt = Attribute.GetCustomAttribute(actionDescriptor.MethodInfo, typeof(DescriptionAttribute)) as DescriptionAttribute;
var message = "请求成功";
if (isRequestSucceed)
{
var result = actionContext.Result;
var resultType = result.GetType();
if (resultType.Name == "ContentResult")
{
var resultContent = ((Microsoft.AspNetCore.Mvc.ContentResult)actionContext.Result)?.Content;
var resultJson = JsonConvert.DeserializeObject<JObject>(resultContent);
message = resultJson["message"]?.ToString();
}
}
else
{
message = actionContext.Exception.Message;
}
var sysOpLog = new SysLogOp
{
Name = descAtt != null ? descAtt.Description : actionDescriptor.ActionName,
OpType = 1,
Success = isRequestSucceed,
//Message = isRequestSucceed ? "成功" : "失败",
Message = message,
Ip = httpContext.GetRemoteIpAddressToIPv4(),
Location = httpRequest.GetRequestUrlAddress(),
Browser = clent.UA.Family + clent.UA.Major,
@@ -48,13 +67,13 @@ namespace Ewide.Core
ClassName = context.Controller.ToString(),
MethodName = actionDescriptor.ActionName,
ReqMethod = httpRequest.Method,
//Param = JsonSerializerUtility.Serialize(context.ActionArguments),
//Result = JsonSerializerUtility.Serialize(actionContext.Result),
Param = JsonConvert.SerializeObject(context.ActionArguments),
// Result = resultContent,
ElapsedTime = sw.ElapsedMilliseconds,
OpTime = DateTime.Now,
Account = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT)
};
await sysOpLog.InsertAsync();
await sysOpLog.InsertNowAsync();
}
}
}

View File

@@ -101,6 +101,24 @@ namespace Ewide.Core.Service
// 设置刷新Token令牌
_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
// 增加登录日志
var loginOutput = user.Adapt<LoginOutput>();
var clent = Parser.GetDefault().Parse(App.GetService<IHttpContextAccessor>().HttpContext.Request.Headers["User-Agent"]);
loginOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major;
loginOutput.LastLoginOs = clent.OS.Family + clent.OS.Major;
await new SysLogVis
{
Name = "登录",
Success = true,
Message = "登录成功",
Ip = loginOutput.LastLoginIp,
Browser = loginOutput.LastLoginBrowser,
Os = loginOutput.LastLoginOs,
VisType = 1,
VisTime = loginOutput.LastLoginTime,
Account = loginOutput.Account
}.InsertAsync();
return accessToken;
}
@@ -163,20 +181,6 @@ namespace Ewide.Core.Service
loginOutput.Menus = await _sysMenuService.GetLoginMenusAntDesign(userId, defaultActiveAppCode);
}
// 增加登录日志
//await new SysLogVis
//{
// Name = "登录",
// Success = true,
// Message = "登录成功",
// Ip = loginOutput.LastLoginIp,
// Browser = loginOutput.LastLoginBrowser,
// Os = loginOutput.LastLoginOs,
// VisType = 1,
// VisTime = loginOutput.LastLoginTime,
// Account = loginOutput.Account
//}.InsertAsync();
return loginOutput;
}

View File

@@ -1,4 +1,5 @@
using Ewide.Core.Extension;
using Dapper;
using Ewide.Core.Extension;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
@@ -20,10 +21,12 @@ namespace Ewide.Core.Service
public class SysOpLogService : ISysOpLogService, IDynamicApiController, ITransient
{
private readonly IRepository<SysLogOp> _sysOpLogRep; // 操作日志表仓储
private readonly IDapperRepository<SysLogOp> _dapperRepository;
public SysOpLogService(IRepository<SysLogOp> sysOpLogRep)
public SysOpLogService(IRepository<SysLogOp> sysOpLogRep, IDapperRepository<SysLogOp> dapperRepository)
{
_sysOpLogRep = sysOpLogRep;
_dapperRepository = dapperRepository;
}
/// <summary>
@@ -54,11 +57,7 @@ namespace Ewide.Core.Service
[HttpPost("/sysOpLog/delete")]
public async Task ClearOpLog()
{
var opLogs = await _sysOpLogRep.Entities.ToListAsync();
opLogs.ForEach(u =>
{
u.Delete();
});
await _dapperRepository.ExecuteAsync("DELETE FROM sys_log_op");
}
}
}

View File

@@ -38,12 +38,17 @@
/// <summary>
/// 路径
/// </summary>
public string Path { get; set; }
public string Link { get; set; }
/// <summary>
/// 控制路由和子路由是否显示在 sidebar
/// </summary>
public bool Hidden { get; set; }
/// <summary>
/// 打开方式
/// </summary>
public int OpenType { get; set; }
}
/// <summary>

View File

@@ -25,7 +25,7 @@ namespace Ewide.Core.Service
/// <summary>
/// 菜单类型(字典 0目录 1菜单 2按钮
/// </summary>
public virtual string Type { get; set; }
public virtual int Type { get; set; }
/// <summary>
/// 图标
@@ -55,7 +55,7 @@ namespace Ewide.Core.Service
/// <summary>
/// 打开方式(字典 0无 1组件 2内链 3外链
/// </summary>
public virtual string OpenType { get; set; }
public virtual int OpenType { get; set; }
/// <summary>
/// 是否可见Y-是N-否)
@@ -99,7 +99,13 @@ namespace Ewide.Core.Service
/// 菜单类型(字典 0目录 1菜单 2按钮
/// </summary>
[Required(ErrorMessage = "菜单类型不能为空")]
public override string Type { get; set; }
public override int Type { get; set; }
/// <summary>
/// 打开方式(字典 0无 1组件 2内链 3外链
/// </summary>
[Required(ErrorMessage = "打开方式不能为空")]
public override int OpenType { get; set; }
}
public class DeleteMenuInput

View File

@@ -53,7 +53,7 @@ namespace Ewide.Core.Service
var roleIdList = await _sysUserRoleService.GetUserRoleIdList(userId);
var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIdList);
permissions = await _sysMenuRep.DetachedEntities.Where(u => menuIdList.Contains(u.Id))
.Where(u => u.Type == (int)MenuType.BTN)
.Where(u => u.Type == (int)MenuType.FUNCTION)
.Where(u => u.Status == (int)CommonStatus.ENABLE)
.Select(u => u.Permission).ToListAsync();
#if DEBUG
@@ -83,8 +83,8 @@ namespace Ewide.Core.Service
sysMenuList = await _sysMenuRep.DetachedEntities
.Where(u => u.Status == (int)CommonStatus.ENABLE)
.Where(u => u.Application == appCode)
.Where(u => u.Type != (int)MenuType.BTN)
//.Where(u => u.Weight != (int)MenuWeight.DEFAULT_WEIGHT)
.Where(u => u.Type != (int)MenuType.FUNCTION)
.Where(u => u.Weight != (int)MenuWeight.DEFAULT_WEIGHT)
.OrderBy(u => u.Sort).ToListAsync();
}
else
@@ -96,7 +96,7 @@ namespace Ewide.Core.Service
.Where(u => menuIdList.Contains(u.Id))
.Where(u => u.Status == (int)CommonStatus.ENABLE)
.Where(u => u.Application == appCode)
.Where(u => u.Type != (int)MenuType.BTN)
.Where(u => u.Type != (int)MenuType.FUNCTION)
.OrderBy(u => u.Sort).ToListAsync();
}
// 转换成登录菜单
@@ -106,8 +106,9 @@ namespace Ewide.Core.Service
Pid = u.Pid,
Name = u.Code,
Component = u.Component,
Redirect = u.OpenType == (int)MenuOpenType.OUTER ? u.Link : u.Redirect,
Path = u.OpenType == (int)MenuOpenType.OUTER ? u.Link : u.Router,
Redirect = u.Redirect,
Link = u.Link,
OpenType = u.OpenType,
Meta = new Meta
{
Title = u.Name,
@@ -185,7 +186,7 @@ namespace Ewide.Core.Service
/// 增加和编辑时检查参数
/// </summary>
/// <param name="input"></param>
private static void CheckMenuParam(MenuInput input)
private async Task CheckMenuParam(MenuInput input)
{
var type = input.Type;
var router = input.Router;
@@ -195,17 +196,17 @@ namespace Ewide.Core.Service
if (type.Equals((int)MenuType.DIR))
{
if (string.IsNullOrEmpty(router))
throw Oops.Oh(ErrorCode.D4001);
//if (string.IsNullOrEmpty(router))
// throw Oops.Oh(ErrorCode.D4001);
}
else if (type.Equals((int)MenuType.MENU))
{
if (string.IsNullOrEmpty(router))
throw Oops.Oh(ErrorCode.D4001);
if (string.IsNullOrEmpty(openType))
throw Oops.Oh(ErrorCode.D4002);
//if (string.IsNullOrEmpty(router))
// throw Oops.Oh(ErrorCode.D4001);
//if (string.IsNullOrEmpty(openType))
// throw Oops.Oh(ErrorCode.D4002);
}
else if (type.Equals((int)MenuType.BTN))
else if (type.Equals((int)MenuType.FUNCTION))
{
if (string.IsNullOrEmpty(permission))
throw Oops.Oh(ErrorCode.D4003);
@@ -217,10 +218,37 @@ namespace Ewide.Core.Service
//if (!urlSet.Contains(permission.Replace(":","/")))
// throw Oops.Oh(ErrorCode.meu1005);
}
//按钮可以设置绑定菜单
if(!isVisibleParent && type.Equals((int)MenuType.BTN))
// 检查上级菜单的类型是否正确
var pid = input.Pid;
var flag = true;
var empty = System.Guid.Empty.ToString();
switch(type)
{
throw Oops.Oh(ErrorCode.D4004);
// 目录必须在顶级下
case (int)MenuType.DIR:
flag = pid.Equals(empty);
break;
// 菜单必须在顶级或目录下
case (int)MenuType.MENU:
if (!pid.Equals(empty))
{
var parent = await _sysMenuRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == pid);
flag = parent.Type.Equals((int)MenuType.DIR);
}
break;
// 功能必须在菜单下
case (int)MenuType.FUNCTION:
{
var parent = await _sysMenuRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == pid);
flag = parent == null ? false : parent.Type.Equals((int)MenuType.MENU);
}
break;
}
if (!flag)
{
throw Oops.Oh("父级菜单类型错误");
}
}
@@ -240,7 +268,7 @@ namespace Ewide.Core.Service
}
// 校验参数
CheckMenuParam(input);
await CheckMenuParam(input);
var menu = input.Adapt<SysMenu>();
menu.Pids = await CreateNewPids(input.Pid);
@@ -296,7 +324,7 @@ namespace Ewide.Core.Service
}
// 校验参数
CheckMenuParam(input);
await CheckMenuParam(input);
// 如果是编辑父id不能为自己的子节点
var childIdList = await _sysMenuRep.DetachedEntities.Where(u => u.Pids.Contains(input.Id.ToString()))
.Select(u => u.Id).ToListAsync();
@@ -360,7 +388,7 @@ namespace Ewide.Core.Service
// 更新当前菜单
oldMenu = input.Adapt<SysMenu>();
oldMenu.Pids = newPids;
await oldMenu.UpdateAsync(ignoreNullValues: true);
await oldMenu.UpdateExcludeAsync(new[] { nameof(SysMenu.Type) }, ignoreNullValues: true);
// 清除缓存
await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU);

View File

@@ -92,10 +92,10 @@ namespace Ewide.Core.Service
// emps.Add(_sysEmpService.GetEmpInfo(long.Parse(u.Id)));
//});
//await Task.WhenAll(emps);
foreach (var user in users.Items)
{
user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
}
//foreach (var user in users.Items)
//{
// user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
//}
return PageDataResult<UserOutput>.PageResult(users);
}
@@ -176,8 +176,17 @@ namespace Ewide.Core.Service
if (isExist) throw Oops.Oh(ErrorCode.D1003);
var user = input.Adapt<SysUser>();
await user.UpdateExcludeAsync(new[] { nameof(SysUser.Password), nameof(SysUser.Status), nameof(SysUser.AdminType) }, true);
user.UpdateIncludeNow(new[] { nameof(SysUser.Birthday) });
await user.UpdateIncludeAsync(new[] {
nameof(SysUser.Account),
nameof(SysUser.NickName),
nameof(SysUser.Name),
nameof(SysUser.Birthday),
nameof(SysUser.Sex),
nameof(SysUser.Email),
nameof(SysUser.Phone),
nameof(SysUser.Tel),
}, true);
// user.UpdateIncludeNow(new[] { nameof(SysUser.Birthday) });
input.SysEmpParam.Id = user.Id.ToString();
// 更新员工及附属机构职位信息
await _sysEmpService.AddOrUpdate(input.SysEmpParam);