feat(valuation): 添加datetime序列化支持并优化统计查询

为valuation模型添加json_encoders以支持datetime序列化
使用annotate替代原始SQL进行统计查询计数
在API响应中使用model_dump_json确保datetime正确序列化
This commit is contained in:
邹方成 2025-10-02 12:25:19 +08:00
parent cf95553adc
commit 3aa806ea6b
4 changed files with 28 additions and 12 deletions

View File

@ -28,7 +28,10 @@ async def create_valuation(
user_id=user_id, user_id=user_id,
data=data data=data
) )
return Success(data=result, msg="估值评估申请提交成功") # 使用model_dump_json()来正确序列化datetime然后解析为dict
import json
result_dict = json.loads(result.model_dump_json())
return Success(data=result_dict, msg="估值评估申请提交成功")
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@ -49,8 +52,11 @@ async def get_my_valuations(
user_id=user_id, user_id=user_id,
query=query query=query
) )
# 使用model_dump_json()来正确序列化datetime然后解析为dict列表
import json
serialized_items = [json.loads(item.model_dump_json()) for item in result.items]
return SuccessExtra( return SuccessExtra(
data=result.items, data=serialized_items,
total=result.total, total=result.total,
page=result.page, page=result.page,
size=result.size, size=result.size,
@ -84,7 +90,10 @@ async def get_valuation_detail(
detail="估值评估记录不存在" detail="估值评估记录不存在"
) )
return Success(data=result, msg="获取估值评估详情成功") # 使用model_dump_json()来正确序列化datetime然后解析为dict
import json
result_dict = json.loads(result.model_dump_json())
return Success(data=result_dict, msg="获取估值评估详情成功")
except HTTPException: except HTTPException:
raise raise
except Exception as e: except Exception as e:

View File

@ -27,6 +27,13 @@ async def create_valuation(data: ValuationAssessmentCreate):
raise HTTPException(status_code=400, detail=f"创建失败: {str(e)}") raise HTTPException(status_code=400, detail=f"创建失败: {str(e)}")
@valuations_router.get("/statistics/overview", summary="获取统计信息")
async def get_statistics():
"""获取估值评估统计信息"""
result = await valuation_controller.get_statistics()
return Success(data=result, msg="获取统计信息成功")
@valuations_router.get("/{valuation_id}", summary="获取估值评估详情") @valuations_router.get("/{valuation_id}", summary="获取估值评估详情")
async def get_valuation(valuation_id: int): async def get_valuation(valuation_id: int):
"""根据ID获取估值评估详情""" """根据ID获取估值评估详情"""
@ -105,13 +112,6 @@ async def search_valuations(
) )
@valuations_router.get("/statistics/overview", summary="获取统计信息")
async def get_statistics():
"""获取估值评估统计信息"""
result = await valuation_controller.get_statistics()
return Success(data=result, msg="获取统计信息成功")
# 批量操作接口 # 批量操作接口
@valuations_router.post("/batch/delete", summary="批量删除估值评估") @valuations_router.post("/batch/delete", summary="批量删除估值评估")
async def batch_delete_valuations(valuation_ids: list[int]): async def batch_delete_valuations(valuation_ids: list[int]):

View File

@ -1,6 +1,7 @@
from typing import List, Optional from typing import List, Optional
from tortoise.expressions import Q from tortoise.expressions import Q
from tortoise.queryset import QuerySet from tortoise.queryset import QuerySet
from tortoise.functions import Count
from app.models.valuation import ValuationAssessment from app.models.valuation import ValuationAssessment
from app.schemas.valuation import ( from app.schemas.valuation import (
@ -107,13 +108,13 @@ class ValuationController:
total_count = await self.model.filter(is_active=True).count() total_count = await self.model.filter(is_active=True).count()
# 按行业统计 # 按行业统计
industry_stats = await self.model.filter(is_active=True).group_by('industry').values('industry', count='COUNT(*)') industry_stats = await self.model.filter(is_active=True).group_by('industry').annotate(count=Count('id')).values('industry', 'count')
# 按非遗等级统计 # 按非遗等级统计
heritage_level_stats = await self.model.filter( heritage_level_stats = await self.model.filter(
is_active=True, is_active=True,
heritage_level__isnull=False heritage_level__isnull=False
).group_by('heritage_level').values('heritage_level', count='COUNT(*)') ).group_by('heritage_level').annotate(count=Count('id')).values('heritage_level', 'count')
return { return {
'total_count': total_count, 'total_count': total_count,

View File

@ -121,6 +121,9 @@ class UserValuationOut(BaseModel):
class Config: class Config:
from_attributes = True from_attributes = True
json_encoders = {
datetime: lambda v: v.isoformat()
}
class UserValuationDetail(ValuationAssessmentBase): class UserValuationDetail(ValuationAssessmentBase):
@ -133,6 +136,9 @@ class UserValuationDetail(ValuationAssessmentBase):
class Config: class Config:
from_attributes = True from_attributes = True
json_encoders = {
datetime: lambda v: v.isoformat()
}
class UserValuationList(BaseModel): class UserValuationList(BaseModel):