Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨feature(toCheck): 添加送检功能 #18

Merged
merged 4 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions backend/app/api/v1/admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@
# @FileName :users.py
# @Time :2024/4/16 下午9:31
# @Author :dayezi
from typing import Union

from fastapi import APIRouter, Request, Query
from tortoise.expressions import Q, F

from app.controllers import user_controller
from app.controllers.checked import checkedController
from app.controllers.depart import departController
from app.controllers.dutyLog import dutyLogController, dutyNotesController
from app.models import Checked
from app.schemas.checked import ReturnChecked, CheckedCreate
from app.settings import settings
from app.core.init_db import test_db, set_db
from app.log import logger
from app.schemas import Success, Fail, SuccessExtra
from app.schemas.admin import DbInfo
from app.utils import now

router = APIRouter()

Expand Down Expand Up @@ -76,3 +84,68 @@ async def get_duty_note(id: int = Query(..., description="值班备注id")):
data = await dutyNotesController.get(id)
data = await data.to_dict()
return Success(data=data)


@router.get("/getChecked", summary="获取物资送检信息")
async def get_checked(
area: str = Query("glb", description="区域"),
metaType: str = Query("tool", description="工具类型"),
returnStatus: bool = Query(False, description="归还状态"),
page: int = Query(1, description="页码"),
pageSize: int = Query(10, description="每页数量"),
):
q = Q(area__contains=area) & Q(type__contains=metaType) & Q(returnStatus=returnStatus)
total, checked_objs = await checkedController.list(page=page, page_size=pageSize, search=q)
data = []
for obj in checked_objs:
user = await obj.toCheckUser.all()
userDepart = await departController.get_all_name(user)
material = await obj.material.all()
material_dict = await material.to_dict()
user_dict = await user.to_dict()
user_dict["depart"] = userDepart
obj_dict = await obj.to_dict()
obj_dict["material"] = material_dict
obj_dict["toCheckUser"] = user_dict
try:
user2 = await obj.toReturnUser.all()
user2Depart = await departController.get_all_name(user2)
user_dict2 = await user2.to_dict()
obj_dict["toReturnUser"] = user_dict2
user_dict2["depart"] = user2Depart
except Exception as e:
logger.warning(f"物资【{material.name}】暂无归还人信息:{e}")
data.append(obj_dict)
return SuccessExtra(data=data, total=total, currentPage=page, pageSize=pageSize)


@router.post("/updateChecked", summary="归还送检物资")
async def update_checked(data: ReturnChecked):
obj: Checked = await checkedController.get(id=data.id)
material = await obj.material.all()
material.checking -= obj.number
user = await user_controller.get_by_uuid(data.toReturnUserUUID)
obj.toReturnUser = user
obj.returnStatus = True
obj.note = data.note
obj.returnDate = now()
await obj.save()
return Success(msg="更新成功!")


@router.post("/createChecked", summary="创建物资送检信息")
async def create_checked(data: dict):
user = await user_controller.get_by_uuid(data.get("toCheckUserUUID"))
data["toCheckUser"] = user
obj: Checked = await checkedController.create(obj_in=data)
material = await obj.material.all()
material.checking += obj.number
await material.save()
return Success(data=await obj.to_dict(m2m=True))


@router.get("/deleteChecked", summary="删除物资送检信息")
async def delete_checked(data: list[int]):
for id in data:
await checkedController.remove(id)
return Success(msg="删除成功!")
15 changes: 14 additions & 1 deletion backend/app/api/v1/base/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,20 @@ async def refresh_token(refreshToken: refreshTokenSchema):
return Success(data=data.model_dump())


@router.get("/userinfo", summary="查看用户信息", dependencies=[DependAuth])
@router.post("/userinfo", summary="获取用户UUID")
async def get_user_id(credentials: CredentialsSchema):
user: User = await user_controller.authenticate(credentials)
depart = await departController.get_all_name(user)
data = {
"uuid": user.uuid.__str__(),
"username": user.username,
"phone": user.phone,
"depart": depart
}
return Success(data=data)


