category.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from typing import Any, List
  4. from fastapi import Depends, Query, Path
  5. from sqlalchemy import text
  6. from sqlalchemy.ext.asyncio import AsyncSession
  7. from common.const import PERIODS, SUBJECTS, RESOURCE_TYPES, WORK_RESOURCE_TYPES
  8. from crud.base import CrudManager
  9. from crud.resource import crud_work_category, crud_exam_category
  10. from models.user import SysUser
  11. from schemas.resource import NewCategory, UpdateCategory
  12. from utils.depends import get_async_db, get_current_user
  13. # 学段列表
  14. async def get_periods(current_user: SysUser = Depends(get_current_user)):
  15. data = [{"name": item} for item in PERIODS]
  16. return {"data": data}
  17. # 学科列表
  18. async def get_subjects(current_user: SysUser = Depends(get_current_user)):
  19. data = [{"name": item} for item in SUBJECTS]
  20. return {"data": data}
  21. async def get_work_types(current_user: SysUser = Depends(get_current_user)):
  22. data = [{"name": item} for item in WORK_RESOURCE_TYPES]
  23. return {"data": data}
  24. # 分类
  25. async def get_category_tree(crud: CrudManager,
  26. db: AsyncSession = Depends(get_async_db),
  27. root: List[Any] = None):
  28. for item in root:
  29. children = await crud.fetch_all(db, filters=[text(f"pid={item.id}")])
  30. item.children = children
  31. await get_category_tree(crud, db, item.children)
  32. async def get_categories(ctype: str = Query(...,
  33. description="资源类型,exam / work"),
  34. db: AsyncSession = Depends(get_async_db),
  35. current_user: SysUser = Depends(get_current_user)):
  36. if ctype not in RESOURCE_TYPES:
  37. return {"errcode": 400, "mess": "资源类型错误!"}
  38. crud = crud_work_category if ctype == "work" else crud_exam_category
  39. root = await crud.fetch_all(db, filters=[text("pid = 0")])
  40. await get_category_tree(crud, db, root)
  41. return {"data": root}
  42. # 创建资源分类
  43. async def create_category(info: NewCategory,
  44. db: AsyncSession = Depends(get_async_db),
  45. current_user: SysUser = Depends(get_current_user)):
  46. # 判断提交参数是否为空
  47. info_dict = info.dict(exclude_none=True)
  48. if not info_dict:
  49. return {"errcode": 400, "mess": "提交参数为空!"}
  50. # 分类
  51. crud = crud_work_category if info.ctype == "work" else crud_exam_category
  52. filters = {
  53. "name": info.name,
  54. "period": info.period,
  55. "subject": info.subject
  56. }
  57. if info.pid: # 判断上级分类是否存在
  58. category = await crud.find_one(db, filters={"id": info.pid})
  59. if not category:
  60. return {"errcode": 404, "mess": "上级分类不存在!"}
  61. else:
  62. info.pname = category.name
  63. # 判断同级分类是否存在重复
  64. existed = await crud.count(db, filters=filters)
  65. if existed:
  66. return {"errcode": 400, "mess": "存在同名分类!"}
  67. # 创建
  68. delattr(info, "ctype")
  69. db_obj = await crud.insert_one(db, info)
  70. return {"data": db_obj}
  71. # 更新资源分类
  72. async def update_category(info: UpdateCategory,
  73. cid: int = Path(..., description="分类ID"),
  74. db: AsyncSession = Depends(get_async_db),
  75. current_user: SysUser = Depends(get_current_user)):
  76. # 判断提交参数是否为空
  77. info_dict = info.dict(exclude_none=True)
  78. if not info_dict:
  79. return {"errcode": 400, "mess": "提交参数为空!"}
  80. # 判断分类是否存在
  81. crud = crud_work_category if info.ctype == "work" else crud_exam_category
  82. db_obj = await crud.find_one(db, filters={"id": cid})
  83. if not db_obj:
  84. return {"errcode": 404, "mess": "分类不存在!"}
  85. # 判断上级分类是否存在
  86. if ("pid" in info_dict) or ("pname" in info_dict):
  87. if bool(info.pid) ^ bool(info.pname):
  88. return {"errcode": 400, "mess": "缺少上级分类ID或名称"}
  89. existed = await crud.count(db,
  90. filters={
  91. "id": info.pid,
  92. "name": info.pname
  93. })
  94. if not existed:
  95. return {"errcode": 404, "mess": "上级分类不存在!"}
  96. # 判断同级分类是否存在重复
  97. if "name" in info_dict:
  98. existed = await crud.count(
  99. db,
  100. filters=[
  101. text(f"id != {cid} AND name = '{info.name}'"),
  102. text(f"pid = {info.pid} AND pname = '{info.pname}'")
  103. ])
  104. if existed:
  105. return {"errcode": 400, "mess": "存在同名分类!"}
  106. # 更新
  107. db_obj = await crud.update(db, db_obj, info)
  108. return {"data": db_obj}
  109. # 删除资源分类
  110. async def delete_category(cid: int = Path(..., description="资源分类ID"),
  111. ctype: str = Query(...,
  112. description="分类类型,exam / work"),
  113. db: AsyncSession = Depends(get_async_db),
  114. current_user: SysUser = Depends(get_current_user)):
  115. if ctype not in RESOURCE_TYPES:
  116. return {"errcode": 400, "mess": "分类类型错误!"}
  117. crud = crud_work_category if ctype == "work" else crud_exam_category
  118. existed = await crud.count(db, {"id": cid})
  119. if not existed:
  120. return {"errcode": 404, "mess": "分类不存在!"}
  121. else:
  122. await crud.delete(db, obj_id=cid)
  123. # TODO: 删除关联数据
  124. # bg_task.add_task(delete_related_object, db, cid=id)
  125. return {"data": None}