1.优化商城参数配置菜单-以及配置生效问题
This commit is contained in:
@@ -18,7 +18,7 @@ DATABASE_CHARSET = utf8mb4
|
|||||||
DATABASE_PREFIX =
|
DATABASE_PREFIX =
|
||||||
|
|
||||||
# PlayX 配置
|
# PlayX 配置
|
||||||
# 以下三项比例以数据库表 mall_config 为准(后台 积分商城 → 商城参数配置);未迁移或无记录时回退为下列 env 默认值
|
# 以下三项比例以数据库表 mall_business_config 为准(后台 积分商城 → 商城参数配置);无记录时回退为下列 env 默认值
|
||||||
# 提现折算:积分 -> 现金(如 10 分 = 1 元,则 points_to_cash_ratio=0.1)
|
# 提现折算:积分 -> 现金(如 10 分 = 1 元,则 points_to_cash_ratio=0.1)
|
||||||
PLAYX_POINTS_TO_CASH_RATIO=0.1
|
PLAYX_POINTS_TO_CASH_RATIO=0.1
|
||||||
# 返还比例:新增保障金 = ABS(yesterday_win_loss_net) * return_ratio(仅亏损时)
|
# 返还比例:新增保障金 = ABS(yesterday_win_loss_net) * return_ratio(仅亏损时)
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ namespace app\admin\controller\mall;
|
|||||||
|
|
||||||
use app\common\controller\Backend;
|
use app\common\controller\Backend;
|
||||||
use app\common\library\MallPlayxRatios;
|
use app\common\library\MallPlayxRatios;
|
||||||
use app\common\model\MallConfig;
|
use app\common\model\MallBusinessConfig;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
use Webman\Http\Request;
|
use Webman\Http\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 积分商城参数(PlayX 比例等)
|
* 积分商城参数(PlayX 比例等,读写 mall_business_config)
|
||||||
*/
|
*/
|
||||||
class PlayxConfig extends Backend
|
class PlayxConfig extends Backend
|
||||||
{
|
{
|
||||||
@@ -22,17 +22,21 @@ class PlayxConfig extends Backend
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = MallConfig::order('id', 'asc')->find();
|
$row = MallBusinessConfig::order('id', 'asc')->find();
|
||||||
if (!$row) {
|
if (!$row) {
|
||||||
$now = time();
|
$now = time();
|
||||||
MallConfig::create([
|
MallBusinessConfig::create([
|
||||||
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
||||||
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_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')),
|
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
||||||
'create_time' => $now,
|
'create_time' => $now,
|
||||||
'update_time' => $now,
|
'update_time' => $now,
|
||||||
]);
|
]);
|
||||||
$row = MallConfig::order('id', 'asc')->find();
|
$row = MallBusinessConfig::order('id', 'asc')->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($row) {
|
||||||
|
MallPlayxRatios::syncFromRow($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->success('', [
|
return $this->success('', [
|
||||||
@@ -67,10 +71,10 @@ class PlayxConfig extends Backend
|
|||||||
return $this->error(__('Parameter error'));
|
return $this->error(__('Parameter error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = MallConfig::order('id', 'asc')->find();
|
$row = MallBusinessConfig::order('id', 'asc')->find();
|
||||||
if (!$row) {
|
if (!$row) {
|
||||||
$now = time();
|
$now = time();
|
||||||
MallConfig::create([
|
MallBusinessConfig::create([
|
||||||
'return_ratio' => $returnF,
|
'return_ratio' => $returnF,
|
||||||
'unlock_ratio' => $unlockF,
|
'unlock_ratio' => $unlockF,
|
||||||
'points_to_cash_ratio' => $cashF,
|
'points_to_cash_ratio' => $cashF,
|
||||||
@@ -84,7 +88,10 @@ class PlayxConfig extends Backend
|
|||||||
$row->save();
|
$row->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
MallPlayxRatios::forget();
|
$fresh = MallBusinessConfig::order('id', 'asc')->find();
|
||||||
|
if ($fresh) {
|
||||||
|
MallPlayxRatios::syncFromRow($fresh);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->success(__('The current page configuration item was updated successfully'));
|
return $this->success(__('The current page configuration item was updated successfully'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,47 +4,148 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace app\common\library;
|
namespace app\common\library;
|
||||||
|
|
||||||
use app\common\model\MallConfig;
|
use app\common\model\MallBusinessConfig;
|
||||||
|
use support\Redis as RedisSupport;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PlayX 与积分商城相关的比例配置:优先读 mall_config,无表记录时回退 .env
|
* PlayX 与积分商城相关的比例配置:优先读 Redis,未命中则读 mall_business_config 并回写 Redis;无表记录时回退 .env 并写入 Redis。
|
||||||
*/
|
*/
|
||||||
final class MallPlayxRatios
|
final class MallPlayxRatios
|
||||||
{
|
{
|
||||||
private static ?array $cache = null;
|
public const REDIS_KEY = 'mall:business_config:playx_ratios';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}
|
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}
|
||||||
*/
|
*/
|
||||||
public static function get(): array
|
public static function get(): array
|
||||||
{
|
{
|
||||||
if (self::$cache !== null) {
|
$conn = self::redisConnection();
|
||||||
return self::$cache;
|
if ($conn !== null) {
|
||||||
|
$cached = self::readFromRedis($conn);
|
||||||
|
if ($cached !== null) {
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = MallConfig::order('id', 'asc')->find();
|
return self::loadFromDatabaseAndWriteRedis($conn);
|
||||||
if ($row) {
|
|
||||||
self::$cache = [
|
|
||||||
'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),
|
|
||||||
];
|
|
||||||
|
|
||||||
return self::$cache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$cache = [
|
/**
|
||||||
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
* @param array{return_ratio?: mixed, unlock_ratio?: mixed, points_to_cash_ratio?: mixed} $ratios
|
||||||
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
|
*/
|
||||||
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
return self::$cache;
|
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
|
public static function forget(): void
|
||||||
{
|
{
|
||||||
self::$cache = null;
|
$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
|
private static function toFloat(mixed $v): float
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ namespace app\common\model;
|
|||||||
use support\think\Model;
|
use support\think\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 积分商城配置(比例等)
|
* 积分商城业务配置(含 PlayX 比例等)
|
||||||
*/
|
*/
|
||||||
class MallConfig extends Model
|
class MallBusinessConfig extends Model
|
||||||
{
|
{
|
||||||
protected string $name = 'mall_config';
|
protected string $name = 'mall_business_config';
|
||||||
|
|
||||||
protected bool $autoWriteTimestamp = true;
|
protected bool $autoWriteTimestamp = true;
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
/**
|
/**
|
||||||
* 以下三项比例以数据表 mall_config 为准(后台「商城参数配置」)。
|
* 以下三项比例以数据表 mall_business_config 为准(后台「商城参数配置」)。
|
||||||
* 此处保留 env 仅作兼容/文档默认值;业务代码请使用 MallPlayxRatios::get()。
|
* 此处保留 env 仅作兼容/文档默认值;业务代码请使用 MallPlayxRatios::get()。
|
||||||
*/
|
*/
|
||||||
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
||||||
|
|||||||
@@ -53,6 +53,6 @@ export default {
|
|||||||
},
|
},
|
||||||
playxConfig: {
|
playxConfig: {
|
||||||
title: 'About this page',
|
title: 'About this page',
|
||||||
desc: 'Edit return/unlock/points-to-cash ratios used by daily push and asset APIs; values are stored in mall_config and apply immediately after save.',
|
desc: 'Edit return/unlock/points-to-cash ratios used by daily push and asset APIs; values are stored in mall_business_config and apply immediately after save.',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,6 @@ export default {
|
|||||||
},
|
},
|
||||||
playxConfig: {
|
playxConfig: {
|
||||||
title: '页面说明',
|
title: '页面说明',
|
||||||
desc: '配置每日推送用到的返还比例、解锁比例及积分折算现金比例;保存后立即作用于接口逻辑(mall_config)。',
|
desc: '配置每日推送用到的返还比例、解锁比例及积分折算现金比例;保存后立即作用于接口逻辑(mall_business_config)。',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user