fix: 组队仅队长提交修改,组员可见交付;罚单聚合改撤联动
详情返回 can_submit/can_modify;交付图按订单聚合;组队均摊罚单展示总额并联动修改/撤销;罚单 ClubID 归属订单店。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -81,6 +81,78 @@ def get_active_recruit(order_id: str):
|
||||
).first()
|
||||
|
||||
|
||||
def get_team_role_for_user(order_id: str, user_uid: str) -> dict:
|
||||
"""
|
||||
当前用户在本单组队中的角色。
|
||||
返回: has_team, is_leader, is_member, leader_uid, my_share, recruit
|
||||
"""
|
||||
from orders.models import TeamMember, TeamRecruit
|
||||
out = {
|
||||
'has_team': False,
|
||||
'is_leader': False,
|
||||
'is_member': False,
|
||||
'leader_uid': '',
|
||||
'my_share': None,
|
||||
'recruit': None,
|
||||
}
|
||||
oid = (order_id or '').strip()
|
||||
uid = (user_uid or '').strip()
|
||||
if not oid or not uid:
|
||||
return out
|
||||
rec = get_active_recruit(oid)
|
||||
if not rec:
|
||||
rec = TeamRecruit.query.filter(order_id=oid).order_by('-id').first()
|
||||
if not rec:
|
||||
return out
|
||||
out['has_team'] = True
|
||||
out['recruit'] = rec
|
||||
out['leader_uid'] = rec.leader_uid or ''
|
||||
out['is_leader'] = (rec.leader_uid or '') == uid
|
||||
mem = TeamMember.query.filter(
|
||||
recruit_id=rec.id, user_uid=uid, join_status=TeamMember.JOIN_ACTIVE,
|
||||
).first()
|
||||
if mem:
|
||||
out['is_member'] = True
|
||||
out['my_share'] = float(_d(mem.share_amount))
|
||||
elif out['is_leader']:
|
||||
out['is_member'] = True
|
||||
return out
|
||||
|
||||
|
||||
def ensure_team_leader_can_submit(order, user_uid: str) -> Optional[str]:
|
||||
"""
|
||||
有有效组队时:仅队长可提交/修改交付。
|
||||
无组队时:须为订单 PlayerID。
|
||||
返回错误文案;通过返回 None。
|
||||
"""
|
||||
oid = getattr(order, 'OrderID', None) or ''
|
||||
uid = (user_uid or '').strip()
|
||||
player = (getattr(order, 'PlayerID', None) or '').strip()
|
||||
from orders.models import TeamRecruit
|
||||
ctx = get_team_role_for_user(oid, uid)
|
||||
if ctx['has_team'] and ctx['recruit'] and int(ctx['recruit'].status or 0) in (
|
||||
TeamRecruit.STATUS_RECRUITING, TeamRecruit.STATUS_LOCKED,
|
||||
):
|
||||
if not ctx['is_leader']:
|
||||
return '仅队长可提交或修改交付内容'
|
||||
return None
|
||||
if player and player != uid:
|
||||
return '订单不存在或没有提交权限'
|
||||
return None
|
||||
|
||||
|
||||
def list_team_split_penalties(order_id: str, *, include_rejected=False):
|
||||
"""同订单【组队均摊】罚单列表(按创建顺序)。"""
|
||||
from orders.models import Penalty
|
||||
qs = Penalty.query.filter(
|
||||
RelatedOrderID=order_id,
|
||||
Reason__startswith='【组队均摊】',
|
||||
)
|
||||
if not include_rejected:
|
||||
qs = qs.exclude(Status=4)
|
||||
return list(qs.order_by('id'))
|
||||
|
||||
|
||||
def team_should_split(order) -> bool:
|
||||
"""结单是否走组队分账:已锁定(或招募中但已有人——进8会强制锁)且有在队成员。"""
|
||||
from orders.models import TeamRecruit, TeamMember
|
||||
@@ -702,7 +774,15 @@ def maybe_split_penalties(*, order_id: str, total_amount, reason: str, applicant
|
||||
|
||||
reason_text = f'【组队均摊】{reason or ""}'
|
||||
created = []
|
||||
cid = (club_id or rec.club_id or 'xq')[:16]
|
||||
# 罚单归属订单俱乐部,避免跨店接单时记到错误店;利率仍按申请人俱乐部在 lock_penalty_bonus 锁定
|
||||
order_club = ''
|
||||
try:
|
||||
from orders.models import Order
|
||||
o = Order.query.filter(OrderID=order_id).only('ClubID').first()
|
||||
order_club = (getattr(o, 'ClubID', None) or '').strip() if o else ''
|
||||
except Exception:
|
||||
order_club = ''
|
||||
cid = (order_club or club_id or rec.club_id or 'xq')[:16]
|
||||
for i, m in enumerate(members):
|
||||
p = Penalty(
|
||||
PenalizedUserID=m.user_uid,
|
||||
|
||||
Reference in New Issue
Block a user