fix: 恢复collections.py并添加用户认证检查

This commit is contained in:
甲辰生产 2026-04-08 14:39:10 +08:00
parent 9956ed3f61
commit 79ce79b92c
1 changed files with 79 additions and 118 deletions

View File

@ -64,28 +64,23 @@ def to_camel_case(data: dict) -> dict:
# 编码生成函数 # 编码生成函数
def generate_code(version: str, user_id: str, db: Session) -> str: def generate_code(version: str, user_id: str, db: Session) -> str:
"""自动生成藏品编号 - 按用户独立编码,使用行锁防止并发冲突""" """自动生成藏品编号 - 按用户独立编码"""
import re import re
from sqlalchemy import text
# 使用 FOR UPDATE 行锁防止并发冲突 # 查询当前用户的非空编码(不与其他用户混算)
result = db.execute( user_codes = db.query(Collection.f01_02_code).filter(
text(""" Collection.f01_02_code.isnot(None),
SELECT f01_02_code FROM collections Collection.f99_91_user_id == user_id
WHERE f99_91_user_id = :user_id ).all()
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 max_num = 0
if result and result[0]: for (code,) in user_codes:
# 处理纯数字编码支持4位和5位
if re.match(r'^\d{4,5}$', code):
try: try:
max_num = int(result[0]) num = int(code)
if num > max_num:
max_num = num
except (ValueError, TypeError): except (ValueError, TypeError):
pass pass
@ -138,6 +133,10 @@ def get_collections(
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
# 管理员默认查看全库,普通用户只看自己 # 管理员默认查看全库,普通用户只看自己
if current_user is None:
return {"error": "Unauthorized", "totalCount": 0}
# 获取所有藏品
if current_user.role == "admin": if current_user.role == "admin":
# 联表查询获取用户名 # 联表查询获取用户名
query = db.query(Collection, User.f01_01_name.label('owner_name')).join( query = db.query(Collection, User.f01_01_name.label('owner_name')).join(
@ -207,6 +206,10 @@ def get_collections(
data_list = [] data_list = []
for item in data: for item in data:
# 处理联表查询结果 # 处理联表查询结果
if current_user is None:
return {"error": "Unauthorized", "totalCount": 0}
# 获取所有藏品
if current_user.role == "admin": if current_user.role == "admin":
collection_item, owner_name = item collection_item, owner_name = item
else: else:
@ -281,110 +284,72 @@ 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 func, case # 获取所有藏品
if current_user is None:
return {"error": "Unauthorized", "totalCount": 0}
# 基础查询条件 - 检查用户是否登录 # 获取所有藏品
if current_user is None or not hasattr(current_user, 'role'): if current_user.role == "admin":
base_filter = False # 未登录用户不能查看任何藏品 all_collections = db.query(Collection).all()
else: else:
base_filter = True if current_user.role == "admin" else Collection.f99_91_user_id == current_user.f99_90_id all_collections = db.query(Collection).filter(
Collection.f99_91_user_id == current_user.f99_90_id
).all()
# 总数 # 总数
total_count = db.query(func.count(Collection.f99_90_id)).filter(base_filter).scalar() or 0 total_count = len(all_collections)
# 按分类统计 # 按分类统计
by_category = db.query( from collections import Counter
Collection.f01_03_category, by_category = Counter(c.f01_03_category for c in all_collections).items()
func.count(Collection.f99_90_id)
).filter(base_filter).group_by(Collection.f01_03_category).all()
# 按状态统计 # 按状态统计
by_status = db.query( by_status = Counter(c.f01_04_status for c in all_collections).items()
Collection.f01_04_status,
func.count(Collection.f99_90_id)
).filter(base_filter).group_by(Collection.f01_04_status).all()
# 按是否评级统计 # 按是否评级统计
by_graded = db.query( by_graded = Counter(c.f03_20_is_graded for c in all_collections).items()
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 = db.query( by_packaging = Counter(c.f02_12_packaging for c in all_collections if c.f02_12_packaging).items()
Collection.f02_12_packaging, by_rarity = Counter(c.f02_13_rarity for c in all_collections if c.f02_13_rarity).items()
func.count(Collection.f99_90_id) by_version = Counter(c.f02_11_version for c in all_collections if c.f02_11_version).items()
).filter(base_filter, Collection.f02_12_packaging.isnot(None)).group_by(Collection.f02_12_packaging).all() 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()
# 按稀有度统计 # 总成本: SUM(cost_price + repair_fee + grading_fee) for ALL collections
by_rarity = db.query( total_cost = sum(
Collection.f02_13_rarity, (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 all_collections
).filter(base_filter, Collection.f02_13_rarity.isnot(None)).group_by(Collection.f02_13_rarity).all()
# 按版本统计
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()
# 按评级公司统计
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()
# 按评级分数统计
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()
# 按特殊标记统计
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
# 预期利润 # 预期利润: SUM(target_price - cost_price) for collections with target_price > 0
target_result = db.query( expected_profit = sum(
func.sum(Collection.f05_41_target_price) (c.f05_41_target_price or 0) - (c.f05_40_cost_price or 0)
).filter(base_filter, Collection.f05_41_target_price > 0).scalar() or 0 for c in all_collections
if c.f05_41_target_price and c.f05_41_target_price > 0
expected_profit = target_result - cost_result )
# 已售商品统计 # 已售商品:状态为 sold 且出售价 > 0
sold_filter = (Collection.f01_04_status == 'sold') & (Collection.f05_42_goal_price > 0) sold_collections = [
if current_user.role != "admin": c for c in all_collections
sold_filter = sold_filter & (Collection.f99_91_user_id == current_user.f99_90_id) if c.f01_04_status == 'sold' and c.f05_42_goal_price and c.f05_42_goal_price > 0
]
total_revenue = db.query(func.sum(Collection.f05_42_goal_price)).filter(sold_filter).scalar() or 0
# 总收入SUM(出售价) for 已售商品(售价>0
# 总利润 total_revenue = sum(
total_profit = db.query( c.f05_42_goal_price or 0
func.sum( for c in sold_collections
(Collection.f05_42_goal_price or 0) - )
(Collection.f05_40_cost_price or 0) -
(Collection.f05_43_repair_fee or 0) - # 总利润已实现利润SUM(出售价 - 成本价 - 修复费 - 评级费) for 已售商品
(Collection.f05_44_grading_fee or 0) # 单藏品总成本 = 成本价 + 修复费 + 评级费
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
) )
).filter(sold_filter).scalar() or 0
return { return {
"totalCount": total_count, "totalCount": total_count,
@ -398,17 +363,13 @@ 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": db.query(func.count(Collection.f99_90_id)).filter( {"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)},
sold_filter, Collection.f05_42_goal_price > Collection.f05_40_cost_price {"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)}
).scalar() or 0},
{"type": "loss", "label": "亏损", "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}
], ],
"totalCost": cost_result, "totalCost": total_cost,
"totalTarget": target_result, "totalTarget": sum(c.f05_41_target_price or 0 for c in all_collections),
"expectedProfit": expected_profit, "expectedProfit": expected_profit,
"totalRevenue": total_revenue, "totalRevenue": total_revenue,
"totalProfit": total_profit "totalProfit": total_profit