feat: user api

This commit is contained in:
zy7y
2022-09-12 15:11:12 +08:00
parent 28013b0e8e
commit 7db1277dd9
30 changed files with 513 additions and 304 deletions

View File

@@ -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
)

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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)

View File

@@ -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$"
)
])