140 lines
4.6 KiB
PHP
140 lines
4.6 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | saiadmin [ saiadmin快速开发框架 ]
|
||
// +----------------------------------------------------------------------
|
||
namespace app\dice\model\reward;
|
||
|
||
use plugin\saiadmin\basic\think\BaseModel;
|
||
use support\think\Cache;
|
||
|
||
/**
|
||
* 奖励对照模型
|
||
*
|
||
* dice_reward 奖励对照表(主键 id 自增)
|
||
* 唯一约束 (direction, grid_number),保证每个点数、每个方向各一条;end_index 关联 DiceRewardConfig.id
|
||
*
|
||
* @property $id 主键
|
||
* @property $tier 档位 T1-T5/BIGWIN
|
||
* @property $direction 方向:0=顺时针,1=逆时针
|
||
* @property $end_index 结束索引(DiceRewardConfig.id)
|
||
* @property $weight 权重 1-10000,档位内按权重比抽取
|
||
* @property $grid_number 色子点数(摇取值)
|
||
* @property $start_index 起始索引(DiceRewardConfig.id)
|
||
* @property $ui_text 显示文本(来自config)
|
||
* @property $real_ev 实际中奖金额(来自config)
|
||
* @property $remark 备注(来自config)
|
||
* @property $type 奖励类型(来自config)
|
||
*/
|
||
class DiceReward extends BaseModel
|
||
{
|
||
/** 方向:顺时针 */
|
||
public const DIRECTION_CLOCKWISE = 0;
|
||
/** 方向:逆时针 */
|
||
public const DIRECTION_COUNTERCLOCKWISE = 1;
|
||
|
||
/** 缓存键:奖励对照实例 */
|
||
private const CACHE_KEY_INSTANCE = 'dice:reward:instance';
|
||
|
||
private const CACHE_TTL = 86400 * 30;
|
||
|
||
private static ?array $instance = null;
|
||
|
||
protected $table = 'dice_reward';
|
||
|
||
/** 主键 id 自增,唯一约束 (direction, grid_number) */
|
||
protected $pk = 'id';
|
||
|
||
/**
|
||
* 获取奖励对照实例(按档位+方向索引,用于抽奖与权重配比)
|
||
* @return array{list: array, by_tier_direction: array}
|
||
*/
|
||
public static function getCachedInstance(): array
|
||
{
|
||
if (self::$instance !== null) {
|
||
return self::$instance;
|
||
}
|
||
$instance = Cache::get(self::CACHE_KEY_INSTANCE);
|
||
if ($instance !== null && is_array($instance)) {
|
||
self::$instance = $instance;
|
||
return $instance;
|
||
}
|
||
self::refreshCache();
|
||
$instance = Cache::get(self::CACHE_KEY_INSTANCE);
|
||
self::$instance = is_array($instance) ? $instance : self::buildEmptyInstance();
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* 按档位+方向取权重列表(用于抽奖:该档位该方向下 end_index => weight)
|
||
* @return array<int, int> end_index => weight
|
||
*/
|
||
public static function getCachedByTierAndDirection(string $tier, int $direction): array
|
||
{
|
||
$inst = self::getCachedInstance();
|
||
$byTierDirection = $inst['by_tier_direction'] ?? [];
|
||
$list = $byTierDirection[$tier][$direction] ?? [];
|
||
$result = [];
|
||
foreach ($list as $row) {
|
||
$endIndex = isset($row['end_index']) ? (int) $row['end_index'] : 0;
|
||
$weight = isset($row['weight']) ? (int) $row['weight'] : 1;
|
||
$result[$endIndex] = $weight;
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 重新从数据库加载并写入缓存;修改/新增/删除后需调用以实例化
|
||
*/
|
||
public static function refreshCache(): void
|
||
{
|
||
$list = (new self())->order('tier')->order('direction')->order('end_index')->select()->toArray();
|
||
$byTierDirection = [];
|
||
foreach ($list as $row) {
|
||
$tier = isset($row['tier']) ? (string) $row['tier'] : '';
|
||
$direction = isset($row['direction']) ? (int) $row['direction'] : 0;
|
||
if ($tier !== '') {
|
||
if (!isset($byTierDirection[$tier])) {
|
||
$byTierDirection[$tier] = [0 => [], 1 => []];
|
||
}
|
||
if (!isset($byTierDirection[$tier][$direction])) {
|
||
$byTierDirection[$tier][$direction] = [];
|
||
}
|
||
$byTierDirection[$tier][$direction][] = $row;
|
||
}
|
||
}
|
||
self::$instance = [
|
||
'list' => $list,
|
||
'by_tier_direction' => $byTierDirection,
|
||
];
|
||
Cache::set(self::CACHE_KEY_INSTANCE, self::$instance, self::CACHE_TTL);
|
||
}
|
||
|
||
private static function buildEmptyInstance(): array
|
||
{
|
||
return [
|
||
'list' => [],
|
||
'by_tier_direction' => [],
|
||
];
|
||
}
|
||
|
||
public static function clearRequestInstance(): void
|
||
{
|
||
self::$instance = null;
|
||
}
|
||
|
||
public static function onAfterInsert($model): void
|
||
{
|
||
self::refreshCache();
|
||
}
|
||
|
||
public static function onAfterUpdate($model): void
|
||
{
|
||
self::refreshCache();
|
||
}
|
||
|
||
public static function onAfterDelete($model): void
|
||
{
|
||
self::refreshCache();
|
||
}
|
||
}
|