license.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from fastapi import APIRouter, Depends, Header, HTTPException, Query
  2. from sqlalchemy.ext.asyncio import AsyncSession
  3. from app.database import get_db
  4. from app.services.license import (
  5. get_super_admins,
  6. create_license,
  7. list_licenses,
  8. get_license_status,
  9. revoke_license,
  10. restore_license,
  11. update_license,
  12. delete_license,
  13. check_license_by_referer,
  14. )
  15. from app.schemas.license import LicenseCreate, LicenseUpdate
  16. from app.schemas.visitor import VisitorInfoCreate
  17. from app.services.visitor import store_visitor_info
  18. router = APIRouter(prefix="/api/license", tags=["License许可"])
  19. # 公开接口,不带 /api/license 前缀,放在 /api/public 下
  20. public_router = APIRouter(prefix="/api/public", tags=["License公开接口"])
  21. @router.get("/super-admins", summary="超级管理员列表(下拉选项)")
  22. async def handle_get_super_admins(
  23. db: AsyncSession = Depends(get_db),
  24. ):
  25. return await get_super_admins(db)
  26. @router.post("/", summary="创建/更新 License")
  27. async def handle_create_license(
  28. payload: LicenseCreate,
  29. db: AsyncSession = Depends(get_db),
  30. ):
  31. return await create_license(db, payload)
  32. @router.get("/list", summary="License 列表")
  33. async def handle_list_licenses(
  34. super_admin_id: int | None = Query(None),
  35. status: str | None = Query(None),
  36. page: int = Query(1, ge=1),
  37. size: int = Query(20, ge=1, le=100),
  38. db: AsyncSession = Depends(get_db),
  39. ):
  40. return await list_licenses(db, super_admin_id, status, page, size)
  41. @router.get("/{license_id}", summary="License 状态详情")
  42. async def handle_get_license(
  43. license_id: int,
  44. db: AsyncSession = Depends(get_db),
  45. ):
  46. try:
  47. return await get_license_status(db, license_id)
  48. except ValueError as e:
  49. raise HTTPException(status_code=404, detail=str(e))
  50. @router.put("/{license_id}", summary="更新 License(key 或过期时间)")
  51. async def handle_update_license(
  52. license_id: int,
  53. payload: LicenseUpdate,
  54. db: AsyncSession = Depends(get_db),
  55. ):
  56. try:
  57. return await update_license(db, license_id, payload)
  58. except ValueError as e:
  59. raise HTTPException(status_code=400, detail=str(e))
  60. @router.post("/{license_id}/revoke", summary="吊销 License")
  61. async def handle_revoke_license(
  62. license_id: int,
  63. db: AsyncSession = Depends(get_db),
  64. ):
  65. try:
  66. return await revoke_license(db, license_id)
  67. except ValueError as e:
  68. raise HTTPException(status_code=404, detail=str(e))
  69. @router.post("/{license_id}/restore", summary="恢复已吊销的 License")
  70. async def handle_restore_license(
  71. license_id: int,
  72. db: AsyncSession = Depends(get_db),
  73. ):
  74. try:
  75. return await restore_license(db, license_id)
  76. except ValueError as e:
  77. raise HTTPException(status_code=400, detail=str(e))
  78. @router.delete("/{license_id}", summary="删除 License")
  79. async def handle_delete_license(
  80. license_id: int,
  81. db: AsyncSession = Depends(get_db),
  82. ):
  83. try:
  84. return await delete_license(db, license_id)
  85. except ValueError as e:
  86. raise HTTPException(status_code=404, detail=str(e))
  87. @public_router.post("/visitor", summary="公开接口:存储域名联系人信息")
  88. async def handle_store_visitor(
  89. payload: VisitorInfoCreate,
  90. referer: str | None = Header(None),
  91. db: AsyncSession = Depends(get_db),
  92. ):
  93. """第三方系统通过请求携带的 Referer 头匹配域名,存储联系人信息(名字/手机/邮箱)。"""
  94. return await store_visitor_info(db, referer, payload)
  95. @public_router.get("/license/check", summary="公开 License 校验接口(通过 Referer 匹配域名)")
  96. async def handle_license_check(
  97. referer: str | None = Header(None),
  98. db: AsyncSession = Depends(get_db),
  99. ):
  100. """第三方系统通过请求携带的 Referer 头,匹配对应的监控域名,检查 License 状态。"""
  101. return await check_license_by_referer(db, referer)