@router.get("/userinfos", summary="查看用户信息", dependencies=[DependAuth])
async def get_userinfo():
user_id = CTX_USER_ID.get()
user_obj = await user_controller.get(id=user_id)
Expand Down
13 changes: 7 additions & 6 deletions backend/app/api/v1/home/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ async def get_home_list(
area: str = Query("glb", description="区域"),
page: int = Query(1, description="页码"),
pageSize: int = Query(10, description="每页数量"),
borrowedStatus: bool = Query(False, description="借用批准状态"),
borrowedStatus: Union[bool, None] = Query(None, description="借用批准状态"),
borrowWhether: Union[bool, None] = Query(None, description="借用通过状态"),
returnStatus: Union[bool, None] = Query(None, description="归还批准状态")
):
if returnStatus is None:
q = Q(Q(material__area=area), Q(borrowApproveStatus=borrowedStatus))
else:
q = Q(Q(material__area=area), Q(borrowApproveWhether=borrowWhether), Q(returnApproveStatus=returnStatus))
q = Q(material__area=area)
if borrowedStatus is not None:
q &= Q(borrowApproveStatus=borrowedStatus)
if borrowWhether is not None:
q &= Q(Q(borrowApproveWhether=borrowWhether), Q(returnApproveStatus=returnStatus))
total, objs = await borrowedController.list(page=page, page_size=pageSize, search=q)
data = [await obj.to_dict(m2m=True, exclude_fields=["password"]) for obj in objs]
data = [await obj.to_dict(m2m=True) for obj in objs]
return SuccessExtra(data=data, total=total, currentPage=page, pageSize=pageSize)


Expand Down
15 changes: 15 additions & 0 deletions backend/app/controllers/checked.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# coding=utf-8
# @FileName :checked.py
# @Time :2024/6/20 下午10:29
# @Author :dayezi
from app.core.crud import CRUDBase
from app.models import Checked
from app.schemas.checked import CheckedCreate, CheckedUpdate


class CheckedController(CRUDBase[Checked, CheckedCreate, CheckedUpdate]):
def __init__(self):
super().__init__(model=Checked)


checkedController = CheckedController()
1 change: 1 addition & 0 deletions backend/app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from .borrowed import *
from .materialType import *
from .area import *
from .checked import *
2 changes: 2 additions & 0 deletions backend/app/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ async def to_dict(self, m2m: bool = False, exclude_fields: list[str] | None = No

d = {}
for field in self._meta.db_fields:
if field == "password":
continue
if field not in exclude_fields:
value = getattr(self, field)
if isinstance(value, datetime):
Expand Down
25 changes: 25 additions & 0 deletions backend/app/models/checked.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# coding=utf-8
# @FileName :checked.py
# @Time :2024/6/20 下午10:14
# @Author :dayezi
from tortoise import fields

from .base import BaseModel, TimestampMixin


class Checked(BaseModel, TimestampMixin):
area = fields.CharField(max_length=20, description="所属区域")
type = fields.CharField(max_length=20, description="物资类型")
material = fields.ForeignKeyField("models.Material", related_name="checked_material")
number = fields.IntField(description="送检数量")
toCheckUser = fields.ForeignKeyField('models.User', related_name='checked_user')
returnStatus = fields.BooleanField(default=False, description="归还状态")
returnDate = fields.DatetimeField(null=True, description="归还时间")
toReturnUser = fields.ForeignKeyField('models.User', related_name='return_user', null=True)
note = fields.CharField(max_length=200, null=True, description="备注")

class Meta:
table = "checked"

class PydanticMeta:
exclude = ("id", "created_at", "updated_at")
4 changes: 1 addition & 3 deletions backend/app/schemas/borrowed.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
# @FileName :borrowed.py
# @Time :2024/5/31 上午12:49
# @Author :dayezi
from typing import Union

from pydantic import BaseModel, Field
from pydantic import BaseModel
from tortoise.contrib.pydantic import pydantic_model_creator
from app.models.borrowed import Borrowed
from app.schemas.material import MaterialCreate
Expand Down
28 changes: 28 additions & 0 deletions backend/app/schemas/checked.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# coding=utf-8
# @FileName :checked.py
# @Time :2024/6/20 下午10:26
# @Author :dayezi
from pydantic import BaseModel
from tortoise.contrib.pydantic import pydantic_model_creator

from app.models import Checked

CheckedPydantic = pydantic_model_creator(Checked)


class CheckedCreate(CheckedPydantic):

def create_dict(self):
return self.model_dump(exclude={"id", "created_at", "updated_at"})


class CheckedUpdate(CheckedPydantic):

def update_dict(self):
return self.model_dump(exclude={"id", "created_at", "updated_at"})


class ReturnChecked(BaseModel):
id: int
note: str
toReturnUserUUID: str
1 change: 1 addition & 0 deletions backend/app/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def now(s: bool = True) -> str | datetime:
"""
获取当前时间,datatime格式或 xxxx-xx-xx xx:xx:xx 字符串格式

:param s: 是否返回格式化字符串
:return: 当前日期时间
"""
today = datetime.now()
Expand Down
30 changes: 30 additions & 0 deletions frontend/src/api/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,33 @@ export const getDutyNote = (id: number) => {
}
});
};

