roles.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. """角色管理:角色 CRUD、可访问部门、权限矩阵与用户关联。"""
  2. from __future__ import annotations
  3. from flask import request
  4. from dms.api.v1.blueprint import api_v1
  5. from dms.common.errors import InvalidArgumentError
  6. from dms.common.pagination import PageRequest
  7. from dms.common.response import success_response
  8. from dms.security.decorators import admin_required, bearer_auth_required
  9. from dms.services.role_service import (
  10. create_role,
  11. delete_role,
  12. list_role_departments,
  13. list_role_permissions,
  14. list_role_users,
  15. list_roles,
  16. update_role,
  17. update_role_departments,
  18. update_role_permissions,
  19. update_role_users,
  20. )
  21. def _integer_query(name: str, default: int) -> int:
  22. raw_value = request.args.get(name)
  23. if raw_value is None or raw_value == "":
  24. return default
  25. try:
  26. return int(raw_value)
  27. except ValueError as exc:
  28. raise InvalidArgumentError(f"{name}必须是整数") from exc
  29. def _json_body():
  30. if not request.is_json:
  31. raise InvalidArgumentError("请求体必须是JSON对象")
  32. body = request.get_json(silent=True)
  33. if not isinstance(body, dict):
  34. raise InvalidArgumentError("请求体必须是JSON对象")
  35. return body
  36. def _parse_role_id(value: str) -> int:
  37. if not value.isdecimal() or int(value) <= 0:
  38. raise InvalidArgumentError("id必须是正整数形式的字符串ID")
  39. return int(value)
  40. def _parse_delete_row_version(value: str | None) -> int:
  41. if value is None or not value.isdecimal():
  42. raise InvalidArgumentError("rowVersion必须是非负整数")
  43. return int(value)
  44. @api_v1.get("/roles")
  45. @bearer_auth_required
  46. @admin_required
  47. def roles():
  48. data = list_roles(
  49. keyword=request.args.get("keyword"),
  50. status=request.args.get("status"),
  51. page_request=PageRequest(
  52. page=_integer_query("page", 1),
  53. page_size=_integer_query("pageSize", 20),
  54. ),
  55. )
  56. return success_response(data)
  57. @api_v1.post("/roles")
  58. @bearer_auth_required
  59. @admin_required
  60. def create_role_route():
  61. return success_response(create_role(_json_body()), status=201)
  62. @api_v1.put("/roles/<id>")
  63. @bearer_auth_required
  64. @admin_required
  65. def update_role_route(id: str):
  66. return success_response(update_role(_parse_role_id(id), _json_body()))
  67. @api_v1.delete("/roles/<id>")
  68. @bearer_auth_required
  69. @admin_required
  70. def delete_role_route(id: str):
  71. return success_response(
  72. delete_role(
  73. _parse_role_id(id),
  74. _parse_delete_row_version(request.args.get("rowVersion")),
  75. )
  76. )
  77. @api_v1.get("/roles/<id>/departments")
  78. @bearer_auth_required
  79. @admin_required
  80. def role_departments(id: str):
  81. return success_response(list_role_departments(_parse_role_id(id)))
  82. @api_v1.put("/roles/<id>/departments")
  83. @bearer_auth_required
  84. @admin_required
  85. def update_role_departments_route(id: str):
  86. return success_response(
  87. update_role_departments(_parse_role_id(id), _json_body())
  88. )
  89. @api_v1.get("/roles/<id>/permissions")
  90. @bearer_auth_required
  91. @admin_required
  92. def role_permissions(id: str):
  93. return success_response(list_role_permissions(_parse_role_id(id)))
  94. @api_v1.put("/roles/<id>/permissions")
  95. @bearer_auth_required
  96. @admin_required
  97. def update_role_permissions_route(id: str):
  98. return success_response(
  99. update_role_permissions(_parse_role_id(id), _json_body())
  100. )
  101. @api_v1.get("/roles/<id>/users")
  102. @bearer_auth_required
  103. @admin_required
  104. def role_users(id: str):
  105. return success_response(list_role_users(_parse_role_id(id)))
  106. @api_v1.put("/roles/<id>/users")
  107. @bearer_auth_required
  108. @admin_required
  109. def update_role_users_route(id: str):
  110. return success_response(update_role_users(_parse_role_id(id), _json_body()))