controller.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. from typing import Annotated
  2. from fastapi import APIRouter, Body, Depends, Path
  3. from fastapi.responses import JSONResponse, StreamingResponse
  4. from redis.asyncio.client import Redis
  5. from app.api.v1.module_system.auth.schema import AuthSchema
  6. from app.common.response import ResponseSchema, StreamResponse, SuccessResponse
  7. from app.core.base_params import PaginationQueryParam
  8. from app.core.base_schema import BatchSetAvailable
  9. from app.core.dependencies import AuthPermission, redis_getter
  10. from app.core.logger import log
  11. from app.core.router_class import OperationLogRoute
  12. from app.utils.common_util import bytes2file_response
  13. from .schema import (
  14. DictDataCreateSchema,
  15. DictDataOutSchema,
  16. DictDataQueryParam,
  17. DictDataUpdateSchema,
  18. DictTypeCreateSchema,
  19. DictTypeOutSchema,
  20. DictTypeQueryParam,
  21. DictTypeUpdateSchema,
  22. )
  23. from .service import DictDataService, DictTypeService
  24. DictRouter = APIRouter(route_class=OperationLogRoute, prefix="/dict", tags=["字典管理"])
  25. @DictRouter.get(
  26. "/type/detail/{id}",
  27. summary="获取字典类型详情",
  28. description="获取字典类型详情",
  29. response_model=ResponseSchema[DictTypeOutSchema],
  30. )
  31. async def get_type_detail_controller(
  32. id: Annotated[int, Path(description="字典类型ID", ge=1)],
  33. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:detail"]))],
  34. ) -> JSONResponse:
  35. """
  36. 获取字典类型详情
  37. 参数:
  38. - id (int): 字典类型ID
  39. - auth (AuthSchema): 认证信息模型
  40. 返回:
  41. - JSONResponse: 包含字典类型详情的响应模型
  42. 异常:
  43. - CustomException: 获取字典类型详情失败时抛出异常。
  44. """
  45. result_dict = await DictTypeService.get_obj_detail_service(id=id, auth=auth)
  46. log.info(f"获取字典类型详情成功 {id}")
  47. return SuccessResponse(data=result_dict, msg="获取字典类型详情成功")
  48. @DictRouter.get(
  49. "/type/list",
  50. summary="查询字典类型",
  51. description="查询字典类型",
  52. response_model=ResponseSchema[list[DictTypeOutSchema]],
  53. )
  54. async def get_type_list_controller(
  55. page: Annotated[PaginationQueryParam, Depends()],
  56. search: Annotated[DictTypeQueryParam, Depends()],
  57. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:query"]))],
  58. ) -> JSONResponse:
  59. """
  60. 查询字典类型
  61. 参数:
  62. - page (PaginationQueryParam): 分页参数模型
  63. - search (DictTypeQueryParam): 查询参数模型
  64. - auth (AuthSchema): 认证信息模型
  65. 返回:
  66. - JSONResponse: 包含查询字典类型结果的响应模型
  67. 异常:
  68. - CustomException: 查询字典类型失败时抛出异常。
  69. """
  70. result_dict = await DictTypeService.get_obj_page_service(
  71. auth=auth,
  72. page_no=page.page_no,
  73. page_size=page.page_size,
  74. search=search,
  75. order_by=page.order_by,
  76. )
  77. log.info("查询字典类型列表成功")
  78. return SuccessResponse(data=result_dict, msg="查询字典类型列表成功")
  79. @DictRouter.get(
  80. "/type/optionselect",
  81. summary="获取全部字典类型",
  82. description="获取全部字典类型",
  83. response_model=ResponseSchema[list[DictTypeOutSchema]],
  84. )
  85. async def get_type_loptionselect_controller(
  86. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:query"]))],
  87. ) -> JSONResponse:
  88. """
  89. 获取全部字典类型
  90. 参数:
  91. - auth (AuthSchema): 认证信息模型
  92. 返回:
  93. - JSONResponse: 包含全部字典类型的响应模型
  94. 异常:
  95. - CustomException: 获取字典类型列表失败时抛出异常。
  96. """
  97. result_dict_list = await DictTypeService.get_obj_list_service(auth=auth)
  98. log.info("获取字典类型列表成功")
  99. return SuccessResponse(data=result_dict_list, msg="获取字典类型列表成功")
  100. @DictRouter.post(
  101. "/type/create",
  102. summary="创建字典类型",
  103. description="创建字典类型",
  104. response_model=ResponseSchema[DictTypeOutSchema],
  105. )
  106. async def create_type_controller(
  107. data: DictTypeCreateSchema,
  108. redis: Annotated[Redis, Depends(redis_getter)],
  109. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:create"]))],
  110. ) -> JSONResponse:
  111. """
  112. 创建字典类型
  113. 参数:
  114. - data (DictTypeCreateSchema): 创建字典类型的入参模型
  115. - redis (Redis): Redis数据库连接
  116. - auth (AuthSchema): 认证信息模型
  117. 返回:
  118. - JSONResponse: 包含创建字典类型结果的响应模型
  119. 异常:
  120. - CustomException: 创建字典类型失败时抛出异常。
  121. """
  122. result_dict = await DictTypeService.create_obj_service(auth=auth, redis=redis, data=data)
  123. log.info(f"创建字典类型成功: {result_dict}")
  124. return SuccessResponse(data=result_dict, msg="创建字典类型成功")
  125. @DictRouter.put(
  126. "/type/update/{id}",
  127. summary="修改字典类型",
  128. description="修改字典类型",
  129. response_model=ResponseSchema[DictTypeOutSchema],
  130. )
  131. async def update_type_controller(
  132. data: DictTypeUpdateSchema,
  133. redis: Annotated[Redis, Depends(redis_getter)],
  134. id: Annotated[int, Path(description="字典类型ID", ge=1)],
  135. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:update"]))],
  136. ) -> JSONResponse:
  137. """
  138. 修改字典类型
  139. 参数:
  140. - data (DictTypeUpdateSchema): 修改字典类型的入参模型
  141. - redis (Redis): Redis数据库连接
  142. - id (int): 字典类型ID
  143. - auth (AuthSchema): 认证信息模型
  144. 返回:
  145. - JSONResponse: 包含修改字典类型结果的响应模型
  146. 异常:
  147. - CustomException: 修改字典类型失败时抛出异常。
  148. """
  149. result_dict = await DictTypeService.update_obj_service(auth=auth, redis=redis, id=id, data=data)
  150. log.info(f"修改字典类型成功: {result_dict}")
  151. return SuccessResponse(data=result_dict, msg="修改字典类型成功")
  152. @DictRouter.delete(
  153. "/type/delete",
  154. summary="删除字典类型",
  155. description="删除字典类型",
  156. response_model=ResponseSchema[None],
  157. )
  158. async def delete_type_controller(
  159. redis: Annotated[Redis, Depends(redis_getter)],
  160. ids: Annotated[list[int], Body(description="ID列表")],
  161. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:delete"]))],
  162. ) -> JSONResponse:
  163. """
  164. 删除字典类型
  165. 参数:
  166. - redis (Redis): Redis数据库连接
  167. - ids (list[int]): 字典类型ID列表
  168. - auth (AuthSchema): 认证信息模型
  169. 返回:
  170. - JSONResponse: 包含删除字典类型结果的响应模型
  171. 异常:
  172. - CustomException: 删除字典类型失败时抛出异常。
  173. """
  174. await DictTypeService.delete_obj_service(auth=auth, redis=redis, ids=ids)
  175. log.info(f"删除字典类型成功: {ids}")
  176. return SuccessResponse(msg="删除字典类型成功")
  177. @DictRouter.patch(
  178. "/type/available/setting",
  179. summary="批量修改字典类型状态",
  180. description="批量修改字典类型状态",
  181. response_model=ResponseSchema[None],
  182. )
  183. async def batch_set_available_dict_type_controller(
  184. data: BatchSetAvailable,
  185. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:patch"]))],
  186. ) -> JSONResponse:
  187. """
  188. 批量修改字典类型状态
  189. 参数:
  190. - data (BatchSetAvailable): 批量修改字典类型状态负载模型
  191. - auth (AuthSchema): 认证信息模型
  192. 返回:
  193. - JSONResponse: 包含批量修改字典类型状态结果的响应模型
  194. 异常:
  195. - CustomException: 批量修改字典类型状态失败时抛出异常。
  196. """
  197. await DictTypeService.set_obj_available_service(auth=auth, data=data)
  198. log.info(f"批量修改字典类型状态成功: {data.ids}")
  199. return SuccessResponse(msg="批量修改字典类型状态成功")
  200. @DictRouter.post(
  201. "/type/export",
  202. summary="导出字典类型",
  203. description="导出字典类型",
  204. response_model=ResponseSchema[None],
  205. )
  206. async def export_type_list_controller(
  207. search: Annotated[DictTypeQueryParam, Depends()],
  208. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:export"]))],
  209. ) -> StreamingResponse:
  210. """
  211. 导出字典类型
  212. 参数:
  213. - search (DictTypeQueryParam): 查询参数模型
  214. - auth (AuthSchema): 认证信息模型
  215. 返回:
  216. - StreamingResponse: 包含导出字典类型结果的响应模型
  217. 异常:
  218. - CustomException: 导出字典类型失败时抛出异常。
  219. """
  220. # 获取全量数据
  221. result_dict_list = await DictTypeService.get_obj_list_service(search=search, auth=auth)
  222. export_result = await DictTypeService.export_obj_service(data_list=result_dict_list)
  223. log.info("导出字典类型成功")
  224. return StreamResponse(
  225. data=bytes2file_response(export_result),
  226. media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  227. headers={"Content-Disposition": "attachment; filename=dict_type.xlsx"},
  228. )
  229. @DictRouter.get(
  230. "/data/detail/{id}",
  231. summary="获取字典数据详情",
  232. description="获取字典数据详情",
  233. response_model=ResponseSchema[DictDataOutSchema],
  234. )
  235. async def get_data_detail_controller(
  236. id: Annotated[int, Path(description="字典数据ID", ge=1)],
  237. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:detail"]))],
  238. ) -> JSONResponse:
  239. """
  240. 获取字典数据详情
  241. 参数:
  242. - id (int): 字典数据ID
  243. - auth (AuthSchema): 认证信息模型
  244. 返回:
  245. - JSONResponse: 包含字典数据详情的响应模型
  246. 异常:
  247. - CustomException: 获取字典数据详情失败时抛出异常。
  248. """
  249. result_dict = await DictDataService.get_obj_detail_service(id=id, auth=auth)
  250. log.info(f"获取字典数据详情成功 {id}")
  251. return SuccessResponse(data=result_dict, msg="获取字典数据详情成功")
  252. @DictRouter.get(
  253. "/data/list",
  254. summary="查询字典数据",
  255. description="查询字典数据",
  256. response_model=ResponseSchema[list[DictDataOutSchema]],
  257. )
  258. async def get_data_list_controller(
  259. page: Annotated[PaginationQueryParam, Depends()],
  260. search: Annotated[DictDataQueryParam, Depends()],
  261. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:query"]))],
  262. ) -> JSONResponse:
  263. """
  264. 查询字典数据
  265. 参数:
  266. - page (PaginationQueryParam): 分页查询参数模型
  267. - search (DictDataQueryParam): 查询参数模型
  268. - auth (AuthSchema): 认证信息模型
  269. 返回:
  270. - JSONResponse: 包含字典数据列表的响应模型
  271. 异常:
  272. - CustomException: 查询字典数据列表失败时抛出异常。
  273. """
  274. order_by = [{"order": "asc"}]
  275. if page.order_by:
  276. order_by = page.order_by
  277. result_dict = await DictDataService.get_obj_page_service(
  278. auth=auth,
  279. page_no=page.page_no,
  280. page_size=page.page_size,
  281. search=search,
  282. order_by=order_by,
  283. )
  284. log.info("查询字典数据列表成功")
  285. return SuccessResponse(data=result_dict, msg="查询字典数据列表成功")
  286. @DictRouter.post(
  287. "/data/create",
  288. summary="创建字典数据",
  289. description="创建字典数据",
  290. response_model=ResponseSchema[DictDataOutSchema],
  291. )
  292. async def create_data_controller(
  293. data: DictDataCreateSchema,
  294. redis: Annotated[Redis, Depends(redis_getter)],
  295. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:create"]))],
  296. ) -> JSONResponse:
  297. """
  298. 创建字典数据
  299. 参数:
  300. - data (DictDataCreateSchema): 创建字典数据负载模型
  301. - redis (Redis): Redis数据库连接
  302. - auth (AuthSchema): 认证信息模型
  303. 返回:
  304. - JSONResponse: 包含创建字典数据结果的响应模型
  305. 异常:
  306. - CustomException: 创建字典数据失败时抛出异常。
  307. """
  308. result_dict = await DictDataService.create_obj_service(auth=auth, redis=redis, data=data)
  309. log.info(f"创建字典数据成功: {result_dict}")
  310. return SuccessResponse(data=result_dict, msg="创建字典数据成功")
  311. @DictRouter.put(
  312. "/data/update/{id}",
  313. summary="修改字典数据",
  314. description="修改字典数据",
  315. response_model=ResponseSchema[DictDataOutSchema],
  316. )
  317. async def update_data_controller(
  318. data: DictDataUpdateSchema,
  319. redis: Annotated[Redis, Depends(redis_getter)],
  320. id: Annotated[int, Path(description="字典数据ID")],
  321. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:update"]))],
  322. ) -> JSONResponse:
  323. """
  324. 修改字典数据
  325. 参数:
  326. - data (DictDataUpdateSchema): 修改字典数据负载模型
  327. - redis (Redis): Redis数据库连接
  328. - id (int): 字典数据ID
  329. - auth (AuthSchema): 认证信息模型
  330. 返回:
  331. - JSONResponse: 包含修改字典数据结果的响应模型
  332. 异常:
  333. - CustomException: 修改字典数据失败时抛出异常。
  334. """
  335. result_dict = await DictDataService.update_obj_service(auth=auth, redis=redis, id=id, data=data)
  336. log.info(f"修改字典数据成功: {result_dict}")
  337. return SuccessResponse(data=result_dict, msg="修改字典数据成功")
  338. @DictRouter.delete(
  339. "/data/delete",
  340. summary="删除字典数据",
  341. description="删除字典数据",
  342. response_model=ResponseSchema[None],
  343. )
  344. async def delete_data_controller(
  345. redis: Annotated[Redis, Depends(redis_getter)],
  346. ids: Annotated[list[int], Body(description="ID列表")],
  347. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:delete"]))],
  348. ) -> JSONResponse:
  349. """
  350. 删除字典数据
  351. 参数:
  352. - redis (Redis): Redis数据库连接
  353. - ids (list[int]): 字典数据ID列表
  354. - auth (AuthSchema): 认证信息模型
  355. 返回:
  356. - JSONResponse: 包含删除字典数据结果的响应模型
  357. 异常:
  358. - CustomException: 删除字典数据失败时抛出异常。
  359. """
  360. await DictDataService.delete_obj_service(auth=auth, redis=redis, ids=ids)
  361. log.info(f"删除字典数据成功: {ids}")
  362. return SuccessResponse(msg="删除字典数据成功")
  363. @DictRouter.patch(
  364. "/data/available/setting",
  365. summary="批量修改字典数据状态",
  366. description="批量修改字典数据状态",
  367. response_model=ResponseSchema[None],
  368. )
  369. async def batch_set_available_dict_data_controller(
  370. data: BatchSetAvailable,
  371. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:patch"]))],
  372. ) -> JSONResponse:
  373. """
  374. 批量修改字典数据状态
  375. 参数:
  376. - data (BatchSetAvailable): 批量修改字典数据状态负载模型
  377. - auth (AuthSchema): 认证信息模型
  378. 返回:
  379. - JSONResponse: 包含批量修改字典数据状态结果的响应模型
  380. 异常:
  381. - CustomException: 批量修改字典数据状态失败时抛出异常。
  382. """
  383. await DictDataService.set_obj_available_service(auth=auth, data=data)
  384. log.info(f"批量修改字典数据状态成功: {data.ids}")
  385. return SuccessResponse(msg="批量修改字典数据状态成功")
  386. @DictRouter.post(
  387. "/data/export",
  388. summary="导出字典数据",
  389. description="导出字典数据",
  390. response_model=ResponseSchema[None],
  391. )
  392. async def export_data_list_controller(
  393. search: Annotated[DictDataQueryParam, Depends()],
  394. page: Annotated[PaginationQueryParam, Depends()],
  395. auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:export"]))],
  396. ) -> StreamingResponse:
  397. """
  398. 导出字典数据
  399. 参数:
  400. - search (DictDataQueryParam): 查询参数模型
  401. - page (PaginationQueryParam): 分页参数模型
  402. - auth (AuthSchema): 认证信息模型
  403. 返回:
  404. - StreamingResponse: 包含导出字典数据结果的响应模型
  405. 异常:
  406. - CustomException: 导出字典数据失败时抛出异常。
  407. """
  408. result_dict_list = await DictDataService.get_obj_list_service(
  409. auth=auth, search=search, order_by=page.order_by
  410. )
  411. export_result = await DictDataService.export_obj_service(data_list=result_dict_list)
  412. log.info("导出字典数据成功")
  413. return StreamResponse(
  414. data=bytes2file_response(export_result),
  415. media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  416. headers={"Content-Disposition": "attachment; filename=dice_data.xlsx"},
  417. )
  418. @DictRouter.get(
  419. "/data/info/{dict_type}",
  420. summary="根据字典类型获取数据",
  421. description="根据字典类型获取数据",
  422. response_model=ResponseSchema[list[DictDataOutSchema]],
  423. )
  424. async def get_init_dict_data_controller(
  425. dict_type: str, redis: Annotated[Redis, Depends(redis_getter)]
  426. ) -> JSONResponse:
  427. """
  428. 根据字典类型获取数据
  429. 参数:
  430. - dict_type (str): 字典类型
  431. - redis (Redis): Redis数据库连接
  432. 返回:
  433. - JSONResponse: 包含根据字典类型获取数据结果的响应模型
  434. 异常:
  435. - CustomException: 根据字典类型获取数据失败时抛出异常。
  436. """
  437. dict_data_query_result = await DictDataService.get_init_dict_service(
  438. redis=redis, dict_type=dict_type
  439. )
  440. log.info(f"获取初始化字典数据成功:{dict_data_query_result}")
  441. return SuccessResponse(data=dict_data_query_result, msg="获取初始化字典数据成功")