feat(jituan): 集团多俱乐部改造 — club 隔离、财务/提现/分红/展示配置

This commit is contained in:
XingQue
2026-06-24 05:02:18 +08:00
parent ce9b09f096
commit dcc4936428
82 changed files with 5748 additions and 924 deletions

View File

@@ -56,17 +56,18 @@ from orders.notice_tasks import dingdan_guangbo
from .models import (
Order, MerchantOrderExt, PlatformOrderExt, PlayerDeliveryImage,
PenaltyRecord, PenaltyEvidenceImage, Penalty, PenaltyBonus
)
from orders.models import (
CommissionRate, PlayerRating, RefundRecord
PenaltyRecord, PenaltyEvidenceImage, Penalty, PenaltyBonus,
CommissionRate, PlayerRating, RefundRecord,
)
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_penalty import resolve_penalty_club_id
from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai
from users.models import UserDashou, UserShangjia, UserBoss
from users.business_models import User
from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao
from config.models import (
Szjilu, ShangjiaLianjie
ShangjiaLianjie
)
@@ -133,8 +134,11 @@ class WechatPayNotifyView(APIView):
out_trade_no = root.find('out_trade_no').text if root.find('out_trade_no') is not None else ''
transaction_id = root.find('transaction_id').text if root.find('transaction_id') is not None else ''
from jituan.services.wechat_pay import club_id_from_order, verify_wechat_v2_signature
notify_club_id = club_id_from_order(out_trade_no)
# 3. 签名验证
if not self._verify_signature(xml_data):
if not verify_wechat_v2_signature(xml_data, notify_club_id):
logger.warning("签名验证失败")
return self._gen_response_xml('FAIL', '签名验证失败')
@@ -303,10 +307,10 @@ class WechatPayNotifyView(APIView):
# 更新收支记录(总累计)
self._update_szjilu(dingdan.Amount)
self._update_szjilu(dingdan.Amount, getattr(dingdan, 'ClubID', None))
# 更新每日收入统计
update_daily_income(dingdan.Amount)
update_daily_income(dingdan.Amount, getattr(dingdan, 'ClubID', None))
# 构建通知数据(你的 _get_game_type_name 方法保留在视图里直接用)
order_info = {
@@ -346,28 +350,12 @@ class WechatPayNotifyView(APIView):
logger.error(f"处理支付失败异常: {e}")
logger.error(traceback.format_exc())
def _update_szjilu(self, jine):
"""更新收支记录表(ID=1的记录"""
def _update_szjilu(self, jine, club_id=None):
"""更新收支记录表(按俱乐部"""
from jituan.services.szjilu_accounting import apply_szjilu_income
try:
jine_decimal = Decimal(str(jine))
with transaction.atomic():
szjilu, created = Szjilu.objects.select_for_update().get_or_create(
id=1,
defaults={
'TotalIncome': Decimal('0.00'),
'TotalFlow': Decimal('0.00'),
'TotalExpense': Decimal('0.00'),
'DailyExpense': Decimal('0.00'),
'DailyFlow': Decimal('0.00')
}
)
if created:
logger.info("创建ID=1的收支记录")
szjilu.TotalIncome += jine_decimal
szjilu.TotalFlow += jine_decimal
szjilu.DailyFlow += jine_decimal
szjilu.save()
logger.info(f"收支记录更新成功,增加金额: {jine}")
apply_szjilu_income(jine, club_id)
logger.info(f"收支记录更新成功,增加金额: {jine}, club={club_id}")
except Exception as e:
logger.error(f"更新收支记录失败: {e}")
@@ -580,10 +568,10 @@ class PaymentVerifyView(APIView):
# 更新收支记录
self._update_szjilu(dingdan.Amount)
self._update_szjilu(dingdan.Amount, getattr(dingdan, 'ClubID', None))
# 更新每日收入统计
update_daily_income(dingdan.Amount)
update_daily_income(dingdan.Amount, getattr(dingdan, 'ClubID', None))
def _query_wechat_payment(self, out_trade_no):
"""
@@ -620,28 +608,12 @@ class PaymentVerifyView(APIView):
err_msg = result.get('return_msg', '未知错误')
raise Exception(f"微信订单查询失败: {err_msg}")
def _update_szjilu(self, jine):
"""更新收支记录表(ID=1的记录"""
def _update_szjilu(self, jine, club_id=None):
"""更新收支记录表(按俱乐部"""
from jituan.services.szjilu_accounting import apply_szjilu_income
try:
jine_decimal = Decimal(str(jine))
with transaction.atomic():
szjilu, created = Szjilu.objects.select_for_update().get_or_create(
id=1,
defaults={
'TotalIncome': Decimal('0.00'),
'TotalFlow': Decimal('0.00'),
'TotalExpense': Decimal('0.00'),
'DailyExpense': Decimal('0.00'),
'DailyFlow': Decimal('0.00')
}
)
if created:
logger.info("创建ID=1的收支记录")
szjilu.TotalIncome += jine_decimal
szjilu.TotalFlow += jine_decimal
szjilu.DailyFlow += jine_decimal
szjilu.save()
logger.info(f"收支记录更新成功,增加金额: {jine}")
apply_szjilu_income(jine, club_id)
logger.info(f"收支记录更新成功,增加金额: {jine}, club={club_id}")
except Exception as e:
logger.error(f"更新收支记录失败: {e}")
# 不抛出异常,因为收支记录不是核心流程,但记录错误供排查
@@ -738,8 +710,8 @@ class CreateOrderView(APIView):
dingdanid = f"PT{timestamp:011d}{timestamp_ns:06d}{random_num:02d}"
# 6. 查询利率并计算分成
# 查询打手利率(字符'1'
dashou_lilu = CommissionRate.query.filter(Platform='1').first()
club_id = resolve_club_id_from_request(request)
dashou_lilu = get_commission_rate_object(club_id, '1')
# 🔥 新增:判断是否使用商品配置的额外分成
@@ -754,11 +726,9 @@ class CreateOrderView(APIView):
# 查询管事利率(字符'2'
#guanshi_lilu = CommissionRate.query.filter(Platform='2').first()
if not dashou_lilu: #or not guanshi_lilu:
return Response({'code': 9, 'msg': '系统利率配置不完整', 'data': None})
# 计算打手分成
#dashou_fencheng = Decimal(str(shangpin_jiage)) * Decimal(str(dashou_lilu.Rate))
if not (shangpin.kaioi_ewai_dashou_fencheng and shangpin.ewai_dashou_fencheng is not None):
if get_commission_rate(club_id, '1') <= 0 and not CommissionRate.query.filter(Platform='1').exists():
return Response({'code': 9, 'msg': '系统利率配置不完整', 'data': None})
# 开始数据库事务
@@ -788,7 +758,8 @@ class CreateOrderView(APIView):
'Nickname': nicheng,
'ImageURL':shangpin_tupian,
'User1ID':f"Boss{request.user.UserUID}",
'ProductTypeID':shangpin.leixing_id
'ProductTypeID':shangpin.leixing_id,
'ClubID': getattr(request, 'club_id', None) or 'xq',
}
# 创建订单记录
@@ -1943,7 +1914,8 @@ class ShangjiaPaifaView(APIView):
return Response({'code': 400, 'msg': '指定用户不是打手'})
# ----- 10. 利率(打手+管事分成,打手优先) -----
dashou_fencheng, guanshi_fencheng = calc_shangjia_order_fencheng(jiage)
club_id = resolve_club_id_from_request(request)
dashou_fencheng, guanshi_fencheng = calc_shangjia_order_fencheng(jiage, club_id=club_id)
# ----- 11. 生成订单ID -----
def generate_dingdan_id():
@@ -1973,7 +1945,8 @@ class ShangjiaPaifaView(APIView):
Remark=dingdan_beizhu[:1000],
Nickname=laoban_name[:50],
ImageURL=request.user.Avatar,
User1ID=f"Sj{request.user.UserUID}"
User1ID=f"Sj{request.user.UserUID}",
ClubID=club_id,
)
logger.info(f"订单主表创建: {dingdan.OrderID}")
@@ -5579,19 +5552,11 @@ class AdTongYiTuiKuanPingTai(APIView):
except (User.DoesNotExist, AttributeError):
logger.warning(f"平台退款:老板{laoban_id}不存在或扩展信息缺失,跳过")
# 16. 更新收支记录表(id=1
# 16. 更新收支记录表(按俱乐部
try:
update_daily_payout(jine)
szjilu_obj = Szjilu.query.get(id=1)
szjilu_obj.TotalIncome -= jine
szjilu_obj.TotalExpense += jine
szjilu_obj.DailyExpense += jine
szjilu_obj.save()
except Szjilu.DoesNotExist:
logger.error(f"平台退款:收支记录表(id=1)不存在,跳过")
from jituan.services.szjilu_accounting import apply_szjilu_expense
update_daily_payout(jine, getattr(dingdan_obj, 'ClubID', None))
apply_szjilu_expense(jine, getattr(dingdan_obj, 'ClubID', None))
except Exception as e:
logger.error(f"更新收支记录表异常: {str(e)}")
@@ -6450,6 +6415,7 @@ class ShangjiaFakuanApplyView(APIView):
Status=1, # 待缴纳
AffectsGrabbing=yingxiang_qiangdan,
ApplicantIdentity=5, # 申请人是商家
ClubID=resolve_penalty_club_id(order=order, penalized_user_id=dashou_id),
)
logger.info(f"商家{shangjia_id}对订单{dingdan_id}打手{dashou_id}罚款成功,金额{fakuanjine}")
return Response({'code': 0, 'msg': '罚款申请已提交'})