Files
webman-buildadmin-mall/app/common/library/MallPlayxRatios.php

160 lines
4.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\library;
use app\common\model\MallBusinessConfig;
use support\Redis as RedisSupport;
use Throwable;
/**
* PlayX 与积分商城相关的比例配置:优先读 Redis未命中则读 mall_business_config 并回写 Redis无表记录时回退 .env 并写入 Redis。
*/
final class MallPlayxRatios
{
public const REDIS_KEY = 'mall:business_config:playx_ratios';
/**
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}
*/
public static function get(): array
{
$conn = self::redisConnection();
if ($conn !== null) {
$cached = self::readFromRedis($conn);
if ($cached !== null) {
return $cached;
}
}
return self::loadFromDatabaseAndWriteRedis($conn);
}
/**
* @param array{return_ratio?: mixed, unlock_ratio?: mixed, points_to_cash_ratio?: mixed} $ratios
*/
public static function syncToRedis(array $ratios): void
{
$payload = [
'return_ratio' => self::toFloat($ratios['return_ratio'] ?? 0),
'unlock_ratio' => self::toFloat($ratios['unlock_ratio'] ?? 0),
'points_to_cash_ratio' => self::toFloat($ratios['points_to_cash_ratio'] ?? 0),
];
self::writeRedis(self::redisConnection(), $payload);
}
public static function syncFromRow(MallBusinessConfig $row): void
{
self::syncToRedis([
'return_ratio' => $row->return_ratio,
'unlock_ratio' => $row->unlock_ratio,
'points_to_cash_ratio' => $row->points_to_cash_ratio,
]);
}
public static function forget(): void
{
$conn = self::redisConnection();
if ($conn === null) {
return;
}
try {
$conn->del(self::REDIS_KEY);
} catch (Throwable) {
}
}
private static function redisConnection(): ?object
{
$cfg = config('redis');
if (!is_array($cfg) || empty($cfg)) {
return null;
}
try {
return RedisSupport::connection('default');
} catch (Throwable) {
return null;
}
}
/**
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}|null
*/
private static function readFromRedis(object $conn): ?array
{
try {
$raw = $conn->get(self::REDIS_KEY);
} catch (Throwable) {
return null;
}
if (!is_string($raw) || $raw === '') {
return null;
}
$data = json_decode($raw, true);
if (!is_array($data)) {
return null;
}
if (!isset($data['return_ratio'], $data['unlock_ratio'], $data['points_to_cash_ratio'])) {
return null;
}
return [
'return_ratio' => self::toFloat($data['return_ratio']),
'unlock_ratio' => self::toFloat($data['unlock_ratio']),
'points_to_cash_ratio' => self::toFloat($data['points_to_cash_ratio']),
];
}
/**
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}
*/
private static function loadFromDatabaseAndWriteRedis(?object $conn): array
{
$row = MallBusinessConfig::order('id', 'asc')->find();
if ($row) {
$out = [
'return_ratio' => self::toFloat($row->return_ratio),
'unlock_ratio' => self::toFloat($row->unlock_ratio),
'points_to_cash_ratio' => self::toFloat($row->points_to_cash_ratio),
];
self::writeRedis($conn, $out);
return $out;
}
$out = [
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
];
self::writeRedis($conn, $out);
return $out;
}
/**
* @param array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float} $payload
*/
private static function writeRedis(?object $conn, array $payload): void
{
if ($conn === null) {
return;
}
try {
$json = json_encode($payload, JSON_THROW_ON_ERROR);
$conn->set(self::REDIS_KEY, $json);
} catch (Throwable) {
}
}
private static function toFloat(mixed $v): float
{
if (is_numeric($v)) {
return floatval($v);
}
return 0.0;
}
}