1.优化常规配置/admin/config/gameConfig新增派彩时间设置
2.修复后台翻译问题
This commit is contained in:
@@ -25,13 +25,14 @@ final class GameLiveService
|
|||||||
private const EVT_PERIOD_PAYOUT = 'period.payout';
|
private const EVT_PERIOD_PAYOUT = 'period.payout';
|
||||||
private const KEY_PERIOD_SECONDS = 'period_seconds';
|
private const KEY_PERIOD_SECONDS = 'period_seconds';
|
||||||
private const KEY_BET_SECONDS = 'bet_seconds';
|
private const KEY_BET_SECONDS = 'bet_seconds';
|
||||||
|
private const KEY_PAYOUT_SECONDS = 'payout_seconds';
|
||||||
private const KEY_PICK_MAX_NUMBER_COUNT = 'pick_max_number_count';
|
private const KEY_PICK_MAX_NUMBER_COUNT = 'pick_max_number_count';
|
||||||
|
|
||||||
/** 开奖结果号码池:1 至此上限(与单注可选号码个数配置无关) */
|
/** 开奖结果号码池:1 至此上限(与单注可选号码个数配置无关) */
|
||||||
private const DRAW_NUMBER_MAX = 36;
|
private const DRAW_NUMBER_MAX = 36;
|
||||||
|
|
||||||
/** 开奖后派彩展示宽限期(秒),之后再创建下一期 */
|
/** 派彩展示宽限期默认值(秒),可被 game_config.payout_seconds 覆盖 */
|
||||||
private const PAYOUT_GRACE_SECONDS = 3;
|
private const DEFAULT_PAYOUT_SECONDS = 3;
|
||||||
/** 启动自愈:判定“异常卡局”的最小超时冗余秒数 */
|
/** 启动自愈:判定“异常卡局”的最小超时冗余秒数 */
|
||||||
private const STARTUP_RECOVER_GRACE_SECONDS = 10;
|
private const STARTUP_RECOVER_GRACE_SECONDS = 10;
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ final class GameLiveService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$periodSeconds = self::getConfigInt(self::KEY_PERIOD_SECONDS, 30);
|
$periodSeconds = self::getConfigInt(self::KEY_PERIOD_SECONDS, 30);
|
||||||
$timeoutAt = $periodStartAt + $periodSeconds + self::PAYOUT_GRACE_SECONDS + self::STARTUP_RECOVER_GRACE_SECONDS;
|
$timeoutAt = $periodStartAt + $periodSeconds + self::getPayoutGraceSeconds() + self::STARTUP_RECOVER_GRACE_SECONDS;
|
||||||
if (time() <= $timeoutAt) {
|
if (time() <= $timeoutAt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,7 @@ final class GameLiveService
|
|||||||
GameBetSettleService::settleBetsForDraw($recordId, $resultNumber);
|
GameBetSettleService::settleBetsForDraw($recordId, $resultNumber);
|
||||||
if ($status === 2) {
|
if ($status === 2) {
|
||||||
if ($payoutUntil <= 0) {
|
if ($payoutUntil <= 0) {
|
||||||
$payoutUntil = $now + self::PAYOUT_GRACE_SECONDS;
|
$payoutUntil = $now + self::getPayoutGraceSeconds();
|
||||||
}
|
}
|
||||||
Db::name('game_record')->where('id', $recordId)->update([
|
Db::name('game_record')->where('id', $recordId)->update([
|
||||||
'status' => 3,
|
'status' => 3,
|
||||||
@@ -575,7 +576,7 @@ final class GameLiveService
|
|||||||
$bets = Db::name('bet_order')->where('period_id', (int) $record['id'])->select()->toArray();
|
$bets = Db::name('bet_order')->where('period_id', (int) $record['id'])->select()->toArray();
|
||||||
$finalLoss = self::estimateLossForNumber($bets, $finalNumber);
|
$finalLoss = self::estimateLossForNumber($bets, $finalNumber);
|
||||||
$now = time();
|
$now = time();
|
||||||
$payoutUntil = $now + self::PAYOUT_GRACE_SECONDS;
|
$payoutUntil = $now + self::getPayoutGraceSeconds();
|
||||||
|
|
||||||
$settleOut = ['jackpot_hits' => []];
|
$settleOut = ['jackpot_hits' => []];
|
||||||
Db::startTrans();
|
Db::startTrans();
|
||||||
@@ -1099,6 +1100,18 @@ final class GameLiveService
|
|||||||
return (int) $v;
|
return (int) $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function getPayoutGraceSeconds(): int
|
||||||
|
{
|
||||||
|
$seconds = self::getConfigInt(self::KEY_PAYOUT_SECONDS, self::DEFAULT_PAYOUT_SECONDS);
|
||||||
|
if ($seconds < 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ($seconds > 300) {
|
||||||
|
return 300;
|
||||||
|
}
|
||||||
|
return $seconds;
|
||||||
|
}
|
||||||
|
|
||||||
private static function getPickMaxNumberCount(): int
|
private static function getPickMaxNumberCount(): int
|
||||||
{
|
{
|
||||||
$max = self::getConfigInt(self::KEY_PICK_MAX_NUMBER_COUNT, 36);
|
$max = self::getConfigInt(self::KEY_PICK_MAX_NUMBER_COUNT, 36);
|
||||||
|
|||||||
@@ -455,25 +455,28 @@ if (!function_exists('get_route_remark')) {
|
|||||||
function get_route_remark(): string
|
function get_route_remark(): string
|
||||||
{
|
{
|
||||||
$controllerPath = get_controller_path() ?? '';
|
$controllerPath = get_controller_path() ?? '';
|
||||||
$actionName = '';
|
if ($controllerPath === '') {
|
||||||
if (function_exists('request')) {
|
return '';
|
||||||
$req = request();
|
|
||||||
if ($req) {
|
|
||||||
$path = trim($req->path(), '/');
|
|
||||||
$parts = explode('/', $path);
|
|
||||||
$actionName = $parts[array_key_last($parts)] ?? '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$path = str_replace('.', '/', $controllerPath);
|
$path = str_replace('.', '/', $controllerPath);
|
||||||
$names = [$path];
|
$menuNames = [$path];
|
||||||
if ($actionName) {
|
$parts = explode('/', $path);
|
||||||
$names[] = $path . '/' . $actionName;
|
foreach ($parts as &$part) {
|
||||||
|
if (str_contains($part, '_')) {
|
||||||
|
$part = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $part))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($part);
|
||||||
|
$camelPath = implode('/', $parts);
|
||||||
|
if ($camelPath !== $path) {
|
||||||
|
$menuNames[] = $camelPath;
|
||||||
}
|
}
|
||||||
$remark = \support\think\Db::name('admin_rule')
|
$remark = \support\think\Db::name('admin_rule')
|
||||||
->where('name', 'in', $names)
|
->where('name', 'in', array_values(array_unique($menuNames)))
|
||||||
|
->where('type', 'in', ['menu', 'menu_dir'])
|
||||||
->value('remark');
|
->value('remark');
|
||||||
$remarkStr = (string) ($remark ?? '');
|
$remarkStr = (string) ($remark ?? '');
|
||||||
if (!$remarkStr) {
|
if ($remarkStr === '') {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return function_exists('trans') ? trans($remarkStr, [], $controllerPath ?: null) : $remarkStr;
|
return function_exists('trans') ? trans($remarkStr, [], $controllerPath ?: null) : $remarkStr;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export default {
|
|||||||
'field_tip period_seconds': 'Duration of each period in seconds',
|
'field_tip period_seconds': 'Duration of each period in seconds',
|
||||||
'field bet_seconds': 'Betting duration (seconds)',
|
'field bet_seconds': 'Betting duration (seconds)',
|
||||||
'field_tip bet_seconds': 'How many seconds betting stays open in each period',
|
'field_tip bet_seconds': 'How many seconds betting stays open in each period',
|
||||||
|
'field payout_seconds': 'Payout duration (seconds)',
|
||||||
|
'field_tip payout_seconds': 'Grace period after draw before the next period starts; lock/calc duration = period duration − betting duration',
|
||||||
'field pick_max_number_count': 'Max numbers per ticket',
|
'field pick_max_number_count': 'Max numbers per ticket',
|
||||||
'field_tip pick_max_number_count': 'Maximum amount of selectable numbers per ticket',
|
'field_tip pick_max_number_count': 'Maximum amount of selectable numbers per ticket',
|
||||||
'field bet_chips': 'Quick chip amounts',
|
'field bet_chips': 'Quick chip amounts',
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export default {
|
|||||||
'field_tip period_seconds': '每一局的总时长(秒)',
|
'field_tip period_seconds': '每一局的总时长(秒)',
|
||||||
'field bet_seconds': '下注时长(秒)',
|
'field bet_seconds': '下注时长(秒)',
|
||||||
'field_tip bet_seconds': '每一局允许下注的时长(秒)',
|
'field_tip bet_seconds': '每一局允许下注的时长(秒)',
|
||||||
|
'field payout_seconds': '派彩时长(秒)',
|
||||||
|
'field_tip payout_seconds': '开奖后派彩展示宽限期(秒),结束后自动进入下一期;封盘计算时长 = 每期时长 − 下注时长',
|
||||||
'field pick_max_number_count': '单注最多号码个数',
|
'field pick_max_number_count': '单注最多号码个数',
|
||||||
'field_tip pick_max_number_count': '单注最多可选号码数量',
|
'field_tip pick_max_number_count': '单注最多可选号码数量',
|
||||||
'field bet_chips': '快捷筹码面额',
|
'field bet_chips': '快捷筹码面额',
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<el-row v-loading="state.loading">
|
<el-row v-loading="state.loading">
|
||||||
<el-col :xs="24" :sm="18">
|
<el-col :xs="24" :sm="18">
|
||||||
@@ -132,7 +132,9 @@ const { t, te } = useI18n()
|
|||||||
const formRef = useTemplateRef('formRef')
|
const formRef = useTemplateRef('formRef')
|
||||||
const api = new baTableApi('/admin/config.GameConfig/')
|
const api = new baTableApi('/admin/config.GameConfig/')
|
||||||
const excludedConfigKeys = new Set(['period_auto_create_enabled', 'period_manual_create_enabled'])
|
const excludedConfigKeys = new Set(['period_auto_create_enabled', 'period_manual_create_enabled'])
|
||||||
const canSave = auth('save')
|
const canSave =
|
||||||
|
auth('save') ||
|
||||||
|
auth({ name: '/admin/config/gameConfig', subNodeName: '/admin/config/game_config/save' })
|
||||||
|
|
||||||
const state: {
|
const state: {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
@@ -157,6 +159,16 @@ const getData = () => {
|
|||||||
api.index({ page: 1, limit: 999 }).then((res) => {
|
api.index({ page: 1, limit: 999 }).then((res) => {
|
||||||
const allList = (res.data.list || []) as GameConfigItem[]
|
const allList = (res.data.list || []) as GameConfigItem[]
|
||||||
const list = allList.filter((item) => !excludedConfigKeys.has(item.config_key))
|
const list = allList.filter((item) => !excludedConfigKeys.has(item.config_key))
|
||||||
|
const displayOrder: Record<string, number> = {
|
||||||
|
period_seconds: 10,
|
||||||
|
bet_seconds: 20,
|
||||||
|
payout_seconds: 30,
|
||||||
|
}
|
||||||
|
list.sort((a, b) => {
|
||||||
|
const orderA = displayOrder[a.config_key] ?? 1000 + a.id
|
||||||
|
const orderB = displayOrder[b.config_key] ?? 1000 + b.id
|
||||||
|
return orderA - orderB
|
||||||
|
})
|
||||||
state.configList = list
|
state.configList = list
|
||||||
state.remark = res.data.remark || ''
|
state.remark = res.data.remark || ''
|
||||||
const nextForm: Record<string, string | number> = {}
|
const nextForm: Record<string, string | number> = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user