Grp_VisaProcessSteps.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using System.Text.Encodings.Web;
  2. using System.Text.Json;
  3. namespace OASystem.Domain.Entities.Groups
  4. {
  5. /// <summary>
  6. /// 签证流程管控步骤
  7. /// </summary>
  8. [SugarTable(tableName: "Grp_VisaProcessSteps", TableDescription = "签证流程步骤")]
  9. public class Grp_VisaProcessSteps : EntityBase
  10. {
  11. /// <summary>
  12. /// 团组Id(Grp_DelegationInfo)
  13. /// </summary>
  14. [SugarColumn(ColumnName = "GroupId", ColumnDescription = "团组Id(Grp_DelegationInfo)", IsNullable = true, ColumnDataType = "int")]
  15. public int GroupId { get; set; }
  16. /// <summary>
  17. /// 步骤
  18. /// </summary>
  19. [SugarColumn(ColumnName = "Step", ColumnDescription = "步骤", IsNullable = true, ColumnDataType = "int")]
  20. public int Step { get; set; }
  21. /// <summary>
  22. /// 标识数据类型
  23. /// </summary>
  24. [SugarColumn(ColumnName = "DataType", ColumnDescription = "标识数据类型", IsNullable = true, ColumnDataType = "varchar(50)")]
  25. public string DataType { get; set; }
  26. /// <summary>
  27. /// 存储值(办理日期(2025-01-01))、bool(false,true))
  28. /// </summary>
  29. [SugarColumn(ColumnName = "StoreVal", ColumnDescription = "存储值(办理日期(2025-01-01))、bool(false,true))", IsNullable = true, ColumnDataType = "varchar(max)")]
  30. public string StoreVal { get; set; }
  31. /// <summary>
  32. /// 附件地址
  33. /// </summary>
  34. [SugarColumn(ColumnName = "AttachUrl", ColumnDescription = "附件地址", IsNullable = true, ColumnDataType = "varchar(max)")]
  35. public string AttachUrl { get; set; }
  36. /// <summary>
  37. /// 是否确认完成
  38. /// </summary>
  39. [SugarColumn(ColumnName = "IsCompleted", ColumnDescription = "确认完成", IsNullable = true, ColumnDataType = "bit")]
  40. public bool IsCompleted { get; set; } = false;
  41. /// <summary>
  42. /// 最后更新人
  43. /// </summary>
  44. [SugarColumn(ColumnName = "LastUpdateUserId", ColumnDescription = "最后更新人", IsNullable = true, ColumnDataType = "int")]
  45. public int LastUpdateUserId { get; set; }
  46. /// <summary>
  47. /// 最后更新时间
  48. /// </summary>
  49. [SugarColumn(ColumnName = "LastUpdateTime", ColumnDescription = "最后更新时间", IsNullable = true, ColumnDataType = "DateTime")]
  50. public DateTime LastUpdateTime { get; set; } = DateTime.Now;
  51. #region 动态获取、设置StoreVal值
  52. /// <summary>
  53. /// Converts a given value to its string representation and determines its storage data type.
  54. /// </summary>
  55. /// <remarks>If the value is an enumerable of strings or integers, it is serialized as a JSON array.
  56. /// For other class types not explicitly handled, the value is serialized as a JSON object. Date and time values
  57. /// are formatted using the round-trip format specifier ("O").</remarks>
  58. /// <param name="value">The value to convert. Can be null or an instance of a supported type such as string, numeric types, boolean,
  59. /// DateTime, DateOnly, TimeOnly, Guid, or enumerable collections of strings or integers.</param>
  60. /// <returns>A tuple containing the string representation of the value and a string indicating the data type for storage.
  61. /// If the input is null, the Value is null and the DataType is "null".</returns>
  62. private static (string? Value, string DataType) ConvertToStorage(object? value)
  63. {
  64. if (value == null) return (null, "null");
  65. return value switch
  66. {
  67. string s => (s, "string"),
  68. int i => (i.ToString(), "int"),
  69. long l => (l.ToString(), "long"),
  70. decimal d => (d.ToString(), "decimal"),
  71. double d => (d.ToString(), "double"),
  72. float f => (f.ToString(), "float"),
  73. bool b => (b.ToString(), "bool"),
  74. DateTime dt => (dt.ToString("O"), "datetime"),
  75. DateOnly date => (date.ToString("O"), "date"),
  76. TimeOnly time => (time.ToString("O"), "time"),
  77. Guid guid => (guid.ToString(), "guid"),
  78. IEnumerable<string> list => (JsonSerializer.Serialize(list), "string[]"),
  79. IEnumerable<int> list => (JsonSerializer.Serialize(list), "int[]"),
  80. _ when value.GetType().IsClass => (JsonSerializer.Serialize(value), "object"),
  81. _ => (value.ToString(), "string")
  82. };
  83. }
  84. /// <summary>
  85. /// Converts a string representation of a value from storage to its corresponding .NET type based on the
  86. /// specified data type.
  87. /// </summary>
  88. /// <remarks>If the specified data type is not recognized, the original string value is returned.
  89. /// For array and object types, the method attempts to deserialize the string as JSON. If conversion fails for
  90. /// numeric, boolean, or date/time types, the method returns null.</remarks>
  91. /// <param name="value">The string value to convert. Can be null or empty, in which case the method returns null.</param>
  92. /// <param name="dataType">The name of the target data type. Supported values include "string", "int", "long", "decimal", "double",
  93. /// "float", "bool", "datetime", "date", "time", "guid", "string[]", "int[]", and "object". The comparison is
  94. /// case-insensitive.</param>
  95. /// <returns>An object representing the converted value in the specified .NET type, or null if the input is null, empty,
  96. /// or cannot be converted.</returns>
  97. private static object? ConvertFromStorage(string? value, string dataType)
  98. {
  99. if (string.IsNullOrEmpty(value)) return null;
  100. return dataType?.ToLower() switch
  101. {
  102. "string" => value,
  103. "int" => int.TryParse(value, out var result) ? result : null,
  104. "long" => long.TryParse(value, out var result) ? result : null,
  105. "decimal" => decimal.TryParse(value, out var result) ? result : null,
  106. "double" => double.TryParse(value, out var result) ? result : null,
  107. "float" => float.TryParse(value, out var result) ? result : null,
  108. "bool" => bool.TryParse(value, out var result) ? result : null,
  109. "datetime" => DateTime.TryParse(value, out var result) ? result : null,
  110. "date" => DateOnly.TryParse(value, out var result) ? result : null,
  111. "time" => TimeOnly.TryParse(value, out var result) ? result : null,
  112. "guid" => Guid.TryParse(value, out var result) ? result : null,
  113. "string[]" => JsonSerializer.Deserialize<string[]>(value),
  114. "int[]" => JsonSerializer.Deserialize<int[]>(value),
  115. "object" => JsonSerializer.Deserialize<JsonElement>(value),
  116. "null" => null,
  117. _ => value
  118. };
  119. }
  120. [SugarColumn(IsIgnore = true)]
  121. public List<string> TypedFileNameValue
  122. {
  123. get
  124. {
  125. if (!string.IsNullOrEmpty(AttachUrl))
  126. {
  127. string rootRrl = "http://132.232.92.186:24/Office/";
  128. var result = JsonSerializer.Deserialize<List<string>>(AttachUrl);
  129. for (int i = 0; i < result.Count; i++)
  130. {
  131. result[i] = $"{rootRrl}{result[i]}";
  132. }
  133. return result;
  134. }
  135. return new List<string>();
  136. }
  137. set
  138. {
  139. if (value == null || value.Count < 1)
  140. {
  141. AttachUrl = "";
  142. }
  143. else
  144. {
  145. var options = new JsonSerializerOptions
  146. {
  147. Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
  148. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  149. WriteIndented = true
  150. };
  151. AttachUrl = JsonSerializer.Serialize(value, options);
  152. }
  153. }
  154. }
  155. [SugarColumn(IsIgnore = true)]
  156. public object? TypedValue
  157. {
  158. get => ConvertFromStorage(StoreVal, DataType);
  159. set
  160. {
  161. var (storageValue, dataType) = ConvertToStorage(value);
  162. StoreVal = storageValue;
  163. DataType = dataType;
  164. }
  165. }
  166. [SugarColumn(IsIgnore = true)]
  167. public string? StringValue
  168. {
  169. get => DataType == "string" ? StoreVal : null;
  170. set => (StoreVal, DataType) = (value, "string");
  171. }
  172. [SugarColumn(IsIgnore = true)]
  173. public int? IntValue
  174. {
  175. get => DataType == "int" && int.TryParse(StoreVal, out var result) ? result : null;
  176. set => (StoreVal, DataType) = (value?.ToString(), "int");
  177. }
  178. [SugarColumn(IsIgnore = true)]
  179. public decimal? DecimalValue
  180. {
  181. get => DataType == "decimal" && decimal.TryParse(StoreVal, out var result) ? result : null;
  182. set => (StoreVal, DataType) = (value?.ToString(), "decimal");
  183. }
  184. [SugarColumn(IsIgnore = true)]
  185. public bool? BooleanValue
  186. {
  187. get => DataType == "bool" && bool.TryParse(StoreVal, out var result) ? result : null;
  188. set => (StoreVal, DataType) = (value?.ToString(), "bool");
  189. }
  190. [SugarColumn(IsIgnore = true)]
  191. public DateTime? DateTimeValue
  192. {
  193. get => DataType == "datetime" && DateTime.TryParse(StoreVal, out var result) ? result : null;
  194. set => (StoreVal, DataType) = (value?.ToString("O"), "datetime");
  195. }
  196. #endregion
  197. public Grp_VisaProcessSteps() { }
  198. /// <summary>
  199. /// 流程步骤初始化
  200. /// </summary>
  201. /// <param name="groupId"></param>
  202. /// <param name="createUserId"></param>
  203. /// <returns></returns>
  204. public static List<Grp_VisaProcessSteps> StepsInit(int groupId,int createUserId)
  205. {
  206. return new List<Grp_VisaProcessSteps>() {
  207. new(){ GroupId = groupId, Step = 1, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第一步:签证启动日(团组信息操作里面打勾确认出团)
  208. new(){ GroupId = groupId, Step = 2, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第二步:分配工作(从倒退表里-出批件、护照办理取时间)
  209. new(){ GroupId = groupId, Step = 3, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第三步:送外办时间(从倒退表里-送签签证取时间)
  210. new(){ GroupId = groupId, Step = 4, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第四步:读取预计出签时间(从签证费用标准-签证时间工作日取时间,送外办时间+签证时间(工作日))
  211. new(){ GroupId = groupId, Step = 5, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第五步:实际出签时间(手动填写) 附件
  212. new(){ GroupId = groupId, Step = 6, DataType = "bool", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第六步:是否需要开出境证明 (否,是) 附件
  213. new(){ GroupId = groupId, Step = 7, DataType = "string[]", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第七步:是否需要办理电子入境卡手续(否,是) -> 如果是,系统生成附件(个人信息资料+机票航班信息+酒店信息)【在出发前三天内填写,取具体的日期】
  214. new(){ GroupId = groupId, Step = 8, DataType = "string", CreateUserId = createUserId, LastUpdateUserId = createUserId }, //第八步:确认完成操作 (确认完成操作后,不可更改该流程数据)
  215. };
  216. }
  217. }
  218. }