优化临时插入用户接口/api/user/Login和抽奖接口/api/game/playStart

This commit is contained in:
2026-04-08 17:32:14 +08:00
parent ef684a1c55
commit 765f50963a
5 changed files with 39 additions and 14 deletions

View File

@@ -26,9 +26,13 @@ class UserController extends BaseController
*/ */
public function Login(Request $request): Response public function Login(Request $request): Response
{ {
$username = trim((string) ($request->post('username', ''))); $usernameRaw = $request->post('username', '');
$password = trim((string) ($request->post('password', ''))); $passwordRaw = $request->post('password', '');
$lang = trim((string) ($request->post('lang', 'chs'))); $langRaw = $request->post('lang', 'zh');
$username = is_string($usernameRaw) ? trim($usernameRaw) : '';
$password = is_string($passwordRaw) ? trim($passwordRaw) : '';
$lang = is_string($langRaw) ? trim($langRaw) : 'zh';
$coin = $request->post('coin'); $coin = $request->post('coin');
$coin = $coin !== null && $coin !== '' ? (float) $coin : 0.0; $coin = $coin !== null && $coin !== '' ? (float) $coin : 0.0;
$time = $request->post('time'); $time = $request->post('time');

View File

@@ -58,7 +58,7 @@ class GameController extends BaseController
try { try {
$logic = new UserLogic(); $logic = new UserLogic();
$result = $logic->loginByUsername($username, $password, $lang === 'en' ? 'en' : 'chs', 0.0, $time, $adminId, $adminIdsInTopDept); $result = $logic->loginByUsername($username, $password, $lang, 0.0, $time, $adminId, $adminIdsInTopDept);
} catch (\plugin\saiadmin\exception\ApiException $e) { } catch (\plugin\saiadmin\exception\ApiException $e) {
return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR); return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
} }

View File

@@ -19,6 +19,7 @@ return [
'账号已被禁用,无法登录' => 'Account is disabled and cannot log in', '账号已被禁用,无法登录' => 'Account is disabled and cannot log in',
'购买抽奖券错误' => 'Invalid lottery ticket purchase', '购买抽奖券错误' => 'Invalid lottery ticket purchase',
'平台币不足' => 'Insufficient balance', '平台币不足' => 'Insufficient balance',
'余额不足' => 'Insufficient balance',
'direction 必须为 0 或 1' => 'direction must be 0 or 1', 'direction 必须为 0 或 1' => 'direction must be 0 or 1',
'当前玩家余额%s小于%s无法继续游戏' => 'Balance %s is less than %s, cannot continue', '当前玩家余额%s小于%s无法继续游戏' => 'Balance %s is less than %s, cannot continue',
'服务超时,' => 'Service timeout: ', '服务超时,' => 'Service timeout: ',

View File

@@ -115,16 +115,29 @@ class PlayStartLogic
throw new ApiException('Lottery pool config not found (name=default required)'); throw new ApiException('Lottery pool config not found (name=default required)');
} }
// 余额校验:统一校验 ante * min(real_ev) // 付费抽奖:开始前扣除费用 ante * UNIT_COST
$minEv = DiceRewardConfig::getCachedMinRealEv();
$needMinBalance = abs((float) $minEv) * $ante;
if ($coin < $needMinBalance) {
throw new ApiException('未达抽奖余额 ' . $needMinBalance . ',无法开始游戏');
}
// 付费抽奖:开始前扣除费用 ante * UNIT_COST不足则提示余额不足
$paidAmount = $ticketType === self::LOTTERY_TYPE_PAID ? round($ante * self::UNIT_COST, 2) : 0.0; $paidAmount = $ticketType === self::LOTTERY_TYPE_PAID ? round($ante * self::UNIT_COST, 2) : 0.0;
if ($ticketType === self::LOTTERY_TYPE_PAID && $coin < $paidAmount) {
// 游玩前余额校验(按 T4 惩罚最大值兜底):
// 门槛 = paidAmount(压注*1) + abs(T4最小real_ev)*ante
$t4List = DiceRewardConfig::getCachedByTier('T4');
$t4MinRealEv = null;
foreach ($t4List as $row) {
$ev = $row['real_ev'] ?? null;
if ($ev === null || $ev === '') {
continue;
}
$evFloat = filter_var($ev, FILTER_VALIDATE_FLOAT);
if ($evFloat === false) {
continue;
}
if ($t4MinRealEv === null || $evFloat < $t4MinRealEv) {
$t4MinRealEv = $evFloat;
}
}
$t4PenaltyAbs = $t4MinRealEv === null ? 0.0 : abs($t4MinRealEv) * $ante;
$needMinBalance = round($paidAmount + $t4PenaltyAbs, 2);
if ($coin < $needMinBalance) {
throw new ApiException('余额不足'); throw new ApiException('余额不足');
} }
@@ -303,6 +316,10 @@ class PlayStartLogic
$coinBefore = (float) $p->coin; $coinBefore = (float) $p->coin;
// 开始前先扣付费金额,再加中奖金额(免费抽奖 paid_amount=0 // 开始前先扣付费金额,再加中奖金额(免费抽奖 paid_amount=0
$coinAfter = round($coinBefore - $paidAmount + $winCoin, 2); $coinAfter = round($coinBefore - $paidAmount + $winCoin, 2);
// T4 惩罚兜底:扣完购券费用后若余额不足以承受本次惩罚(导致为负),统一按“余额不足”提示
if ($rewardTier === 'T4' && $coinAfter < 0) {
throw new ApiException('余额不足');
}
$p->coin = $coinAfter; $p->coin = $coinAfter;
// 免费抽奖消耗:优先消耗 free_ticket.count耗尽则清空 free_ticket否则兼容旧 free_ticket_count // 免费抽奖消耗:优先消耗 free_ticket.count耗尽则清空 free_ticket否则兼容旧 free_ticket_count
if ($ticketType === self::LOTTERY_TYPE_FREE) { if ($ticketType === self::LOTTERY_TYPE_FREE) {

View File

@@ -174,7 +174,10 @@ class UserLogic
UserCache::setPlayerByUsername($username, $userArr); UserCache::setPlayerByUsername($username, $userArr);
$baseUrl = rtrim(config('api.login_url_base', 'https://127.0.0.1:6777'), '/'); $baseUrl = rtrim(config('api.login_url_base', 'https://127.0.0.1:6777'), '/');
$lang = in_array($lang, ['chs', 'en'], true) ? $lang : 'chs'; $lang = strtolower(trim($lang));
if ($lang !== 'en') {
$lang = 'zh';
}
$tokenInUrl = str_replace('%3D', '=', urlencode($token)); $tokenInUrl = str_replace('%3D', '=', urlencode($token));
$url = $baseUrl . '?token=' . $tokenInUrl . '&lang=' . $lang; $url = $baseUrl . '?token=' . $tokenInUrl . '&lang=' . $lang;