fix: 商家老板可绑定为其他店子客服

允许已是商家老板的用户担任其他商家子客服,禁止绑自己的店。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-04 20:48:12 +08:00
parent 9d98ac9e83
commit 26dcbc1dc9
2 changed files with 17 additions and 15 deletions

View File

@@ -33,9 +33,7 @@ def get_active_staff_member(user):
def require_active_staff_member(user):
"""子客服接口鉴权:区分老板误入、未绑定、禁用、移除等场景。"""
if is_merchant_owner(user):
raise StaffAuthError(403, '您是商家老板,请使用商家端原接口')
"""子客服接口鉴权:区分未绑定、禁用、移除等场景(已是商家老板也可担任其他店子客服)"""
member = MerchantStaffMember.query.filter(
staff_user_id=user.UserUID,
).select_related('role').order_by('-id').first()
@@ -132,9 +130,21 @@ def resolve_owner_or_staff(request, perm_code=None):
return 'staff', member.merchant_id, member, user.UserUID
def assert_not_merchant_when_bind(user):
if is_merchant_owner(user):
raise StaffAuthError(403, '您已是商家,无法成为子客服')
def assert_not_self_merchant_when_bind(user, invite_merchant_id):
"""不能绑定为自己店铺的客服;可以是其他商家的子客服。"""
if invite_merchant_id is not None and str(user.UserUID) == str(invite_merchant_id):
raise StaffAuthError(403, '不能绑定为自己商家的客服')
def assert_can_bind_staff(user, invite_merchant_id=None):
assert_not_self_merchant_when_bind(user, invite_merchant_id)
existing = MerchantStaffMember.query.filter(
staff_user_id=user.UserUID, status=MEMBER_STATUS_ACTIVE
).first()
if existing:
if invite_merchant_id and str(existing.merchant_id) == str(invite_merchant_id):
raise StaffAuthError(400, '您已是该商家客服')
raise StaffAuthError(403, '您已绑定其他商家客服,请先联系原商家解除后再绑定')
def assert_no_active_staff_when_merchant_register(user):
@@ -144,14 +154,6 @@ def assert_no_active_staff_when_merchant_register(user):
raise StaffAuthError(403, '您当前是商家客服,请先联系商家解除后再认证商家')
def assert_can_bind_staff(user):
assert_not_merchant_when_bind(user)
if MerchantStaffMember.query.filter(
staff_user_id=user.UserUID, status=MEMBER_STATUS_ACTIVE
).exists():
raise StaffAuthError(403, '您已绑定商家客服,无法重复绑定')
def get_owner_permissions():
return list(OWNER_ALL_PERMISSIONS)

View File

@@ -35,7 +35,6 @@ class StaffBindView(APIView):
def post(self, request):
try:
assert_can_bind_staff(request.user)
invite_code = str(request.data.get('inviteCode') or request.data.get('invite_code') or '').strip()
if not invite_code or invite_code == 'XQKF2026':
return Response({'code': 400, 'msg': '请使用商家提供的一次性邀请码', 'data': None})
@@ -44,6 +43,7 @@ class StaffBindView(APIView):
inv = MerchantStaffInvite.objects.select_for_update().get(
invite_code=invite_code, status=INVITE_STATUS_UNUSED,
)
assert_can_bind_staff(request.user, invite_merchant_id=inv.merchant_id)
if inv.expire_at and inv.expire_at < timezone.now():
inv.status = 3
inv.save(update_fields=['status'])