serializer.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. # -*- coding: utf-8 -*-
  2. # @Author : YY
  3. import functools
  4. from typing import Any, Callable
  5. from flask import Response, make_response
  6. from werkzeug.exceptions import HTTPException, InternalServerError
  7. from ruoyi_common.base.model import BaseEntity,VoSerializerContext
  8. from ruoyi_common.base.signal import log_signal
  9. from ruoyi_common.exception import ServiceException
  10. from ruoyi_common.utils.base import DescriptUtil
  11. class BaseSerializer:
  12. def __call__(self, func) -> Callable:
  13. @functools.wraps(func)
  14. def wrapper(*args: Any, **kwargs: Any) -> Any:
  15. try:
  16. res = func(*args, **kwargs)
  17. except HTTPException as e:
  18. # self.send_http_exception(func, e)
  19. raise e
  20. except Exception as e:
  21. raise e
  22. else:
  23. response = self.serialize(func, res)
  24. self.send_success(func, res)
  25. return response
  26. return wrapper
  27. def send_http_exception(self, func, e:HTTPException):
  28. """
  29. 发送http异常的消息
  30. Args:
  31. func: 被装饰的函数
  32. e: http异常
  33. """
  34. raw_func = DescriptUtil.get_raw(func)
  35. log_signal.send(raw_func,message=e)
  36. def send_success(self, func, res:Response):
  37. """
  38. 发送成功响应的消息
  39. Args:
  40. func: 被装饰的函数
  41. res: 成功响应
  42. """
  43. raw_func = DescriptUtil.get_raw(func)
  44. log_signal.send(raw_func,message=res)
  45. def serialize(self, func, res:Any) -> Response:
  46. """
  47. 序列化对象
  48. Args:
  49. func: 被装饰的函数
  50. res: 被序列化的对象
  51. Returns:
  52. Response: 序列化后的Response对象
  53. """
  54. if isinstance(res, Response):
  55. response = res
  56. else:
  57. response = make_response(res, 200)
  58. return response
  59. class JsonSerializer(BaseSerializer):
  60. def __init__(self,
  61. exclude_fields: list=[],
  62. include_fields: list|None=None,
  63. exclude_none: bool=False,
  64. exclude_unset: bool=False,
  65. exclude_default: bool=False,
  66. success_code: int=200,
  67. mimetype: str='application/json',
  68. headers: dict={},
  69. ):
  70. self.mimetype = mimetype
  71. self.headers = headers
  72. self.success_code = success_code
  73. self.context = VoSerializerContext(
  74. by_alias=True,
  75. exclude_fields=exclude_fields,
  76. include_fields=include_fields,
  77. exclude_none=exclude_none,
  78. exclude_unset=exclude_unset,
  79. exclude_default=exclude_default
  80. )
  81. def serialize(self, func, res:Any) -> Response:
  82. """
  83. 序列化对象
  84. Args:
  85. func: 被装饰的函数
  86. res: 被序列化的对象
  87. Returns:
  88. Response: 序列化后的Response对象
  89. """
  90. if isinstance(res, BaseEntity):
  91. response = self.handle_entity(func, res)
  92. elif isinstance(res, list) and len(res) == 2:
  93. res, code = res
  94. response = self.serialize(func,res)
  95. response.status_code = code
  96. elif isinstance(res, Response):
  97. response = res
  98. else:
  99. response = self.handle_other(func, res)
  100. return response
  101. def handle_entity(self, func, res:BaseEntity) -> Response:
  102. """
  103. 处理BaseEntity对象
  104. Args:
  105. func: 被装饰的函数
  106. res: 被序列化的对象
  107. Returns:
  108. Response: 序列化后的Response对象
  109. """
  110. try:
  111. res = res.model_dump_json(
  112. **self.context.as_kwargs(),
  113. context=self.context
  114. )
  115. except HTTPException as e:
  116. http_exc = InternalServerError(description="序列化实体对象异常")
  117. self.send_http_exception(func, http_exc)
  118. raise http_exc
  119. except Exception as e:
  120. raise e
  121. else:
  122. response = make_response(res, self.success_code)
  123. if self.mimetype:
  124. response.mimetype = self.mimetype
  125. if self.headers:
  126. response.headers.update(self.headers)
  127. return response
  128. def handle_other(self, func, res:Any) -> Response:
  129. """
  130. 处理其他对象
  131. Args:
  132. func: 被装饰的函数
  133. res: 被序列化的对象
  134. Returns:
  135. Response: 序列化后的Response对象
  136. """
  137. try:
  138. response = make_response(res)
  139. if self.mimetype:
  140. response.mimetype = self.mimetype
  141. if self.headers:
  142. response.headers.update(self.headers)
  143. except HTTPException as e:
  144. http_exc = InternalServerError(description="序列化其他对象异常")
  145. self.send_http_exception(func, http_exc)
  146. raise http_exc
  147. except Exception as e:
  148. raise e
  149. return response