using Dpz.Core.Entity.Base;
using Dpz.Core.Entity.Base.Indexes;

namespace Dpz.Core.Public.Entity;

/// <summary>
/// 账号活跃登录会话
/// </summary>
public class AccountSession : BaseEntity, IIndexedEntity<AccountSession>
{
    /// <summary>
    /// 账号
    /// </summary>
    public required string Account { get; set; }

    /// <summary>
    /// 登录会话 ID
    /// </summary>
    public required string SessionId { get; set; }

    /// <summary>
    /// 设备 ID(浏览器持久设备 Cookie,用于识别同一设备)
    /// </summary>
    public string? DeviceId { get; set; }

    /// <summary>
    /// IP 地址
    /// </summary>
    public string? IpAddress { get; set; }

    /// <summary>
    /// User-Agent
    /// </summary>
    public string? UserAgent { get; set; }

    /// <summary>
    /// 设备名称
    /// </summary>
    public string? DeviceName { get; set; }

    /// <summary>
    /// 设备类型
    /// </summary>
    public string? DeviceType { get; set; }

    /// <summary>
    /// 浏览器名称
    /// </summary>
    public string? BrowserName { get; set; }

    /// <summary>
    /// 浏览器版本
    /// </summary>
    public string? BrowserVersion { get; set; }

    /// <summary>
    /// 操作系统名称
    /// </summary>
    public string? OsName { get; set; }

    /// <summary>
    /// 操作系统版本
    /// </summary>
    public string? OsVersion { get; set; }

    /// <summary>
    /// 平台
    /// </summary>
    public string? Platform { get; set; }

    /// <summary>
    /// 屏幕宽度
    /// </summary>
    public int? ScreenWidth { get; set; }

    /// <summary>
    /// 屏幕高度
    /// </summary>
    public int? ScreenHeight { get; set; }

    /// <summary>
    /// 浏览器语言
    /// </summary>
    public string? Language { get; set; }

    /// <summary>
    /// 纬度
    /// </summary>
    public double? Latitude { get; set; }

    /// <summary>
    /// 经度
    /// </summary>
    public double? Longitude { get; set; }

    /// <summary>
    /// 定位精度(米)
    /// </summary>
    public double? LocationAccuracy { get; set; }

    /// <summary>
    /// 定位来源
    /// </summary>
    public string? LocationSource { get; set; }

    /// <summary>
    /// 国家或地区
    /// </summary>
    public string? Country { get; set; }

    /// <summary>
    /// 省/州/区域
    /// </summary>
    public string? Region { get; set; }

    /// <summary>
    /// 城市
    /// </summary>
    public string? City { get; set; }

    /// <summary>
    /// 时区
    /// </summary>
    public string? TimeZone { get; set; }

    /// <summary>
    /// 网络服务商
    /// </summary>
    public string? Isp { get; set; }

    /// <summary>
    /// 位置信息更新时间
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime? LocationUpdatedTime { get; set; }

    /// <summary>
    /// 登录方式
    /// </summary>
    [BsonRepresentation(BsonType.String)]
    public LoginMethod Method { get; set; }

    /// <summary>
    /// 是否已撤销
    /// </summary>
    public bool Revoked { get; set; }

    /// <summary>
    /// 撤销时间
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime? RevokedTime { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime CreateTime { get; set; }

    /// <summary>
    /// 最后活跃时间
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime LastActiveTime { get; set; }

    public static IReadOnlyList<EntityIndexDefinition> GetIndexDefinitions()
    {
        return new[]
        {
            new EntityIndexDefinition
            {
                Fields = [EntityIndexField.Ascending<AccountSession>(x => x.Account)],
            },
            new EntityIndexDefinition
            {
                Fields = [EntityIndexField.Ascending<AccountSession>(x => x.SessionId)],
                Unique = true,
            },
            new EntityIndexDefinition
            {
                Fields =
                [
                    EntityIndexField.Ascending<AccountSession>(x => x.Account),
                    EntityIndexField.Ascending<AccountSession>(x => x.DeviceId),
                    EntityIndexField.Ascending<AccountSession>(x => x.Revoked),
                ],
            },
        };
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 账号活跃登录会话 的实体类定义,用于记录和管理用户的登录会话信息。

类结构

public class AccountSession : BaseEntity, IIndexedEntity<AccountSession>
  • 继承自 BaseEntity(基础实体类)
  • 实现 IIndexedEntity<AccountSession> 接口(用于定义数据库索引)

主要属性分类

1. 核心标识信息

  • Account: 用户账号(必填)
  • SessionId: 登录会话唯一标识(必填)
  • DeviceId: 设备唯一标识(浏览器 Cookie)

2. 网络信息

  • IpAddress: IP 地址
  • UserAgent: 浏览器用户代理字符串

3. 设备信息

  • DeviceName: 设备名称
  • DeviceType: 设备类型(如手机、平板、电脑)
  • BrowserName/BrowserVersion: 浏览器名称和版本
  • OsName/OsVersion: 操作系统名称和版本
  • Platform: 平台信息
  • ScreenWidth/ScreenHeight: 屏幕分辨率
  • Language: 浏览器语言

4. 地理位置信息

  • Latitude/Longitude: 经纬度坐标
  • LocationAccuracy: 定位精度(米)
  • LocationSource: 定位来源(如 GPS、IP)
  • Country/Region/City: 国家/地区/城市
  • TimeZone: 时区
  • Isp: 网络服务提供商
  • LocationUpdatedTime: 位置信息更新时间

5. 会话管理

  • Method: 登录方式(枚举类型,存储为字符串)
  • Revoked: 会话是否已撤销
  • RevokedTime: 撤销时间
  • CreateTime: 会话创建时间
  • LastActiveTime: 最后活跃时间

数据库索引定义

GetIndexDefinitions() 方法定义了三个索引:

  1. 按账号索引:用于快速查询某个账号的所有会话
  2. 按会话ID唯一索引:确保会话ID唯一,快速定位特定会话
  3. 组合索引(Account + DeviceId + Revoked):用于查询特定账号在特定设备上的活跃会话

使用场景

此实体类适用于:

  • 用户登录会话管理
  • 多设备登录追踪
  • 安全审计和异常登录检测
  • 设备指纹识别
  • 地理位置分析
  • 会话撤销(如强制登出)

技术特点

  • 使用 MongoDB 的 BSON 特性(BsonDateTimeOptions、BsonRepresentation)
  • 使用 required 关键字标记必填字段(C# 11+)
  • 支持可空类型,灵活处理可选信息
评论加载中...