From 93bf2193d21c0bebefaedbf240a8b2a2a8b40411 Mon Sep 17 00:00:00 2001 From: XingQue Date: Sat, 27 Jun 2026 07:55:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=95=86=E5=AE=B6=E5=88=86=E7=BA=A2?= =?UTF-8?q?=E5=88=A9=E7=8E=87=E9=A2=84=E8=A7=88=E5=9B=9E=E9=80=80=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E9=85=8D=E7=BD=AE=EF=BC=9B=E6=92=A4=E9=94=80=E7=BD=9A?= =?UTF-8?q?=E5=8D=95=E8=AE=B0=E5=BD=95=E5=A4=84=E7=90=86=E4=BA=BA=EF=BC=9B?= =?UTF-8?q?=E9=98=B2=E9=87=8D=E5=A4=8D=E5=88=86=E7=BA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orders/views.py | 35 +++++++++++++++++++++------------- users/fadan_fenhong_utils.py | 37 ++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/orders/views.py b/orders/views.py index b37ccf0..517d157 100644 --- a/orders/views.py +++ b/orders/views.py @@ -57,7 +57,7 @@ from orders.notice_tasks import dingdan_guangbo from .models import ( Order, MerchantOrderExt, PlatformOrderExt, PlayerDeliveryImage, - PenaltyRecord, PenaltyEvidenceImage, Penalty, PenaltyAppealImage, PenaltyBonus, + PenaltyRecord, PenaltyEvidenceImage, Penalty, PenaltyAppealImage, PenaltyBonus, PenaltyBonusRate, CommissionRate, PlayerRating, RefundRecord, ) from jituan.services.club_config import get_commission_rate, get_commission_rate_object @@ -2299,16 +2299,19 @@ class ShangjiaDingdanXiangqingView(APIView): 'update_time': ut, } - # 7. 商家自己的分红利率(用于罚款分红计算) + # 7. 商家分红利率(申请页预览):个人记录优先,否则全局 fadan_fenhong_lilv shenfen=5 fenhong_lilv = 0.0 try: - # 查找商家作为分红者的最新记录,取应得利率 last_fenhong = PenaltyBonus.query.filter( BeneficiaryID=yonghuid, - Identity=1 # 1=商家 + Identity=1, # fadan_fenhong 表:1=商家 ).order_by('-CreateTime').first() - if last_fenhong: - fenhong_lilv = float(last_fenhong.IndividualRate or 0) + if last_fenhong and last_fenhong.IndividualRate: + fenhong_lilv = float(last_fenhong.IndividualRate) + else: + global_rate = PenaltyBonusRate.query.filter(Identity=5).first() + if global_rate and global_rate.Rate: + fenhong_lilv = float(global_rate.Rate) except Exception as e: logger.warning(f'获取分红利率失败: {e}') @@ -6593,9 +6596,9 @@ class ShangjiaFakuaiXiugaiView(APIView): return Response({'code': 403, 'msg': '罚单与订单不匹配'}, status=status.HTTP_403_FORBIDDEN) if operation == 'modify_penalty': - return self._modify_penalty(fadan, request.data.get('liyou', ''), request.data.get('jine')) + return self._modify_penalty(fadan, request.data.get('liyou', ''), request.data.get('jine'), user.UserUID) elif operation == 'cancel_penalty': - return self._cancel_penalty(fadan, request.data.get('liyou', '')) + return self._cancel_penalty(fadan, request.data.get('liyou', ''), user.UserUID) elif operation == 'resubmit_penalty': return self._resubmit_penalty(fadan, request.data.get('liyou', ''), request.data.get('jine')) elif operation == 'manage_penalty_evidence': @@ -6625,7 +6628,7 @@ class ShangjiaFakuaiXiugaiView(APIView): dingdan.save() return Response({'code': 0, 'msg': '退款理由修改成功'}) - def _modify_penalty(self, fadan, liyou, jine_str): + def _modify_penalty(self, fadan, liyou, jine_str, processor_id=None): """修改罚款(仅状态1待缴纳 或 3申诉中)""" if fadan.Status not in (1, 3): return Response({'code': 400, 'msg': '当前罚单状态不可修改'}) @@ -6640,15 +6643,16 @@ class ShangjiaFakuaiXiugaiView(APIView): with transaction.atomic(): fadan.Reason = liyou[:500] fadan.FineAmount = jine - # 如果之前是驳回状态修改,需要重置状态为待缴纳?不,修改不应改变状态 + if processor_id: + fadan.ProcessorID = processor_id fadan.save() logger.info( f"商家修改罚单{fadan.id}:理由={liyou[:50]},金额={jine}," - f"操作人={fadan.ApplicantID}" + f"操作人={processor_id or fadan.ApplicantID}" ) return Response({'code': 0, 'msg': '罚款修改成功'}) - def _cancel_penalty(self, fadan, liyou): + def _cancel_penalty(self, fadan, liyou, processor_id=None): """撤销罚款(状态1或3 → 状态4 已驳回)""" if fadan.Status not in (1, 3): return Response({'code': 400, 'msg': '当前罚单状态不可撤销'}) @@ -6657,8 +6661,13 @@ class ShangjiaFakuaiXiugaiView(APIView): with transaction.atomic(): fadan.Status = 4 # 已驳回 fadan.RejectReason = liyou[:500] + if processor_id: + fadan.ProcessorID = processor_id fadan.save() - logger.info(f"商家撤销罚单{fadan.id},驳回理由={liyou[:50]}") + logger.info( + f"商家撤销罚单{fadan.id},驳回理由={liyou[:50]}," + f"操作人={processor_id or fadan.ApplicantID}" + ) return Response({'code': 0, 'msg': '罚款已撤销(驳回)'}) def _resubmit_penalty(self, fadan, liyou, jine_str): diff --git a/users/fadan_fenhong_utils.py b/users/fadan_fenhong_utils.py index d8b44b6..1f68e04 100644 --- a/users/fadan_fenhong_utils.py +++ b/users/fadan_fenhong_utils.py @@ -37,6 +37,13 @@ def process_fadan_fenhong(fadan_id): logger.error(f"罚单 {fadan_id} 不存在或状态不是已缴纳") return False, "罚单不存在或状态异常" + # 防重复分红(微信回调重试时不可二次加钱) + if fadan.ApplicantBonusAmount and Decimal(str(fadan.ApplicantBonusAmount)) > 0: + logger.info( + f"罚单 {fadan_id} 已分红 {fadan.ApplicantBonusAmount} 元,跳过重复处理" + ) + return True, "已分红" + # 2. 获取申请处罚者ID和身份(源身份数字) shenqing_chufa = fadan.ApplicantID src_shenfen = fadan.ApplicantIdentity @@ -84,8 +91,17 @@ def process_fadan_fenhong(fadan_id): # 7. 根据申请处罚者身份执行不同的分红逻辑 # src_shenfen == 5 代表商家(源身份) if src_shenfen == 5: - # 商家特殊处理:只记录总额,可提现分红永远为0,直接加到商家余额 + # 商家:分红统计累加 + 余额入账(可提现分红字段保持0,钱进商家余额) with transaction.atomic(): + fadan = Penalty.objects.select_for_update().get(id=fadan_id, Status=2) + if fadan.ApplicantBonusAmount and Decimal(str(fadan.ApplicantBonusAmount)) > 0: + logger.info(f"罚单 {fadan_id} 事务内检测到已分红,跳过") + return True, "已分红" + + if not UserShangjia.objects.filter(user__UserUID=shenqing_chufa).exists(): + logger.error(f"商家 {shenqing_chufa} 扩展表不存在,无法分红入账") + return False, "商家资料不存在,无法分红" + fenhong_record, created = PenaltyBonus.objects.get_or_create( BeneficiaryID=shenqing_chufa, Identity=fenhong_shenfen, @@ -104,22 +120,23 @@ def process_fadan_fenhong(fadan_id): fenhong_record.save() # 直接增加商家余额(UserShangjia.yue) - try: - shangjia = UserShangjia.objects.get(user__UserUID=shenqing_chufa) - shangjia.yue += fenhong_jine - shangjia.save(update_fields=['yue']) - logger.info(f"商家 {shenqing_chufa} 余额增加 {fenhong_jine} 元") - except UserShangjia.DoesNotExist: - logger.error(f"商家 {shenqing_chufa} 扩展表不存在,无法增加余额") - raise Exception(f"商家 {shenqing_chufa} 扩展表不存在,无法增加余额") + shangjia = UserShangjia.objects.select_for_update().get(user__UserUID=shenqing_chufa) + shangjia.yue += fenhong_jine + shangjia.save(update_fields=['yue']) + logger.info(f"商家 {shenqing_chufa} 余额增加 {fenhong_jine} 元") # 更新罚单中的申请人分红金额 fadan.ApplicantBonusAmount = fenhong_jine fadan.save(update_fields=['ApplicantBonusAmount']) else: - # 其他身份(客服、售后、管理员、店铺):同时增加总额和可提现分红 + # 其他身份(客服、售后、管理员、店铺):累加可提现分红 with transaction.atomic(): + fadan = Penalty.objects.select_for_update().get(id=fadan_id, Status=2) + if fadan.ApplicantBonusAmount and Decimal(str(fadan.ApplicantBonusAmount)) > 0: + logger.info(f"罚单 {fadan_id} 事务内检测到已分红,跳过") + return True, "已分红" + fenhong_record, created = PenaltyBonus.objects.get_or_create( BeneficiaryID=shenqing_chufa, Identity=fenhong_shenfen,