diff --git a/api/api_v1/api.py b/api/api_v1/api.py index e3e6c7a..904778d 100644 --- a/api/api_v1/api.py +++ b/api/api_v1/api.py @@ -1,6 +1,10 @@ from fastapi import APIRouter from api.api_v1.endpoints import login +from api.api_v1.endpoints import project +from api.api_v1.endpoints import dashboard api_router = APIRouter() -api_router.include_router(login.router, tags=["登录接口"]) +api_router.include_router(login.router, tags=["登录接口"], prefix='/user') +api_router.include_router(project.router, tags=["项目管理"], prefix='/project') +api_router.include_router(dashboard.router, tags=["看板管理"], prefix='/dashboard') diff --git a/api/api_v1/endpoints/dashboard.py b/api/api_v1/endpoints/dashboard.py index 0b534df..6fc0855 100644 --- a/api/api_v1/endpoints/dashboard.py +++ b/api/api_v1/endpoints/dashboard.py @@ -1,31 +1,68 @@ from datetime import timedelta -from typing import Any +from typing import Any, List from fastapi import APIRouter, Body, Depends, HTTPException, Request from sqlalchemy.orm import Session import crud, models, schemas from api import deps -from core import security -from core.config import settings -from core.security import get_password_hash -from utils import ( - verify_password_reset_token, -) router = APIRouter() +@router.get('/') +def read_dashboard(project_id: int = Depends(deps.check_project), + db: Session = Depends(deps.get_db), + current_user: models.User = Depends(deps.get_current_active_user) + ): + dashboard = crud.authority.get_my_dashboard(db=db, project_id=project_id, user_id=current_user.id) + return dashboard + + +# 新建看板 +@router.post("/create-dashboard") +def create_dashboard(dashboard_in: schemas.DashboardCreate, + project_id: int = Depends(deps.check_project), + db: Session = Depends(deps.get_db), + current_user: models.User = Depends(deps.get_current_active_user)) -> Any: + dashboard = crud.dashboard.create_with_dashboard(db=db, obj_in=dashboard_in, user_id=current_user.id) + + # 自己创建的拥有权限 + crud.authority.create_with_authority(db=db, obj_in=schemas.AuthorityCreate( + dashboard_id=dashboard.id, + project_id=project_id, + authority='rw', + space_id=dashboard.space_id, + folder_id=dashboard.folder_id + ), user_id=current_user.id) + + return {"msg": "新建成功", 'code': 0} + + +@router.post("/create-folder") +def create_folder(folder_in: schemas.FolderCreate, project_id: int = Depends(deps.check_project), + db: Session = Depends(deps.get_db), + current_user: models.User = Depends(deps.get_current_active_user)) -> Any: + folder = crud.folder.create_with_folder(db=db, obj_in=folder_in, user_id=current_user.id, project_id=project_id) + # 自己创建的拥有权限 + crud.authority.create_with_authority(db=db, obj_in=schemas.AuthorityCreate( + project_id=project_id, + authority='rw', + space_id=folder.space_id, + folder_id=folder.id + ), user_id=current_user.id) + return {"msg": "新建成功", 'code': 0} + + @router.post("/create-space") -def create_space() -> Any: - pass - - -@router.post("/create-folder") -def create_folder() -> Any: - pass - - -@router.post("/create-folder") -def create_folder() -> Any: - pass +def create_space(space_in: schemas.SpaceCreate, project_id: int = Depends(deps.check_project), + db: Session = Depends(deps.get_db), + current_user: models.User = Depends(deps.get_current_active_user)) -> Any: + space = crud.space.create_with_space(db=db, obj_in=space_in, user_id=current_user.id,project_id=project_id) + # 自己创建的拥有权限 + crud.authority.create_with_authority(db=db, obj_in=schemas.AuthorityCreate( + project_id=project_id, + authority='rw', + space_id=space.id, + ), user_id=current_user.id) + return {"msg": "新建成功", 'code': 0} diff --git a/api/api_v1/endpoints/login.py b/api/api_v1/endpoints/login.py index 9504369..37e5995 100644 --- a/api/api_v1/endpoints/login.py +++ b/api/api_v1/endpoints/login.py @@ -40,7 +40,7 @@ def login( 'name': user.name, 'email': user.email, 'token': security.create_access_token( - expires_delta=access_token_expires, user_id=user.id, email=user.email, is_active=user.is_active, + expires_delta=access_token_expires, id=user.id, email=user.email, is_active=user.is_active, is_superuser=user.is_superuser, name=user.name ), }, @@ -50,13 +50,12 @@ def login( } -@router.post("/me", response_model=schemas.UserBase) -# @router.post("/me/") -def me(request: Request) -> Any: +@router.get("/me", response_model=schemas.UserDBBase) +def me(current_user: models.User = Depends(deps.get_current_active_user)) -> Any: """ Test access token """ - return request.state.user + return current_user @router.post("/reset-password", response_model=schemas.Msg) diff --git a/api/api_v1/endpoints/manage.py b/api/api_v1/endpoints/manage.py deleted file mode 100644 index a78adfb..0000000 --- a/api/api_v1/endpoints/manage.py +++ /dev/null @@ -1,22 +0,0 @@ -from datetime import timedelta -from typing import Any - -from fastapi import APIRouter, Body, Depends, HTTPException, Request -from sqlalchemy.orm import Session - -import crud, models, schemas -from api import deps -from core import security -from core.config import settings -from core.security import get_password_hash -from utils import ( - verify_password_reset_token, -) - -router = APIRouter() - - -@router.post("/create-project") -def create_project() -> Any: - pass - diff --git a/api/api_v1/endpoints/project.py b/api/api_v1/endpoints/project.py new file mode 100644 index 0000000..5abc347 --- /dev/null +++ b/api/api_v1/endpoints/project.py @@ -0,0 +1,35 @@ +from datetime import timedelta +from typing import Any + +from fastapi import APIRouter, Body, Depends, HTTPException, Request +from sqlalchemy.orm import Session + +import crud, models, schemas +from api import deps + +router = APIRouter() + + +@router.post("/create-project", response_model=schemas.Project) +def create_project(project_in: schemas.ProjectCreate, db: Session = Depends(deps.get_db), + current_user: models.User = Depends(deps.get_current_active_user) + ) -> Any: + project = crud.project.create_with_project(db=db, obj_in=project_in, user_id=current_user.id) + # 我的看板 新建 未分组 和 共享给我的 文件夹 + kanban = crud.kanban.create(db=db, obj_in=schemas.KanBanCreate(project_id=project.id, user_id=current_user.id)) + unknown_folder = schemas.FolderCreate( + project_id=project.id, + user_id=current_user.id, + kanban_id=kanban.id, + name='未分组的' + ) + share_folder = schemas.FolderCreate( + project_id=project.id, + + kanban_id=kanban.id, + name='共享给我的' + ) + crud.folder.create_with_folder(db=db, obj_in=unknown_folder, user_id=current_user.id, ) + crud.folder.create_with_folder(db=db, obj_in=share_folder, user_id=current_user.id) + + return project diff --git a/api/deps.py b/api/deps.py index ca8e8fa..66d5747 100644 --- a/api/deps.py +++ b/api/deps.py @@ -25,13 +25,15 @@ def get_db() -> Generator: db.close() -def get_current_user(token:str - ) -> schemas.UserBase: +# def get_current_user(token: str = Depends(reusable_oauth2) +# ) -> schemas.UserDBBase: +def get_current_user(token: str + ) -> schemas.UserDBBase: try: payload = jwt.decode( token, settings.SECRET_KEY, algorithms=[security.ALGORITHM] ) - user = schemas.UserBase(**payload) + user = schemas.UserDBBase(**payload) except (jwt.JWTError, ValidationError): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, @@ -58,3 +60,9 @@ def get_current_active_superuser( status_code=400, detail="The user doesn't have enough privileges" ) return current_user + + +def check_project(project_id: int, db: Session = Depends(get_db)): + if not crud.project.get(db, id=project_id): + raise HTTPException(status_code=404, detail="没有这个项目") + return project_id diff --git a/crud/__init__.py b/crud/__init__.py index fd75a0e..9cf2535 100644 --- a/crud/__init__.py +++ b/crud/__init__.py @@ -1,3 +1,7 @@ from .crud_user import user - - +from .curd_project import project +from .curd_kanban import kanban +from .curd_folder import folder +from .curd_dashboard import dashboard +from .curd_space import space +from .curd_authority import authority diff --git a/crud/curd_authority.py b/crud/curd_authority.py new file mode 100644 index 0000000..d600c5e --- /dev/null +++ b/crud/curd_authority.py @@ -0,0 +1,70 @@ +from typing import Any, Dict, Optional, Union + +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase +from models.authority import Authority +from schemas import AuthorityCreate, AuthorityUpdate + + +class CRUDAuthority(CRUDBase[Authority, AuthorityCreate, AuthorityUpdate]): + def create_with_authority( + self, db: Session, *, obj_in: AuthorityCreate, user_id: int + ) -> Authority: + obj_in_data = jsonable_encoder(obj_in) + db_obj = self.model(**obj_in_data, user_id=user_id) + db.add(db_obj) + db.commit() + db.refresh(db_obj) + return db_obj + + def get_my_dashboard(self, db: Session, project_id: int, user_id: int): + dashboards = db.query(Authority).filter(Authority.project_id == project_id, Authority.user_id == user_id).all() + res = {'kanban': dict(), 'space': dict()} + for item in dashboards: + # 是空间的 + dashboard = item.dashboard + folder = item.folder + space = item.space + if space: + s = res['space'].setdefault(space.id, {'dashboard': [], 'folder': {}}) + s['name'] = space.name + s['id'] = space.id + if folder: + f = s['folder'].setdefault(folder.id, {'dashboard': []}) + f['name'] = folder.name + f['id'] = folder.id + if dashboard: + f['dashboard'].append({ + 'name': dashboard.name, + 'id': dashboard.id + }) + elif dashboard: + d = s['dashboard'] + d.append({ + 'name': dashboard.name, + 'id': dashboard.id + }) + + else: + # 是看板的文件夹 + folder = item.folder + f = res['kanban'].setdefault(folder.id, {'dashboard': []}) + f['name'] = folder.name + f['id'] = folder.id + if dashboard: + f['dashboard'].append({ + 'name': dashboard.name, + 'id': dashboard.id + }) + return res + # return { + # 'kanban': list(res['kanban'].values()), + # 'space': list(res['space'].values()) + # } + + + + +authority = CRUDAuthority(Authority) diff --git a/crud/curd_dashboard.py b/crud/curd_dashboard.py new file mode 100644 index 0000000..387380f --- /dev/null +++ b/crud/curd_dashboard.py @@ -0,0 +1,28 @@ +from typing import Any, Dict, Optional, Union + +from fastapi import HTTPException +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase +from models.dashboard import Dashboard +from models.folders import Folder +from models.space import Space +from schemas import DashboardCreate, DashboardUpdate + + +class CRUDDashboard(CRUDBase[Dashboard, DashboardCreate, DashboardUpdate]): + def create_with_dashboard( + self, db: Session, *, obj_in: DashboardCreate, user_id: int + ) -> Dashboard: + obj_in_data = jsonable_encoder(obj_in) + db_obj = self.model(**obj_in_data, user_id=user_id) + db.add(db_obj) + db.commit() + db.refresh(db_obj) + return db_obj + + + + +dashboard = CRUDDashboard(Dashboard) diff --git a/crud/curd_folder.py b/crud/curd_folder.py new file mode 100644 index 0000000..3904859 --- /dev/null +++ b/crud/curd_folder.py @@ -0,0 +1,31 @@ +from typing import Any, Dict, Optional, Union + +from fastapi import HTTPException +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase +from models.folders import Folder +from models.kanban import KanBan +from models.space import Space +from schemas import FolderUpdate, FolderCreate + + +class CRUDFolder(CRUDBase[Folder, FolderCreate, FolderUpdate]): + def create_with_folder( + self, db: Session, *, obj_in: FolderCreate, user_id: int, project_id: int + ) -> Folder: + + if (not (obj_in.space_id and db.query(Space).get(obj_in.space_id))) ^ \ + (not (obj_in.kanban_id and db.query(KanBan).get(obj_in.kanban_id))): + obj_in_data = jsonable_encoder(obj_in) + db_obj = self.model(**obj_in_data, user_id=user_id, project_id=project_id) + db.add(db_obj) + db.commit() + db.refresh(db_obj) + return db_obj + else: + raise HTTPException(status_code=404, detail="找不到上级") + + +folder = CRUDFolder(Folder) diff --git a/crud/curd_kanban.py b/crud/curd_kanban.py new file mode 100644 index 0000000..4c038e4 --- /dev/null +++ b/crud/curd_kanban.py @@ -0,0 +1,15 @@ +from typing import Any, Dict, Optional, Union + +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase +from models.kanban import KanBan +from schemas import KanBanUpdate,KanBanCreate + + +class CRUDKanBan(CRUDBase[KanBan, KanBanCreate, KanBanUpdate]): + pass + + +kanban = CRUDKanBan(KanBan) diff --git a/crud/curd_project.py b/crud/curd_project.py new file mode 100644 index 0000000..a69450a --- /dev/null +++ b/crud/curd_project.py @@ -0,0 +1,27 @@ +from typing import Any, Dict, Optional, Union + +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase + +from models.project import Project + +from schemas.project import ProjectCreate, ProjectUpdate + + +class CRUDProject(CRUDBase[Project, ProjectCreate, ProjectUpdate]): + def create_with_project( + self, db: Session, *, obj_in: ProjectCreate, user_id: int + ) -> Project: + obj_in_data = jsonable_encoder(obj_in) + db_obj = self.model(**obj_in_data, user_id=user_id) + db.add(db_obj) + db.commit() + db.refresh(db_obj) + return db_obj + + + + +project = CRUDProject(Project) diff --git a/crud/curd_space.py b/crud/curd_space.py new file mode 100644 index 0000000..e104bae --- /dev/null +++ b/crud/curd_space.py @@ -0,0 +1,23 @@ +from typing import Any, Dict, Optional, Union + +from fastapi.encoders import jsonable_encoder +from sqlalchemy.orm import Session + +from crud.base import CRUDBase +from models.space import Space +from schemas import SpaceCreate, SpaceUpdate + + +class CRUDSpace(CRUDBase[Space, SpaceCreate, SpaceUpdate]): + def create_with_space( + self, db: Session, *, obj_in: SpaceCreate, user_id: int, project_id: int + ) -> Space: + obj_in_data = jsonable_encoder(obj_in) + db_obj = self.model(**obj_in_data, user_id=user_id, project_id=project_id) + db.add(db_obj) + db.commit() + db.refresh(db_obj) + return db_obj + + +space = CRUDSpace(Space) diff --git a/db/base.py b/db/base.py index e69de29..e8857cd 100644 --- a/db/base.py +++ b/db/base.py @@ -0,0 +1 @@ +from .base_class import Base # noqa \ No newline at end of file diff --git a/main.py b/main.py index a208b01..ea45f4b 100644 --- a/main.py +++ b/main.py @@ -13,23 +13,6 @@ app = FastAPI(title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/o allow_anonymous = [f'{settings.API_V1_STR}/{page}' for page in settings.ALLOW_ANONYMOUS] allow_anonymous.extend(['/docs']) - -@app.middleware("http") -async def add_jwt_auth(request: Request, call_next): - fail = {'code': -1, 'msg': '身份验证失败'} - if request.scope.get('path') not in allow_anonymous: - token = request.headers.get("Authorization") - try: - user = get_current_user(token) - except: - return JSONResponse(fail) - # - # request.state.user = user - - response = await call_next(request) - return response - - if settings.BACKEND_CORS_ORIGINS: app.add_middleware( CORSMiddleware, diff --git a/models/authority.py b/models/authority.py new file mode 100644 index 0000000..7f38338 --- /dev/null +++ b/models/authority.py @@ -0,0 +1,20 @@ +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime, Enum +from sqlalchemy.orm import relationship, backref + +from db.base_class import Base + + +class Authority(Base): + id = Column(Integer, primary_key=True, index=True) + user_id = Column(Integer, ForeignKey('user.id')) + project_id = Column(Integer, ForeignKey('project.id')) + dashboard_id = Column(Integer, ForeignKey('dashboard.id')) + folder_id = Column(Integer, ForeignKey('folder.id')) + space_id = Column(Integer, ForeignKey('space.id')) + authority = Column(Enum('rw', 'r')) + create_date = Column(DateTime, default=datetime.datetime.now()) + dashboard = relationship('Dashboard', backref="authority") + folder = relationship('Folder', backref="authority") + space = relationship('Space', backref="authority") diff --git a/models/dashboard.py b/models/dashboard.py index c9079d2..8e98d90 100644 --- a/models/dashboard.py +++ b/models/dashboard.py @@ -1,15 +1,21 @@ -from sqlalchemy import Boolean, Column, Integer, String, ForeignKey -from sqlalchemy.orm import relationship +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship, backref from db.base_class import Base class Dashboard(Base): id = Column(Integer, primary_key=True, index=True) - folder_type = Column(String) - pid = Column(Integer, ForeignKey('dashboard.id')) - parent = relationship('Dashboard', remote_side=[id]) - children = relationship('Dashboard', remote_side=[pid]) - name = Column(String, nullable=False) + name = Column(String) user_id = Column(Integer, ForeignKey('user.id')) - project_id = Column(Integer, ForeignKey('project.id')) + folder_id = Column(Integer, ForeignKey('folder.id')) + space_id = Column(Integer, ForeignKey('space.id')) + create_date = Column(DateTime, default=datetime.datetime.now()) + + folder = relationship('Folder', backref="dashboard") + space = relationship('Space', backref="dashboard") + + # authority = relationship('Authority', backref=backref("dashboard", lazy="joined")) + diff --git a/models/folders.py b/models/folders.py new file mode 100644 index 0000000..b84c764 --- /dev/null +++ b/models/folders.py @@ -0,0 +1,21 @@ +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship, backref + +from db.base_class import Base + + +class Folder(Base): + id = Column(Integer, primary_key=True, index=True) + name = Column(String) + user_id = Column(Integer, ForeignKey('user.id')) + kanban_id = Column(Integer, ForeignKey('kanban.id')) + project_id = Column(Integer, ForeignKey('project.id')) + space_id = Column(Integer, ForeignKey('space.id')) + create_date = Column(DateTime, default=datetime.datetime.now()) + + kanban = relationship('KanBan', backref='folder') + space = relationship('Space', backref='folder') + + # dashboard = relationship('Dashboard', backref=backref("folder", lazy="joined")) diff --git a/models/kanban.py b/models/kanban.py new file mode 100644 index 0000000..2067d36 --- /dev/null +++ b/models/kanban.py @@ -0,0 +1,18 @@ +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship, backref + +from db.base_class import Base + + +class KanBan(Base): + id = Column(Integer, primary_key=True, index=True) + project_id = Column(Integer, ForeignKey('project.id')) + user_id = Column(Integer, ForeignKey('user.id')) + create_date = Column(DateTime, default=datetime.datetime.now()) + + project = relationship('Project', backref='kanban') + + # folder = relationship('Folder', backref=backref("kanban", lazy="joined")) + diff --git a/models/project.py b/models/project.py index 1714f0d..bcd9e53 100644 --- a/models/project.py +++ b/models/project.py @@ -1,8 +1,15 @@ -from sqlalchemy import Boolean, Column, Integer, String, ForeignKey +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime from sqlalchemy.orm import relationship from db.base_class import Base -class Dashboard(Base): +class Project(Base): id = Column(Integer, primary_key=True, index=True) + game = Column(String, unique=True) + name = Column(String) + user_id = Column(Integer, ForeignKey('user.id')) + create_date = Column(DateTime, default=datetime.datetime.now()) + diff --git a/models/space.py b/models/space.py new file mode 100644 index 0000000..523ade0 --- /dev/null +++ b/models/space.py @@ -0,0 +1,21 @@ +import datetime + +from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime +from sqlalchemy.orm import relationship, backref + +from db.base_class import Base + + +class Space(Base): + id = Column(Integer, primary_key=True, index=True) + name = Column(String) + user_id = Column(Integer, ForeignKey('user.id')) + project_id = Column(Integer, ForeignKey('project.id')) + create_date = Column(DateTime, default=datetime.datetime.now()) + + project = relationship('Project', backref='space') + + # dashboard = relationship('Dashboard', backref=backref("space", lazy="joined")) + # folder = relationship('Folder', backref=backref("space", lazy="joined")) + + diff --git a/models/user.py b/models/user.py index 209f44d..6ac184b 100644 --- a/models/user.py +++ b/models/user.py @@ -10,4 +10,4 @@ class User(Base): hashed_password = Column(String, nullable=False) is_active = Column(Boolean(), default=True) is_superuser = Column(Boolean(), default=False) - dashboard = relationship('Dashboard', back_populates='user') + # dashboard = relationship('Dashboard', back_populates='user') diff --git a/schemas/__init__.py b/schemas/__init__.py index d8b73d6..d86320d 100644 --- a/schemas/__init__.py +++ b/schemas/__init__.py @@ -1,3 +1,10 @@ -from .user import User, UserCreate, UserInDB, UserUpdate,UserLogin,UserBase +from .user import User, UserCreate, UserInDB, UserUpdate, UserLogin, UserBase, UserDBBase from .token import Token, TokenPayload -from .msg import Msg \ No newline at end of file +from .msg import Msg + +from .project import ProjectCreate, Project +from .kanban import KanBanCreate, KanBanUpdate +from .folders import FolderCreate, FolderUpdate +from .dashboard import Dashboard,DashboardCreate, DashboardUpdate +from .space import SpaceCreate, SpaceUpdate +from .authority import AuthorityCreate, AuthorityUpdate diff --git a/schemas/authority.py b/schemas/authority.py new file mode 100644 index 0000000..e035fac --- /dev/null +++ b/schemas/authority.py @@ -0,0 +1,38 @@ +from datetime import datetime +from enum import Enum +from pydantic import BaseModel + + +class AuthorityBase(BaseModel): + project_id: int = None + dashboard_id: int = None + authority: str = None + space_id: str = None + folder_id: str = None + + +class AuthorityCreate(AuthorityBase): + project_id: int + authority: str + + + +class AuthorityUpdate(AuthorityBase): + pass + + +class AuthorityEnum(str, Enum): + write = 'rw' + read = 'r' + + +class Authority(AuthorityBase): + id = int + user_id = int + project_id = int + dashboard_id = int + authority = AuthorityEnum + create_date = datetime + + class Config: + orm_mode = True diff --git a/schemas/dashboard.py b/schemas/dashboard.py new file mode 100644 index 0000000..bd6b4bd --- /dev/null +++ b/schemas/dashboard.py @@ -0,0 +1,35 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel, root_validator, Field + + +class DashboardBase(BaseModel): + name: str = None + folder_id: int = None + space_id: int = None + + +class DashboardCreate(DashboardBase): + name: str + + # @root_validator(pre=True) + # def check_parent(cls, values): + # if (values.get('folder_id') is None) ^ (values.get('space_id') is None): + # return values + # else: + # raise ValueError('看板必须有一个上级') + + +class DashboardUpdate(DashboardBase): + pass + + +class Dashboard(DashboardBase): + name: str=None + user_id: int=None + folder_id: int=None + space_id: int=None + + class Config: + orm_mode = True diff --git a/schemas/folders.py b/schemas/folders.py new file mode 100644 index 0000000..04e9b98 --- /dev/null +++ b/schemas/folders.py @@ -0,0 +1,36 @@ +from datetime import datetime + +from pydantic import BaseModel, root_validator + + +class FolderBase(BaseModel): + kanban_id: int = None + name: str = None + space_id: int = None + + +class FolderCreate(FolderBase): + name: str + + @root_validator(pre=True) + def check_parent(cls, values): + if (values.get('kanban_id') is None) ^ (values.get('space_id') is None): + return values + else: + raise ValueError('必须只有一个上级') + + +class FolderUpdate(FolderBase): + pass + + +class Folder(FolderBase): + id: int + name: str + kanban_id: str + user_id: int + project_id: int + create_date: datetime + + class Config: + orm_mode = True diff --git a/schemas/kanban.py b/schemas/kanban.py new file mode 100644 index 0000000..743c550 --- /dev/null +++ b/schemas/kanban.py @@ -0,0 +1,28 @@ +from datetime import datetime + +from pydantic import BaseModel + + +class KanBanBase(BaseModel): + project_id: int = None + user_id: int = None + + + +class KanBanCreate(KanBanBase): + pass + + +class KanBanUpdate(KanBanBase): + pass + + +class KanBan(KanBanBase): + id: int + game: str + name: str + user_id: int + create_date: datetime + + class Config: + orm_mode = True diff --git a/schemas/project.py b/schemas/project.py new file mode 100644 index 0000000..16107e8 --- /dev/null +++ b/schemas/project.py @@ -0,0 +1,29 @@ +from datetime import datetime + +from pydantic import BaseModel + + +# 创建项目请求 +class ProjectBase(BaseModel): + game: str = None + name: str = None + + +class ProjectCreate(ProjectBase): + game: str + name: str + + +class ProjectUpdate(ProjectBase): + pass + + +class Project(ProjectBase): + id: int + game: str + name: str + user_id: int + create_date: datetime + + class Config: + orm_mode = True diff --git a/schemas/space.py b/schemas/space.py new file mode 100644 index 0000000..6950547 --- /dev/null +++ b/schemas/space.py @@ -0,0 +1,26 @@ +from datetime import datetime + +from pydantic import BaseModel + + +class SpaceBase(BaseModel): + name: str = None + + +class SpaceCreate(SpaceBase): + name: str + + +class SpaceUpdate(SpaceBase): + pass + + +class Space(SpaceBase): + id: int + name: str + user_id: int + project_id: int + create_date: datetime + + class Config: + orm_mode = True diff --git a/schemas/user.py b/schemas/user.py index 7a28596..d65988e 100644 --- a/schemas/user.py +++ b/schemas/user.py @@ -27,7 +27,7 @@ class UserUpdate(UserBase): password: Optional[str] = None -class UserInDBBase(UserBase): +class UserDBBase(UserBase): id: Optional[int] = None class Config: @@ -35,10 +35,10 @@ class UserInDBBase(UserBase): # Additional properties to return via API -class User(UserInDBBase): +class User(UserDBBase): pass # Additional properties stored in DB -class UserInDB(UserInDBBase): +class UserInDB(UserDBBase): hashed_password: str