11 Commits
10 changed files with 320 additions and 2 deletions
+18
View File
@@ -0,0 +1,18 @@
# Python 缓存
__pycache__/
*.pyc
*.pyo
*.pyd
# Python 虚拟环境
.venv/
venv/
env/
# IDE
.idea/
.vscode/
# 系统垃圾
.DS_Store
Thumbs.db
+5
View File
@@ -1,2 +1,7 @@
# test2222
test33
gesd
+63
View File
@@ -0,0 +1,63 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from core.database import get_db
from schemas.consultant import ConsultantCreate, ConsultantUpdate, ConsultantResponse
from dao import consultant as dao_consultant
router = APIRouter()
@router.get(
path="/consultants",
tags=['顾问管理模块'],summary='顾问模糊分页查询')
def read_consultants(
db: Session = Depends(get_db),
page:int=1,
page_size:int=20,
name:str|None=None,
phone:str|None=None
):
return dao_consultant.get_consultant_list(db, page, page_size, name, phone)
@router.post("/consultants", response_model=ConsultantResponse,tags=['顾问管理模块'],summary='顾问增加')
def create_consultant(
obj_in: ConsultantCreate,
db: Session = Depends(get_db)
):
return dao_consultant.create_consultant(db, obj_in)
@router.get("/consultants/{id}", response_model=ConsultantResponse,tags=['顾问管理模块'],summary='顾问查询')
def read_consultant(id: int, db: Session = Depends(get_db)):
res = dao_consultant.get_consultant_by_id(db, cid=id)
if res is None:
raise HTTPException(status_code=404, detail="顾问不存在或已删除")
return res
@router.put(
path="/consultants/{id}",
response_model=ConsultantResponse,
tags=['顾问管理模块'],summary='顾问更新')
def update_consultant(
id: int,
obj_in: ConsultantUpdate,
db: Session = Depends(get_db)
):
# model_dump 排除为None的字段,只更新前端传过来的字段
update_dict = obj_in.model_dump(exclude_none=True)
res = dao_consultant.update_consultant(db, cid=id, update_data=update_dict)
if res is None:
raise HTTPException(status_code=404, detail="顾问不存在或已删除")
return res
@router.delete("/consultants/{id}", response_model=ConsultantResponse,tags=['顾问管理模块'],summary='顾问删除')
def delete_consultant(id: int, db: Session = Depends(get_db)):
res = dao_consultant.delete_consultant(db, cid=id)
if res is None:
raise HTTPException(status_code=404, detail="顾问不存在或已删除")
return res
+7 -1
View File
@@ -9,10 +9,14 @@ IP:localhost
2.如果还没开始建库,建库时统一将名称命名为 student_manager。
如果已经建库或在 models 目录写好Base函数,那先别提交分支,不然合并的时候会出问题,后天合库的时候再说。
3.在 /models 目录下写数据库对应类时,不要自己写Base = declarative_base(),
直接 from core.database import Base ,否则会出现 Base 不一致的情况,导致数据库无法创建表。
'''
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import sessionmaker,declarative_base
from .config import (
database_connect_user,
database_connect_password,
@@ -31,3 +35,5 @@ def get_db():
yield db
finally:
db.close()
Base = declarative_base()
+82
View File
@@ -0,0 +1,82 @@
from models.consultant import Consultant
from schemas.consultant import ConsultantCreate, ConsultantUpdate
from sqlalchemy.orm import Session
def create_consultant(db:Session, obj_in: ConsultantCreate):
try:
db_obj = Consultant(**obj_in.model_dump())
db.add(db_obj)
except:
db.rollback()
return False
else:
db.commit()
return db_obj
# 查询全部可分页(过滤已删除)
def get_consultant_list(
db: Session,
page: int = 1,
page_size: int = 20,
name: str | None = None,
phone: str | None = None
):
page_size = max(1, min(page_size, 100))
skip = (page - 1) * page_size
query = db.query(Consultant).filter(Consultant.is_deleted == 0)
# 有传参数才追加过滤条件
if name:
query = query.filter(Consultant.consultant_name.like(f"%{name}%"))
if phone:
query = query.filter(Consultant.phone.like(f"%{phone}%"))
total = query.count()
items = query.offset(skip).limit(page_size).all()
return {
"items": items,
"total": total,
"page": page,
"page_size": page_size
}
# 根据id查单条
def get_consultant_by_id(db:Session, cid: int):
return db.query(Consultant).filter(Consultant.id == cid, Consultant.is_deleted == 0 ).first()
# 修改
def update_consultant(db: Session, cid: int, update_data: dict):
try:
db_obj = db.query(Consultant).filter(
Consultant.id == cid,
Consultant.is_deleted == 0
).first()
if not db_obj:
return None
# 循环赋值
for k, v in update_data.items():
setattr(db_obj, k, v)
db.commit()
db.refresh(db_obj) # 刷新从数据库拿最新数据(updated_at)
return db_obj
except Exception:
db.rollback()
return None
# 逻辑删除(只改is_deleted=1)
def delete_consultant(db:Session, cid: int):
try:
db_obj = get_consultant_by_id(db, cid)
if not db_obj:
return None
db_obj.is_deleted = 1
except:
db.rollback()
return None
else:
db.commit()
return db_obj
+2 -1
View File
@@ -12,7 +12,8 @@ app.middleware("http")(log_middleware)
#-------------张义---------------
#-------------薄鑫---------------
from api import consultant
app.include_router(consultant.router)
#-------------张昕浩---------------
app.include_router(example_router)
+50
View File
@@ -0,0 +1,50 @@
from sqlalchemy import *
from datetime import datetime,time,date
Base = declarative_base() # 执行函数,返回一个基类
class Classes( Base ): # 在python里的名字
__tablename__ = 'classes' # 在数据库中表的名字
#————创建班级"主键"的字段名————
id = Column( Integer # 声明字段的数据类型是"整数"
, primary_key = True # 声明是"主键"
, autoincrement = True # 声明是"自增主键"
, nullable = False # 声明是"非空"
)
# ————创建班级"编号"的字段名————
class_no = Column( String(50) # 声明字段的数据类型是"字符串,且最长为50个字符"
, unique = True # 声明是"唯一约束"
, nullable = False # 声明是"非空"
)
# ————创建"班级名称"的字段名————
class_name = Column( String(100) # 声明字段的数据类型是"字符串,且最长为100个字符"
, nullable = False # 声明是"非空"
)
# ————创建班级"开课时间"的字段名————
start_date = Column( DATE # 声明是字段数据类型是日期
, nullable = True # 声明是'可为空'
)
# ————创建班级"结课时间"的字段名————
end_date = Column( DATE # 声明是字段数据类型是'日期'
, nullable = True # 声明是"可为空"
)
# ————创建班级"创建时间"的字段名————
created_at = Column( DATETIME # 声明是字段数据类型是"日期时间"
, default=datetime.now # 声明是创建的默认值就是"当前时间"
, nullable = False # 声明是"非空"
)
# ————创建班级"更新时间"的字段名————
update_at = Column( DATETIME # 声明是字段数据类型是"日期时间"
, default=datetime.now #声明是第一次更新的时间就是第一次创建的时间一致
, onupdate=datetime.now # 声明"最后修改的时间"
, nullable = False # 声明是"非空"
)
# ————创建班级"备注信息"的字段名————
remark = Column( String(100) # 声明是字段数据类型是"字符串"
, nullable = True # 声明是"可以为空"
)
# ————创建班级"逻辑删除"的字段名————
is_deleted = Column( INTEGER # 声明是字段数据类型是"数字"
, default = 0 # 声明默认值是"0,未删除"
, nullable = False # 声明是"非空"
)
+17
View File
@@ -0,0 +1,17 @@
from sqlalchemy import *
from datetime import datetime
from core.database import Base
class Consultant(Base):
__tablename__ = "consultant_info_detail"
id = Column(Integer, primary_key=True, autoincrement=True, comment="主键")
consultant_no = Column(String(50), unique=True, nullable=False, comment="顾问编号")
consultant_name = Column(String(50), nullable=False, comment="顾问姓名")
phone = Column(String(20), nullable=True, comment="联系电话")
email = Column(String(100), nullable=True, comment="邮箱")
remark = Column(String(255), nullable=True, comment="备注")
created_at = Column(DateTime, default=datetime.now, nullable=False, comment="创建时间")
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now, nullable=False, comment="更新时间")
is_deleted = Column(Integer, default=0, nullable=False, comment="逻辑删除:0正常,1删除")
+33
View File
@@ -0,0 +1,33 @@
from pydantic import BaseModel
from datetime import datetime
from typing import Optional
# 新增顾问 请求体
class ConsultantCreate(BaseModel):
consultant_no: str
consultant_name: str
phone: Optional[str] = None
email: Optional[str] = None
remark: Optional[str] = None
# 修改顾问 请求体
class ConsultantUpdate(BaseModel):
consultant_name: Optional[str] = None
phone: Optional[str] = None
email: Optional[str] = None
remark: Optional[str] = None
# 返回模型
class ConsultantResponse(BaseModel):
id: int
consultant_no: str
consultant_name: str
phone: Optional[str]
email: Optional[str]
remark: Optional[str]
created_at: datetime
updated_at: datetime
+43
View File
@@ -0,0 +1,43 @@
'''
1. 参数说明:
field_name:业务编号字段名,例如 student_no
prefix:业务编号前缀,例如 STU
db_object:已实例化的 ORM 对象,例如 stu
db:当前接口中的数据库 Session
2. ORM 主键统一命名为 id。
业务编号字段按文档命名,例如 student_no、teacher_no、class_no。
3. 必须先执行 db.add(db_object),再调用 generate_no()。
4. 主键id一定要设置成自增。
dao模块示例代码:
def add_student(
result: CreateStudent,
db: Session
):
stu = Student(**result.model_dump())
db.add(stu)
generate_no("student_no", "STU", stu, db)
db.commit()
return stu
'''
def generate_no(field_name: str, prefix: str, db_object, db: Session):
if getattr(db_object, field_name):
return
db.flush()
record_no = f"{prefix}{db_object.id:04d}"
setattr(db_object, field_name, record_no)