修复一下这个函数 新增一个字段, 输赢整数 # 赔付状态 -1:闲输 1:正常赔付玩家赢 2 部分赔付玩家赢 3 喝水赔付玩家赢
def calculate_winning(agent_id, draw_period, winning_numbers, return_principal_on_loss=True):
"""
计算某一期所有投注的赔付结果,并在结果中包含 username 和 balance
:param agent_id: 代理ID
:param draw_period: 期号
:param winning_numbers: 开奖号码(格式如 "7,8,6,9")
:param mysql: MySQL 数据库连接对象
:param return_principal_on_loss: 是否在部分赔付时返还本金(默认 True)
:return: 赔付明细列表,每个条目包含 user_id, username, bet_amount, win_amount, status, balance 等字段
"""
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
#cursor = mysql.cursor(dictionary=True) #这个可以调试
# 1. 获取投注记录并结合 users 表获取 username 和 balance
query_bets = """
SELECT b.*, u.username, u.balance
FROM bets b
JOIN users u ON b.user_id = u.id
WHERE b.agent_id = %s AND b.draw_period = %s
"""
cursor.execute(query_bets, (agent_id, draw_period))
bets = cursor.fetchall()
if not bets:
print("没有找到相关下注记录")
return []
# 2. 获取庄家信息
query_bank = """
SELECT * FROM banks WHERE agent_id = %s
"""
cursor.execute(query_bank, (agent_id,))
bank = cursor.fetchone()
if not bank:
print("没有找到对应庄家信息")
return []
bank_balance = float(bank['balance'])
# 3. 获取赔率配置
query_agent = """
SELECT odds_settings FROM agents WHERE id = %s
"""
cursor.execute(query_agent, (agent_id,))
agent = cursor.fetchone()
if not agent or not agent['odds_settings']:
print("代理配置缺失")
return []
odds_settings = json.loads(agent['odds_settings'])["赔率_限红"]
code_to_odds = {}
code_to_tie_rule = {}
for key in odds_settings:
point_code = str(odds_settings[key]['代码'])
code_to_odds[point_code] = float(odds_settings[key]['赔率'])
code_to_tie_rule[point_code] = bool(odds_settings[key].get('同点庄赢', False))
# 4. 解析开奖号码
try:
winning_list = [int(num) for num in winning_numbers.split(',')]
except:
print("开奖号码格式错误")
return []
if len(winning_list) < 2:
print("开奖号码数据不完整")
return []
banker_point = int(winning_list[0])
player_points = [int(p) for p in winning_list[1:]]
# 5. 按 bet_type 分组
def get_player_index(bet):
try:
return int(bet['bet_type'].replace('门', ''))
except:
return -1
bets_by_position = {}
for bet in bets:
pos = get_player_index(bet)
if pos not in bets_by_position:
bets_by_position[pos] = []
bets_by_position[pos].append(bet)
# 6. 构造有效门次并排序
valid_positions = [
(idx + 1, player_points[idx])
for idx in range(len(player_points))
if (idx + 1) in bets_by_position
]
sorted_positions = sorted(valid_positions, key=lambda x: x[1], reverse=True)
results = []
# 7. 先杀阶段:比庄小或平局
print("【第一阶段】开始:先杀(比庄小或平局)")
for idx, player_point in enumerate(player_points, start=1):
if idx not in bets_by_position:
continue
current_bets = bets_by_position.get(idx, [])
for bet in current_bets:
amount = float(bet['amount'])
user_id = bet['user_id']
username = bet['username']
balance = float(bet['balance']) # 用户原始余额
bet_code = str(player_point)
if player_point < banker_point:
# 比庄小,输
bank_balance += amount
total_win = 0 if not return_principal_on_loss else amount
status = "输(先杀)"
reason = f"玩家点数 {player_point} 小于庄家点数 {banker_point}"
results.append({
"user_id": user_id,
"username": username,
"bet_amount": amount,
"win_amount": total_win,
"odds": 0,
"status": status,
"reason": reason,
"balance": balance + total_win
})
update_query = "UPDATE bets SET win_amount = %s WHERE id = %s"
cursor.execute(update_query, (total_win, bet['id']))
# 新增:更新用户余额
update_user_balance_query = "UPDATE users SET balance = %s WHERE id = %s"
cursor.execute(update_user_balance_query, (balance + total_win, user_id))
elif player_point == banker_point:
tie_rule = code_to_tie_rule.get(bet_code, False)
if tie_rule:
max_payout = amount * code_to_odds.get(bet_code, 1.0)
if bank_balance >= max_payout:
win_amount = max_payout
bank_balance -= win_amount
total_win = win_amount
status = "正常赔付(平局且闲赢)"
reason = f"平局,但赔率配置允许闲赢,赔付 {max_payout:.2f}"
elif bank_balance > 0:
win_amount = bank_balance
bank_balance -= win_amount
total_win = win_amount
if return_principal_on_loss:
total_win += amount
status = "部分赔付(平局且闲赢)"
reason = f"平局,但庄家余额不足,赔付 {win_amount:.2f}" + (
f",返还本金 {amount:.2f}" if return_principal_on_loss else "")
else:
total_win = amount if return_principal_on_loss else 0
status = "喝水赔付(返还本金)"
reason = "平局且庄家无余额,仅返还本金"
results.append({
"user_id": user_id,
"username": username,
"bet_amount": amount,
"win_amount": total_win,
"odds": code_to_odds.get(bet_code, 1.0),
"status": status,
"reason": reason,
"balance": balance + total_win
})
update_query = "UPDATE bets SET win_amount = %s WHERE id = %s"
cursor.execute(update_query, (total_win, bet['id']))
# 新增:更新用户余额
update_user_balance_query = "UPDATE users SET balance = %s WHERE id = %s"
cursor.execute(update_user_balance_query, (balance + total_win, user_id))
else:
bank_balance += amount
total_win = 0 if not return_principal_on_loss else amount
results.append({
"user_id": user_id,
"username": username,
"bet_amount": amount,
"win_amount": total_win,
"odds": 0,
"status": "输(平局且庄赢)",
"reason": f"平局且赔率配置规定庄赢,没收投注金额 {amount:.2f}",
"balance": balance + total_win
})
update_query = "UPDATE bets SET win_amount = %s WHERE id = %s"
cursor.execute(update_query, (total_win, bet['id']))
# 新增:更新用户余额
update_user_balance_query = "UPDATE users SET balance = %s WHERE id = %s"
cursor.execute(update_user_balance_query, (balance + total_win, user_id))
print(f"当前庄家余额:{bank_balance:.2f}")
# 8. 后赔阶段:从高到低赔付
print("【第二阶段】开始:后赔(点数从高到低)")
for idx, player_point in sorted_positions:
if player_point <= banker_point:
continue
current_bets = bets_by_position.get(idx, [])
for bet in current_bets:
amount = float(bet['amount'])
user_id = bet['user_id']
username = bet['username']
balance = float(bet['balance']) # 原始余额
bet_code = str(player_point)
odds = code_to_odds.get(bet_code, 1.0)
max_payout = amount * odds
if bank_balance >= max_payout:
win_amount = max_payout
bank_balance -= win_amount
total_win = win_amount
status = "正常赔付"
reason = f"玩家点数 {player_point} 大于庄家点数 {banker_point},赔付 {win_amount:.2f}"
elif bank_balance > 0:
win_amount = bank_balance
bank_balance -= win_amount
total_win = win_amount
if return_principal_on_loss:
total_win += amount
status = "部分赔付(庄家余额不足)"
reason = f"玩家点数 {player_point} 大于庄家点数 {banker_point},但庄家余额不足,赔付 {win_amount:.2f}" + (
f",返还本金 {amount:.2f}" if return_principal_on_loss else ""
)
else:
total_win = amount if return_principal_on_loss else 0
status = "喝水赔付(返还本金)"
reason = "玩家点数大于庄家,但庄家无余额,仅返还本金"
new_balance = balance + total_win
results.append({
"user_id": user_id,
"username": username,
"bet_amount": amount,
"win_amount": total_win,
"odds": odds if total_win != amount else 1.0,
"status": status,
"reason": reason,
"balance": new_balance,
"player_point":player_point
})
update_query = "UPDATE bets SET win_amount = %s WHERE id = %s"
cursor.execute(update_query, (total_win, bet['id']))
# 新增:更新用户余额
update_user_balance_query = "UPDATE users SET balance = %s WHERE id = %s"
cursor.execute(update_user_balance_query, (new_balance, user_id))
print(f"门次:{idx}, 点数:{player_point}, 当前庄家余额:{bank_balance:.2f}")
if bank_balance <= 0:
print("庄家余额已耗尽,后续投注仅返还本金(喝水)")
# 9. 更新庄家余额
update_bank_query = "UPDATE banks SET balance = %s WHERE id = %s"
cursor.execute(update_bank_query, (bank_balance, bank['id']))
cursor.close()
print(f"\n最终庄家余额:{bank_balance:.2f}")
print(f"赔付明细:\n{json.dumps(results, indent=4, ensure_ascii=False)}")
return format_payout_result(results, draw_period)