export const createCheckMaterial = (data: object) => {
return http.request<Result>("post", baseUrlApi("/admin/createChecked"), {
data
});
};

export const getCheckedMaterial = (
area: string,
metaType: string,
returnStatus: boolean,
page: number,
pageSize: number
) => {
return http.request<ResultTable>("get", baseUrlApi("/admin/getChecked"), {
params: {
area,
metaType,
returnStatus,
page,
pageSize
}
});
};

export const updateCheckedMaterial = (data: object) => {
return http.request<Result>("post", baseUrlApi("/admin/updateChecked"), {
data
});
};
6 changes: 6 additions & 0 deletions frontend/src/api/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ export const updateBorrowedInfo = (
data: { borrowStatus, uuid, idList, borrowWhether, returnStatus }
});
};

export const deleteBorrowed = (idList: number[]) => {
return http.request<Result>("post", baseUrlApi("/home/delete"), {
data: { idList }
});
};
46 changes: 9 additions & 37 deletions frontend/src/api/user.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,17 @@
import { http } from "@/utils/http";
import { baseUrlApi } from "./utils";

export type UserResult = {
code: number;
success: boolean;
msg: string;
data: {
/** 用户名 */
username: string;
/** uuid */
uuid: string;
/** 部门 */
depart: string;
/** 当前登陆用户的角色 */
roles: [string];
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */
expires: Date;
};
};

export type RefreshTokenResult = {
code: number;
success: boolean;
msg: string;
data: {
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */
expires: Date;
};
};
import type { RefreshTokenResult, LoginResult, UserResult } from "@/types/user";

/** 登录 */
export const getLogin = (data?: object) => {
return http.request<UserResult>("post", baseUrlApi("/base/accessToken"), {
return http.request<LoginResult>("post", baseUrlApi("/base/accessToken"), {
data
});
};

/** 获取用户信息 */
export const getUserInfo = (data?: object) => {
return http.request<UserResult>("post", baseUrlApi("/base/userinfo"), {
data
});
};
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/store/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { routerArrays } from "@/layout/types";
import { router, resetRouter } from "@/router";
import { storageLocal } from "@pureadmin/utils";
import { getLogin, refreshTokenApi } from "@/api/user";
import type { UserResult, RefreshTokenResult } from "@/api/user";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { type DataInfo, setToken, removeToken, userKey } from "@/utils/auth";
import type { RefreshTokenResult, LoginResult } from "@/types/user";

export const useUserStore = defineStore({
id: "pure-user",
Expand Down Expand Up @@ -51,7 +51,7 @@ export const useUserStore = defineStore({
},
/** 登入 */
async loginByUsername(data) {
return new Promise<UserResult>((resolve, reject) => {
return new Promise<LoginResult>((resolve, reject) => {
getLogin(data)
.then(data => {
if (data) {
Expand Down
Loading
Loading