新增小程序后端代码,包括数据库、路由、服务层等。
小程序前后端打通,包括登录、注册、绑定设备、查询绑定信息,修改小朋友名称等功能。
This commit is contained in:
BIN
mini-program/app/service/.DS_Store
vendored
Normal file
BIN
mini-program/app/service/.DS_Store
vendored
Normal file
Binary file not shown.
12
mini-program/app/service/__init__.py
Normal file
12
mini-program/app/service/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import get_db
|
||||
|
||||
|
||||
def get_db_session():
|
||||
db = next(get_db())
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
45
mini-program/app/service/binding.py
Normal file
45
mini-program/app/service/binding.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from collections.abc import Mapping
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from app.dao.binding import BindingDAO
|
||||
|
||||
|
||||
class BindingService:
|
||||
def __init__(self, db):
|
||||
self.dao = BindingDAO(db)
|
||||
|
||||
def start_bind(self, user_id: int, device_id: str, child_id: int) -> tuple[str, datetime]:
|
||||
bind_token = self.dao.start_bind(user_id, device_id, child_id)
|
||||
return bind_token, datetime.utcnow()
|
||||
|
||||
def confirm_bind(self, bind_token: str, user_id: int) -> Mapping:
|
||||
session = self.dao.get_session(bind_token, user_id)
|
||||
if not session:
|
||||
raise ValueError("Bind session not found")
|
||||
if datetime.utcnow() > session["expires_at"]:
|
||||
raise ValueError("Bind session expired")
|
||||
if session["status"] != 1:
|
||||
raise ValueError("Bind session already processed")
|
||||
|
||||
self.dao.confirm_bind(session["id"], session["device_id"], session["target_child_id"], user_id)
|
||||
return {"device_id": session["device_id"], "child_id": session["target_child_id"]}
|
||||
|
||||
def get_binding(self, device_id: str, user_id: int) -> Optional[Mapping]:
|
||||
return self.dao.get_by_device(device_id, user_id)
|
||||
|
||||
def get_current_binding(self, user_id: int) -> Optional[Mapping]:
|
||||
return self.dao.get_current_by_user(user_id)
|
||||
|
||||
def direct_bind(self, device_id: str, child_id: int, user_id: int) -> Mapping:
|
||||
self.dao.direct_bind(device_id, child_id, user_id)
|
||||
return {"device_id": device_id, "child_id": child_id}
|
||||
|
||||
def unbind(self, device_id: str, user_id: int) -> bool:
|
||||
return self.dao.unbind(device_id, user_id)
|
||||
|
||||
def list_history(self, device_id: str, limit: int = 20, cursor: datetime = None) -> tuple[list, bool]:
|
||||
rows = self.dao.list_history(device_id, limit, cursor)
|
||||
has_more = len(rows) > limit
|
||||
rows = rows[:limit]
|
||||
return rows, has_more
|
||||
42
mini-program/app/service/child.py
Normal file
42
mini-program/app/service/child.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from collections.abc import Mapping
|
||||
from datetime import date
|
||||
from typing import Optional
|
||||
|
||||
from app.dao.child import ChildDAO
|
||||
|
||||
|
||||
class ChildService:
|
||||
def __init__(self, db):
|
||||
self.dao = ChildDAO(db)
|
||||
|
||||
def create(
|
||||
self,
|
||||
user_id: int,
|
||||
child_name: str,
|
||||
child_gender: int = 2,
|
||||
child_birthday: Optional[date] = None,
|
||||
) -> Mapping:
|
||||
child_id = self.dao.create(user_id, child_name, child_gender, child_birthday)
|
||||
return self.dao.get_by_id(child_id)
|
||||
|
||||
def list_children(self, user_id: int, limit: int = 20, cursor: int = None) -> tuple[list, bool]:
|
||||
rows = self.dao.list_by_parent(user_id, limit, cursor)
|
||||
has_more = len(rows) > limit
|
||||
rows = rows[:limit]
|
||||
return rows, has_more
|
||||
|
||||
def get(self, child_id: int) -> Optional[Mapping]:
|
||||
return self.dao.get_by_id(child_id)
|
||||
|
||||
def update(
|
||||
self,
|
||||
child_id: int,
|
||||
user_id: int,
|
||||
child_name: Optional[str] = None,
|
||||
child_gender: Optional[int] = None,
|
||||
child_birthday: Optional[date] = None,
|
||||
) -> Mapping:
|
||||
if not self.dao.has_access(child_id, user_id):
|
||||
raise PermissionError("No access to this child")
|
||||
self.dao.update(child_id, child_name, child_gender, child_birthday)
|
||||
return self.dao.get_by_id(child_id)
|
||||
33
mini-program/app/service/parent.py
Normal file
33
mini-program/app/service/parent.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from collections.abc import Mapping
|
||||
from typing import Optional
|
||||
|
||||
from app.dao.parent import ParentDAO
|
||||
from app.service import get_db_session
|
||||
|
||||
|
||||
class ParentService:
|
||||
def __init__(self, db):
|
||||
self.dao = ParentDAO(db)
|
||||
|
||||
def create(
|
||||
self,
|
||||
openid: str,
|
||||
unionid: Optional[str] = None,
|
||||
nickname: Optional[str] = None,
|
||||
avatar_url: Optional[str] = None,
|
||||
) -> Mapping:
|
||||
user_id = self.dao.upsert(openid, unionid, nickname, avatar_url)
|
||||
return self.dao.get_by_id(user_id)
|
||||
|
||||
def get(self, user_id: int) -> Optional[Mapping]:
|
||||
return self.dao.get_by_id(user_id)
|
||||
|
||||
def update(
|
||||
self,
|
||||
user_id: int,
|
||||
nickname: Optional[str] = None,
|
||||
avatar_url: Optional[str] = None,
|
||||
phone: Optional[str] = None,
|
||||
) -> Mapping:
|
||||
self.dao.update(user_id, nickname, avatar_url, phone)
|
||||
return self.dao.get_by_id(user_id)
|
||||
Reference in New Issue
Block a user