197 lines
7.6 KiB
PHP
197 lines
7.6 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | saiadmin [ saiadmin快速开发框架 ]
|
||
// +----------------------------------------------------------------------
|
||
// | Author: your name
|
||
// +----------------------------------------------------------------------
|
||
namespace app\dice\logic\lottery_pool_config;
|
||
|
||
use app\api\service\LotteryService;
|
||
use app\dice\helper\AdminScopeHelper;
|
||
use app\dice\helper\ConfigScopeEditHelper;
|
||
use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
|
||
use app\dice\model\player\DicePlayer;
|
||
use app\dice\basic\DiceBaseLogic;
|
||
use plugin\saiadmin\exception\ApiException;
|
||
use plugin\saiadmin\utils\Helper;
|
||
use support\think\Cache;
|
||
|
||
/**
|
||
* 色子奖池配置逻辑层
|
||
*/
|
||
class DiceLotteryPoolConfigLogic extends DiceBaseLogic
|
||
{
|
||
/** Redis 当前彩金池(type=0 实例)key,无则按 type=0 创建 */
|
||
private const REDIS_KEY_CURRENT_POOL = 'api:game:lottery_pool:default';
|
||
|
||
private const EXPIRE = 86400 * 7;
|
||
|
||
/**
|
||
* 构造函数
|
||
*/
|
||
public function __construct()
|
||
{
|
||
$this->model = new DiceLotteryPoolConfig();
|
||
}
|
||
|
||
/**
|
||
* 按渠道隔离更新(主键 id 全局唯一,仍校验 dept_id 防止越权)
|
||
*/
|
||
public function edit($id, array $data, ?array $adminInfo = null, $requestDeptId = null): mixed
|
||
{
|
||
$pickedDeptId = AdminScopeHelper::pickRequestDeptId($requestDeptId, $data);
|
||
$deptId = AdminScopeHelper::resolveConfigDeptId($adminInfo, $pickedDeptId);
|
||
$result = ConfigScopeEditHelper::updateByPkAndDept(
|
||
$this->model,
|
||
$id,
|
||
$deptId,
|
||
$data,
|
||
['id', 'dept_id', 'create_time', 'update_time', 'delete_time', 'row_id'],
|
||
$adminInfo,
|
||
$pickedDeptId
|
||
);
|
||
if ($result) {
|
||
$pool = DiceLotteryPoolConfig::find($id);
|
||
if ($pool && $pool->isPlayerDefaultTemplate()) {
|
||
$this->syncPlayersBoundToPlayerDefaultPool($pool);
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 修改 playerDefault 后:同步同渠道所有 lottery_config_id 指向该池的玩家 T1–T5 权重,并刷新 Redis 彩金池快照
|
||
*
|
||
* @return int 已同步玩家数量
|
||
*/
|
||
public function syncPlayersBoundToPlayerDefaultPool(DiceLotteryPoolConfig $pool): int
|
||
{
|
||
$poolId = (int) ($pool->id ?? 0);
|
||
if ($poolId <= 0) {
|
||
return 0;
|
||
}
|
||
$weights = [
|
||
't1_weight' => (int) ($pool->t1_weight ?? 0),
|
||
't2_weight' => (int) ($pool->t2_weight ?? 0),
|
||
't3_weight' => (int) ($pool->t3_weight ?? 0),
|
||
't4_weight' => (int) ($pool->t4_weight ?? 0),
|
||
't5_weight' => (int) ($pool->t5_weight ?? 0),
|
||
];
|
||
$poolDeptId = AdminScopeHelper::normalizeRecordDeptId($pool->dept_id ?? null);
|
||
|
||
$query = DicePlayer::where('lottery_config_id', $poolId);
|
||
if (AdminScopeHelper::isTemplateDeptId($poolDeptId)) {
|
||
$query->where(function ($q) {
|
||
$q->where('dept_id', AdminScopeHelper::DEFAULT_TEMPLATE_DEPT)
|
||
->whereOr('dept_id', null);
|
||
});
|
||
} else {
|
||
$query->where('dept_id', $poolDeptId);
|
||
}
|
||
|
||
$playerIds = $query->column('id');
|
||
if ($playerIds === [] || $playerIds === null) {
|
||
return 0;
|
||
}
|
||
$ids = array_map('intval', is_array($playerIds) ? $playerIds : [$playerIds]);
|
||
|
||
DicePlayer::whereIn('id', $ids)->update($weights);
|
||
|
||
foreach ($ids as $playerId) {
|
||
LotteryService::patchPlayerWeightsCache($playerId, $weights);
|
||
}
|
||
|
||
return count($ids);
|
||
}
|
||
|
||
/**
|
||
* 获取当前彩金池(type=0)+ 杀分权重为 type=1 的只读展示
|
||
* profit_amount 每次从 DB 实时读取;t1_weight~t5_weight 来自 type=1(杀分权重,不可在弹窗内修改)
|
||
*
|
||
* @return array{id:int,name:string,safety_line:int,kill_enabled:int,t1_weight:int,...,t5_weight:int,profit_amount:float}
|
||
*/
|
||
public function getCurrentPool(int $deptId = AdminScopeHelper::DEFAULT_TEMPLATE_DEPT): array
|
||
{
|
||
$query0 = DiceLotteryPoolConfig::where('name', 'default');
|
||
if (AdminScopeHelper::isTemplateDeptId($deptId)) {
|
||
$query0->where(function ($q) {
|
||
$q->where('dept_id', AdminScopeHelper::DEFAULT_TEMPLATE_DEPT)
|
||
->whereOr('dept_id', null);
|
||
});
|
||
} else {
|
||
$query0->where('dept_id', $deptId);
|
||
}
|
||
$configType0 = $query0->find();
|
||
if (!$configType0) {
|
||
throw new ApiException('No name=default pool config found, please create one first');
|
||
}
|
||
$query1 = DiceLotteryPoolConfig::where('name', 'killScore');
|
||
if (AdminScopeHelper::isTemplateDeptId($deptId)) {
|
||
$query1->where(function ($q) {
|
||
$q->where('dept_id', AdminScopeHelper::DEFAULT_TEMPLATE_DEPT)
|
||
->whereOr('dept_id', null);
|
||
});
|
||
} else {
|
||
$query1->where('dept_id', $deptId);
|
||
}
|
||
$configType1 = $query1->find();
|
||
$row0 = $configType0->toArray();
|
||
$profitAmount = isset($row0['profit_amount']) ? (float) $row0['profit_amount'] : (isset($row0['ev']) ? (float) $row0['ev'] : 0.0);
|
||
$pool = [
|
||
'id' => (int) $row0['id'],
|
||
'name' => (string) ($row0['name'] ?? ''),
|
||
'safety_line' => (int) ($row0['safety_line'] ?? 0),
|
||
'kill_enabled' => (int) ($row0['kill_enabled'] ?? 1),
|
||
'profit_amount' => $profitAmount,
|
||
];
|
||
$row1 = $configType1 ? $configType1->toArray() : [];
|
||
$pool['t1_weight'] = (int) ($row1['t1_weight'] ?? 0);
|
||
$pool['t2_weight'] = (int) ($row1['t2_weight'] ?? 0);
|
||
$pool['t3_weight'] = (int) ($row1['t3_weight'] ?? 0);
|
||
$pool['t4_weight'] = (int) ($row1['t4_weight'] ?? 0);
|
||
$pool['t5_weight'] = (int) ($row1['t5_weight'] ?? 0);
|
||
return $pool;
|
||
}
|
||
|
||
/**
|
||
* 更新当前彩金池:仅允许修改 type=0 的 safety_line、kill_enabled(杀分权重来自 type=1,不可在此接口修改)
|
||
*
|
||
* @param array{safety_line?:int,kill_enabled?:int} $data
|
||
*/
|
||
public function updateCurrentPool(array $data, int $deptId = AdminScopeHelper::DEFAULT_TEMPLATE_DEPT): void
|
||
{
|
||
$pool = $this->getCurrentPool($deptId);
|
||
$id = (int) $pool['id'];
|
||
if (!array_key_exists('safety_line', $data) && !array_key_exists('kill_enabled', $data)) {
|
||
return;
|
||
}
|
||
$update = [];
|
||
if (array_key_exists('safety_line', $data)) {
|
||
$update['safety_line'] = (int) $data['safety_line'];
|
||
}
|
||
if (array_key_exists('kill_enabled', $data)) {
|
||
$update['kill_enabled'] = ((int) $data['kill_enabled']) === 1 ? 1 : 0;
|
||
}
|
||
if ($update === []) {
|
||
return;
|
||
}
|
||
$query = DiceLotteryPoolConfig::where('id', $id);
|
||
ConfigScopeEditHelper::applyDeptIdWhere($query, $deptId);
|
||
$query->update($update);
|
||
}
|
||
|
||
/**
|
||
* 重置当前彩金池的玩家累计盈利:将 profit_amount 置为 0,并刷新 Redis 缓存
|
||
*/
|
||
public function resetProfitAmount(int $deptId = AdminScopeHelper::DEFAULT_TEMPLATE_DEPT): void
|
||
{
|
||
$pool = $this->getCurrentPool($deptId);
|
||
$id = (int) $pool['id'];
|
||
$query = DiceLotteryPoolConfig::where('id', $id);
|
||
ConfigScopeEditHelper::applyDeptIdWhere($query, $deptId);
|
||
$query->update(['profit_amount' => 0]);
|
||
$pool['profit_amount'] = 0.0;
|
||
Cache::set(self::REDIS_KEY_CURRENT_POOL, json_encode($pool), self::EXPIRE);
|
||
}
|
||
}
|