feat: user api
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
from typing import Generic, Optional, TypeVar
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic.generics import GenericModel
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Response(GenericModel, Generic[T]):
|
||||
code: int = 200
|
||||
data: Optional[T]
|
||||
msg: str = "请求成功"
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ReadBase(BaseModel):
|
||||
"""数据读取的基类"""
|
||||
|
||||
id: int
|
||||
status: int = Field(default=1, description="数据状态 1正常默认值 9 删除 5使用中 ")
|
||||
created: datetime
|
||||
modified: datetime
|
||||
|
||||
|
||||
from typing import Any, Callable, get_type_hints
|
||||
|
||||
from fastapi import routing
|
||||
|
||||
|
||||
class Route(routing.APIRoute):
|
||||
"""
|
||||
https://github.com/tiangolo/fastapi/issues/620
|
||||
Django挂载视图方法
|
||||
def index() -> User:
|
||||
pass
|
||||
Route("/", endpoint=index)
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path: str,
|
||||
endpoint: Callable[..., Any],
|
||||
tags: list[str],
|
||||
summary: str,
|
||||
**kwargs: Any
|
||||
):
|
||||
if kwargs.get("response_model") is None:
|
||||
kwargs["response_model"] = get_type_hints(endpoint).get("return")
|
||||
super(Route, self).__init__(
|
||||
path=path, endpoint=endpoint, tags=tags, summary=summary, **kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def post(
|
||||
cls,
|
||||
path: str,
|
||||
endpoint: Callable[..., Any],
|
||||
tags: list[str],
|
||||
summary: str,
|
||||
**kwargs: Any
|
||||
):
|
||||
return Route(
|
||||
path=path,
|
||||
endpoint=endpoint,
|
||||
methods=["POST"],
|
||||
tags=tags,
|
||||
summary=summary,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get(
|
||||
cls,
|
||||
path: str,
|
||||
endpoint: Callable[..., Any],
|
||||
tags: list[str],
|
||||
summary: str,
|
||||
**kwargs: Any
|
||||
):
|
||||
return Route(
|
||||
path=path,
|
||||
endpoint=endpoint,
|
||||
methods=["GET"],
|
||||
tags=tags,
|
||||
summary=summary,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def delete(
|
||||
cls,
|
||||
path: str,
|
||||
endpoint: Callable[..., Any],
|
||||
tags: list[str],
|
||||
summary: str,
|
||||
**kwargs: Any
|
||||
):
|
||||
return Route(
|
||||
path=path,
|
||||
endpoint=endpoint,
|
||||
methods=["DELETE"],
|
||||
tags=tags,
|
||||
summary=summary,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def put(
|
||||
cls,
|
||||
path: str,
|
||||
endpoint: Callable[..., Any],
|
||||
tags: list[str],
|
||||
summary: str,
|
||||
**kwargs: Any
|
||||
):
|
||||
return Route(
|
||||
path=path,
|
||||
endpoint=endpoint,
|
||||
methods=["PUT"],
|
||||
tags=tags,
|
||||
summary=summary,
|
||||
**kwargs
|
||||
)
|
||||
|
@@ -1,35 +0,0 @@
|
||||
import enum
|
||||
|
||||
|
||||
class Status(enum.IntEnum):
|
||||
"""
|
||||
数据库状态枚举值
|
||||
9 删除 5 无效 1 有效 3 使用
|
||||
"""
|
||||
|
||||
DELETED: int = 9
|
||||
INACTIVE: int = 5
|
||||
ACTIVE: int = 1
|
||||
SELECTED: int = 3
|
||||
|
||||
|
||||
class UserType(enum.IntEnum):
|
||||
"""
|
||||
数据库超级管理员枚举
|
||||
0 超级管理员 1用户
|
||||
"""
|
||||
|
||||
ADMIN: int = 0
|
||||
USER: int = 1
|
||||
|
||||
|
||||
class MenuType(enum.IntEnum):
|
||||
"""
|
||||
菜单类型枚举
|
||||
目录 0
|
||||
组件 1 按钮 2
|
||||
"""
|
||||
|
||||
DIR = 0
|
||||
CPN = 1
|
||||
BTN = 2
|
@@ -3,9 +3,7 @@ from tortoise import Tortoise
|
||||
|
||||
async def init_orm():
|
||||
"""初始化orm"""
|
||||
await Tortoise.init(
|
||||
db_url="sqlite://mini.db", modules={"models": ["models"]},
|
||||
)
|
||||
await Tortoise.init(db_url="sqlite://mini.db", modules={"models": ["models"]})
|
||||
await Tortoise.generate_schemas()
|
||||
|
||||
|
||||
|
@@ -1,32 +0,0 @@
|
||||
import enum
|
||||
from typing import Generic, Optional, TypeVar, Union
|
||||
|
||||
from pydantic.generics import GenericModel
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Status(enum.IntEnum):
|
||||
OK = 200
|
||||
CREATED = 201
|
||||
ACCEPTED = 202
|
||||
NO_CONTENT = 204
|
||||
BAD_REQUEST = 400
|
||||
UNAUTHORIZED = 401
|
||||
FORBIDDEN = 403
|
||||
NOT_FOUND = 404
|
||||
INTERNAL_SERVER_ERROR = 500
|
||||
NOT_IMPLEMENTED = 501
|
||||
BAD_GATEWAY = 502
|
||||
SERVICE_UNAVAILABLE = 503
|
||||
|
||||
|
||||
class Msg(enum.Enum):
|
||||
OK = "OK"
|
||||
FAIL = "FAIL"
|
||||
|
||||
|
||||
class Response(GenericModel, Generic[T]):
|
||||
code: Status = Status.OK
|
||||
data: Optional[T]
|
||||
msg: Union[Msg, str] = Msg.OK
|
@@ -1,48 +0,0 @@
|
||||
from typing import TYPE_CHECKING, Any, Callable, get_type_hints
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.routing import APIRoute
|
||||
|
||||
"""
|
||||
根据类型标注自动返回模型
|
||||
https://github.com/tiangolo/fastapi/issues/620
|
||||
"""
|
||||
|
||||
|
||||
class Router(APIRouter):
|
||||
"""
|
||||
装饰器用法
|
||||
@app.get("/")
|
||||
def index() -> User:
|
||||
"""
|
||||
|
||||
if not TYPE_CHECKING:
|
||||
|
||||
def add_api_route(
|
||||
self, path: str, endpoint: Callable[..., Any], **kwargs: Any
|
||||
) -> None:
|
||||
if kwargs.get("response_model") is None:
|
||||
kwargs["response_model"] = get_type_hints(endpoint).get("return")
|
||||
return super().add_api_route(path, endpoint, **kwargs)
|
||||
|
||||
else: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class Route(APIRoute):
|
||||
"""
|
||||
Django挂载视图方法
|
||||
def index() -> User:
|
||||
pass
|
||||
Route("/", endpoint=index)
|
||||
"""
|
||||
|
||||
if not TYPE_CHECKING:
|
||||
|
||||
def __init__(self, path: str, endpoint: Callable[..., Any], **kwargs: Any):
|
||||
if kwargs.get("response_model") is None:
|
||||
kwargs["response_model"] = get_type_hints(endpoint).get("return")
|
||||
super(Route, self).__init__(path=path, endpoint=endpoint, **kwargs)
|
||||
|
||||
else: # pragma: no cover
|
||||
pass
|
@@ -14,7 +14,7 @@ SECRET_KEY = "lLNiBWPGiEmCLLR9kRGidgLY7Ac1rpSWwfGzTJpTmCU"
|
||||
|
||||
ALGORITHM = "HS256"
|
||||
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = 60 *24 * 7
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
bearer = HTTPBearer()
|
||||
@@ -45,13 +45,9 @@ def generate_token(username: str, expires_delta: Optional[timedelta] = None):
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + timedelta(
|
||||
minutes=ACCESS_TOKEN_EXPIRE_MINUTES
|
||||
)
|
||||
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
to_encode.update(dict(exp=expire))
|
||||
encoded_jwt = jwt.encode(
|
||||
to_encode, SECRET_KEY, algorithm=ALGORITHM
|
||||
)
|
||||
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
||||
return encoded_jwt
|
||||
|
||||
|
||||
@@ -59,9 +55,7 @@ async def check_token(security: HTTPAuthorizationCredentials = Depends(bearer)):
|
||||
"""检查用户token"""
|
||||
token = security.credentials
|
||||
try:
|
||||
payload = jwt.decode(
|
||||
token, SECRET_KEY, algorithms=[ALGORITHM]
|
||||
)
|
||||
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||
username: str = payload.get("sub")
|
||||
return await get_user({"username": username})
|
||||
except JWTError:
|
||||
|
@@ -1,7 +1,5 @@
|
||||
from tortoise import fields, models
|
||||
|
||||
from core.enums import Status
|
||||
|
||||
|
||||
class Table(models.Model):
|
||||
"""
|
||||
@@ -9,7 +7,7 @@ class Table(models.Model):
|
||||
"""
|
||||
|
||||
id = fields.IntField(pk=True, description="主键")
|
||||
status = fields.IntEnumField(Status, description="状态", default=Status.ACTIVE)
|
||||
status = fields.SmallIntField(default=1, description="状态 1有效 9 删除 5选中")
|
||||
created = fields.DatetimeField(auto_now_add=True, description="创建时间", null=True)
|
||||
modified = fields.DatetimeField(auto_now=True, description="更新时间", null=True)
|
||||
|
||||
|
@@ -24,28 +24,3 @@ def list_to_tree(
|
||||
else:
|
||||
arr.append(menu)
|
||||
return arr
|
||||
|
||||
|
||||
def menu_table():
|
||||
"""生成菜单表数据"""
|
||||
from models import MenuModel
|
||||
MenuModel.bulk_create([
|
||||
MenuModel(name="系统管理",
|
||||
meta={"icon": "Grid"},
|
||||
path="/system",
|
||||
type=0),
|
||||
MenuModel(name="系统设置",
|
||||
meta={"icon": "Setting"},
|
||||
path="/setting",
|
||||
type=0),
|
||||
MenuModel(name="菜单管理",
|
||||
meta={"icon": "Menu"},
|
||||
path="/system/menu",
|
||||
type=1,
|
||||
component="/system/menu",
|
||||
pid=1,
|
||||
api="/menu",
|
||||
method="{'GET}",
|
||||
regx="^/menu$"
|
||||
)
|
||||
])
|
Reference in New Issue
Block a user