263 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			263 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
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 增删改查
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="input"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<ApiResult> Add(AddUser input)
 | 
						||
        {
 | 
						||
            var exists = await _db.Queryable<UserEntity>().AnyAsync(s => s.Name == input.Name && s.Disable == false);
 | 
						||
            if (!exists)
 | 
						||
            {
 | 
						||
                var entity = input.Adapt<UserEntity>();
 | 
						||
                // var entity = _mapper.Map<UserEntity>(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 = "已存在该用户名" };
 | 
						||
            }
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 删除用户,标记删除,不是物理删除
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="ids"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<string> SoftDelete(IEnumerable<long> ids)
 | 
						||
        {
 | 
						||
            if (ids.Any())
 | 
						||
            {
 | 
						||
                foreach (var item in ids)
 | 
						||
                {
 | 
						||
                    var entity = await _db.Queryable<UserEntity>().FirstAsync(s => s.Id == item);
 | 
						||
                    if (entity?.Name != "admin")
 | 
						||
                    {
 | 
						||
                        entity.Disable = entity.Disable == true ? false : true;
 | 
						||
                        await _db.Updateable<UserEntity>(entity).ExecuteCommandAsync();
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                        return "admin 不可删除!";
 | 
						||
                }
 | 
						||
                return "";
 | 
						||
            }
 | 
						||
            return "ids不能为空";
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 获取用户信息
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="userId"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<ApiResult> GetUserById(long userId)
 | 
						||
        {
 | 
						||
            var entity = await _db.Queryable<UserEntity>().FirstAsync(s => s.Id == userId);
 | 
						||
            if (entity != null)
 | 
						||
            {
 | 
						||
                entity.Password = "";
 | 
						||
                return new ApiResult() { code = 0, data = entity };
 | 
						||
            }
 | 
						||
            return null;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 监测登录次数
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="username"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private async Task<bool> 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<int>(key);
 | 
						||
            if (num >= int.Parse(node))
 | 
						||
            {
 | 
						||
                return true;
 | 
						||
            }
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 登录
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="input"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<ApiResult> 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<UserEntity>()
 | 
						||
                 .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<string>(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<int>(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;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="pageSize"></param>
 | 
						||
        /// <param name="pageNum"></param>
 | 
						||
        /// <param name="key"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<object> GetPage(int pageSize, int pageNum, string key)
 | 
						||
        {
 | 
						||
            RefAsync<int> total = 0;
 | 
						||
            var query = await _db.Queryable<UserEntity>()
 | 
						||
                .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<PositionInfo>().Where(p => s.positionId.Contains(p.Id.ToString())).Select(p => p.Name).ToList();
 | 
						||
                }
 | 
						||
            });
 | 
						||
            return new
 | 
						||
            {
 | 
						||
                total = total.Value,
 | 
						||
                items = query
 | 
						||
            };
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 更新密码
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="input"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public async Task<string> UpdatePwd(UpdatePwdDto input)
 | 
						||
        {
 | 
						||
            var md5 = MD5CypherUtil.Hash("ly_" + input.oldPwd);
 | 
						||
            var entity = await _db.Queryable<UserEntity>().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<string> Update(UpdateUser input)
 | 
						||
        {
 | 
						||
            if (!string.IsNullOrEmpty(input.Name))
 | 
						||
            {
 | 
						||
                var entity = input.Adapt<UserEntity>();
 | 
						||
                await _db.Updateable(entity).UpdateColumns(it => new
 | 
						||
                {
 | 
						||
                    it.IsAdmin
 | 
						||
                }).ExecuteCommandAsync();
 | 
						||
                return null;
 | 
						||
            }
 | 
						||
            return "用户名不能为空";
 | 
						||
        }
 | 
						||
        #endregion
 | 
						||
    }
 | 
						||
}
 |