using Admin.NET.Core; namespace Admin.NET.Plugin.AiDOP.Entity; [SugarTable("ado_smart_ops_improvement_action", "智慧诊断改善行动项")] [SugarIndex("uk_improve_action_seq", nameof(TenantId), OrderByType.Asc, nameof(PlanId), OrderByType.Asc, nameof(SequenceNo), OrderByType.Asc, IsUnique = true)] [SugarIndex("idx_improve_action_owner", nameof(TenantId), OrderByType.Asc, nameof(OwnerUserId), OrderByType.Asc, nameof(Status), OrderByType.Asc)] [SugarIndex("idx_improve_action_due", nameof(TenantId), OrderByType.Asc, nameof(DueDate), OrderByType.Asc)] public class AdoSmartOpsImprovementAction : ITenantIdFilter { [SugarColumn(ColumnName = "id", ColumnDescription = "主键", IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } [SugarColumn(ColumnName = "tenant_id", ColumnDescription = "租户")] public long? TenantId { get; set; } [SugarColumn(ColumnName = "factory_id", ColumnDescription = "工厂")] public long FactoryId { get; set; } [SugarColumn(ColumnName = "plan_id", ColumnDescription = "改善计划")] public long PlanId { get; set; } [SugarColumn(ColumnName = "sequence_no", ColumnDescription = "序号")] public int SequenceNo { get; set; } [SugarColumn(ColumnName = "content", ColumnDescription = "内容", Length = 500)] public string Content { get; set; } = ""; [SugarColumn(ColumnName = "owner_user_id", ColumnDescription = "负责人用户", IsNullable = true)] public long? OwnerUserId { get; set; } [SugarColumn(ColumnName = "owner_name", ColumnDescription = "负责人/部门", Length = 100, IsNullable = true)] public string? OwnerName { get; set; } [SugarColumn(ColumnName = "due_date", ColumnDescription = "计划完成日", IsNullable = true)] public DateTime? DueDate { get; set; } [SugarColumn(ColumnName = "status", ColumnDescription = "状态", Length = 32)] public string Status { get; set; } = SmartOpsImprovementActionStatus.Pending; [SugarColumn(ColumnName = "completed_at", ColumnDescription = "实际完成时间", IsNullable = true)] public DateTime? CompletedAt { get; set; } [SugarColumn(ColumnName = "proof_remark", ColumnDescription = "完成证明/备注", ColumnDataType = "text", IsNullable = true)] public string? ProofRemark { get; set; } [SugarColumn(ColumnName = "version", ColumnDescription = "乐观锁")] public int Version { get; set; } = 1; [SugarColumn(ColumnName = "create_user_id", IsNullable = true)] public long? CreateUserId { get; set; } [SugarColumn(ColumnName = "update_user_id", IsNullable = true)] public long? UpdateUserId { get; set; } [SugarColumn(ColumnName = "create_time")] public DateTime CreateTime { get; set; } = DateTime.Now; [SugarColumn(ColumnName = "update_time")] public DateTime UpdateTime { get; set; } = DateTime.Now; } [SugarTable("ado_smart_ops_improvement_action_log", "智慧诊断改善行动项日志")] [SugarIndex("idx_improve_action_log", nameof(TenantId), OrderByType.Asc, nameof(ActionId), OrderByType.Asc, nameof(CreateTime), OrderByType.Desc)] public class AdoSmartOpsImprovementActionLog : ITenantIdFilter { [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } [SugarColumn(ColumnName = "tenant_id")] public long? TenantId { get; set; } [SugarColumn(ColumnName = "action_id")] public long ActionId { get; set; } [SugarColumn(ColumnName = "plan_id")] public long PlanId { get; set; } [SugarColumn(ColumnName = "operation", Length = 32)] public string Operation { get; set; } = ""; [SugarColumn(ColumnName = "before_json", ColumnDataType = "text", IsNullable = true)] public string? BeforeJson { get; set; } [SugarColumn(ColumnName = "after_json", ColumnDataType = "text", IsNullable = true)] public string? AfterJson { get; set; } [SugarColumn(ColumnName = "operator_user_id", IsNullable = true)] public long? OperatorUserId { get; set; } [SugarColumn(ColumnName = "remark", Length = 500, IsNullable = true)] public string? Remark { get; set; } [SugarColumn(ColumnName = "create_time")] public DateTime CreateTime { get; set; } = DateTime.Now; } [SugarTable("ado_smart_ops_improvement_action_notice", "改善行动项通知去重")] [SugarIndex("uk_improve_action_notice", nameof(TenantId), OrderByType.Asc, nameof(ActionId), OrderByType.Asc, nameof(NoticeType), OrderByType.Asc, nameof(NoticeDate), OrderByType.Asc, IsUnique = true)] public class AdoSmartOpsImprovementActionNotice : ITenantIdFilter { [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } [SugarColumn(ColumnName = "tenant_id")] public long? TenantId { get; set; } [SugarColumn(ColumnName = "action_id")] public long ActionId { get; set; } [SugarColumn(ColumnName = "notice_type", Length = 32)] public string NoticeType { get; set; } = ""; [SugarColumn(ColumnName = "notice_date", ColumnDataType = "date")] public DateTime NoticeDate { get; set; } [SugarColumn(ColumnName = "notice_id", IsNullable = true)] public long? NoticeId { get; set; } [SugarColumn(ColumnName = "create_time")] public DateTime CreateTime { get; set; } = DateTime.Now; } public static class SmartOpsImprovementActionStatus { public const string Pending = "pending"; public const string InProgress = "in_progress"; public const string Completed = "completed"; public const string Cancelled = "cancelled"; public static string Normalize(string? raw) { return (raw ?? "").Trim().ToLowerInvariant() switch { "completed" or "done" => Completed, "doing" or "in_progress" => InProgress, "cancelled" or "canceled" => Cancelled, _ => Pending, }; } public static bool CanTransition(string from, string to) { from = Normalize(from); to = Normalize(to); if (from == to) return true; return (from, to) switch { (Pending, InProgress) => true, (Pending, Cancelled) => true, (InProgress, Completed) => true, (InProgress, Cancelled) => true, (InProgress, Pending) => true, (Cancelled, Pending) => true, _ => false, }; } public static bool IsOpen(string? status) { var normalized = Normalize(status); return normalized is Pending or InProgress; } public static bool IsOverdue(string? status, DateTime? dueDate, DateTime today) => IsOpen(status) && dueDate.HasValue && dueDate.Value.Date < today.Date; public static string DisplayStatus(string? status, DateTime? dueDate, DateTime today) => IsOverdue(status, dueDate, today) ? "overdue" : Normalize(status); } public static class SmartOpsImprovementNoticeType { public const string Assigned = "assigned"; public const string DueSoon = "due_soon"; public const string Overdue = "overdue"; public const string StatusChanged = "status_changed"; public static string NoticeKey(long tenantId, long actionId, string noticeType, DateTime date) => $"{tenantId}:{actionId}:{noticeType}:{date:yyyy-MM-dd}"; } [SugarTable("ado_smart_ops_improvement_verify_log", "改善计划有效性评价日志")] [SugarIndex("idx_improve_verify_log", nameof(TenantId), OrderByType.Asc, nameof(PlanId), OrderByType.Asc, nameof(CreateTime), OrderByType.Desc)] public class AdoSmartOpsImprovementVerifyLog : ITenantIdFilter { [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } [SugarColumn(ColumnName = "tenant_id")] public long? TenantId { get; set; } [SugarColumn(ColumnName = "plan_id")] public long PlanId { get; set; } [SugarColumn(ColumnName = "auto_result", Length = 32, IsNullable = true)] public string? AutoResult { get; set; } [SugarColumn(ColumnName = "manual_result", Length = 32, IsNullable = true)] public string? ManualResult { get; set; } [SugarColumn(ColumnName = "remark", ColumnDataType = "text", IsNullable = true)] public string? Remark { get; set; } [SugarColumn(ColumnName = "operator_user_id", IsNullable = true)] public long? OperatorUserId { get; set; } [SugarColumn(ColumnName = "create_time")] public DateTime CreateTime { get; set; } = DateTime.Now; }