From ee7867b36f29e9529f6319b955b05cdb20dbdd98 Mon Sep 17 00:00:00 2001 From: XingQue Date: Sat, 27 Jun 2026 18:15:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BD=9A=E5=8D=95/=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E5=A4=84=E7=BD=9A=E5=BD=92=E5=B1=9E=E7=94=B3=E8=AF=B7=E4=BA=BA?= =?UTF-8?q?=E4=BF=B1=E4=B9=90=E9=83=A8=EF=BC=9B=E7=94=B3=E8=AF=B7=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E5=88=86=E7=BA=A2=E7=BC=B4=E7=BA=B3=E6=8C=89=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E5=80=BC=E5=85=A5=E8=B4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/view.py | 19 +++++- jituan/services/club_penalty.py | 104 +++++++++++++++++++++++--------- orders/views.py | 29 +++++++-- shop/views.py | 7 +++ users/fadan_fenhong_utils.py | 14 +++-- users/views.py | 7 +++ 6 files changed, 139 insertions(+), 41 deletions(-) diff --git a/backend/view.py b/backend/view.py index 23ad6e7..3486aaa 100644 --- a/backend/view.py +++ b/backend/view.py @@ -6648,7 +6648,9 @@ class FaKuanChuangJianView(APIView): AffectsGrabbing=AffectsGrabbing, Status=1, # 待缴纳 ClubID=resolve_penalty_club_id( - penalized_user_id=PenalizedUserID, request=request, + penalized_user_id=PenalizedUserID, + request=request, + user=request.user, ), ) for relative_url in uploaded_urls: @@ -6753,7 +6755,12 @@ class FineApplyView(APIView): Status=1, # 待缴纳 AffectsGrabbing=AffectsGrabbing, ApplicantIdentity=1, # 申请人身份:1 客服 - ClubID=resolve_penalty_club_id(order=order, request=request), + ClubID=resolve_penalty_club_id( + order=order, + request=request, + user=request.user, + applicant_id=getattr(request.user, 'UserUID', None), + ), ) for relative_url in uploaded_urls: PenaltyAppealImage.query.create( @@ -6834,7 +6841,13 @@ class PunishDashouView(APIView): ApplyStatus=0, DeductedPoints=jifen, OrderID=OrderID, - ClubID=resolve_penalty_record_club_id(order_id=OrderID, player_id=dashou_id), + ClubID=resolve_penalty_record_club_id( + order_id=OrderID, + player_id=dashou_id, + request=request, + user=request.user, + applicant_id=getattr(request.user, 'UserUID', None) or username, + ), ) # 扣除打手积分 dashou.jifen = F('jifen') - jifen diff --git a/jituan/services/club_penalty.py b/jituan/services/club_penalty.py index 8f4334e..d7e203b 100644 --- a/jituan/services/club_penalty.py +++ b/jituan/services/club_penalty.py @@ -10,19 +10,82 @@ from jituan.services.club_context import ( from jituan.services.club_user import get_user_club_id -def resolve_penalty_club_id(order=None, penalized_user_id=None, request=None): - """创建罚单时写入 club_id。""" +def _club_id_from_user_uid(uid): + if not uid: + return None + from users.business_models import User + u = User.query.filter(UserUID=str(uid)).first() + if u: + return get_user_club_id(u) + return None + + +def resolve_penalty_club_id( + order=None, + penalized_user_id=None, + request=None, + applicant_id=None, + user=None, +): + """ + 创建金额罚单时写入 club_id。 + 归属:申请人俱乐部 > 当前操作人/请求俱乐部 > 订单俱乐部 > 被罚人俱乐部 > xq。 + """ + cid = _club_id_from_user_uid(applicant_id) + if cid: + return cid + + if request is not None or user is not None: + from jituan.services.club_write import resolve_club_id_for_write + u = user or getattr(request, 'user', None) + cid = resolve_club_id_for_write(request, u) + if cid: + return cid + if order is not None: cid = getattr(order, 'ClubID', None) if cid: return cid - if penalized_user_id: - from users.business_models import User - u = User.query.filter(UserUID=penalized_user_id).first() - if u: - return get_user_club_id(u) - if request is not None: - return resolve_club_id_from_request(request) + + cid = _club_id_from_user_uid(penalized_user_id) + if cid: + return cid + + return CLUB_ID_DEFAULT + + +def resolve_penalty_record_club_id( + order_id=None, + player_id=None, + request=None, + applicant_id=None, + user=None, +): + """ + 创建积分处罚(chufajilu)时写入 club_id。 + 归属规则与金额罚单一致:申请人俱乐部优先。 + """ + cid = _club_id_from_user_uid(applicant_id) + if cid: + return cid + + if request is not None or user is not None: + from jituan.services.club_write import resolve_club_id_for_write + u = user or getattr(request, 'user', None) + cid = resolve_club_id_for_write(request, u) + if cid: + return cid + + if order_id: + from orders.models import Order + o = Order.query.filter(OrderID=order_id).first() + if o and getattr(o, 'ClubID', None): + return o.ClubID + + cid = _club_id_from_user_uid(player_id) + if cid: + return cid + return CLUB_ID_DEFAULT @@ -44,10 +107,9 @@ def resolve_gsfenhong_club_id(dingdan_id=None, dashouid=None, order=None, czjilu if o and getattr(o, 'ClubID', None): return o.ClubID if dashouid: - from users.business_models import User - u = User.query.filter(UserUID=dashouid).first() - if u: - return get_user_club_id(u) + cid = _club_id_from_user_uid(dashouid) + if cid: + return cid return CLUB_ID_DEFAULT @@ -91,7 +153,7 @@ def _filter_club_penalty_like_qs(qs, request, user_id_field, order_id_field): if not parts: return qs.none() combined = parts[0] - for p in parts[1:]: + for p in parts[1]: combined |= p return qs.filter(combined) @@ -119,20 +181,6 @@ def forbid_penalty_out_of_scope(request, penalty): return None -def resolve_penalty_record_club_id(order_id=None, player_id=None): - if order_id: - from orders.models import Order - o = Order.query.filter(OrderID=order_id).first() - if o and getattr(o, 'ClubID', None): - return o.ClubID - if player_id: - from users.business_models import User - u = User.query.filter(UserUID=player_id).first() - if u: - return get_user_club_id(u) - return CLUB_ID_DEFAULT - - def filter_penalty_record_qs(qs, request): """积分处罚记录(chufajilu)按俱乐部过滤。""" return _filter_club_penalty_like_qs( diff --git a/orders/views.py b/orders/views.py index 1af629e..902c07b 100644 --- a/orders/views.py +++ b/orders/views.py @@ -63,7 +63,7 @@ from .models import ( from jituan.services.club_config import get_commission_rate, get_commission_rate_object from jituan.services.club_context import resolve_club_id_from_request from jituan.services.club_user import get_payment_openid -from jituan.services.club_penalty import resolve_penalty_club_id +from jituan.services.club_penalty import resolve_penalty_club_id, resolve_penalty_record_club_id from users.fadan_fenhong_utils import lock_penalty_bonus from users.fadan_fenhong_utils import lock_penalty_bonus from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai @@ -2304,12 +2304,16 @@ class ShangjiaDingdanXiangqingView(APIView): 'update_time': ut, } - # 7. 商家分红利率(申请页预览):与缴纳后分红同一套规则 + # 7. 商家分红利率:已有罚单用锁定值;否则按商家所在俱乐部预览 fenhong_lilv = 0.0 try: - from users.fadan_fenhong_utils import get_merchant_fenhong_lilv - order_club_id = getattr(order, 'ClubID', None) or 'xq' - fenhong_lilv = get_merchant_fenhong_lilv(yonghuid, club_id=order_club_id) + if fadan_obj and fadan_obj.ApplicantBonusRate: + fenhong_lilv = float(fadan_obj.ApplicantBonusRate) + else: + from users.fadan_fenhong_utils import get_merchant_fenhong_lilv + from jituan.services.club_write import resolve_club_id_for_write + merchant_club_id = resolve_club_id_for_write(request, current_user) + fenhong_lilv = get_merchant_fenhong_lilv(yonghuid, club_id=merchant_club_id) except Exception as e: logger.warning(f'获取分红利率失败: {e}') @@ -2976,6 +2980,13 @@ class ShangjiaChufaShenqingView(APIView): ApplyStatus=0, # 待处理 DeductedPoints=5, # 扣除5积分 OrderID=dingdan_id, + ClubID=resolve_penalty_record_club_id( + order_id=dingdan_id, + player_id=dashou_id, + request=request, + applicant_id=current_user.UserUID, + user=current_user, + ), ) # 🔴【新增】在创建处罚记录后立即扣除打手积分 # 注意:这里使用前面已经获取的dashou对象(打手扩展表) @@ -6539,7 +6550,13 @@ class ShangjiaFakuanApplyView(APIView): Status=1, # 待缴纳 AffectsGrabbing=yingxiang_qiangdan, ApplicantIdentity=5, # 申请人是商家 - ClubID=resolve_penalty_club_id(order=order, penalized_user_id=dashou_id), + ClubID=resolve_penalty_club_id( + order=order, + penalized_user_id=dashou_id, + request=request, + applicant_id=shangjia_id, + user=current_user, + ), ShopStaffUserID=staff_kefu_id, ) lock_penalty_bonus(fadan) diff --git a/shop/views.py b/shop/views.py index d632b99..da3d54b 100644 --- a/shop/views.py +++ b/shop/views.py @@ -3095,6 +3095,7 @@ class ShopFineApplyView(APIView): return Response({'code': 400, 'msg': '该打手已被罚款过'}) # ---------- 6. 创建罚单 ---------- + from jituan.services.club_penalty import resolve_penalty_club_id with transaction.atomic(): penalty = Penalty.query.create( PenalizedUserID=dashou_id, @@ -3106,6 +3107,12 @@ class ShopFineApplyView(APIView): Status=1, # 待缴纳 AffectsGrabbing=yingxiang_qiangdan, ApplicantIdentity=4, # 申请人身份:4 店铺管理员 + ClubID=resolve_penalty_club_id( + order=order, + request=request, + user=request.user, + applicant_id=str(shop_id), + ), ) from users.fadan_fenhong_utils import lock_penalty_bonus lock_penalty_bonus(penalty) diff --git a/users/fadan_fenhong_utils.py b/users/fadan_fenhong_utils.py index 37cf9b4..3ae0797 100644 --- a/users/fadan_fenhong_utils.py +++ b/users/fadan_fenhong_utils.py @@ -12,12 +12,15 @@ logger = logging.getLogger(__name__) # 身份映射字典 +# 罚单 ApplicantIdentity(shenqingren_shenfen)→ fadan_fenhong 表 Identity + fadan_fenhong_lilv 表 shenfen +# 罚单侧:1=客服 2=售后 3=管理员 4=店铺 5=商家 +# fadan_fenhong 表:1=商家 2=客服 3=平台管理者 4=店铺 5=售后 IDENTITY_MAP = { - 1: {'fenhong': 2, 'lilv': 1}, # 客服 - 2: {'fenhong': 5, 'lilv': 2}, # 售后 + 1: {'fenhong': 2, 'lilv': 1}, # 客服 → 分红记录身份2,利率表 shenfen=1 + 2: {'fenhong': 5, 'lilv': 2}, # 售后 → 分红记录身份5,利率表 shenfen=2 3: {'fenhong': 3, 'lilv': 3}, # 管理员 4: {'fenhong': 4, 'lilv': 4}, # 店铺 - 5: {'fenhong': 1, 'lilv': 5}, # 商家 + 5: {'fenhong': 1, 'lilv': 5}, # 商家 → 分红记录身份1,利率表 shenfen=5;钱进 user_shangjia.yue } MERCHANT_LILV_SHENFEN = 5 @@ -151,7 +154,10 @@ def process_fadan_fenhong(fadan_id): locked_amount = Decimal(str(fadan.ApplicantBonusAmount or 0)) locked_rate = fadan.ApplicantBonusRate - if locked_amount > 0: + # 申请时已锁定:缴纳只按锁定值入账,不因全局利率后续变更而重算 + if locked_amount > 0 or ( + locked_rate is not None and Decimal(str(locked_rate)) > 0 + ): fenhong_jine = locked_amount rate = locked_rate else: diff --git a/users/views.py b/users/views.py index 019b183..3157933 100644 --- a/users/views.py +++ b/users/views.py @@ -10441,6 +10441,7 @@ class KefuPunishView(APIView): return Response({'code': 400, 'msg': '该用户不是打手'}, status=status.HTTP_400_BAD_REQUEST) # 6. 使用事务 + from jituan.services.club_penalty import resolve_penalty_record_club_id with transaction.atomic(): # 创建处罚记录(积分扣除5分) jifen = 5 @@ -10451,6 +10452,12 @@ class KefuPunishView(APIView): ApplyStatus=0, # 待处理 DeductedPoints=jifen, OrderID=dingdan_id, + ClubID=resolve_penalty_record_club_id( + order_id=dingdan_id, + player_id=dashou_id, + request=request, + user=request.user, + ), ) # 扣除打手积分