fix: 组队仅队长提交修改,组员可见交付;罚单聚合改撤联动

详情返回 can_submit/can_modify;交付图按订单聚合;组队均摊罚单展示总额并联动修改/撤销;罚单 ClubID 归属订单店。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-27 08:05:34 +08:00
parent c5ceacf3d3
commit 7d366e8075
4 changed files with 275 additions and 73 deletions

View File

@@ -862,18 +862,28 @@ class DashouCOSZhengshuView(APIView):
if not allowed:
return Response({'code': 403, 'msg': '无权上传退款图片'}, status=403)
else:
# 默认为订单相关,需要验证订单且打手必须接单
# 默认为订单交付图:组队仅队长;非组队须接单
try:
dingdan = Order.query.get(
OrderID=dingdan_id,
PlayerID=request.user.UserUID,
Status__in=[2, 8]
)
except Order.DoesNotExist:
return Response(
{'code': 403, 'msg': '此功能暂未开放', 'error': f'Order {dingdan_id} not found or not assigned to user {request.user.UserUID}'},
{'code': 403, 'msg': '此功能暂未开放', 'error': f'Order {dingdan_id} not found'},
status=status.HTTP_403_FORBIDDEN
)
try:
from orders.services.team_recruit import ensure_team_leader_can_submit
deny = ensure_team_leader_can_submit(dingdan, request.user.UserUID)
if deny:
return Response({'code': 403, 'msg': deny}, status=status.HTTP_403_FORBIDDEN)
except Exception:
if dingdan.PlayerID != request.user.UserUID:
return Response(
{'code': 403, 'msg': '此功能暂未开放'},
status=status.HTTP_403_FORBIDDEN
)
# 4. 获取腾讯云STS临时密钥
try:
@@ -1220,26 +1230,34 @@ class DashouTijiaoView(APIView):
'data': None
}, status=status.HTTP_403_FORBIDDEN)
# 4. 验证订单状态和权限
# 4. 验证订单状态和权限(组队单仅队长可提交)
try:
dingdan = Order.query.get(
OrderID=dingdan_id,
PlayerID=yonghuid,
Status=2 # 必须是进行中的订单
)
dingdan = Order.query.get(OrderID=dingdan_id, Status=2)
except Order.DoesNotExist:
return Response({
'code': 7,
'msg': '订单不存在或没有提交权限',
'data': None
}, status=status.HTTP_403_FORBIDDEN)
try:
from orders.services.team_recruit import ensure_team_leader_can_submit
deny = ensure_team_leader_can_submit(dingdan, yonghuid)
if deny:
return Response({'code': 7, 'msg': deny, 'data': None}, status=status.HTTP_403_FORBIDDEN)
except Exception:
if dingdan.PlayerID != yonghuid:
return Response({
'code': 7,
'msg': '订单不存在或没有提交权限',
'data': None
}, status=status.HTTP_403_FORBIDDEN)
# 5. 存储图片到Dashoutupian表
# 5. 存储图片到Dashoutupian表(统一记在接单人/队长名下,组员可读)
owner_uid = dingdan.PlayerID or yonghuid
for tupian_url in jiaofu_tupian_urls:
# 创建打手提交图片记录
PlayerDeliveryImage.query.create(
OrderID=dingdan_id,
PlayerID=yonghuid,
PlayerID=owner_uid,
ImageURL=tupian_url,
CreateTime=timezone.now()
)
@@ -1342,11 +1360,32 @@ class DashouDingdanXiangqingView(APIView):
'data': None
}, status=status.HTTP_403_FORBIDDEN)
# 5. 构建基础订单数据
# 5. 构建基础订单数据(组队:组员看本人份额;交付图全员可见)
from orders.services.team_recruit import get_team_role_for_user, ensure_team_leader_can_submit
team_ctx = get_team_role_for_user(dingdan.OrderID, yonghuid)
full_commission = float(dingdan.PlayerCommission) if dingdan.PlayerCommission else 0.0
my_share = team_ctx.get('my_share')
show_jine = full_commission
if team_ctx.get('has_team') and not team_ctx.get('is_leader') and my_share is not None:
show_jine = float(my_share)
submit_deny = ensure_team_leader_can_submit(dingdan, yonghuid)
can_submit = int(dingdan.Status or 0) == 2 and submit_deny is None
can_modify = int(dingdan.Status or 0) in (4, 8) and submit_deny is None
is_team_leader = (
bool(team_ctx.get('is_leader'))
if team_ctx.get('has_team')
else (dingdan.PlayerID == yonghuid)
)
dingdan_data = {
'dingdan_id': dingdan.OrderID,
'zhuangtai': dingdan.Status,
'jine': float(dingdan.PlayerCommission) if dingdan.PlayerCommission else 0.0,
'jine': show_jine,
'order_commission': full_commission,
'my_share_amount': my_share if my_share is not None else full_commission,
'is_team_leader': is_team_leader,
'can_submit': bool(can_submit),
'can_modify': bool(can_modify),
'jieshao': dingdan.Description or '',
'tupian': dingdan.ImageURL or '',
'nicheng': dingdan.Nickname or '',
@@ -1391,10 +1430,9 @@ class DashouDingdanXiangqingView(APIView):
except Exception:
dingdan_data['team'] = None
# 6. 查询打手提交的图片
# 6. 订单交付图(组队全员可见,不按当前用户过滤)
dashou_tupian_list = PlayerDeliveryImage.query.filter(
OrderID=dingdan_id,
PlayerID=yonghuid
).order_by('CreateTime')
jiaofu_tupian_urls = []
@@ -1606,30 +1644,34 @@ class DashouXiugaiView(APIView):
return Response({'code': 5, 'msg': '用户不是打手身份', 'data': None},
status=status.HTTP_403_FORBIDDEN)
# ---------- 订单查询及权限验证 ----------
# ---------- 订单查询及权限验证(组队仅队长) ----------
try:
# 订单必须属于该打手且状态为4退款中或8结算中
dingdan = Order.query.get(
OrderID=dingdan_id,
PlayerID=yonghuid,
Status__in=[4, 8] # 只允许修改退款中或结算中的订单
)
dingdan = Order.query.get(OrderID=dingdan_id, Status__in=[4, 8])
except Order.DoesNotExist:
return Response({'code': 6, 'msg': '订单不存在或没有修改权限', 'data': None},
status=status.HTTP_403_FORBIDDEN)
try:
from orders.services.team_recruit import ensure_team_leader_can_submit
deny = ensure_team_leader_can_submit(dingdan, yonghuid)
if deny:
return Response({'code': 6, 'msg': deny, 'data': None},
status=status.HTTP_403_FORBIDDEN)
except Exception:
if dingdan.PlayerID != yonghuid:
return Response({'code': 6, 'msg': '订单不存在或没有修改权限', 'data': None},
status=status.HTTP_403_FORBIDDEN)
owner_uid = dingdan.PlayerID or yonghuid
# ---------- 执行修改(使用事务保证原子性) ----------
try:
with transaction.atomic():
# 1. 处理删除的图片:从 Dashoutupian 表中删除记录
if deleted_images:
# 根据订单ID、打手ID和图片URL删除记录
delete_count, _ = PlayerDeliveryImage.query.filter(
OrderID=dingdan_id,
PlayerID=yonghuid,
ImageURL__in=deleted_images
).delete()
# 可选:记录删除数量
logger.info(f"订单 {dingdan_id} 删除图片 {delete_count}")
# 2. 处理新增的图片:插入新记录
@@ -1639,7 +1681,7 @@ class DashouXiugaiView(APIView):
for url in new_images:
new_records.append(PlayerDeliveryImage(
OrderID=dingdan_id,
PlayerID=yonghuid,
PlayerID=owner_uid,
ImageURL=url,
CreateTime=timezone.now()
))