feat: 拆分project model与project service

This commit is contained in:
martsforever
2025-08-24 02:18:27 +08:00
parent 4fc252be38
commit 7a30b179e8
3 changed files with 89 additions and 13 deletions
+24 -12
View File
@@ -1,12 +1,11 @@
from decimal import Decimal
from typing import Optional
from pydantic import computed_field
from sqlalchemy.orm import selectinload
from sqlmodel import Field, Relationship, select
from pydantic import computed_field, PrivateAttr
from sqlmodel import Field, Relationship
from app.model.BasicModel import BasicModel
from app.model.UserModel import UserServiceModel
from app.utils.create_module_service import create_model_service
class ProjectModel(BasicModel, table=True):
@@ -17,6 +16,27 @@ class ProjectModel(BasicModel, table=True):
budget: float = Field(default=None, description="项目预算金额")
version: int = Field(default=None, description="项目版本号")
# 使用 PrivateAttr 声明私有属性
_spent: Optional[Decimal] = PrivateAttr(default=None)
_balance: Optional[Decimal] = PrivateAttr(default=None)
# 属性访问器
@property
def spent(self) -> Optional[Decimal]:
return self._spent
@spent.setter
def spent(self, value: Optional[Decimal]) -> None:
self._spent = value
@property
def balance(self) -> Optional[Decimal]:
return self._balance
@balance.setter
def balance(self, value: Optional[Decimal]) -> None:
self._balance = value
# /*---------------------------------------leader_id-------------------------------------------*/
leader_id: str = Field(
@@ -42,11 +62,3 @@ class ProjectModel(BasicModel, table=True):
@leader_name.setter
def leader_name(self, value: Optional[str]) -> None:
pass
ProjectService = create_model_service(
Cls=ProjectModel,
custom_query=lambda: select(ProjectModel).options(
selectinload(ProjectModel.leader),
),
)
+64
View File
@@ -0,0 +1,64 @@
from decimal import Decimal
from typing import List
from sqlalchemy.orm import selectinload
from sqlmodel import select
from app.model.ApproveModel import ApproveService, ApproveModel
from app.model.ProjectModel import ProjectModel
from app.utils.create_module_service import create_model_service
from app.utils.db_utils import AsyncSessionDep
ProjectService = create_model_service(
Cls=ProjectModel,
custom_query=lambda: select(ProjectModel).options(
selectinload(ProjectModel.leader),
),
after_query_list=lambda query_cls_list, has_next, query_param, session: set_list_spent(query_cls_list, session),
after_query_item=lambda item_cls, row_dict, session: set_item_spent(item_cls, session),
after_insert=lambda insert_cls, row_dict, session: set_item_spent(insert_cls, session),
after_update=lambda update_cls, row_dict, session: set_item_spent(update_cls, session),
after_batch_insert=lambda refresh_cls_list, row_dict_list, session: set_list_spent(refresh_cls_list, session),
after_batch_update=lambda refresh_cls_list, row_dict_list, session: set_list_spent(refresh_cls_list, session),
)
async def set_list_spent(cls_list: List[ProjectModel], session: AsyncSessionDep):
project_dict_list, project_dict_map = await query_proj_spent([item.id for item in cls_list], session)
for item in cls_list:
target = project_dict_map.get(item.id, None)
if target:
item.spent = target['spent']
item.balance = target['balance']
for item in cls_list:
print("==============>>>>>>>>>>>>")
print(item.id, item.spent, item.balance)
dict_val = item.model_dump()
print(dict_val.get('spent'), dict_val.get('balance'))
async def set_item_spent(cls: ProjectModel, session: AsyncSessionDep):
project_dict_list, project_dict_map = await query_proj_spent([cls.id], session)
target = project_dict_map.get(cls.id, None)
if target:
cls.spent = target['spent']
cls.balance = target['balance']
async def query_proj_spent(proj_id_list: List[str], session: AsyncSessionDep):
result = {item: Decimal(0) for item in proj_id_list}
approve_cls_list = (await session.execute(ApproveService.select_cls().where(ApproveModel.proj_id.in_(proj_id_list)))).scalars().all()
for approve_item in approve_cls_list:
if approve_item.status == 'approved':
result[approve_item.proj_id] += Decimal(approve_item.amount)
project_cls_list = (await session.execute(ProjectService.select_cls().where(ProjectModel.id.in_(proj_id_list)))).scalars().all()
project_dict_list = [item.model_dump() for item in project_cls_list]
for dict_item in project_dict_list:
# 已花费金额
dict_item['spent'] = result[dict_item['id']]
# 剩余金额
dict_item['balance'] = Decimal(dict_item['budget']) - Decimal(dict_item['spent'])
project_dict_map = {item['id']: item for item in project_dict_list}
return project_dict_list, project_dict_map
+1 -1
View File
@@ -27,7 +27,7 @@ from app.model.LlmOrder import LlmOrderService
from app.model.LlmProduct import LlmProductService
from app.model.OrgModel import OrgService
from app.model.PosModel import PosService
from app.model.ProjectModel import ProjectService
from app.model.ProjectService import ProjectService
from app.model.ReimburseModel import ReimburseService
from app.model.ReimburseOtherModel import ReimburseOtherService
from app.model.ReimburseTravelModel import ReimburseTravelService