feat: 初始化工程
This commit is contained in:
42
service/crop_service.py
Normal file
42
service/crop_service.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.patch import Crops, Records
|
||||
from schemas.patch import CropCreate, CropUpdate
|
||||
|
||||
|
||||
def create_crop(db: Session, data: CropCreate) -> bool:
|
||||
crop = Crops(**data.model_dump())
|
||||
db.add(crop)
|
||||
db.commit()
|
||||
db.refresh(crop)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_crop(db: Session, crop_id: int, data: CropUpdate) -> bool:
|
||||
result = db.execute(select(Crops).where(Crops.id == crop_id))
|
||||
crop = result.scalar_one_or_none()
|
||||
if not crop:
|
||||
return False
|
||||
|
||||
for k, v in data.model_dump(exclude_unset=True).items():
|
||||
setattr(crop, k, v)
|
||||
db.commit()
|
||||
db.refresh(crop)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def delete_crop(db: Session, crop_id: int) -> bool:
|
||||
result = db.execute(select(Crops).where(Crops.id == crop_id))
|
||||
crop = result.scalar_one_or_none()
|
||||
if not crop:
|
||||
return False
|
||||
|
||||
db.execute(delete(Records).where(Records.crop_id == crop_id))
|
||||
|
||||
db.delete(crop)
|
||||
db.commit()
|
||||
|
||||
return True
|
||||
50
service/file_service.py
Normal file
50
service/file_service.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import uuid
|
||||
|
||||
from fastapi import UploadFile, File, HTTPException
|
||||
|
||||
from config.rustfs import s3
|
||||
|
||||
ALLOWED_IMAGE_TYPES = [
|
||||
# 图片
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/gif",
|
||||
"image/webp",
|
||||
"image/svg+xml",
|
||||
# 视频
|
||||
"video/mp4",
|
||||
"video/mpeg",
|
||||
"video/quicktime",
|
||||
"video/x-msvideo",
|
||||
"video/webm",
|
||||
"video/x-matroska",
|
||||
"video/ogg",
|
||||
]
|
||||
|
||||
BUCKET = 'patch'
|
||||
NGINX_PROXY = 'rustfs'
|
||||
|
||||
|
||||
async def upload_file(file: UploadFile = File(...)) -> str:
|
||||
# 校验文件类型
|
||||
if file.content_type not in ALLOWED_IMAGE_TYPES:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="只允许上传图片或视频文件 (JPEG, PNG, GIF, WEBP, SVG, MP4, MOV, AVI, WEBM, MKV, OGV)"
|
||||
)
|
||||
|
||||
file_ext = file.filename.split('.')[-1]
|
||||
unique_filename = f"{uuid.uuid4().hex}.{file_ext}"
|
||||
|
||||
file_content = await file.read()
|
||||
|
||||
# 上传到S3
|
||||
s3.put_object(
|
||||
Bucket=BUCKET,
|
||||
Key=unique_filename,
|
||||
Body=file_content,
|
||||
ContentType=file.content_type
|
||||
)
|
||||
|
||||
# 返回文件url
|
||||
return f"{NGINX_PROXY}/{BUCKET}/{unique_filename}"
|
||||
79
service/patch_service.py
Normal file
79
service/patch_service.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.orm import Session, selectinload
|
||||
|
||||
from models.patch import Patches, Crops, Records
|
||||
from schemas.patch import PatchCreate, PatchUpdate, PatchResponse, CropResponse
|
||||
|
||||
|
||||
def create_patch(db: Session, data: PatchCreate) -> bool:
|
||||
patch = Patches(**data.model_dump())
|
||||
db.add(patch)
|
||||
db.commit()
|
||||
db.refresh(patch)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_patches(db: Session) -> list[PatchResponse]:
|
||||
patches = db.execute(select(Patches)).scalars().all()
|
||||
result = []
|
||||
for p in patches:
|
||||
crop = db.execute(
|
||||
select(Crops).where(Crops.patch_id == p.id)
|
||||
).scalar_one_or_none()
|
||||
data = PatchResponse.model_validate(p)
|
||||
data.crop = CropResponse.from_orm(crop) if crop else None
|
||||
result.append(data)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_patch(db: Session, patch_id: int) -> PatchResponse | None:
|
||||
patch = db.execute(
|
||||
select(Patches).where(Patches.id == patch_id)
|
||||
).scalar_one_or_none()
|
||||
if not patch:
|
||||
return None
|
||||
crop = db.execute(
|
||||
select(Crops).where(Crops.patch_id == patch_id)
|
||||
).scalar_one_or_none()
|
||||
data = PatchResponse.model_validate(patch)
|
||||
data.crop = CropResponse.from_orm(crop) if crop else None
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def update_patch(db: Session, patch_id: int, data: PatchUpdate) -> bool:
|
||||
result = db.execute(select(Patches).where(Patches.id == patch_id))
|
||||
patch = result.scalar_one_or_none()
|
||||
if not patch:
|
||||
return False
|
||||
|
||||
for k, v in data.model_dump(exclude_unset=True).items():
|
||||
setattr(patch, k, v)
|
||||
db.commit()
|
||||
db.refresh(patch)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def delete_patch(db: Session, patch_id: int) -> bool:
|
||||
result = db.execute(select(Patches).where(Patches.id == patch_id))
|
||||
patch = result.scalar_one_or_none()
|
||||
if not patch:
|
||||
return False
|
||||
|
||||
# 先查作物
|
||||
crop_result = db.execute(select(Crops).where(Crops.patch_id == patch_id))
|
||||
crop = crop_result.scalar_one_or_none()
|
||||
|
||||
# 有作物就先删记录,再删作物
|
||||
if crop:
|
||||
db.execute(delete(Records).where(Records.crop_id == crop.id))
|
||||
db.delete(crop)
|
||||
|
||||
# 最后删菜地
|
||||
db.delete(patch)
|
||||
db.commit()
|
||||
|
||||
return True
|
||||
55
service/record_service.py
Normal file
55
service/record_service.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.patch import Records
|
||||
from schemas.patch import RecordCreate, RecordResponse, RecordUpdate
|
||||
|
||||
|
||||
def create_record(db: Session, data: RecordCreate) -> bool:
|
||||
record = Records(**data.model_dump())
|
||||
db.add(record)
|
||||
db.commit()
|
||||
db.refresh(record)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_record(db: Session, record_id: int) -> RecordResponse | None:
|
||||
result = db.execute(select(Records).where(Records.id == record_id))
|
||||
record = result.scalar_one_or_none()
|
||||
|
||||
return RecordResponse.from_orm(record) if record else None
|
||||
|
||||
|
||||
def get_records_by_crop(db: Session, crop_id: int) -> list[RecordResponse]:
|
||||
result = db.execute(
|
||||
select(Records)
|
||||
.where(Records.crop_id == crop_id)
|
||||
.order_by(Records.date.desc())
|
||||
)
|
||||
return [RecordResponse.from_orm(r) for r in result.scalars().all()]
|
||||
|
||||
|
||||
def update_record(db: Session, record_id: int, data: RecordUpdate) -> bool:
|
||||
result = db.execute(select(Records).where(Records.id == record_id))
|
||||
record = result.scalar_one_or_none()
|
||||
if not record:
|
||||
return False
|
||||
|
||||
for k, v in data.model_dump(exclude_unset=True).items():
|
||||
setattr(record, k, v)
|
||||
db.commit()
|
||||
db.refresh(record)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def delete_record(db: Session, record_id: int) -> bool:
|
||||
result = db.execute(select(Records).where(Records.id == record_id))
|
||||
record = result.scalar_one_or_none()
|
||||
if record:
|
||||
db.delete(record)
|
||||
db.commit()
|
||||
return True
|
||||
|
||||
return False
|
||||
Reference in New Issue
Block a user