From 563a22cd93b9e04e3e4cd2d9c0a9b59559dd0aa3 Mon Sep 17 00:00:00 2001 From: xiaochanghai Date: Thu, 18 Apr 2024 16:18:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Authorize/AuthorizeController.cs | 313 ++++++++++++++++++ .../{ => Ggra}/Ghra_GradeController.cs | 0 .../Controllers/LoginController.cs | 2 +- Tiobon.Core.Api/Tiobon.Core.Model.xml | 36 +- Tiobon.Core.Api/Tiobon.Core.xml | 62 +++- Tiobon.Core.Api/appsettings.json | 3 +- .../Policys/PermissionHandler.cs | 151 ++++----- .../ServiceExtensions/AuthorizationSetup.cs | 6 +- Tiobon.Core.Model/Base/BasePoco.cs | 6 +- Tiobon.Core.Model/Models/Ghrs/Ghrs_User.cs | 3 +- 10 files changed, 478 insertions(+), 104 deletions(-) create mode 100644 Tiobon.Core.Api/Controllers/Authorize/AuthorizeController.cs rename Tiobon.Core.Api/Controllers/{ => Ggra}/Ghra_GradeController.cs (100%) diff --git a/Tiobon.Core.Api/Controllers/Authorize/AuthorizeController.cs b/Tiobon.Core.Api/Controllers/Authorize/AuthorizeController.cs new file mode 100644 index 00000000..c0177273 --- /dev/null +++ b/Tiobon.Core.Api/Controllers/Authorize/AuthorizeController.cs @@ -0,0 +1,313 @@ +using Tiobon.Core.AuthHelper; +using Tiobon.Core.AuthHelper.OverWrite; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Tiobon.Core.Common.Swagger; +using MySqlX.XDevAPI.Common; + + +namespace Tiobon.Core.Controllers +{ + /// + /// 登录管理【无权限】 + /// + [Produces("application/json")] + [Route("api/[controller]")] + [ApiExplorerSettings(GroupName = Grouping.GroupName_Auth)] + [AllowAnonymous] + public class AuthorizeController : BaseApiController + { + readonly ISysUserInfoServices _sysUserInfoServices; + readonly IGhrs_UserServices _ghrs_UserServices; + readonly PermissionRequirement _requirement; + private readonly IRoleModulePermissionServices _roleModulePermissionServices; + private readonly ILogger _logger; + + /// + /// 构造函数注入 + /// + /// + /// + /// + /// + /// + public AuthorizeController(ISysUserInfoServices sysUserInfoServices, IGhrs_UserServices ghrs_UserServices, PermissionRequirement requirement, IRoleModulePermissionServices roleModulePermissionServices, ILogger logger) + { + this._sysUserInfoServices = sysUserInfoServices; + this._ghrs_UserServices = ghrs_UserServices; + _requirement = requirement; + _roleModulePermissionServices = roleModulePermissionServices; + _logger = logger; + } + + + #region 获取token的第1种方法 + + /// + /// 获取JWT的方法1 + /// + /// + /// + /// + [NonAction] + [HttpGet, Route("Token")] + public async Task> GetJwtStr(string name, string pass) + { + string jwtStr = string.Empty; + bool suc = false; + //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作 + + var user = await _sysUserInfoServices.GetUserRoleNameStr(name, MD5Helper.MD5Encrypt32(pass)); + if (user != null) + { + TokenModelJwt tokenModel = new TokenModelJwt { Uid = 1, Role = user }; + + jwtStr = JwtHelper.IssueJwt(tokenModel); + suc = true; + } + else + jwtStr = "login fail!!!"; + + return new ServiceResult() + { + Success = suc, + Message = suc ? "获取成功" : "获取失败", + Data = jwtStr + }; + } + + + /// + /// 获取JWT的方法2:给Nuxt提供 + /// + /// + /// + /// + [HttpGet] + [NonAction] + [Route("GetTokenNuxt")] + public ServiceResult GetJwtStrForNuxt(string name, string pass) + { + string jwtStr = string.Empty; + bool suc = false; + //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作 + //这里直接写死了 + if (name == "admins" && pass == "admins") + { + TokenModelJwt tokenModel = new TokenModelJwt + { + Uid = 1, + Role = "Admin" + }; + + jwtStr = JwtHelper.IssueJwt(tokenModel); + suc = true; + } + else + jwtStr = "login fail!!!"; + + //var result = new + //{ + // data = new { success = suc, token = jwtStr } + //}; + + return new ServiceResult() + { + Success = suc, + Message = suc ? "获取成功" : "获取失败", + Data = jwtStr + }; + } + + #endregion + + + /// + /// 获取JWT的方法3:整个系统主要方法 + /// + /// + /// + /// + [NonAction] + [HttpGet, Route("JWTToken3.0")] + public async Task> GetJwtToken3(string name = "", string pass = "") + { + string jwtStr = string.Empty; + + if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) + return Failed("用户名或密码不能为空"); + + pass = MD5Helper.MD5Encrypt32(pass); + + var user = await _sysUserInfoServices.Query(d => + d.LoginName == name && d.LoginPWD == pass && d.IsDeleted == false); + if (user.Count > 0) + { + var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass); + //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 + var claims = new List + { + new Claim(ClaimTypes.Name, user.FirstOrDefault().Id.ToString()), + new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().Id.ToString()), + new Claim("TenantId", user.FirstOrDefault().TenantId.ToString()), + new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.DateToTimeStamp()), + new Claim(ClaimTypes.Expiration, + DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) + }; + claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); + + + // ids4和jwt切换 + // jwt + if (!Permissions.IsUseIds4) + { + var data = await _roleModulePermissionServices.RoleModuleMaps(); + var list = (from item in data + where item.IsDeleted == false + orderby item.Id + select new PermissionItem + { + Url = item.Module?.LinkUrl, + Role = item.Role?.Name.ObjToString(), + }).ToList(); + + _requirement.Permissions = list; + } + + var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); + return Success(token, "获取成功"); + } + else + return Failed("认证失败"); + } + + [NonAction] + [HttpGet, Route("GetJwtTokenSecret")] + public async Task> GetJwtTokenSecret(string name = "", string pass = "") + { + var rlt = await GetJwtToken3(name, pass); + return rlt; + } + + /// + /// 请求刷新Token(以旧换新) + /// + /// + /// + [HttpGet, Route("RefreshToken")] + public async Task> RefreshToken(string token = "") + { + string jwtStr = string.Empty; + + if (string.IsNullOrEmpty(token)) + return Failed("token无效,请重新登录!"); + var tokenModel = JwtHelper.SerializeJwt(token); + if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0) + { + var user = await _sysUserInfoServices.QueryById(tokenModel.Uid); + var value = User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value; + if (value != null && user.CriticalModifyTime > value.ObjToDate()) + return Failed("很抱歉,授权已失效,请重新授权!"); + + if (user != null && !(value != null && user.CriticalModifyTime > value.ObjToDate())) + { + var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(user.LoginName, user.LoginPWD); + //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 + var claims = new List + { + new Claim(ClaimTypes.Name, user.LoginName), + new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ObjToString()), + new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.DateToTimeStamp()), + new Claim(ClaimTypes.Expiration, + DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) + }; + claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); + + //用户标识 + var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); + identity.AddClaims(claims); + + var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); + return Success(refreshToken, "获取成功"); + } + } + + return Failed("认证失败!"); + } + + #region 用户登录 + /// + /// 用户登录 + /// + /// + /// + [HttpPost, Route("Login")] + public async Task Login([FromBody] SwaggerLoginRequest loginRequest) + { + if (loginRequest is null) + return new { result = false }; + + try + { + var result = await GetJwtToken3(loginRequest.name, loginRequest.pwd); + if (result.Success) + { + HttpContext.SuccessSwagger(); + HttpContext.SuccessSwaggerJwt(result.Data.token); + return new { result = true }; + } + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Swagger登录异常"); + } + + return new { result = false }; + } + + /// + /// 用户自动登录 + /// + /// + /// + [HttpGet("AutoLogin/{Id}")] + public async Task> AutoLogin(long? Id) + { + if (Id is null) + return Failed("无效的用户ID"); + + try + { + var user = await _ghrs_UserServices.Query(d => d.UserId == Id); + if (user.Count > 0) + { + //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 + var claims = new List { + new Claim(ClaimTypes.Name, user.FirstOrDefault().UserId.ToString()), + new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().UserId.ToString()), + new Claim("TenantId", "0"), + new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.DateToTimeStamp()), + new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) + }; + var result = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); + + if (result.success) + { + HttpContext.SuccessSwagger(); + HttpContext.SuccessSwaggerJwt(result.token); + return Success(result.token); + } + } + } + catch (Exception E) + { + _logger.LogWarning(E, E.Message); + return Failed(E.Message); + } + return Failed("自动登录失败"); + } + + #endregion + } +} \ No newline at end of file diff --git a/Tiobon.Core.Api/Controllers/Ghra_GradeController.cs b/Tiobon.Core.Api/Controllers/Ggra/Ghra_GradeController.cs similarity index 100% rename from Tiobon.Core.Api/Controllers/Ghra_GradeController.cs rename to Tiobon.Core.Api/Controllers/Ggra/Ghra_GradeController.cs diff --git a/Tiobon.Core.Api/Controllers/LoginController.cs b/Tiobon.Core.Api/Controllers/LoginController.cs index 3fa15ab5..4f953268 100644 --- a/Tiobon.Core.Api/Controllers/LoginController.cs +++ b/Tiobon.Core.Api/Controllers/LoginController.cs @@ -12,7 +12,7 @@ namespace Tiobon.Core.Controllers /// 登录管理【无权限】 /// [Produces("application/json")] - [Route("api/Login"), ApiExplorerSettings(GroupName = Grouping.GroupName_Auth)] + [Route("api/Login"), ApiExplorerSettings(GroupName = Grouping.GroupName_Other)] [AllowAnonymous] public class LoginController : BaseApiController { diff --git a/Tiobon.Core.Api/Tiobon.Core.Model.xml b/Tiobon.Core.Api/Tiobon.Core.Model.xml index 93fe2f63..99769651 100644 --- a/Tiobon.Core.Api/Tiobon.Core.Model.xml +++ b/Tiobon.Core.Api/Tiobon.Core.Model.xml @@ -9,67 +9,67 @@ 表主键 - + 序号 - + 1:有效,0:未生效 - + 是否默认 - + 操作日志ID - + 创建人 - + 创建时间 - + 创建程序 - + 创建IP - + 最后修改人 - + 最后修改时间 - + 最后修改程序 - + 最后修改IP - + 备注 @@ -156,7 +156,7 @@ - Ghrs_User (Dto.Base) + 系统用户 (Dto.Base) @@ -335,7 +335,7 @@ - Ghrs_User (Dto.EditInput) + 系统用户 (Dto.EditInput) @@ -345,7 +345,7 @@ - Ghrs_User (Dto.InsertInput) + 系统用户 (Dto.InsertInput) @@ -651,7 +651,7 @@ - Ghrs_User (Model) + 系统用户 (Model) @@ -1679,7 +1679,7 @@ - Ghrs_User(Dto.View) + 系统用户(Dto.View) diff --git a/Tiobon.Core.Api/Tiobon.Core.xml b/Tiobon.Core.Api/Tiobon.Core.xml index 6da100a7..ebbfae5e 100644 --- a/Tiobon.Core.Api/Tiobon.Core.xml +++ b/Tiobon.Core.Api/Tiobon.Core.xml @@ -4,6 +4,66 @@ Tiobon.Core.Api + + + 登录管理【无权限】 + + + + + 构造函数注入 + + + + + + + + + + 获取JWT的方法1 + + + + + + + + 获取JWT的方法2:给Nuxt提供 + + + + + + + + 获取JWT的方法3:整个系统主要方法 + + + + + + + + 请求刷新Token(以旧换新) + + + + + + + 用户登录 + + + + + + + 用户自动登录 + + + + 增删改查基础服务 @@ -374,7 +434,7 @@ - Ghrs_User(Controller) + 系统用户(Controller) diff --git a/Tiobon.Core.Api/appsettings.json b/Tiobon.Core.Api/appsettings.json index 58704b32..5bb8db0f 100644 --- a/Tiobon.Core.Api/appsettings.json +++ b/Tiobon.Core.Api/appsettings.json @@ -191,7 +191,8 @@ "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //不要太短,16位+ "SecretFile": "C:\\my-file\\Tiobon.core.audience.secret.txt", //安全。内容就是Secret "Issuer": "Tiobon.Core", //这个值一定要在自己的项目里修改!! - "Audience": "wr" //这个值一定要在自己的项目里修改!! + "Audience": "wr", //这个值一定要在自己的项目里修改!! + "ExpirationHour": 72 //过去时长,单位小时 }, "Mongo": { "ConnectionString": "mongodb://nosql.data", diff --git a/Tiobon.Core.Extensions/Authorizations/Policys/PermissionHandler.cs b/Tiobon.Core.Extensions/Authorizations/Policys/PermissionHandler.cs index a2e5f359..febbc555 100644 --- a/Tiobon.Core.Extensions/Authorizations/Policys/PermissionHandler.cs +++ b/Tiobon.Core.Extensions/Authorizations/Policys/PermissionHandler.cs @@ -1,21 +1,16 @@ -using Tiobon.Core.Common; -using Tiobon.Core.Common.Helper; -using Tiobon.Core.Common.HttpContextUser; -using Tiobon.Core.IServices; -using Tiobon.Core.Model; +using System.Security.Claims; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens.Jwt; -using System.Linq; -using System.Security.Claims; -using System.Text.RegularExpressions; -using System.Threading.Tasks; +using Tiobon.Core.Common; +using Tiobon.Core.Common.Helper; +using Tiobon.Core.Common.HttpContextUser; using Tiobon.Core.Common.Swagger; +using Tiobon.Core.IServices; +using Tiobon.Core.Model; using Tiobon.Core.Model.Models; +using Tiobon.Core.Services; namespace Tiobon.Core.AuthHelper { @@ -31,7 +26,7 @@ namespace Tiobon.Core.AuthHelper private readonly IRoleModulePermissionServices _roleModulePermissionServices; private readonly IHttpContextAccessor _accessor; - private readonly ISysUserInfoServices _userServices; + private readonly IGhrs_UserServices _ghrs_UserServices; private readonly IUser _user; /// @@ -40,14 +35,14 @@ namespace Tiobon.Core.AuthHelper /// /// /// - /// + /// /// public PermissionHandler(IAuthenticationSchemeProvider schemes, IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor, - ISysUserInfoServices userServices, IUser user) + IGhrs_UserServices ghrs_UserServices, IUser user) { _accessor = accessor; - _userServices = userServices; + _ghrs_UserServices = ghrs_UserServices; _user = user; Schemes = schemes; _roleModulePermissionServices = roleModulePermissionServices; @@ -135,11 +130,11 @@ namespace Tiobon.Core.AuthHelper //应该要先校验用户的信息 再校验菜单权限相关的 // JWT模式下校验当前用户状态 // IDS4也可以校验,可以通过服务或者接口形式 - SysUserInfo user = new(); + Ghrs_User user = new(); if (!Permissions.IsUseIds4) { //校验用户 - user = await _userServices.QueryById(_user.ID, true); + user = await _ghrs_UserServices.QueryById(_user.ID, true); if (user == null) { _user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户不存在或已被删除").MessageModel; @@ -147,19 +142,19 @@ namespace Tiobon.Core.AuthHelper return; } - if (user.IsDeleted) + if (user.IsEnable == 0) { _user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被删除,禁止登陆!").MessageModel; context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.Message)); return; } - if (!user.Enable) - { - _user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被禁用!禁止登陆!").MessageModel; - context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.Message)); - return; - } + //if (!user.Enable) + //{ + // _user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被禁用!禁止登陆!").MessageModel; + // context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.Message)); + // return; + //} } // 判断token是否过期,过期则重新登录 @@ -190,63 +185,63 @@ namespace Tiobon.Core.AuthHelper //校验签发时间 - if (!Permissions.IsUseIds4) - { - var value = httpContext.User.Claims - .FirstOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value; - if (value != null) - { - if (user.CriticalModifyTime > value.ObjToDate()) - { - _user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权") - .MessageModel; - context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.Message)); - return; - } - } - } + //if (!Permissions.IsUseIds4) + //{ + // var value = httpContext.User.Claims + // .FirstOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value; + // if (value != null) + // { + // if (user.CriticalModifyTime > value.ObjToDate()) + // { + // _user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权") + // .MessageModel; + // context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.Message)); + // return; + // } + // } + //} // 获取当前用户的角色信息 - var currentUserRoles = new List(); - currentUserRoles = (from item in httpContext.User.Claims - where item.Type == ClaimTypes.Role - select item.Value).ToList(); - if (!currentUserRoles.Any()) - { - currentUserRoles = (from item in httpContext.User.Claims - where item.Type == "role" - select item.Value).ToList(); - } + //var currentUserRoles = new List(); + //currentUserRoles = (from item in httpContext.User.Claims + // where item.Type == ClaimTypes.Role + // select item.Value).ToList(); + //if (!currentUserRoles.Any()) + //{ + // currentUserRoles = (from item in httpContext.User.Claims + // where item.Type == "role" + // select item.Value).ToList(); + //} - //超级管理员 默认拥有所有权限 - if (currentUserRoles.All(s => s != "SuperAdmin")) - { - var isMatchRole = false; - var permisssionRoles = - requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); - foreach (var item in permisssionRoles) - { - try - { - if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) - { - isMatchRole = true; - break; - } - } - catch (Exception) - { - // ignored - } - } + ////超级管理员 默认拥有所有权限 + //if (currentUserRoles.All(s => s != "SuperAdmin")) + //{ + // var isMatchRole = false; + // var permisssionRoles = + // requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); + // foreach (var item in permisssionRoles) + // { + // try + // { + // if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) + // { + // isMatchRole = true; + // break; + // } + // } + // catch (Exception) + // { + // // ignored + // } + // } - //验证权限 - if (currentUserRoles.Count <= 0 || !isMatchRole) - { - context.Fail(); - return; - } - } + // //验证权限 + // if (currentUserRoles.Count <= 0 || !isMatchRole) + // { + // context.Fail(); + // return; + // } + //} context.Succeed(requirement); diff --git a/Tiobon.Core.Extensions/ServiceExtensions/AuthorizationSetup.cs b/Tiobon.Core.Extensions/ServiceExtensions/AuthorizationSetup.cs index dc5a77ae..3b553bd0 100644 --- a/Tiobon.Core.Extensions/ServiceExtensions/AuthorizationSetup.cs +++ b/Tiobon.Core.Extensions/ServiceExtensions/AuthorizationSetup.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Security.Claims; using System.Text; +using System.Security; namespace Tiobon.Core.Extensions { @@ -47,7 +48,8 @@ namespace Tiobon.Core.Extensions var signingKey = new SymmetricSecurityKey(keyByteArray); var Issuer = AppSettings.app(new string[] { "Audience", "Issuer" }); var Audience = AppSettings.app(new string[] { "Audience", "Audience" }); - + var ExpirationHourString = AppSettings.app(new string[] { "Audience", "ExpirationHour" }); + var ExpirationHour = string.IsNullOrWhiteSpace(ExpirationHourString) ? 4 : Convert.ToInt32(ExpirationHourString); var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); // 如果要数据库动态绑定,这里先留个空,后边处理器里动态赋值 @@ -61,7 +63,7 @@ namespace Tiobon.Core.Extensions Issuer,//发行人 Audience,//听众 signingCredentials,//签名凭据 - expiration: TimeSpan.FromSeconds(240 * 60)//接口的过期时间 + expiration: TimeSpan.FromSeconds(240 * 60 * ExpirationHour)//接口的过期时间 ); #endregion // 3、自定义复杂的策略授权 diff --git a/Tiobon.Core.Model/Base/BasePoco.cs b/Tiobon.Core.Model/Base/BasePoco.cs index 36737bb2..a190589f 100644 --- a/Tiobon.Core.Model/Base/BasePoco.cs +++ b/Tiobon.Core.Model/Base/BasePoco.cs @@ -5,7 +5,7 @@ using Tiobon.Core.Model.Models.RootTkey.Interface; namespace Tiobon.Core.Model { - public class BasePoco : IBaseDeleteFilter + public class BasePoco : BasePoco1 { /// @@ -14,7 +14,9 @@ namespace Tiobon.Core.Model //public long Id { get; set; } [SugarColumn(IsNullable = false, IsPrimaryKey = true, IsIdentity = false), Display(Name = "表主键")] public long Id { get; set; } - + } + public class BasePoco1 : IBaseDeleteFilter + { /// /// 序号 /// diff --git a/Tiobon.Core.Model/Models/Ghrs/Ghrs_User.cs b/Tiobon.Core.Model/Models/Ghrs/Ghrs_User.cs index 2f7d383c..fe994146 100644 --- a/Tiobon.Core.Model/Models/Ghrs/Ghrs_User.cs +++ b/Tiobon.Core.Model/Models/Ghrs/Ghrs_User.cs @@ -25,12 +25,13 @@ namespace Tiobon.Core.Model.Models /// 系统用户 (Model) /// [SugarTable("Ghrs_User", "Ghrs_User"), Entity(TableCnName = "系统用户", TableName = "Ghrs_User")] - public class Ghrs_User : BasePoco + public class Ghrs_User : BasePoco1 { /// /// UserId /// + [SugarColumn(IsNullable = false, IsPrimaryKey = true, IsIdentity = false), Display(Name = "表主键")] public int? UserId { get; set; } ///