v1.2.71 - Stats接口性能优化:改用数据库聚合查询替代全量加载

This commit is contained in:
socool 2026-04-08 21:07:23 +08:00
parent 36f617266d
commit 7cbc7a371e
5 changed files with 124 additions and 61 deletions

View File

@ -1 +1 @@
1.2.70 VERSION=1.2.71

View File

@ -1 +1 @@
1.2.70 1.2.71

View File

@ -276,68 +276,132 @@ def get_stats(
current_user: User = Depends(get_current_user), current_user: User = Depends(get_current_user),
db: Session = Depends(get_db) db: Session = Depends(get_db)
): ):
"""获取藏品统计""" """获取藏品统计 - 使用数据库聚合查询优化性能"""
# 获取所有藏品 from sqlalchemy import case, func
if current_user.role == "admin": from sqlalchemy.sql import expression
all_collections = db.query(Collection).all()
else:
all_collections = db.query(Collection).filter(
Collection.f99_91_user_id == current_user.f99_90_id
).all()
# 总数 # 基础过滤条件
total_count = len(all_collections) if current_user.role == "admin":
base_filter = True
else:
base_filter = Collection.f99_91_user_id == current_user.f99_90_id
# 总数 - 使用 COUNT
total_count = db.query(func.count(Collection.f99_90_id)).filter(base_filter).scalar() or 0
# 按分类统计 # 按分类统计
from collections import Counter by_category = db.query(
by_category = Counter(c.f01_03_category for c in all_collections).items() Collection.f01_03_category,
func.count(Collection.f99_90_id)
).filter(base_filter).group_by(Collection.f01_03_category).all()
# 按状态统计 # 按状态统计
by_status = Counter(c.f01_04_status for c in all_collections).items() by_status = db.query(
Collection.f01_04_status,
func.count(Collection.f99_90_id)
).filter(base_filter).group_by(Collection.f01_04_status).all()
# 按是否评级统计 # 按是否评级统计
by_graded = Counter(c.f03_20_is_graded for c in all_collections).items() by_graded = db.query(
Collection.f03_20_is_graded,
func.count(Collection.f99_90_id)
).filter(base_filter).group_by(Collection.f03_20_is_graded).all()
# 新增8 个分布统计 # 按包装统计
by_packaging = Counter(c.f02_12_packaging for c in all_collections if c.f02_12_packaging).items() by_packaging = db.query(
by_rarity = Counter(c.f02_13_rarity for c in all_collections if c.f02_13_rarity).items() Collection.f02_12_packaging,
by_version = Counter(c.f02_11_version for c in all_collections if c.f02_11_version).items() func.count(Collection.f99_90_id)
by_grading_company = Counter(c.f03_21_grading_company for c in all_collections if c.f03_20_is_graded and c.f03_21_grading_company).items() ).filter(base_filter, Collection.f02_12_packaging.isnot(None)).group_by(Collection.f02_12_packaging).all()
by_grading_score = Counter(c.f03_22_grading_score for c in all_collections if c.f03_20_is_graded and c.f03_22_grading_score).items()
by_special_mark = Counter(c.f04_30_special_mark for c in all_collections if c.f04_30_special_mark).items()
by_number_category = Counter(c.f02_14_number_category for c in all_collections if c.f02_14_number_category).items()
# 总成本: SUM(cost_price + repair_fee + grading_fee) for ALL collections # 按稀有度统计
total_cost = sum( by_rarity = db.query(
(c.f05_40_cost_price or 0) + (c.f05_43_repair_fee or 0) + (c.f05_44_grading_fee or 0) Collection.f02_13_rarity,
for c in all_collections func.count(Collection.f99_90_id)
) ).filter(base_filter, Collection.f02_13_rarity.isnot(None)).group_by(Collection.f02_13_rarity).all()
# 预期利润: SUM(target_price - cost_price) for collections with target_price > 0 # 按版本统计
expected_profit = sum( by_version = db.query(
(c.f05_41_target_price or 0) - (c.f05_40_cost_price or 0) Collection.f02_11_version,
for c in all_collections func.count(Collection.f99_90_id)
if c.f05_41_target_price and c.f05_41_target_price > 0 ).filter(base_filter, Collection.f02_11_version.isnot(None)).group_by(Collection.f02_11_version).all()
)
# 已售商品:状态为 sold 且出售价 > 0 # 按评级公司统计
sold_collections = [ by_grading_company = db.query(
c for c in all_collections Collection.f03_21_grading_company,
if c.f01_04_status == 'sold' and c.f05_42_goal_price and c.f05_42_goal_price > 0 func.count(Collection.f99_90_id)
] ).filter(base_filter, Collection.f03_20_is_graded == True, Collection.f03_21_grading_company.isnot(None)).group_by(Collection.f03_21_grading_company).all()
# 总收入SUM(出售价) for 已售商品(售价>0 # 按评级分数统计
total_revenue = sum( by_grading_score = db.query(
c.f05_42_goal_price or 0 Collection.f03_22_grading_score,
for c in sold_collections func.count(Collection.f99_90_id)
) ).filter(base_filter, Collection.f03_20_is_graded == True, Collection.f03_22_grading_score.isnot(None)).group_by(Collection.f03_22_grading_score).all()
# 总利润已实现利润SUM(出售价 - 成本价 - 修复费 - 评级费) for 已售商品 # 按特殊标记统计
# 单藏品总成本 = 成本价 + 修复费 + 评级费 by_special_mark = db.query(
total_profit = sum( Collection.f04_30_special_mark,
(c.f05_42_goal_price or 0) - (c.f05_40_cost_price or 0) - (c.f05_43_repair_fee or 0) - (c.f05_44_grading_fee or 0) func.count(Collection.f99_90_id)
for c in sold_collections ).filter(base_filter, Collection.f04_30_special_mark.isnot(None)).group_by(Collection.f04_30_special_mark).all()
)
# 按号码分类统计
by_number_category = db.query(
Collection.f02_14_number_category,
func.count(Collection.f99_90_id)
).filter(base_filter, Collection.f02_14_number_category.isnot(None)).group_by(Collection.f02_14_number_category).all()
# 财务统计 - 使用数据库 SUM
# 总成本 = SUM(cost_price + repair_fee + grading_fee)
cost_result = db.query(
func.coalesce(func.sum(
func.coalesce(Collection.f05_40_cost_price, 0) +
func.coalesce(Collection.f05_43_repair_fee, 0) +
func.coalesce(Collection.f05_44_grading_fee, 0)
), 0)
).filter(base_filter).scalar() or 0
# 预期利润 = SUM(target_price - cost_price) where target_price > 0
target_result = db.query(
func.coalesce(func.sum(
func.coalesce(Collection.f05_41_target_price, 0) -
func.coalesce(Collection.f05_40_cost_price, 0)
), 0)
).filter(base_filter, Collection.f05_41_target_price > 0).scalar() or 0
expected_profit = target_result
# 已售商品过滤条件
sold_filter = base_filter & (Collection.f01_04_status == 'sold') & (Collection.f05_42_goal_price > 0)
# 总收入
total_revenue = db.query(
func.coalesce(func.sum(Collection.f05_42_goal_price), 0)
).filter(sold_filter).scalar() or 0
# 总利润 = SUM(goal_price - cost_price - repair_fee - grading_fee)
total_profit = db.query(
func.coalesce(func.sum(
func.coalesce(Collection.f05_42_goal_price, 0) -
func.coalesce(Collection.f05_40_cost_price, 0) -
func.coalesce(Collection.f05_43_repair_fee, 0) -
func.coalesce(Collection.f05_44_grading_fee, 0)
), 0)
).filter(sold_filter).scalar() or 0
# 盈亏统计
profit_count = db.query(func.count(Collection.f99_90_id)).filter(
sold_filter,
Collection.f05_42_goal_price > Collection.f05_40_cost_price
).scalar() or 0
loss_count = db.query(func.count(Collection.f99_90_id)).filter(
sold_filter,
Collection.f05_42_goal_price <= Collection.f05_40_cost_price
).scalar() or 0
# 目标总价
total_target = db.query(
func.coalesce(func.sum(func.coalesce(Collection.f05_41_target_price, 0)), 0)
).filter(base_filter).scalar() or 0
return { return {
"totalCount": total_count, "totalCount": total_count,
@ -351,16 +415,15 @@ def get_stats(
"byGradingScore": [{"score": s, "count": n} for s, n in by_grading_score], "byGradingScore": [{"score": s, "count": n} for s, n in by_grading_score],
"bySpecialMark": [{"mark": m, "count": n} for m, n in by_special_mark], "bySpecialMark": [{"mark": m, "count": n} for m, n in by_special_mark],
"byNumberCategory": [{"numberCategory": n, "count": c} for n, c in by_number_category], "byNumberCategory": [{"numberCategory": n, "count": c} for n, c in by_number_category],
# 盈亏统计(只统计已售且有价格的藏品)
"byProfitLoss": [ "byProfitLoss": [
{"type": "profit", "label": "盈利", "count": sum(1 for c in sold_collections if c.f05_42_goal_price and c.f05_40_cost_price and c.f05_42_goal_price > c.f05_40_cost_price)}, {"type": "profit", "label": "盈利", "count": profit_count},
{"type": "loss", "label": "亏损", "count": sum(1 for c in sold_collections if c.f05_42_goal_price and c.f05_40_cost_price and c.f05_42_goal_price <= c.f05_40_cost_price)} {"type": "loss", "label": "亏损", "count": loss_count}
], ],
"totalCost": total_cost, "totalCost": float(cost_result),
"totalTarget": sum(c.f05_41_target_price or 0 for c in all_collections), "totalTarget": float(total_target),
"expectedProfit": expected_profit, "expectedProfit": float(expected_profit),
"totalRevenue": total_revenue, "totalRevenue": float(total_revenue),
"totalProfit": total_profit "totalProfit": float(total_profit)
} }

View File

@ -1 +1 @@
VERSION=1.2.70 VERSION=1.2.71

View File

@ -1,6 +1,6 @@
{ {
"name": "jiachenlong-frontend", "name": "jiachenlong-frontend",
"version": "1.2.70", "version": "1.2.71",
"private": true, "private": true,
"description": "甲辰藏品管理系统 - 移动端前端", "description": "甲辰藏品管理系统 - 移动端前端",
"scripts": { "scripts": {