using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace Rmsys.Domain.Entities; // ============================================================ // 基础数据 // ============================================================ /// 处室(部务会维度:干部一处 / 干部二处 / 人事处) public class Dept { public int Id { get; set; } /// 处室编码,如 yichu / erchu / rsc public string Code { get; set; } = ""; public string Name { get; set; } = ""; /// 职责范围 public string? Duty { get; set; } /// 负责人 public string? Leader { get; set; } public int Sort { get; set; } /// 1=启用 0=停用(停用保留历史留痕) public int Enabled { get; set; } = 1; public DateTime CreatedAt { get; set; } = DateTime.Now; } /// 会议(部务会 / 常委会 / 书记专题会) public class Meeting { public int Id { get; set; } public string Type { get; set; } = MeetingType.BuWu; /// 届次号,如 192 public int? SessionNo { get; set; } public string Name { get; set; } = ""; public DateTime? HeldAt { get; set; } public string? Place { get; set; } /// 主持人 public string? Host { get; set; } /// 密级:机密 / 秘密 / 内部 public string Secret { get; set; } = "机密"; /// 密级星标,如 ★★ public string? SecretStars { get; set; } = "★★"; /// 口令级别:A级 / B级 public string? PwdLevel { get; set; } = "B级"; public string Status { get; set; } = MeetingStatus.Draft; public string? Remark { get; set; } /// 上会批次号:打通「部务会→常委会→书记专题会」同一批干部的会议链条 public string? BatchNo { get; set; } /// 软删除:1=已在回收站(政务系统不做物理删除) public int IsDeleted { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public DateTime UpdatedAt { get; set; } = DateTime.Now; public List Cadres { get; set; } = new(); } /// 干部(上会人员;后续可作为干部库主表) public class Cadre { public int Id { get; set; } public int? DeptId { get; set; } public string Name { get; set; } = ""; public string? Sex { get; set; } /// 出生年月,如 1976.03 public string? Birth { get; set; } public string? Nation { get; set; } /// 籍贯 public string? NativePlace { get; set; } /// 出生地 public string? BirthPlace { get; set; } /// 入党时间 public string? PartyDate { get; set; } /// 参加工作时间 public string? WorkDate { get; set; } public string? Health { get; set; } /// 专业技术职务 public string? TechPost { get; set; } /// 熟悉专业有何专长 public string? Expertise { get; set; } // 全日制教育 public string? EduFullSchool { get; set; } public string? EduFullMajor { get; set; } public string? EduFullLevel { get; set; } public string? EduFullDegree { get; set; } // 在职教育 public string? EduInSchool { get; set; } public string? EduInMajor { get; set; } public string? EduInLevel { get; set; } public string? EduInDegree { get; set; } /// 现任职务 public string? CurrentPost { get; set; } /// 拟任职务 public string? ProposedPost { get; set; } /// 拟免职务 public string? DismissPost { get; set; } /// 奖惩情况 public string? Rewards { get; set; } /// 年度考核结果 public string? Exams { get; set; } /// 任免理由 public string? AppointReason { get; set; } /// 关键词/专长摘要(PAD 搜索与列示用) public string? Kw { get; set; } /// 主要表现(考察材料/汇报材料正文来源) public string? Perf { get; set; } /// 工作经历概述(考察材料用) public string? Care { get; set; } /// 考察组建议(考察材料结论段) public string? Suggest { get; set; } /// /// 身份证号:仅用于存储与同名干部去重匹配,后台与 PAD 一律不展示、不下发到数据包。 /// 唯一性不建库级约束(历史数据可能缺失或重复),由导入逻辑优先按此匹配。 /// [MaxLength(18)] [JsonIgnore] // 仅存库:任何接口都不序列化该字段(后台页面与 PAD 均不展示) public string? IdCard { get; set; } /// 照片相对路径 public string? PhotoPath { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public DateTime UpdatedAt { get; set; } = DateTime.Now; public List Resumes { get; set; } = new(); public List Families { get; set; } = new(); public List Notes { get; set; } = new(); } /// 简历(按顺序成条) public class CadreResume { public int Id { get; set; } public int CadreId { get; set; } public int Sort { get; set; } /// 时间段,如 1992.09—1996.07 public string? Period { get; set; } /// 经历内容 public string Content { get; set; } = ""; public Cadre? Cadre { get; set; } } /// 家庭主要成员及重要社会关系 public class CadreFamily { public int Id { get; set; } public int CadreId { get; set; } public int Sort { get; set; } public string? Relation { get; set; } public string? Name { get; set; } public string? Age { get; set; } public string? Political { get; set; } public string? WorkUnit { get; set; } public Cadre? Cadre { get; set; } } /// 批注(后台可写 / PAD 领导可批,评审意见 P0 补齐项) public class CadreNote { public int Id { get; set; } public int CadreId { get; set; } public int? MeetingId { get; set; } /// 挂接字段名,如 proposedPost public string? FieldName { get; set; } public string Content { get; set; } = ""; /// 来源:admin=干部科 / pad=上会领导 / import=导入 public string Source { get; set; } = "admin"; public string? Author { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public Cadre? Cadre { get; set; } } /// 回避关系(涉及本人及亲属应回避) public class CadreRelation { public int Id { get; set; } public int CadreId { get; set; } public string? RelatedName { get; set; } public string? Relation { get; set; } public string? RelatedPost { get; set; } /// 是否需要回避 1/0 public int NeedAvoid { get; set; } } /// 上会名单(会议 × 干部:议题号 / 顺序 / 结果) public class MeetingCadre { public int Id { get; set; } public int MeetingId { get; set; } public int CadreId { get; set; } /// 议题号,如 议题一 public string? IssueNo { get; set; } /// 上会顺序(即 PAD 端「上一条/下一条」顺序) public int SortNo { get; set; } public string Result { get; set; } = CadreResult.Pending; /// 表决/表态:同意 / 不同意 / 缓议(决定类会议使用) public string? Vote { get; set; } public DateTime? DecidedAt { get; set; } public string? Remark { get; set; } public Meeting? Meeting { get; set; } public Cadre? Cadre { get; set; } } // ============================================================ // 材料 / 任免文件 // ============================================================ /// 材料(任免表 / 考察材料 / 汇报材料 / 说明材料 / 附件) public class Material { public int Id { get; set; } public int MeetingId { get; set; } public int? DeptId { get; set; } /// 干部材料挂干部;说明材料/议题级材料可为空 public int? CadreId { get; set; } public string Type { get; set; } = MaterialType.AppointmentForm; public string? Title { get; set; } public string? FileName { get; set; } public string? FilePath { get; set; } public long FileSize { get; set; } public int Pages { get; set; } /// 版本号,如 v1 / v2 public string Version { get; set; } = "v1"; public string? UploadedBy { get; set; } public DateTime? UploadedAt { get; set; } public string Status { get; set; } = MaterialStatus.Missing; /// 展示顺序 public int Seq { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; // ===== 回收站(软删除)===== /// 1=已进回收站。进回收站时不参与材料完整度统计、不下发数据包 public int IsDeleted { get; set; } /// 进回收站前的状态,恢复时还原(如 passed / pending) public string? PrevStatus { get; set; } /// 文件移入回收目录后的相对路径(相对 App_Data),恢复时搬回去 public string? TrashPath { get; set; } public DateTime? DeletedAt { get; set; } } /// 任免文件(部务会按处室各一份) /// 任免文件 ↔ 干部 的多对多关系(上传时勾选"本文件涉及哪几名干部") public class AppointDocCadre { public int Id { get; set; } public int DocId { get; set; } public int CadreId { get; set; } /// 在上会名单中的顺序,用于名单展示 public int Sort { get; set; } } public class AppointDoc { public int Id { get; set; } public int MeetingId { get; set; } /// 处室;null 表示不设处室的会议(常委会/书记专题会,整会一份) public int? DeptId { get; set; } public string? DocNo { get; set; } public string? Title { get; set; } public int Persons { get; set; } public int Pages { get; set; } public long FileSize { get; set; } public string? FilePath { get; set; } public string Version { get; set; } = "v1"; public string? UploadedBy { get; set; } public DateTime? UploadedAt { get; set; } public string Status { get; set; } = MaterialStatus.Pending; /// 软删除 public int IsDeleted { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; } // ============================================================ // 数据包 / 设备(后台 → PAD 的唯一数据通道) // ============================================================ /// 数据包(导出 SQLite 给 PAD) public class DataPackage { public int Id { get; set; } public int MeetingId { get; set; } /// 包编号,如 PK20261012-01 public string PkgNo { get; set; } = ""; /// 加密:sm4 / sm4_pwd public string Encrypt { get; set; } = "sm4"; /// 口令哈希(口令模式下 PAD 需校验) public string? PwdHash { get; set; } public DateTime? ExpireAt { get; set; } /// 清除策略:exit=退出即清 / expire=到期清 / manual=手动作废 public string ClearPolicy { get; set; } = "expire"; /// 水印内容 public string? Watermark { get; set; } /// 字号档:std / big / huge public string FontLevel { get; set; } = "big"; /// 允许领导自行调字号 public int AllowFontChange { get; set; } = 1; /// 屏幕水印 / 截屏防护 / 外发禁用 等开关(JSON) public string? SwitchesJson { get; set; } public string Status { get; set; } = PackageStatus.Created; public long FileSize { get; set; } /// 导出文件相对路径 public string? FilePath { get; set; } public string? CreatedBy { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public DateTime? DownloadedAt { get; set; } } /// 下发清单(材料类型 + 顺序 + 是否下发) public class PackageItem { public int Id { get; set; } public int PackageId { get; set; } public string MaterialType { get; set; } = ""; public int Enabled { get; set; } = 1; public int Sort { get; set; } } /// 数据包绑定设备 public class PackageDevice { public int Id { get; set; } public int PackageId { get; set; } public int PadId { get; set; } } /// PAD 设备 public class PadDevice { public int Id { get; set; } /// 设备编号,如 PAD-07 public string PadNo { get; set; } = ""; public string? Model { get; set; } /// 归属处室 public int? OwnerDeptId { get; set; } /// 责任人 / 席位标签(部长、副部长、备用……);优先于处室名显示 public string? OwnerLabel { get; set; } /// 1=受管 0=停用 public int Status { get; set; } = 1; public DateTime? LastSeenAt { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; } // ============================================================ // 用户 / 权限 / 审计 // ============================================================ public class SysUser { public int Id { get; set; } public string Account { get; set; } = ""; public string RealName { get; set; } = ""; public int? DeptId { get; set; } public string? Phone { get; set; } /// 数据权限范围:全部处室 / 本处室 / 全部处室(只读) public string? DataScope { get; set; } public string? PwdHash { get; set; } public string? PwdSalt { get; set; } public DateTime? PwdUpdatedAt { get; set; } public DateTime? LastLoginAt { get; set; } public int FailCount { get; set; } public DateTime? LockedUntil { get; set; } /// 1=启用 0=停用(停用保留日志归属) public int Enabled { get; set; } = 1; /// /// 令牌版本号。签发时写入 JWT 的 tv 声明,每次请求比对; /// 改口令 / 停用 / 管理员强制下线 时 +1,使此前签发的令牌立即失效(无需等 8 小时过期)。 /// public int TokenVersion { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; } public class SysRole { public int Id { get; set; } public string Code { get; set; } = ""; public string Name { get; set; } = ""; /// 权限点(JSON 数组字符串) public string? Perms { get; set; } public int Sort { get; set; } } public class SysUserRole { public int Id { get; set; } public int UserId { get; set; } public int RoleId { get; set; } } /// 口令历史(不得重复最近 3 次) public class PwdHistory { public int Id { get; set; } public int UserId { get; set; } public string PwdHash { get; set; } = ""; public DateTime ChangedAt { get; set; } = DateTime.Now; } /// /// PAD 已阅回执。 /// /// 为什么不在线回传:PAD 全程离线(APK 不申请 INTERNET 权限),所以由平板把 /// 「会议 + 干部 + 材料类型 + 设备号 + 首次阅读时间」追加写到本地 JSONL, /// 干部科回收设备后导出该文件,在后台「导入已阅回执」入库。 /// 唯一键 (MeetingId,CadreId,MaterialType,PadNo) 保证重复导入不会翻倍。 /// public class ReadReceipt { public long Id { get; set; } public int MeetingId { get; set; } public int CadreId { get; set; } public string MaterialType { get; set; } = ""; public string PadNo { get; set; } = ""; public DateTime ReadAt { get; set; } public DateTime ImportedAt { get; set; } = DateTime.Now; public string? ImportedBy { get; set; } } /// 审计日志(登录/查看/修改/删除/导出/下发/清除全链路) public class AuditLog { public long Id { get; set; } public DateTime At { get; set; } = DateTime.Now; public int? UserId { get; set; } public string? UserName { get; set; } public string? Role { get; set; } /// 动作:login / view / create / update / delete / export / deliver / clear public string Action { get; set; } = ""; public string? Target { get; set; } public string? Detail { get; set; } public string? Ip { get; set; } /// 来源设备(PAD-07 / PC-GY-021) public string? Device { get; set; } /// 1=成功 0=失败 public int Success { get; set; } = 1; } /// /// 系统配置(键值对)。 /// 用途:把 JWT 签名密钥等敏感参数从 appsettings.json 挪进数据库, /// 避免随代码/配置文件一起流失。首次启动若无记录则自动生成并写入。 /// public class SysConfig { public int Id { get; set; } /// 配置键(唯一) public string ConfigKey { get; set; } = ""; /// 配置值(密钥类不回显、不落日志) public string? ConfigValue { get; set; } /// 说明 public string? Remark { get; set; } /// 1=敏感项,接口不返回 public int IsSecret { get; set; } public DateTime UpdatedAt { get; set; } = DateTime.Now; public string? UpdatedBy { get; set; } } /// 字典 public class DictItem { public int Id { get; set; } public string Type { get; set; } = ""; public string Code { get; set; } = ""; public string Label { get; set; } = ""; public int Sort { get; set; } public int Enabled { get; set; } = 1; }