fix: 子客服(总管)申请罚款证据上传权限,支持商家客服代商家操作

COS 上传接口 fakuan_evidence / fakuan_evidence_draft 现允许具 penalty_apply 或 penalty_manage 且能查看该订单的子客服。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-13 16:00:06 +08:00
parent ce8bda52d3
commit e6e8e718d3
2 changed files with 64 additions and 32 deletions

View File

@@ -2,14 +2,63 @@
import logging
from backend.utils import pick_order_id
from merchant_ops.services.authz import StaffAuthError, member_has_perm
from merchant_ops.services.authz import StaffAuthError, get_active_staff_member, member_has_perm
from merchant_ops.models import MerchantOrderDispatch
from orders.models import MerchantOrderExt
from orders.models import MerchantOrderExt, Penalty
from users.business_models import User
from users.models import UserShangjia
logger = logging.getLogger(__name__)
class PenaltyEvidenceAuthError(Exception):
def __init__(self, code, msg):
self.code = code
self.msg = msg
super().__init__(msg)
def resolve_penalty_evidence_upload_auth(request, dingdan_id, fadan_id=None):
"""
商家老板或具 penalty_apply / penalty_manage 且能查看该订单的子客服。
返回所属 merchant_idApplicantID
"""
user = request.user
try:
shangjia_profile = user.ShopProfile
if shangjia_profile.zhuangtai != 1:
raise PenaltyEvidenceAuthError(403, '商家状态异常')
try:
MerchantOrderExt.query.get(Order__OrderID=dingdan_id, MerchantID=user.UserUID)
except MerchantOrderExt.DoesNotExist:
raise PenaltyEvidenceAuthError(403, '订单不存在或无权操作')
if fadan_id and not Penalty.query.filter(
id=fadan_id,
RelatedOrderID=dingdan_id,
ApplicantID=user.UserUID,
).exists():
raise PenaltyEvidenceAuthError(403, '罚单不存在或无权操作')
return user.UserUID
except UserShangjia.DoesNotExist:
pass
member = get_active_staff_member(user)
if not member:
raise PenaltyEvidenceAuthError(403, '非商家或子客服无权上传')
if not (member_has_perm(member, 'penalty_apply') or member_has_perm(member, 'penalty_manage')):
raise PenaltyEvidenceAuthError(403, '无罚单权限')
ok, _ = staff_can_access_order(member, dingdan_id)
if not ok:
raise PenaltyEvidenceAuthError(403, '无权操作该订单')
if fadan_id and not Penalty.query.filter(
id=fadan_id,
RelatedOrderID=dingdan_id,
ApplicantID=member.merchant_id,
).exists():
raise PenaltyEvidenceAuthError(403, '罚单不存在或无权操作')
return member.merchant_id
def get_merchant_user(merchant_id):
return User.query.get(UserUID=merchant_id)

View File

@@ -748,41 +748,24 @@ class DashouCOSZhengshuView(APIView):
elif yongtu == 'fakuan':
# 罚款申诉不需要订单验证
pass
elif yongtu == 'fakuan_evidence':
# 商家上传罚单证据图Purpose=1
fadan_id = request.data.get('fadan_id')
if not dingdan_id or not fadan_id:
elif yongtu in ('fakuan_evidence', 'fakuan_evidence_draft'):
# 商家或子客服(总管等)上传/补传罚单证据图
from merchant_ops.helpers import (
PenaltyEvidenceAuthError,
resolve_penalty_evidence_upload_auth,
)
if not dingdan_id:
return Response({'code': 400, 'msg': '缺少订单ID'}, status=400)
fadan_id = request.data.get('fadan_id') if yongtu == 'fakuan_evidence' else None
if yongtu == 'fakuan_evidence' and not fadan_id:
return Response(
{'code': 400, 'msg': '缺少订单ID或罚单ID'},
status=status.HTTP_400_BAD_REQUEST,
)
try:
shangjia_profile = request.user.ShopProfile
if shangjia_profile.zhuangtai != 1:
return Response({'code': 403, 'msg': '商家状态异常'}, status=403)
except Exception:
return Response({'code': 403, 'msg': '非商家无权上传'}, status=403)
fadan = Penalty.query.filter(
id=fadan_id,
RelatedOrderID=dingdan_id,
ApplicantID=request.user.UserUID,
).first()
if not fadan:
return Response({'code': 403, 'msg': '罚单不存在或无权操作'}, status=403)
elif yongtu == 'fakuan_evidence_draft':
# 商家申请罚款前上传证据图(仅需订单归属校验)
if not dingdan_id:
return Response({'code': 400, 'msg': '缺少订单ID'}, status=400)
try:
shangjia_profile = request.user.ShopProfile
if shangjia_profile.zhuangtai != 1:
return Response({'code': 403, 'msg': '商家状态异常'}, status=403)
except Exception:
return Response({'code': 403, 'msg': '非商家无权上传'}, status=403)
try:
MerchantOrderExt.query.get(Order__OrderID=dingdan_id, MerchantID=request.user.UserUID)
except MerchantOrderExt.DoesNotExist:
return Response({'code': 403, 'msg': '订单不存在或无权操作'}, status=403)
resolve_penalty_evidence_upload_auth(request, dingdan_id, fadan_id=fadan_id)
except PenaltyEvidenceAuthError as e:
return Response({'code': e.code, 'msg': e.msg}, status=403)
else:
# 默认为订单相关,需要验证订单且打手必须接单
try: