服务器部署测试~~~

This commit is contained in:
heiye111
2025-10-10 16:02:38 +08:00
parent 8ab52738c0
commit 5c186aa446
87 changed files with 5062 additions and 167 deletions

44
Models/RequestModels.cs Normal file
View 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
View 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; }
}
}

View File

@@ -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
View 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!;
}
}