using GraphQL; using LY.App.Common.Cypher; using LY.App.Common.Redis; using LY.App.Extensions.DI; using LY.App.Model; using Mapster; using Microsoft.IdentityModel.Tokens; using SqlSugar; using StackExchange.Redis; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; namespace LY.App.Service { [ServiceInjection(InjectionType.Transient)] public class UserService { private readonly SqlSugarClient _db; private readonly IConfiguration _config; private readonly RedisService _redisService; public UserService(SqlSugarClient db, IConfiguration config, RedisService redisService) { _db = db; _config = config; _redisService = redisService; } #region 增删改查 /// /// /// /// /// public async Task Add(AddUser input) { var exists = await _db.Queryable().AnyAsync(s => s.Name == input.Name && s.Disable == false); if (!exists) { var entity = input.Adapt(); // var entity = _mapper.Map(input); entity.CreateTime = DateTime.Now; entity.UpdatePwdTime = DateTime.Now; entity.Password = MD5CypherUtil.Hash("ly_" + input.Password); var Id = await _db.Insertable(entity).ExecuteReturnSnowflakeIdAsync(); return new ApiResult() { code = 0, data = Id.ToString() }; } else { return new ApiResult() { code = 1, msg = "已存在该用户名" }; } } /// /// 删除用户,标记删除,不是物理删除 /// /// /// public async Task SoftDelete(IEnumerable ids) { if (ids.Any()) { foreach (var item in ids) { var entity = await _db.Queryable().FirstAsync(s => s.Id == item); if (entity?.Name != "admin") { entity.Disable = entity.Disable == true ? false : true; await _db.Updateable(entity).ExecuteCommandAsync(); } else return "admin 不可删除!"; } return ""; } return "ids不能为空"; } /// /// 获取用户信息 /// /// /// public async Task GetUserById(long userId) { var entity = await _db.Queryable().FirstAsync(s => s.Id == userId); if (entity != null) { entity.Password = ""; return new ApiResult() { code = 0, data = entity }; } return null; } /// /// 监测登录次数 /// /// /// private async Task CheckLoginNum(string username) { int num = 0; // var node = SettingHelper.Instance.GetNode("Vertify", "LoginFailed"); var node = _config["Vertify"]; var key = RedisKeyList.LogNum(username); var val = await _redisService.GetAsync(key); if (num >= int.Parse(node)) { return true; } return false; } /// /// 登录 /// /// /// public async Task Login(LoginModel input) { if (await CheckLoginNum(input.username)) { return new ApiResult() { code = 1, msg = "连续登录失败5次,锁定30分钟" }; } var password = MD5CypherUtil.Hash("ly_" + input.password); var entity = await _db.Queryable() .Where(s => s.Disable == false && s.Name == input.username && s.Password == password).FirstAsync(); if (entity == null) { await SetLoginNum(input.username); return new ApiResult() { code = 1, msg = "请检查用户名跟密码!" }; } entity.LoginTime = DateTime.Now; await _db.Updateable(entity).ExecuteCommandAsync(); await RemoveLoginNum(input.username); string token = CreateToken(entity); //加入redis await _redisService.SetAsync(RedisKeyList.TokenUser(input.username), token, TimeSpan.FromSeconds(60 * 60 * 24 * 7)); var positionIds = entity.positionId?.Select(s => s.ToString()).ToList(); return new ApiResult() { code = 1, data = new { token, expires = DateTime.UtcNow.AddSeconds(60 * 60 * 24 * 7), isAdmin = entity.IsAdmin, userid = entity.Id.ToString(), positionIds } }; } private async Task RemoveLoginNum(string username) { var key = $"login_num_{username}"; await _redisService.DeleteAsync(key); } private async Task SetLoginNum(string username) { var key = RedisKeyList.LogNum(username); var num = await _redisService.GetAsync(key); await _redisService.SetAsync(key, num + 1, TimeSpan.FromMinutes(30)); } private string CreateToken(UserEntity user) { // 创建JWT的密钥 var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Token:SecretKey"])); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); // 创建Claims var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub,user.Name), new Claim(JwtRegisteredClaimNames.Sid, user.Id.ToString()) // 还可以添加其他需要的Claims }; // 创建Token var token = new JwtSecurityToken( issuer: _config["Token:Issuer"], audience: _config["Token:Audience"], claims: claims, expires: DateTime.UtcNow.AddSeconds(60 * 60 * 24 * 7), // 设置Token过期时间 signingCredentials: credentials ); // 生成Token字符串 var tokenString = new JwtSecurityTokenHandler().WriteToken(token); return tokenString; } /// /// /// /// /// /// /// public async Task GetPage(int pageSize, int pageNum, string key) { RefAsync total = 0; var query = await _db.Queryable() .Where(s => s.Disable == false) .WhereIF(!string.IsNullOrEmpty(key), s => s.Name.Contains(key)) .OrderBy(s => s.Id) .ToPageListAsync(pageNum, pageSize, total); query.ForEach(s => { if (s.positionId is not null && s.positionId.Any()) { s.positionName = _db.Queryable().Where(p => s.positionId.Contains(p.Id.ToString())).Select(p => p.Name).ToList(); } }); return new { total = total.Value, items = query }; } /// /// 更新密码 /// /// /// public async Task UpdatePwd(UpdatePwdDto input) { var md5 = MD5CypherUtil.Hash("ly_" + input.oldPwd); var entity = await _db.Queryable().FirstAsync(s => s.Id == input.Id); if (entity.Password == md5) { entity.Password = MD5CypherUtil.Hash("ly_" + input.newPwd); entity.UpdatePwdTime = DateTime.Now; await _db.Updateable(entity).UpdateColumns(s => new { s.Password, s.UpdatePwdTime }).ExecuteCommandAsync(); return ""; } return "原密码不正确"; } public async Task Update(UpdateUser input) { if (!string.IsNullOrEmpty(input.Name)) { var entity = input.Adapt(); await _db.Updateable(entity).UpdateColumns(it => new { it.IsAdmin }).ExecuteCommandAsync(); return null; } return "用户名不能为空"; } #endregion } }