优化后台用户管理和发积分

This commit is contained in:
Azmat@qq.com
2026-09-20 16:30:45 +08:00
parent fb3b2904ae
commit 690eb3d843
12 changed files with 470 additions and 22 deletions
+39 -2
View File
@@ -98,20 +98,57 @@ class AdminTeamMemberSerializer(serializers.ModelSerializer):
read_only_fields = fields
def wallet_membership(user):
"""用户的钱包归属:第一个 active 成员关系(与 common.api.get_current_team 同口径,消费从这个团队扣)。
列表页依赖 prefetch 好的 team_memberships,这里只在内存里挑,不要改成 .filter() 否则每行多一次查询。"""
actives = [m for m in user.team_memberships.all() if m.status == TeamMember.Status.ACTIVE]
return min(actives, key=lambda m: m.created_at) if actives else None
class AdminUserSerializer(serializers.ModelSerializer):
teams = serializers.SerializerMethodField()
# 后台按「用户」视角管积分,但账户实际挂在团队上。这里把钱包团队拍平给前端:
# wallet_shared=True 表示这是个多人共享池(老用户),发积分弹窗要明确提示钱会进整个团队。
balance = serializers.SerializerMethodField()
wallet_team = serializers.SerializerMethodField()
wallet_team_name = serializers.SerializerMethodField()
wallet_shared = serializers.SerializerMethodField()
class Meta:
model = User
fields = ["id", "username", "status", "is_platform_admin", "date_joined", "teams"]
fields = [
"id", "username", "status", "is_platform_admin", "date_joined", "teams",
"balance", "wallet_team", "wallet_team_name", "wallet_shared",
]
read_only_fields = fields
def get_teams(self, obj):
return [
{"team_id": str(m.team_id), "team_name": m.team.name, "role": m.role}
for m in obj.team_memberships.select_related("team").all()
for m in obj.team_memberships.all()
if not m.team.is_personal # 个人团队是钱包实现细节,不当「所属团队」展示
]
def get_balance(self, obj):
m = wallet_membership(obj)
acct = getattr(m.team, "credit_account", None) if m else None
return str(acct.balance) if acct is not None else "0"
def get_wallet_team(self, obj):
m = wallet_membership(obj)
return str(m.team_id) if m else None
def get_wallet_team_name(self, obj):
m = wallet_membership(obj)
return m.team.name if m else None
def get_wallet_shared(self, obj):
m = wallet_membership(obj)
if m is None:
return False
count = getattr(m, "team_member_count", None)
return bool((count if count is not None else m.team.members.count()) > 1)
class AdminTaskSerializer(serializers.ModelSerializer):
team_name = serializers.CharField(source="team.name", read_only=True, default=None)