using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using MilliSim.Common.Models; namespace MilliSim.Common.Entities; /// /// 实体基类 /// public abstract class BaseEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public DateTime UpdatedAt { get; set; } = DateTime.Now; public bool IsDeleted { get; set; } = false; } /// /// 用户表(员工 + 客户) /// public class User : BaseEntity { [Required, StringLength(50)] public string Username { get; set; } = string.Empty; [Required, StringLength(255)] public string Password { get; set; } = string.Empty; [StringLength(50)] public string Nickname { get; set; } = string.Empty; [StringLength(500)] public string Avatar { get; set; } = string.Empty; [StringLength(20)] public string Phone { get; set; } = string.Empty; [StringLength(100)] public string Email { get; set; } = string.Empty; public UserRole Role { get; set; } = UserRole.Customer; public UserStatus Status { get; set; } = UserStatus.Active; /// /// 创建人 ID(销售创建客户时记录) /// public long? CreatedBy { get; set; } [NotMapped] public string RoleName => Role.ToString(); } /// /// 项目表 /// public class Project : BaseEntity { [Required, StringLength(100)] public string Name { get; set; } = string.Empty; public long CategoryId { get; set; } [StringLength(500)] public string CoverImage { get; set; } = string.Empty; [StringLength(500)] public string VideoUrl { get; set; } = string.Empty; /// /// 视频封面(已废弃,保留字段避免数据库迁移问题) /// [StringLength(500)] public string VideoCover { get; set; } = string.Empty; [StringLength(1000)] public string Description { get; set; } = string.Empty; public string Content { get; set; } = string.Empty; /// /// 平台标签(逗号分隔) /// [StringLength(200)] public string Platforms { get; set; } = string.Empty; public ProjectStatus Status { get; set; } = ProjectStatus.Offline; /// /// 是否推荐(已废弃,保留字段避免数据库迁移问题) /// public bool IsFeatured { get; set; } = false; /// /// 排序值(已废弃,保留字段避免数据库迁移问题) /// public int SortOrder { get; set; } = 0; public int ViewCount { get; set; } = 0; public int ExperienceCount { get; set; } = 0; public int FavoriteCount { get; set; } = 0; public DateTime? PublishedAt { get; set; } [ForeignKey(nameof(CategoryId))] public ProjectCategory? Category { get; set; } } /// /// 项目分类表 /// public class ProjectCategory : BaseEntity { [Required, StringLength(50)] public string Name { get; set; } = string.Empty; [StringLength(500)] public string Icon { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; public UserStatus Status { get; set; } = UserStatus.Active; } /// /// 平台类型表 /// public class PlatformType : BaseEntity { [Required, StringLength(50)] public string Name { get; set; } = string.Empty; [StringLength(500)] public string Icon { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; public UserStatus Status { get; set; } = UserStatus.Active; } /// /// 特性标签表 /// public class FeatureTag : BaseEntity { [Required, StringLength(50)] public string Name { get; set; } = string.Empty; [StringLength(500)] public string Icon { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; public UserStatus Status { get; set; } = UserStatus.Active; } /// /// 项目标签关联表 /// public class ProjectTagRelation : BaseEntity { public long ProjectId { get; set; } public long TagId { get; set; } [ForeignKey(nameof(ProjectId))] public Project? Project { get; set; } [ForeignKey(nameof(TagId))] public FeatureTag? Tag { get; set; } } /// /// 项目截图表(已废弃,保留表避免数据库迁移问题,不再使用) /// public class ProjectScreenshot : BaseEntity { public long ProjectId { get; set; } [StringLength(500)] public string Url { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; [ForeignKey(nameof(ProjectId))] public Project? Project { get; set; } } /// /// 项目资源包表 /// public class ProjectPackage : BaseEntity { public long ProjectId { get; set; } public PackageType Type { get; set; } /// /// 原始文件名(上传时的文件名,非重命名后的对象键) /// [StringLength(255)] public string FileName { get; set; } = string.Empty; [StringLength(500)] public string Url { get; set; } = string.Empty; public long FileSize { get; set; } /// /// 唤醒协议前缀(固定为 millisim,Android/PC 平台使用) /// [StringLength(50)] public string WakeProtocolPrefix { get; set; } = string.Empty; /// /// 唤醒协议参数(Android/PC 平台使用,用户输入) /// [StringLength(500)] public string WakeProtocolParam { get; set; } = string.Empty; /// /// WebGL 解压后的根路径对象键(仅 WebGL 类型使用,用于在线运行) /// [StringLength(500)] public string ExtractedPath { get; set; } = string.Empty; [ForeignKey(nameof(ProjectId))] public Project? Project { get; set; } } /// /// 收藏表 /// public class Favorite : BaseEntity { public long UserId { get; set; } public long ProjectId { get; set; } [ForeignKey(nameof(UserId))] public User? User { get; set; } [ForeignKey(nameof(ProjectId))] public Project? Project { get; set; } } /// /// 体验记录表 /// public class ExperienceLog : BaseEntity { public long UserId { get; set; } public long ProjectId { get; set; } public int DurationSeconds { get; set; } [ForeignKey(nameof(UserId))] public User? User { get; set; } [ForeignKey(nameof(ProjectId))] public Project? Project { get; set; } } /// /// 授权记录表(客户级授权,授权后可运行所有项目) /// public class Authorization : BaseEntity { public long UserId { get; set; } /// /// 项目 ID(已废弃,改为客户级授权,保留字段避免数据库迁移问题) /// public long? ProjectId { get; set; } public long AuthorizedBy { get; set; } public DateTime StartTime { get; set; } = DateTime.Now; public DateTime EndTime { get; set; } public AuthorizationStatus Status { get; set; } = AuthorizationStatus.Active; [ForeignKey(nameof(UserId))] public User? User { get; set; } } /// /// 轮播图表 /// public class Banner : BaseEntity { [StringLength(100)] public string Title { get; set; } = string.Empty; [Required, StringLength(500)] public string Image { get; set; } = string.Empty; [StringLength(500)] public string Link { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; public UserStatus Status { get; set; } = UserStatus.Active; } /// /// 合作伙伴表 /// public class Partner : BaseEntity { [Required, StringLength(100)] public string Name { get; set; } = string.Empty; [Required, StringLength(500)] public string Logo { get; set; } = string.Empty; [StringLength(500)] public string Link { get; set; } = string.Empty; public int SortOrder { get; set; } = 0; public bool IsVisible { get; set; } = true; } /// /// 咨询消息表 /// public class Consultation : BaseEntity { [Required, StringLength(50)] public string Name { get; set; } = string.Empty; [Required, StringLength(20)] public string Contact { get; set; } = string.Empty; [StringLength(1000)] public string Content { get; set; } = string.Empty; public bool IsRead { get; set; } = false; } /// /// 通知表 /// public class Notification : BaseEntity { public NotificationType Type { get; set; } [Required, StringLength(200)] public string Title { get; set; } = string.Empty; [StringLength(1000)] public string Content { get; set; } = string.Empty; public long? UserId { get; set; } /// /// 业务事件 ID(防重复) /// [StringLength(100)] public string? EventId { get; set; } } /// /// 通知已读记录表 /// public class NotificationRead : BaseEntity { public long UserId { get; set; } public long NotificationId { get; set; } [ForeignKey(nameof(NotificationId))] public Notification? Notification { get; set; } } /// /// 操作日志表 /// public class OperationLog : BaseEntity { public long UserId { get; set; } [StringLength(50)] public string Username { get; set; } = string.Empty; [StringLength(50)] public string Module { get; set; } = string.Empty; [StringLength(50)] public string Operation { get; set; } = string.Empty; [StringLength(1000)] public string Detail { get; set; } = string.Empty; [StringLength(50)] public string Ip { get; set; } = string.Empty; } /// /// 系统设置表 /// public class SystemSetting : BaseEntity { [Required, StringLength(100)] public string Key { get; set; } = string.Empty; [Column(TypeName = "longtext")] public string Value { get; set; } = string.Empty; [StringLength(200)] public string Description { get; set; } = string.Empty; } /// /// 备份记录表 /// public class Backup : BaseEntity { [Required, StringLength(200)] public string FileName { get; set; } = string.Empty; public long FileSize { get; set; } [StringLength(20)] public string Type { get; set; } = "Manual"; [StringLength(500)] public string Url { get; set; } = string.Empty; } /// /// 唤醒协议配置表 /// public class WakeProtocol : BaseEntity { [Required, StringLength(50)] public string TerminalType { get; set; } = string.Empty; [Required, StringLength(200)] public string ProtocolPrefix { get; set; } = string.Empty; [Column(TypeName = "text")] public string ParamTemplate { get; set; } = string.Empty; public UserStatus Status { get; set; } = UserStatus.Active; } /// /// 待消费上传文件记录(用于垃圾资源清理跟踪) /// public class PendingUpload : BaseEntity { /// COS 对象键或本地访问 URL [Required, StringLength(500)] public string ObjectKey { get; set; } = string.Empty; /// 上传目录(icons/videos/logos/packages 等) [StringLength(50)] public string Folder { get; set; } = string.Empty; /// 上传者用户 ID public long? UploadedBy { get; set; } /// 上传时间 public DateTime UploadedAt { get; set; } = DateTime.Now; /// 消费时间(null=待消费,非null=已保存到实体) public DateTime? ConsumedAt { get; set; } }