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; }
}