服务器部署测试~~~
This commit is contained in:
44
Models/RequestModels.cs
Normal file
44
Models/RequestModels.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SimpleTodoApiWithPg.Models
|
||||
{
|
||||
public class UpdateUserRequest
|
||||
{
|
||||
// 设为可空类型,表示这些字段可以选择性更新
|
||||
[MaxLength(50)]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
[EmailAddress] // 仍然应用验证
|
||||
public string? Email { get; set; }
|
||||
|
||||
// 密码更新处理:提供一个用于接收新明文密码的字段
|
||||
// 注意:不应该有 PasswordHash 字段!
|
||||
[MaxLength(50)]
|
||||
public string? NewPassword { get; set; }
|
||||
}
|
||||
|
||||
public class LoginRequest
|
||||
{
|
||||
[Required(ErrorMessage = "用户名不能为空")]
|
||||
[MaxLength(50, ErrorMessage = "用户名长度不能超过50个字符")]
|
||||
public string Username { get; set; } = null!; // null! 表示编译器知道它不会是null
|
||||
|
||||
[Required(ErrorMessage = "密码不能为空")]
|
||||
[MaxLength(50,ErrorMessage = "密码长度不能超过50个字符!")]
|
||||
// 可以添加 MinLength/MaxLength 验证
|
||||
public string Password { get; set; } = null!; // 明文密码
|
||||
}
|
||||
|
||||
public class RegisterRequest()
|
||||
{
|
||||
public required string Username { get; set; }
|
||||
|
||||
public required string Email { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public record RefreshTokenRequest(string RefreshToken);
|
||||
|
||||
|
||||
}
|
||||
50
Models/ResponseModels.cs
Normal file
50
Models/ResponseModels.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
namespace SimpleTodoApiWithPg.Models
|
||||
{
|
||||
// 这是一个泛型记录 (generic record),用于包装所有 API 的返回数据
|
||||
public record ApiResponse<T>(
|
||||
bool Success,
|
||||
string Message,
|
||||
T? Data,
|
||||
int Code = 200
|
||||
);
|
||||
|
||||
// 提供一个静态类,方便快速创建标准响应
|
||||
public static class ApiResponse
|
||||
{
|
||||
public static ApiResponse<T> Ok<T>(T data, string message = "操作成功")
|
||||
{
|
||||
return new ApiResponse<T>(true, message, data);
|
||||
}
|
||||
|
||||
// **** 关键修改在这里:让 Fail 方法也变为泛型 ****
|
||||
// 它接受一个类型参数 T,并返回 ApiResponse<T>
|
||||
// default(T) 对于引用类型(如 AuthResponse)会返回 null
|
||||
public static ApiResponse<T> Fail<T>(string message, int code = 400)
|
||||
{
|
||||
return new ApiResponse<T>(false, message, default(T), code);
|
||||
}
|
||||
|
||||
// 您可以保留一个非泛型版本的 Fail 方便在某些无需特定 Data 类型的地方使用
|
||||
// 但在需要特定返回类型的地方,请使用泛型版本
|
||||
public static ApiResponse<object> Fail(string message, int code = 400)
|
||||
{
|
||||
return new ApiResponse<object>(false, message, null, code);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新登录成功后返回的 DTO
|
||||
public class AuthResponse
|
||||
{
|
||||
public string AccessToken { get; set; } = null!;
|
||||
public string RefreshToken { get; set; } = null!;
|
||||
public DateTime AccessTokenExpiration { get; set; }
|
||||
}
|
||||
|
||||
public class RegisterResponse
|
||||
{
|
||||
public string? Username { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Password { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ namespace SimpleTodoApiWithPg.Models
|
||||
{
|
||||
public class Todo
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid Id { get; set; } = Guid.CreateVersion7();
|
||||
public string Title { get; set; } = string.Empty; // 待办事项标题
|
||||
public bool IsCompleted { get; set; } // 是否已完成
|
||||
}
|
||||
|
||||
56
Models/User.cs
Normal file
56
Models/User.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace SimpleTodoApiWithPg.Models
|
||||
{
|
||||
public class User
|
||||
{
|
||||
[Key] // 标识 Id 为主键
|
||||
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 数据库自动生成(例如 PostgreSQL 的 SERIAL 类型)
|
||||
public Guid Id { get; set; } = Guid.CreateVersion7();
|
||||
|
||||
[Required] // 标识为非空字段
|
||||
[MaxLength(50)] // 限制字符串最大长度
|
||||
public string Username { get; set; } = null!;
|
||||
|
||||
[Required(ErrorMessage = "邮箱是必填项。")]
|
||||
[EmailAddress(ErrorMessage = "邮箱格式不正确。")] //
|
||||
[StringLength(50, MinimumLength = 5, ErrorMessage = "邮箱长度必须在 {2} 到 {1} 个字符之间。")] //
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
// 密码通常会存储哈希值,而不是明文
|
||||
[Required]
|
||||
[MaxLength(100)]
|
||||
public string PasswordHash { get; set; } = null!;
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// 如果需要,可以添加导航属性,例如,一个用户可以有多个 Todo
|
||||
// public ICollection<Todo> Todos { get; set; } = new List<Todo>();
|
||||
}
|
||||
|
||||
public class RefreshToken
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.CreateVersion7();
|
||||
|
||||
[Required]
|
||||
public string Token { get; set; } = null!; // 存储 refresh token 的字符串
|
||||
|
||||
[Required]
|
||||
public DateTime Expires { get; set; } // 过期时间
|
||||
|
||||
public bool IsExpired => DateTime.UtcNow >= Expires; // 计算属性,判断是否已过期
|
||||
|
||||
public DateTime Created { get; set; } // 创建时间
|
||||
|
||||
public DateTime? Revoked { get; set; } // 撤销时间 (可空)
|
||||
|
||||
public bool IsActive => Revoked == null && !IsExpired; // 计算属性,判断是否有效
|
||||
|
||||
// 外键关联到 User 表
|
||||
public Guid UserId { get; set; }
|
||||
[ForeignKey("UserId")]
|
||||
public User User { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user