feat(agent): 编辑代理费率时检测下级未结算注单并二次确认

洗码率/返水率/占成率在下注未结算期间被修改, 结算(openingBet)会按新值
参与代理分账, 导致本局佣金与下注时预期不符。新增编辑时检测: 费率确有
变动且下级存在近1小时内 is_end=0 的注单时返回 code=2, 前端弹框二次
确认, 确认后带 confirm_pending 重提。纯增量护栏, 不改结算逻辑。
This commit is contained in:
2026-05-29 06:43:21 +08:00
parent 50d131aa75
commit 020dd802d6
2 changed files with 59 additions and 0 deletions
+32
View File
@@ -682,6 +682,38 @@ class Agent Extends Common{
die(json_encode(['code'=>0,'msg'=>$lang['rebate_cannot_lower_agent'].' '.$childMaxRebateRate.'%']));
}
// —— 时序风险检测 ——
// 洗码率/返水率/占成率在「下注未结算」期间被修改,结算(openingBet)会按新值参与代理分账,
// 导致本局佣金与下注时预期不符。仅当上述费率确有变化、且该代理下级存在未结算注单时,要求二次确认。
// 限红(limit_*)不参与结算、赔率(price_*)代理端只读,故不在检测范围。
$confirm_pending = Request::instance()->post('confirm_pending');
$rateChanged = (
abs($agent_ximalv - (float)$user['agent_ximalv']) > 0.001 ||
abs($agent_ximalv_dt - (float)$user['agent_ximalv_dt']) > 0.001 ||
abs($agent_ximalv_nn - (float)$user['agent_ximalv_nn']) > 0.001 ||
abs($agent_ximalv_tc - (float)$user['agent_ximalv_tc']) > 0.001 ||
abs($agent_cs - (float)$user['agent_cs']) > 0.001 ||
abs((float)$rebate_rate - (float)$user['rebate_rate']) > 0.001
);
if($rateChanged && !$confirm_pending){
// bet 表位于 DB2 连接(与 Report 模块一致);下级注单路径匹配沿用全站约定的两段 LIKE。
// create_time 限定近 1 小时,规避历史异常残留的 is_end=0 注单造成的误报。
$pendingCount = Db::connect('DB2')->name('bet')
->where('is_end', 0)
->where('create_time', '>=', time() - 3600)
->where(function($q) use ($user_id){
$q->where('agent_parent_id_path', 'like', '%,'.$user_id.',%')
->whereOr('agent_parent_id_path', 'like', $user_id.',%');
})
->count();
if($pendingCount > 0){
die(json_encode([
'code' => 2,
'pending' => $pendingCount,
'msg' => '该代理下级当前有 '.$pendingCount.' 笔注单尚未结算。本次修改的洗码率 / 返水率 / 占成率将按新值参与这些注单的代理分账,可能使本局佣金与下注时预期不符。确定仍要立即保存吗?',
]));
}
}
// 拼装数据创建代理
$user_data = array();
+27
View File
@@ -277,6 +277,33 @@
x_admin_close();
parent.location.reload();
});
} else if (data.code == 2) {
// 时序风险:下级有未结算注单,二次确认后带 confirm_pending 重新提交
layer.confirm(data.msg, {
title: lang.message,
btn: ['确定保存', '取消']
}, function (idx) {
layer.close(idx);
query.confirm_pending = 1;
$.ajax({
url: '/agent/do_edit',
data: query,
type: 'POST',
dataType: 'JSON',
success: function (d) {
if (d.code == 0) {
layer.msg(d.msg);
} else if (d.code == 1) {
layer.alert(d.msg, {
title: lang.message
}, function () {
x_admin_close();
parent.location.reload();
});
}
}
});
});
}
}
})