using System.Text.Encodings.Web; using System.Text.Json; namespace OASystem.Domain.Entities.Groups { /// /// 签证流程管控步骤 /// [SugarTable(tableName: "Grp_VisaProcessSteps", TableDescription = "签证流程步骤")] public class Grp_VisaProcessSteps : EntityBase { /// /// 团组Id(Grp_DelegationInfo) /// [SugarColumn(ColumnName = "GroupId", ColumnDescription = "团组Id(Grp_DelegationInfo)", IsNullable = true, ColumnDataType = "int")] public int GroupId { get; set; } /// /// 步骤 /// [SugarColumn(ColumnName = "Step", ColumnDescription = "步骤", IsNullable = true, ColumnDataType = "int")] public int Step { get; set; } /// /// 标识数据类型 /// [SugarColumn(ColumnName = "DataType", ColumnDescription = "标识数据类型", IsNullable = true, ColumnDataType = "varchar(50)")] public string DataType { get; set; } /// /// 存储值(办理日期(2025-01-01))、bool(false,true)) /// [SugarColumn(ColumnName = "StoreVal", ColumnDescription = "存储值(办理日期(2025-01-01))、bool(false,true))", IsNullable = true, ColumnDataType = "varchar(max)")] public string StoreVal { get; set; } /// /// 附件地址 /// [SugarColumn(ColumnName = "AttachUrl", ColumnDescription = "附件地址", IsNullable = true, ColumnDataType = "varchar(max)")] public string AttachUrl { get; set; } /// /// 是否确认完成 /// [SugarColumn(ColumnName = "IsCompleted", ColumnDescription = "确认完成", IsNullable = true, ColumnDataType = "bit")] public bool IsCompleted { get; set; } = false; /// /// 最后更新人 /// [SugarColumn(ColumnName = "LastUpdateUserId", ColumnDescription = "最后更新人", IsNullable = true, ColumnDataType = "int")] public int LastUpdateUserId { get; set; } /// /// 最后更新时间 /// [SugarColumn(ColumnName = "LastUpdateTime", ColumnDescription = "最后更新时间", IsNullable = true, ColumnDataType = "DateTime")] public DateTime LastUpdateTime { get; set; } = DateTime.Now; #region 动态获取、设置StoreVal值 /// /// Converts a given value to its string representation and determines its storage data type. /// /// If the value is an enumerable of strings or integers, it is serialized as a JSON array. /// For other class types not explicitly handled, the value is serialized as a JSON object. Date and time values /// are formatted using the round-trip format specifier ("O"). /// The value to convert. Can be null or an instance of a supported type such as string, numeric types, boolean, /// DateTime, DateOnly, TimeOnly, Guid, or enumerable collections of strings or integers. /// A tuple containing the string representation of the value and a string indicating the data type for storage. /// If the input is null, the Value is null and the DataType is "null". private static (string? Value, string DataType) ConvertToStorage(object? value) { if (value == null) return (null, "null"); return value switch { string s => (s, "string"), int i => (i.ToString(), "int"), long l => (l.ToString(), "long"), decimal d => (d.ToString(), "decimal"), double d => (d.ToString(), "double"), float f => (f.ToString(), "float"), bool b => (b.ToString(), "bool"), DateTime dt => (dt.ToString("O"), "datetime"), DateOnly date => (date.ToString("O"), "date"), TimeOnly time => (time.ToString("O"), "time"), Guid guid => (guid.ToString(), "guid"), IEnumerable list => (JsonSerializer.Serialize(list), "string[]"), IEnumerable list => (JsonSerializer.Serialize(list), "int[]"), _ when value.GetType().IsClass => (JsonSerializer.Serialize(value), "object"), _ => (value.ToString(), "string") }; } /// /// Converts a string representation of a value from storage to its corresponding .NET type based on the /// specified data type. /// /// If the specified data type is not recognized, the original string value is returned. /// For array and object types, the method attempts to deserialize the string as JSON. If conversion fails for /// numeric, boolean, or date/time types, the method returns null. /// The string value to convert. Can be null or empty, in which case the method returns null. /// The name of the target data type. Supported values include "string", "int", "long", "decimal", "double", /// "float", "bool", "datetime", "date", "time", "guid", "string[]", "int[]", and "object". The comparison is /// case-insensitive. /// An object representing the converted value in the specified .NET type, or null if the input is null, empty, /// or cannot be converted. private static object? ConvertFromStorage(string? value, string dataType) { if (string.IsNullOrEmpty(value)) return null; return dataType?.ToLower() switch { "string" => value, "int" => int.TryParse(value, out var result) ? result : null, "long" => long.TryParse(value, out var result) ? result : null, "decimal" => decimal.TryParse(value, out var result) ? result : null, "double" => double.TryParse(value, out var result) ? result : null, "float" => float.TryParse(value, out var result) ? result : null, "bool" => bool.TryParse(value, out var result) ? result : null, "datetime" => DateTime.TryParse(value, out var result) ? result : null, "date" => DateOnly.TryParse(value, out var result) ? result : null, "time" => TimeOnly.TryParse(value, out var result) ? result : null, "guid" => Guid.TryParse(value, out var result) ? result : null, "string[]" => JsonSerializer.Deserialize(value), "int[]" => JsonSerializer.Deserialize(value), "object" => JsonSerializer.Deserialize(value), "null" => null, _ => value }; } [SugarColumn(IsIgnore = true)] public List TypedFileNameValue { get { if (!string.IsNullOrEmpty(AttachUrl)) { string rootRrl = "http://132.232.92.186:24/Office/"; var result = JsonSerializer.Deserialize>(AttachUrl); for (int i = 0; i < result.Count; i++) { result[i] = $"{rootRrl}{result[i]}"; } return result; } return new List(); } set { if (value == null || value.Count < 1) { AttachUrl = ""; } else { var options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; AttachUrl = JsonSerializer.Serialize(value, options); } } } [SugarColumn(IsIgnore = true)] public object? TypedValue { get => ConvertFromStorage(StoreVal, DataType); set { var (storageValue, dataType) = ConvertToStorage(value); StoreVal = storageValue; DataType = dataType; } } [SugarColumn(IsIgnore = true)] public string? StringValue { get => DataType == "string" ? StoreVal : null; set => (StoreVal, DataType) = (value, "string"); } [SugarColumn(IsIgnore = true)] public int? IntValue { get => DataType == "int" && int.TryParse(StoreVal, out var result) ? result : null; set => (StoreVal, DataType) = (value?.ToString(), "int"); } [SugarColumn(IsIgnore = true)] public decimal? DecimalValue { get => DataType == "decimal" && decimal.TryParse(StoreVal, out var result) ? result : null; set => (StoreVal, DataType) = (value?.ToString(), "decimal"); } [SugarColumn(IsIgnore = true)] public bool? BooleanValue { get => DataType == "bool" && bool.TryParse(StoreVal, out var result) ? result : null; set => (StoreVal, DataType) = (value?.ToString(), "bool"); } [SugarColumn(IsIgnore = true)] public DateTime? DateTimeValue { get => DataType == "datetime" && DateTime.TryParse(StoreVal, out var result) ? result : null; set => (StoreVal, DataType) = (value?.ToString("O"), "datetime"); } #endregion public Grp_VisaProcessSteps() { } /// /// 流程步骤初始化 /// /// /// /// public static List StepsInit(int groupId,int createUserId) { return new List() { new(){ GroupId = groupId, Step = 1, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第一步:签证启动日(团组信息操作里面打勾确认出团) new(){ GroupId = groupId, Step = 2, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第二步:分配工作(从倒退表里-出批件、护照办理取时间) new(){ GroupId = groupId, Step = 3, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第三步:送外办时间(从倒退表里-送签签证取时间) new(){ GroupId = groupId, Step = 4, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第四步:读取预计出签时间(从签证费用标准-签证时间工作日取时间,送外办时间+签证时间(工作日)) new(){ GroupId = groupId, Step = 5, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第五步:实际出签时间(手动填写) 附件 new(){ GroupId = groupId, Step = 6, DataType = "bool", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第六步:是否需要开出境证明 (否,是) 附件 new(){ GroupId = groupId, Step = 7, DataType = "string[]", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第七步:是否需要办理电子入境卡手续(否,是) -> 如果是,系统生成附件(个人信息资料+机票航班信息+酒店信息)【在出发前三天内填写,取具体的日期】 new(){ GroupId = groupId, Step = 8, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第八步:确认完成操作 (确认完成操作后,不可更改该流程数据) }; } } }