feature-nxdev #33

Merged
nanxun merged 3 commits from feature-nxdev into main 2025-12-29 21:57:59 +08:00
12 changed files with 122 additions and 13 deletions
@@ -1,5 +1,9 @@
using IM_API.Interface.Services; using IM_API.Dtos;
using IM_API.Interface.Services;
using IM_API.Services; using IM_API.Services;
using IM_API.Tools;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
namespace IM_API.Configs namespace IM_API.Configs
{ {
@@ -7,6 +11,7 @@ namespace IM_API.Configs
{ {
public static IServiceCollection AddAllService(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddAllService(this IServiceCollection services, IConfiguration configuration)
{ {
services.AddAutoMapper(typeof(MapperConfig)); services.AddAutoMapper(typeof(MapperConfig));
services.AddTransient<IAuthService, AuthService>(); services.AddTransient<IAuthService, AuthService>();
services.AddTransient<IUserService, UserService>(); services.AddTransient<IUserService, UserService>();
@@ -14,8 +19,28 @@ namespace IM_API.Configs
services.AddTransient<IMessageSevice, MessageService>(); services.AddTransient<IMessageSevice, MessageService>();
services.AddTransient<IConversationService, ConversationService>(); services.AddTransient<IConversationService, ConversationService>();
services.AddSingleton<IJWTService, JWTService>(); services.AddSingleton<IJWTService, JWTService>();
services.AddSingleton<IRefreshTokenService,RedisRefreshTokenService>(); services.AddSingleton<IRefreshTokenService, RedisRefreshTokenService>();
return services; return services;
} }
} public static IServiceCollection AddModelValidation(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var errors = context.ModelState
.Where(e => e.Value.Errors.Count > 0)
.Select(e => new
{
Field = e.Key,
Message = e.Value.Errors.First().ErrorMessage
});
return new BadRequestObjectResult(new BaseResponse<object?>(CodeDefine.PARAMETER_ERROR.Code, errors.First().Message));
};
});
return services;
}
}
} }
@@ -28,6 +28,20 @@ namespace IM_API.Controllers
var res = new BaseResponse<List<Conversation>>(list); var res = new BaseResponse<List<Conversation>>(list);
return Ok(res); return Ok(res);
} }
[HttpPost]
public async Task<IActionResult> Clear()
{
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
await _conversationSerivice.ClearConversationsAsync(int.Parse(userIdStr));
return Ok(new BaseResponse<object?>());
}
[HttpPost]
public async Task<IActionResult> Delete(int cid)
{
await _conversationSerivice.DeleteConversationAsync(cid);
return Ok(new BaseResponse<object?>());
}
} }
} }
+1 -1
View File
@@ -83,7 +83,7 @@ namespace IM_API.Controllers
{ {
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier); var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
int userId = int.Parse(userIdStr); int userId = int.Parse(userIdStr);
await _userService.ResetPasswordAsync(userId,dto.oldPassword,dto.Password); await _userService.ResetPasswordAsync(userId,dto.OldPassword,dto.Password);
return Ok(new BaseResponse<object?>()); return Ok(new BaseResponse<object?>());
} }
/// <summary> /// <summary>
+26 -2
View File
@@ -1,7 +1,31 @@
using IM_API.Models; using IM_API.Models;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos namespace IM_API.Dtos
{ {
public record FriendInfoDto(int Id, int UserId,int FriendId,FriendStatus StatusEnum,DateTime Created,string RemarkName,string? Avatar); public record FriendInfoDto
public record FriendRequestHandleDto(HandleFriendRequestAction action,string? remarkName); {
public int Id { get; init; }
public int UserId { get; init; }
public int FriendId { get; init; }
public FriendStatus StatusEnum { get; init; }
public DateTime Created { get; init; }
public string RemarkName { get; init; } = string.Empty;
public string? Avatar { get; init; }
}
public record FriendRequestHandleDto
{
[Required(ErrorMessage = "操作必填")]
public HandleFriendRequestAction Action { get; init; }
[StringLength(20, ErrorMessage = "备注名最大20个字符")]
public string? RemarkName { get; init; }
}
} }
+6 -1
View File
@@ -1,10 +1,15 @@
namespace IM_API.Dtos using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
{ {
public class FriendRequestDto public class FriendRequestDto
{ {
public int FromUserId { get; set; } public int FromUserId { get; set; }
public int ToUserId { get; set; } public int ToUserId { get; set; }
[Required(ErrorMessage = "备注名必填")]
[StringLength(20, ErrorMessage = "备注名不能超过20位字符")]
public string? RemarkName { get; set; } public string? RemarkName { get; set; }
[StringLength(50, ErrorMessage = "描述不能超过50字符")]
public string? Description { get; set; } public string? Description { get; set; }
} }
} }
+10 -1
View File
@@ -1,8 +1,17 @@
namespace IM_API.Dtos using IM_API.Tools;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
{ {
public class LoginRequestDto public class LoginRequestDto
{ {
[Required(ErrorMessage = "用户名不能为空")]
[StringLength(20, ErrorMessage = "用户名不能超过20字符")]
[RegularExpression(@"^[A-Za-z0-9]+$",ErrorMessage = "")]
public string Username { get; set; } public string Username { get; set; }
[Required(ErrorMessage = "密码不能为空")]
[StringLength(50, ErrorMessage = "密码不能超过50字符")]
public string Password { get; set; } public string Password { get; set; }
} }
} }
+11 -1
View File
@@ -1,9 +1,19 @@
namespace IM_API.Dtos using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
{ {
public class RegisterRequestDto public class RegisterRequestDto
{ {
[Required(ErrorMessage = "用户名不能为空")]
[MaxLength(20, ErrorMessage = "用户名不能超过20字符")]
[RegularExpression(@"^[A-Za-z0-9]+$", ErrorMessage = "")]
public string Username { get; set; } public string Username { get; set; }
[Required(ErrorMessage = "密码不能为空")]
[MaxLength(50, ErrorMessage = "密码不能超过50字符")]
public string Password { get; set; } public string Password { get; set; }
[Required(ErrorMessage = "昵称不能为空")]
[MaxLength(20, ErrorMessage = "昵称不能超过20字符")]
public string? NickName { get; set; } public string? NickName { get; set; }
} }
} }
+4 -1
View File
@@ -1,7 +1,10 @@
namespace IM_API.Dtos using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
{ {
public class UpdateUserDto public class UpdateUserDto
{ {
[MaxLength(20, ErrorMessage = "昵称不能超过50字符")]
public string? NickName { get; set; } public string? NickName { get; set; }
public string? Avatar { get; set; } public string? Avatar { get; set; }
+16 -2
View File
@@ -1,7 +1,21 @@
using IM_API.Models; using IM_API.Models;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos namespace IM_API.Dtos
{ {
public record PasswordResetDto(string oldPassword,string Password); public record PasswordResetDto
public record OnlineStatusSetDto(UserOnlineStatus OnlineStatus); {
[Required(ErrorMessage = "旧密码不能为空")]
public string OldPassword { get; init; }
[Required(ErrorMessage = "新密码不能为空")]
[MaxLength(50, ErrorMessage = "密码不能超过50个字符")]
public string Password { get; init; }
}
public record OnlineStatusSetDto
{
[Required]
public UserOnlineStatus OnlineStatus { get; init; }
}
} }
+1
View File
@@ -102,6 +102,7 @@ namespace IM_API
{ {
options.Filters.Add<GlobalExceptionFilter>(); options.Filters.Add<GlobalExceptionFilter>();
}); });
builder.Services.AddModelValidation(configuration);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
+5
View File
@@ -38,6 +38,11 @@ api.interceptors.response.use(
message.error('未登录,请登录后操作。'); message.error('未登录,请登录后操作。');
router.push('/auth/login') router.push('/auth/login')
break; break;
case 400:
if (err.response.data && err.response.data.code == 1003) {
message.error(err.response.data.message);
break;
}
default: default:
message.error('请求错误,请检查网络。'); message.error('请求错误,请检查网络。');
break; break;
-1
View File
@@ -102,7 +102,6 @@ const handleLogin = async () => {
} }
} catch (e) { } catch (e) {
console.error(e) console.error(e)
message.error('登录请求异常')
} finally{ } finally{
loading.value = false; loading.value = false;
} }