v1.2.62 - 性能优化:Stats数据库聚合+编号并发锁+images映射
This commit is contained in:
parent
eb64ce3d8c
commit
3cf8079b33
|
|
@ -56,6 +56,7 @@ def to_camel_case(data: dict) -> dict:
|
|||
'f05_43_repair_fee': 'repairFee',
|
||||
'f05_44_grading_fee': 'gradingFee',
|
||||
'f06_50_purpose': 'purpose',
|
||||
'images': 'images',
|
||||
}
|
||||
|
||||
return {mapping.get(k, k): v for k, v in data.items()}
|
||||
|
|
@ -63,25 +64,30 @@ def to_camel_case(data: dict) -> dict:
|
|||
|
||||
# 编码生成函数
|
||||
def generate_code(version: str, user_id: str, db: Session) -> str:
|
||||
"""自动生成藏品编号 - 按用户独立编码"""
|
||||
"""自动生成藏品编号 - 按用户独立编码,使用行锁防止并发冲突"""
|
||||
import re
|
||||
from sqlalchemy import text
|
||||
|
||||
# 查询当前用户的非空编码(不与其他用户混算)
|
||||
user_codes = db.query(Collection.f01_02_code).filter(
|
||||
Collection.f01_02_code.isnot(None),
|
||||
Collection.f99_91_user_id == user_id
|
||||
).all()
|
||||
# 使用 FOR UPDATE 行锁防止并发冲突
|
||||
result = db.execute(
|
||||
text("""
|
||||
SELECT f01_02_code FROM collections
|
||||
WHERE f99_91_user_id = :user_id
|
||||
AND f01_02_code IS NOT NULL
|
||||
AND f01_02_code ~ '^\\d{4,5}$'
|
||||
ORDER BY f01_02_code::int DESC
|
||||
LIMIT 1
|
||||
FOR UPDATE
|
||||
"""),
|
||||
{"user_id": user_id}
|
||||
).fetchone()
|
||||
|
||||
max_num = 0
|
||||
for (code,) in user_codes:
|
||||
# 处理纯数字编码(支持4位和5位)
|
||||
if re.match(r'^\d{4,5}$', code):
|
||||
try:
|
||||
num = int(code)
|
||||
if num > max_num:
|
||||
max_num = num
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if result and result[0]:
|
||||
try:
|
||||
max_num = int(result[0])
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
# 当前用户最大号 +1
|
||||
next_num = max_num + 1
|
||||
|
|
@ -275,68 +281,107 @@ def get_stats(
|
|||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""获取藏品统计"""
|
||||
# 获取所有藏品
|
||||
if current_user.role == "admin":
|
||||
all_collections = db.query(Collection).all()
|
||||
else:
|
||||
all_collections = db.query(Collection).filter(
|
||||
Collection.f99_91_user_id == current_user.f99_90_id
|
||||
).all()
|
||||
"""获取藏品统计 - 使用数据库聚合查询优化性能"""
|
||||
from sqlalchemy import func, case
|
||||
|
||||
# 基础查询条件
|
||||
base_filter = True if current_user.role == "admin" else Collection.f99_91_user_id == current_user.f99_90_id
|
||||
|
||||
# 总数
|
||||
total_count = len(all_collections)
|
||||
total_count = db.query(func.count(Collection.f99_90_id)).filter(base_filter).scalar() or 0
|
||||
|
||||
# 按分类统计
|
||||
from collections import Counter
|
||||
by_category = Counter(c.f01_03_category for c in all_collections).items()
|
||||
by_category = db.query(
|
||||
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_rarity = Counter(c.f02_13_rarity for c in all_collections if c.f02_13_rarity).items()
|
||||
by_version = Counter(c.f02_11_version for c in all_collections if c.f02_11_version).items()
|
||||
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()
|
||||
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()
|
||||
# 按包装统计
|
||||
by_packaging = db.query(
|
||||
Collection.f02_12_packaging,
|
||||
func.count(Collection.f99_90_id)
|
||||
).filter(base_filter, Collection.f02_12_packaging.isnot(None)).group_by(Collection.f02_12_packaging).all()
|
||||
|
||||
# 总成本: SUM(cost_price + repair_fee + grading_fee) for ALL collections
|
||||
total_cost = sum(
|
||||
(c.f05_40_cost_price or 0) + (c.f05_43_repair_fee or 0) + (c.f05_44_grading_fee or 0)
|
||||
for c in all_collections
|
||||
)
|
||||
# 按稀有度统计
|
||||
by_rarity = db.query(
|
||||
Collection.f02_13_rarity,
|
||||
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(
|
||||
(c.f05_41_target_price or 0) - (c.f05_40_cost_price or 0)
|
||||
for c in all_collections
|
||||
if c.f05_41_target_price and c.f05_41_target_price > 0
|
||||
)
|
||||
# 按版本统计
|
||||
by_version = db.query(
|
||||
Collection.f02_11_version,
|
||||
func.count(Collection.f99_90_id)
|
||||
).filter(base_filter, Collection.f02_11_version.isnot(None)).group_by(Collection.f02_11_version).all()
|
||||
|
||||
# 已售商品:状态为 sold 且出售价 > 0
|
||||
sold_collections = [
|
||||
c for c in all_collections
|
||||
if c.f01_04_status == 'sold' and c.f05_42_goal_price and c.f05_42_goal_price > 0
|
||||
]
|
||||
# 按评级公司统计
|
||||
by_grading_company = db.query(
|
||||
Collection.f03_21_grading_company,
|
||||
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(
|
||||
c.f05_42_goal_price or 0
|
||||
for c in sold_collections
|
||||
)
|
||||
# 按评级分数统计
|
||||
by_grading_score = db.query(
|
||||
Collection.f03_22_grading_score,
|
||||
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 已售商品
|
||||
# 单藏品总成本 = 成本价 + 修复费 + 评级费
|
||||
total_profit = sum(
|
||||
(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)
|
||||
for c in sold_collections
|
||||
)
|
||||
# 按特殊标记统计
|
||||
by_special_mark = db.query(
|
||||
Collection.f04_30_special_mark,
|
||||
func.count(Collection.f99_90_id)
|
||||
).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()
|
||||
|
||||
# 总成本
|
||||
cost_result = db.query(
|
||||
func.sum(
|
||||
(Collection.f05_40_cost_price or 0) +
|
||||
(Collection.f05_43_repair_fee or 0) +
|
||||
(Collection.f05_44_grading_fee or 0)
|
||||
)
|
||||
).filter(base_filter).scalar() or 0
|
||||
|
||||
# 预期利润
|
||||
target_result = db.query(
|
||||
func.sum(Collection.f05_41_target_price)
|
||||
).filter(base_filter, Collection.f05_41_target_price > 0).scalar() or 0
|
||||
|
||||
expected_profit = target_result - cost_result
|
||||
|
||||
# 已售商品统计
|
||||
sold_filter = (Collection.f01_04_status == 'sold') & (Collection.f05_42_goal_price > 0)
|
||||
if current_user.role != "admin":
|
||||
sold_filter = sold_filter & (Collection.f99_91_user_id == current_user.f99_90_id)
|
||||
|
||||
total_revenue = db.query(func.sum(Collection.f05_42_goal_price)).filter(sold_filter).scalar() or 0
|
||||
|
||||
# 总利润
|
||||
total_profit = db.query(
|
||||
func.sum(
|
||||
(Collection.f05_42_goal_price or 0) -
|
||||
(Collection.f05_40_cost_price or 0) -
|
||||
(Collection.f05_43_repair_fee or 0) -
|
||||
(Collection.f05_44_grading_fee or 0)
|
||||
)
|
||||
).filter(sold_filter).scalar() or 0
|
||||
|
||||
return {
|
||||
"totalCount": total_count,
|
||||
|
|
|
|||
Loading…
Reference in New Issue