transformer.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. from types import NoneType
  2. from typing import Callable, List, Optional
  3. from datetime import datetime
  4. from typing_extensions import Annotated
  5. from pydantic import BeforeValidator, ValidationInfo
  6. from ruoyi_common.utils.base import DateUtil
  7. def ids_to_list(value: str) -> Optional[List[int]]:
  8. """
  9. 验证ids转换为整数列表
  10. Args:
  11. value (str | NoneType): 传入参数
  12. Returns:
  13. Optional[List[int]]: 列表
  14. """
  15. return [int(i) for i in value.split(',')]
  16. def ids_to_str_list(value: str) -> Optional[List[str]]:
  17. """
  18. 验证ids转换为字符串列表
  19. Args:
  20. value (str | NoneType): 传入参数
  21. Returns:
  22. Optional[List[str]]: 列表
  23. """
  24. return [i.strip() for i in value.split(',') if i.strip()]
  25. def to_datetime(format=None) -> Callable[[str | NoneType, ValidationInfo], datetime | NoneType]:
  26. """
  27. 根据指定格式,验证datetime
  28. Args:
  29. format (str): 日期格式. Defaults to '%Y-%m-%d %H:%M:%S'.
  30. """
  31. if format is None:
  32. # 默认支持常见的年月日格式,以及仅到月份的格式,方便 Excel 导入
  33. formats: List[str] = [
  34. DateUtil.YYYY_MM_DD_HH_MM_SS,
  35. DateUtil.YYYY_MM_DD,
  36. "%Y.%m",
  37. "%Y-%m",
  38. ]
  39. elif isinstance(format, (list, tuple, set)):
  40. formats = list(format)
  41. else:
  42. formats = [format]
  43. def validate_datetime(value: str | NoneType, info: ValidationInfo) -> datetime | NoneType:
  44. """
  45. 验证datetime
  46. Args:
  47. value (str | NoneType): 传入参数
  48. info (ValidationInfo): pydantic的验证信息
  49. Raises:
  50. ValueError: 日期格式错误
  51. Returns:
  52. _type_: datetime
  53. """
  54. if not value:
  55. return None
  56. if isinstance(value, datetime):
  57. return value
  58. if isinstance(value, str):
  59. for fmt in formats:
  60. try:
  61. return datetime.strptime(value, fmt)
  62. except ValueError:
  63. continue
  64. raise ValueError(f"time data '{value}' does not match formats: {formats}")
  65. raise ValueError(f"Invalid datetime format: {value}")
  66. return validate_datetime
  67. def str_to_int(value: str | NoneType, info: ValidationInfo) \
  68. -> int:
  69. """
  70. 验证str是否为整数,并转换为整数
  71. Args:
  72. value (str | NoneType): 传入参数
  73. info (ValidationInfo): pydantic的验证信息
  74. Raises:
  75. ValueError: 字符串格式错误
  76. Returns:
  77. int: 整数
  78. """
  79. if value:
  80. if isinstance(value, str):
  81. if value.isdecimal():
  82. return int(value)
  83. else:
  84. raise ValueError(f"Invalid str format, cannot convert to int: {value}")
  85. return value
  86. def str_to_float(value: str | NoneType, info: ValidationInfo) -> float | NoneType:
  87. """
  88. 将字符串转换为浮点数;空值直接返回
  89. """
  90. if value is None or value == "":
  91. return value
  92. if isinstance(value, (int, float)):
  93. return float(value)
  94. if isinstance(value, str):
  95. stripped = value.strip()
  96. try:
  97. return float(stripped)
  98. except ValueError:
  99. # 格式化不了就返回 None,避免抛出验证错误
  100. return None
  101. return value
  102. def int_to_str(value: int | NoneType) -> str:
  103. if isinstance(value, int):
  104. return str(value)
  105. else:
  106. return value
  107. ids_convertor = Annotated[List[int], BeforeValidator(ids_to_list)]