238 lines
8.5 KiB
C#
238 lines
8.5 KiB
C#
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
|
||
}
|
||
}
|