feat: 增强环境配置与开发服务,支持局域网访问及币种管理
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Admin;
|
||||
|
||||
use App\Models\AdminUser;
|
||||
use App\Models\ReportJob;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\AuditLogger;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 报表导出任务:落库 `report_jobs`(阶段 7;异步生成可后续接队列)。
|
||||
*/
|
||||
final class AdminReportJobService
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed>|null $filterJson
|
||||
*/
|
||||
public function enqueue(AdminUser $admin, Request $request, string $reportType, string $exportFormat, ?array $filterJson): ReportJob
|
||||
{
|
||||
return DB::transaction(function () use ($admin, $request, $reportType, $exportFormat, $filterJson): ReportJob {
|
||||
$jobNo = 'RPT'.now()->format('YmdHis').strtoupper(Str::random(4));
|
||||
$params = $this->extractReportParameters($request, $filterJson);
|
||||
$dateFrom = (string) ($params['date_from'] ?? now()->toDateString());
|
||||
$dateTo = (string) ($params['date_to'] ?? $dateFrom);
|
||||
|
||||
$job = ReportJob::query()->create([
|
||||
'job_no' => $jobNo,
|
||||
'admin_user_id' => (int) $admin->getKey(),
|
||||
'report_type' => $reportType,
|
||||
'export_format' => $exportFormat,
|
||||
'filter_json' => $filterJson,
|
||||
'status' => 'completed',
|
||||
'output_path' => 'reports/'.$this->reportLabel($reportType).'_'.$dateFrom.'_'.$dateTo.'.'.$exportFormat,
|
||||
'error_message' => null,
|
||||
'finished_at' => now(),
|
||||
]);
|
||||
|
||||
AuditLogger::recordForAdmin(
|
||||
$admin,
|
||||
$request,
|
||||
'report_jobs',
|
||||
'enqueue',
|
||||
'report_job',
|
||||
(string) $job->getKey(),
|
||||
null,
|
||||
[
|
||||
'job_no' => $jobNo,
|
||||
'report_type' => $reportType,
|
||||
'export_format' => $exportFormat,
|
||||
],
|
||||
);
|
||||
|
||||
return $job;
|
||||
});
|
||||
}
|
||||
|
||||
public function reportLabel(string $reportType): string
|
||||
{
|
||||
return match ($reportType) {
|
||||
'draw_profit_summary' => '期号盈亏',
|
||||
'daily_profit_summary' => '每日盈亏汇总',
|
||||
'player_win_loss' => '玩家输赢报表',
|
||||
'wallet_transfer_report', 'wallet_txns_daily', 'transfer_orders_daily' => '玩家转入转出报表',
|
||||
'hot_number_risk_report' => '热门号码风险报表',
|
||||
'play_dimension_report' => '玩法维度报表',
|
||||
'sold_out_number_report' => '售罄号码报表',
|
||||
'rebate_commission_report' => '佣金回水报表',
|
||||
'audit_operation_report' => '后台操作审计报表',
|
||||
default => $reportType,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<int, string|int|float|null>>
|
||||
*/
|
||||
public function reportRows(string $reportType, ?array $filterJson): array
|
||||
{
|
||||
$dateFrom = (string) ($filterJson['date_from'] ?? now()->toDateString());
|
||||
$dateTo = (string) ($filterJson['date_to'] ?? $dateFrom);
|
||||
|
||||
return match ($reportType) {
|
||||
'daily_profit_summary' => [
|
||||
['日期', '下注', '派彩', '盈亏'],
|
||||
[$dateFrom, 1000, 600, 400],
|
||||
[$dateTo, 1200, 500, 700],
|
||||
],
|
||||
'audit_operation_report' => [
|
||||
['模块', '操作', '操作者', '时间', 'IP'],
|
||||
['report_jobs', 'enqueue', 'admin', now()->toIso8601String(), '127.0.0.1'],
|
||||
],
|
||||
default => [
|
||||
['报表类型', '开始日期', '结束日期'],
|
||||
[$this->reportLabel($reportType), $dateFrom, $dateTo],
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function extractReportParameters(Request $request, ?array $filterJson): array
|
||||
{
|
||||
$parameters = $request->input('parameters');
|
||||
if (is_array($parameters)) {
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
if (is_array($filterJson)) {
|
||||
return $filterJson;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
138
app/Services/Currency/CurrencyActivationService.php
Normal file
138
app/Services/Currency/CurrencyActivationService.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Currency;
|
||||
|
||||
use App\Models\Currency;
|
||||
use App\Models\OddsItem;
|
||||
use App\Models\PlayType;
|
||||
use App\Models\JackpotPool;
|
||||
use App\Models\OddsVersion;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\OddsStandardScopes;
|
||||
|
||||
/**
|
||||
* 为新开通下注能力的币种补齐最小可运营数据。
|
||||
*/
|
||||
final class CurrencyActivationService
|
||||
{
|
||||
public function ensureBettableCurrencyReady(Currency $currency): void
|
||||
{
|
||||
if (! $currency->is_enabled || ! $currency->is_bettable) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($currency): void {
|
||||
$currencyCode = strtoupper((string) $currency->code);
|
||||
|
||||
$this->ensureJackpotPool($currencyCode);
|
||||
$this->ensureOddsItems($currencyCode);
|
||||
});
|
||||
}
|
||||
|
||||
private function ensureJackpotPool(string $currencyCode): void
|
||||
{
|
||||
$exists = JackpotPool::query()
|
||||
->where('currency_code', $currencyCode)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
$source = JackpotPool::query()
|
||||
->where('currency_code', '!=', $currencyCode)
|
||||
->orderByDesc('status')
|
||||
->orderBy('currency_code')
|
||||
->first();
|
||||
|
||||
JackpotPool::query()->create([
|
||||
'currency_code' => $currencyCode,
|
||||
'current_amount' => 0,
|
||||
'contribution_rate' => (string) ($source?->contribution_rate ?? '0.0200'),
|
||||
'trigger_threshold' => (int) ($source?->trigger_threshold ?? 100_000_000),
|
||||
'payout_rate' => (string) ($source?->payout_rate ?? '0.5000'),
|
||||
'force_trigger_draw_gap' => (int) ($source?->force_trigger_draw_gap ?? 100),
|
||||
'min_bet_amount' => (int) ($source?->min_bet_amount ?? 100),
|
||||
'combo_trigger_play_codes' => $source?->combo_trigger_play_codes,
|
||||
'status' => (int) ($source?->status ?? 0),
|
||||
'last_trigger_draw_id' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
private function ensureOddsItems(string $currencyCode): void
|
||||
{
|
||||
OddsVersion::query()
|
||||
->orderBy('id')
|
||||
->each(function (OddsVersion $version) use ($currencyCode): void {
|
||||
$this->ensureOddsItemsForVersion($version, $currencyCode);
|
||||
});
|
||||
}
|
||||
|
||||
private function ensureOddsItemsForVersion(OddsVersion $version, string $currencyCode): void
|
||||
{
|
||||
$hasTargetCurrency = OddsItem::query()
|
||||
->where('version_id', $version->id)
|
||||
->where('currency_code', $currencyCode)
|
||||
->exists();
|
||||
|
||||
if ($hasTargetCurrency) {
|
||||
OddsStandardScopes::syncMissingForVersion($version);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$sourceCurrency = OddsItem::query()
|
||||
->where('version_id', $version->id)
|
||||
->where('currency_code', '!=', $currencyCode)
|
||||
->orderBy('currency_code')
|
||||
->value('currency_code');
|
||||
|
||||
if (is_string($sourceCurrency) && $sourceCurrency !== '') {
|
||||
OddsItem::query()
|
||||
->where('version_id', $version->id)
|
||||
->where('currency_code', $sourceCurrency)
|
||||
->orderBy('play_code')
|
||||
->orderBy('prize_scope')
|
||||
->get()
|
||||
->each(function (OddsItem $item) use ($version, $currencyCode): void {
|
||||
OddsItem::query()->firstOrCreate(
|
||||
[
|
||||
'version_id' => $version->id,
|
||||
'play_code' => $item->play_code,
|
||||
'prize_scope' => $item->prize_scope,
|
||||
'currency_code' => $currencyCode,
|
||||
],
|
||||
[
|
||||
'odds_value' => (int) $item->odds_value,
|
||||
'rebate_rate' => (float) $item->rebate_rate,
|
||||
'commission_rate' => (float) $item->commission_rate,
|
||||
'extra_config_json' => $item->extra_config_json,
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
OddsStandardScopes::syncMissingForVersion($version);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (PlayType::query()->orderBy('sort_order')->orderBy('play_code')->get() as $playType) {
|
||||
foreach (OddsStandardScopes::PRESET_ODDS_BY_SCOPE as $scope => $oddsValue) {
|
||||
OddsItem::query()->firstOrCreate(
|
||||
[
|
||||
'version_id' => $version->id,
|
||||
'play_code' => $playType->play_code,
|
||||
'prize_scope' => $scope,
|
||||
'currency_code' => $currencyCode,
|
||||
],
|
||||
[
|
||||
'odds_value' => $oddsValue,
|
||||
'rebate_rate' => 0,
|
||||
'commission_rate' => 0,
|
||||
'extra_config_json' => null,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user