ly/Service/UserService.cs

238 lines
8.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GraphQL;
using LY.App.Common.Cypher;
using LY.App.Common.Redis;
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
{
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<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不能为空";
}
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;
}
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 users = await _db.Queryable<UserEntity>().ToListAsync();
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));
return new ApiResult()
{
code = 1,
data = new
{
token,
expires = DateTime.UtcNow.AddSeconds(60*60*24*7),
isAdmin = entity.IsAdmin,
userid = entity.Id.ToString()
}
};
}
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).ToPageListAsync(pageNum, pageSize, total);
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.UpdatePwdTime,
it.Password,
it.Email,
it.IsAdmin
}).ExecuteCommandAsync();
return null;
}
return "用户名不能为空";
}
#endregion
}
}