entity.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. # -*- coding: utf-8 -*-
  2. # @Author : YY
  3. import uuid
  4. from datetime import datetime
  5. from types import NoneType
  6. from typing_extensions import Annotated
  7. from flask_login import UserMixin
  8. from pydantic import BaseModel, BeforeValidator, Field, Strict, computed_field
  9. from typing import List, Optional
  10. from pydantic.types import UUID4
  11. from ruoyi_common.base.model import AuditEntity, VoAccess, strict_base_config
  12. from ruoyi_common.base.schema_excel import ExcelAccess, ExcelField, ExcelFields
  13. from ruoyi_common.base.schema_vo import VoField
  14. from ruoyi_common.base.transformer import int_to_str, to_datetime, str_to_int
  15. class LoginUser(BaseModel, UserMixin):
  16. model_config = strict_base_config.copy()
  17. user_id: int
  18. dept_id: Optional[int] = None
  19. token: UUID4 = Field(default_factory=uuid.uuid4)
  20. login_time: Annotated[
  21. datetime,
  22. BeforeValidator(to_datetime())
  23. ] = None
  24. expire_time: Annotated[
  25. datetime,
  26. BeforeValidator(to_datetime())
  27. ] = None
  28. ip_addr: Optional[str] = None
  29. login_location: Optional[str] = None
  30. browser: Optional[str] = None
  31. os: Optional[str] = None
  32. permissions: Optional[List] = []
  33. user: Optional["SysUser"] = None
  34. def get_id(self) -> int:
  35. return self.user_id
  36. @property
  37. def user_name(self) -> str:
  38. return self.user.user_name
  39. @property
  40. def dept_name(self) -> str:
  41. if self.user:
  42. if self.user.dept:
  43. return self.user.dept.dept_name
  44. else:
  45. return ""
  46. else:
  47. return ""
  48. class SysUser(AuditEntity):
  49. user_id: Annotated[
  50. int,
  51. BeforeValidator(str_to_int),
  52. Field(gt=0,default=None),
  53. VoField(query=True),
  54. ExcelField(name="用户序号",cell_type="numeric",prompt="用户编号")
  55. ]
  56. dept_id: Annotated[
  57. int,
  58. BeforeValidator(str_to_int),
  59. Field(gt=0,default=None),
  60. VoField(query=True),
  61. ExcelField(name="部门编号",action="import")
  62. ]
  63. user_name: Annotated[
  64. Optional[str],
  65. Field(default=None),
  66. VoField(query=True),
  67. ExcelField(name="登录名称")
  68. ]
  69. nick_name: Annotated[
  70. Optional[str],
  71. Field(default=None),
  72. ExcelField(name="用户名称")
  73. ]
  74. user_type: Optional[str] = None
  75. email: Annotated[
  76. Optional[str],
  77. Field(default=None),
  78. ExcelField(name="用户邮箱")
  79. ]
  80. phonenumber: Annotated[
  81. Optional[str],
  82. Field(default=None),
  83. VoField(query=True),
  84. ExcelField(name="手机号码")
  85. ]
  86. sex: Annotated[
  87. Optional[str],
  88. Field(default=None),
  89. ExcelField(name="用户性别",converter="0=男,1=女,2=未知")
  90. ]
  91. avatar: Optional[str] = None
  92. password: Annotated[
  93. str,
  94. Field(default=None,exclude=True)
  95. ]
  96. salt: Annotated[
  97. Optional[UUID4],
  98. Field(default=None),
  99. VoField(body=False)
  100. ]
  101. status: Annotated[
  102. Optional[str],
  103. Field(default=None),
  104. VoField(query=True),
  105. ExcelField(name="帐号状态",converter="0=正常,1=停用")
  106. ]
  107. del_flag: Optional[str] = None
  108. login_ip: Annotated[
  109. Optional[str],
  110. Field(default=None),
  111. ExcelField(name="最后登录IP",action="export")
  112. ]
  113. login_date: Annotated[
  114. Optional[datetime],
  115. BeforeValidator(to_datetime()),
  116. ExcelField(
  117. name="最后登录IP",
  118. width=30,
  119. date_format="yyyy-MM-dd HH:mm:ss",
  120. action="export"
  121. )
  122. ] = None
  123. dept: Annotated[
  124. "SysDept",
  125. Field(default=None),
  126. VoField(body=False),
  127. ExcelFields(
  128. ExcelAccess(name="部门名称",width=20,attr="dept_name"),
  129. ExcelAccess(name="部门负责人",width=20,attr="leader")
  130. )
  131. ]
  132. roles: Annotated[
  133. List["SysRole"],
  134. Field(default_factory=list),
  135. VoField(body=False)
  136. ]
  137. role_ids: Optional[List[int]] = []
  138. post_ids: Optional[List[int]] = []
  139. role_id: Annotated[
  140. Optional[int],
  141. Field(default=None),
  142. VoField(body=False)
  143. ]
  144. def is_admin(self) -> bool:
  145. # 检查用户是否拥有管理员角色
  146. if self.user_id == 1:
  147. return True
  148. if self.roles:
  149. for role in self.roles:
  150. if role.role_key == "admin":
  151. return True
  152. return False
  153. class SysRole(AuditEntity):
  154. role_id: Annotated[
  155. int,
  156. BeforeValidator(str_to_int),
  157. Field(gt=0,default=None,vo=VoAccess(query=True))
  158. ]
  159. role_name: Annotated[
  160. Optional[str],
  161. Field(default=None,vo=VoAccess(query=True))
  162. ]
  163. role_key: Annotated[
  164. Optional[str],
  165. Field(default=None,vo=VoAccess(query=True))
  166. ]
  167. role_sort: Annotated[
  168. Optional[int],
  169. BeforeValidator(str_to_int),
  170. Field(default=None)
  171. ]
  172. data_scope: Optional[str] = None
  173. menu_check_strictly: Annotated[Optional[bool],Strict(False)] = None
  174. dept_check_strictly: Annotated[Optional[bool],Strict(False)] = None
  175. status: Annotated[
  176. Optional[str],
  177. Field(default=None,vo=VoAccess(query=True))
  178. ]
  179. del_flag: Annotated[
  180. Optional[str],
  181. Field(default=None,vo=VoAccess(body=False))
  182. ]
  183. flag: Annotated[
  184. Optional[bool],
  185. Field(default=None,vo=VoAccess(body=False))
  186. ]
  187. menu_ids: Annotated[
  188. Optional[List[int]],
  189. Field(default=[],vo=VoAccess(body=False))
  190. ]
  191. dept_ids: Annotated[
  192. Optional[List[int]],
  193. Field(default=[],vo=VoAccess(body=False))
  194. ]
  195. def is_admin(self) -> bool:
  196. return self.role_id and self.role_id == 1 if self.role_id else False
  197. class SysMenu(AuditEntity):
  198. menu_id: Annotated[
  199. int,
  200. BeforeValidator(str_to_int),
  201. Field(gt=0,default=None,vo=VoAccess(query=True))
  202. ]
  203. menu_name: Annotated[
  204. Optional[str],
  205. Field(default=None,vo=VoAccess(query=True))
  206. ]
  207. parent_name: Annotated[
  208. Optional[int],
  209. Field(default=None,exclude=True,vo=VoAccess(body=False))
  210. ]
  211. parent_id: Optional[int] = None
  212. order_num: Optional[int] = None
  213. path: Optional[str] = None
  214. component: Optional[str] = None
  215. query: Optional[str] = None
  216. is_frame: Annotated[str,
  217. BeforeValidator(int_to_str),
  218. Field(default=None)
  219. ]
  220. is_cache: Annotated[str,
  221. BeforeValidator(int_to_str),
  222. Field(default=None)
  223. ]
  224. menu_type: Optional[str] = None
  225. visible: Annotated[
  226. Optional[str],
  227. Field(default=None,vo=VoAccess(query=True))
  228. ]
  229. status: Annotated[
  230. Optional[str],
  231. Field(default=None,vo=VoAccess(query=True))
  232. ]
  233. perms: Optional[str] = None
  234. icon: Optional[str] = None
  235. children: Annotated[
  236. List["SysMenu"] | NoneType,
  237. Field(default=[],exclude=True,vo=VoAccess(body=False))
  238. ]
  239. class SysDictType(AuditEntity):
  240. dict_id: Annotated[
  241. int,
  242. BeforeValidator(str_to_int),
  243. Field(default=None,ge=0,vo=VoAccess(query=True))
  244. ]
  245. dict_name: Annotated[
  246. str,
  247. Field(default=None,vo=VoAccess(query=True))
  248. ]
  249. dict_type: Annotated[
  250. str,
  251. Field(default=None,vo=VoAccess(query=True))
  252. ]
  253. status: Annotated[
  254. str,
  255. Field(default=None,vo=VoAccess(query=True))
  256. ]
  257. class SysDictData(AuditEntity):
  258. dict_code: Annotated[
  259. int,
  260. BeforeValidator(str_to_int),
  261. Field(default=None,ge=0,vo=VoAccess(query=True))
  262. ]
  263. dict_sort: Annotated[int,Field(default=None)]
  264. dict_label: Annotated[
  265. str,
  266. Field(default=None,vo=VoAccess(query=True))
  267. ]
  268. dict_value: Annotated[
  269. str,
  270. Field(default=None,vo=VoAccess(query=True))
  271. ]
  272. dict_type: Annotated[
  273. str,
  274. Field(default=None,vo=VoAccess(query=True))
  275. ]
  276. css_class: Annotated[
  277. Optional[str],
  278. Field(default=None,vo=VoAccess(body=False))
  279. ]
  280. list_class: Annotated[
  281. str,
  282. Field(default=None)
  283. ]
  284. is_default: Annotated[str,Field(default=None)]
  285. status: Annotated[
  286. str,
  287. Field(default=None,vo=VoAccess(query=True))
  288. ]
  289. class SysDept(AuditEntity):
  290. dept_id: Annotated[
  291. int,
  292. BeforeValidator(str_to_int),
  293. Field(gt=0,default=None,vo=VoAccess(query=True))
  294. ]
  295. parent_id: Annotated[
  296. Optional[int],
  297. BeforeValidator(str_to_int),
  298. Field(default=None,vo=VoAccess(query=True))
  299. ]
  300. ancestors: Optional[str] = None
  301. dept_name: Annotated[
  302. Optional[str],
  303. Field(default=None,vo=VoAccess(query=True))
  304. ]
  305. order_num: Optional[int] = None
  306. leader: Optional[str] = None
  307. phone: Optional[str] = None
  308. email: Optional[str] = None
  309. status: Annotated[
  310. Optional[str],
  311. Field(default=None,vo=VoAccess(query=True))
  312. ]
  313. del_flag: Optional[str] = None
  314. parent_name: Annotated[Optional[str],Field(default=None,exclude=True,vo=VoAccess(body=False))]
  315. children: Annotated[List["SysDept"],Field(default=[],vo=VoAccess(body=False))]
  316. class TreeSelect(BaseModel):
  317. # 节点ID
  318. id: Annotated[int, Field(default=None)]
  319. # 节点名称
  320. label: Annotated[str, Field(default=None)]
  321. # 子节点
  322. children: Annotated[List["TreeSelect"], Field(default=[])]
  323. @classmethod
  324. def from_menu(cls, menu: SysMenu) -> "TreeSelect":
  325. return cls(id=menu.menu_id, label=menu.menu_name, children=[cls.from_menu(child) for child in menu.children])
  326. @classmethod
  327. def from_dept(cls, dept: SysDept) -> "TreeSelect":
  328. return cls(id=dept.dept_id, label=dept.dept_name, children=[cls.from_dept(child) for child in dept.children])