优化玩游戏中奖权重逻辑

This commit is contained in:
2026-03-10 16:27:11 +08:00
parent 296991f53a
commit e56c3ada34
8 changed files with 539 additions and 36 deletions

View File

@@ -123,4 +123,35 @@ class DiceRewardConfigController extends BaseController
}
}
/**
* T1-T5、BIGWIN 权重配比:按档位分组返回配置列表
* @param Request $request
* @return Response
*/
#[Permission('奖励配置列表', 'dice:reward_config:index:index')]
public function weightRatioList(Request $request): Response
{
$data = $this->logic->getListGroupedByTier();
return $this->success($data);
}
/**
* T1-T5、BIGWIN 权重配比批量更新权重T1-T5 同档位权重和须为 100%BIGWIN 为豹子权重单独设定、无合计要求)
* @param Request $request
* @return Response
*/
#[Permission('奖励配置修改', 'dice:reward_config:index:update')]
public function batchUpdateWeights(Request $request): Response
{
$items = $request->post('items', []);
if (!is_array($items)) {
return $this->fail('参数 items 必须为数组');
}
try {
$this->logic->batchUpdateWeights($items);
return $this->success('保存成功');
} catch (\plugin\saiadmin\exception\ApiException $e) {
return $this->fail($e->getMessage());
}
}
}

View File

@@ -10,6 +10,7 @@ use plugin\saiadmin\basic\think\BaseLogic;
use plugin\saiadmin\exception\ApiException;
use plugin\saiadmin\utils\Helper;
use app\dice\model\reward_config\DiceRewardConfig;
use support\Log;
/**
* 奖励配置逻辑层
@@ -57,4 +58,85 @@ class DiceRewardConfigLogic extends BaseLogic
$data['weight'] = max(0, min(100, $w));
return $data;
}
/**
* 按档位分组返回奖励配置列表(用于 T1-T5、BIGWIN 权重配比)
* @return array<string, array> 键为 T1|T2|T3|T4|T5|BIGWIN值为该档位下的配置行数组
*/
public function getListGroupedByTier(): array
{
$tiers = ['T1', 'T2', 'T3', 'T4', 'T5', 'BIGWIN'];
$list = $this->model->whereIn('tier', $tiers)->order('tier')->order('id')->select()->toArray();
$grouped = [];
foreach ($tiers as $t) {
$grouped[$t] = [];
}
foreach ($list as $row) {
$tier = isset($row['tier']) ? (string) $row['tier'] : '';
if ($tier !== '' && isset($grouped[$tier])) {
$grouped[$tier][] = $row;
}
}
return $grouped;
}
/**
* 批量更新权重T1-T5 同档位权重之和必须等于 100BIGWIN 为豹子权重单独设定,不校验合计
* @param array<int, array{id: int, weight: float}> $items 元素为 [ id => 配置ID, weight => 0-100 ]
* @throws ApiException 当单条 weight 非法或 T1-T5 某档位权重和≠100 时
*/
public function batchUpdateWeights(array $items): void
{
if (empty($items)) {
return;
}
$items = array_values($items);
$ids = [];
$weightById = [];
foreach ($items as $item) {
if (!is_array($item)) {
continue;
}
$id = isset($item['id']) ? (int) $item['id'] : 0;
$w = isset($item['weight']) ? (float) $item['weight'] : 0;
if ($id < 0) {
throw new ApiException('存在无效的配置ID');
}
if ($w < 0 || $w > 100) {
throw new ApiException('权重必须在 0-100 之间');
}
$ids[] = $id;
$w = max(0, min(100, $w));
$weightById[$id] = isset($weightById[$id]) ? min(100, $weightById[$id] + $w) : $w;
}
$list = $this->model->whereIn('id', array_unique($ids))->field('id,tier,grid_number')->select()->toArray();
$idToTier = [];
foreach ($list as $r) {
$id = isset($r['id']) ? (int) $r['id'] : 0;
$idToTier[$id] = isset($r['tier']) ? (string) $r['tier'] : '';
}
$sumByTier = [];
foreach ($weightById as $id => $w) {
$tier = $idToTier[$id] ?? '';
if ($tier === '') {
throw new ApiException('配置ID ' . $id . ' 不存在或档位为空');
}
if ($tier === 'BIGWIN') {
continue;
}
if (!isset($sumByTier[$tier])) {
$sumByTier[$tier] = 0;
}
$sumByTier[$tier] += $w;
}
foreach ($sumByTier as $tier => $sum) {
if (abs($sum - 100)) {
throw new ApiException('档位 ' . $tier . ' 的权重之和必须等于 100%,当前为 ' . round($sum, 2));
}
}
foreach ($weightById as $id => $w) {
DiceRewardConfig::where('id', $id)->update(['weight' => $w]);
}
DiceRewardConfig::refreshCache();
}
}

View File

@@ -110,19 +110,15 @@ class DiceRewardConfig extends BaseModel
}
}
$sEnd = isset($row['s_end_index']) ? (int) $row['s_end_index'] : 0;
if ($sEnd !== 0) {
if (!isset($bySEndIndex[$sEnd])) {
$bySEndIndex[$sEnd] = [];
}
$bySEndIndex[$sEnd][] = $row;
if (!isset($bySEndIndex[$sEnd])) {
$bySEndIndex[$sEnd] = [];
}
$bySEndIndex[$sEnd][] = $row;
$nEnd = isset($row['n_end_index']) ? (int) $row['n_end_index'] : 0;
if ($nEnd !== 0) {
if (!isset($byNEndIndex[$nEnd])) {
$byNEndIndex[$nEnd] = [];
}
$byNEndIndex[$nEnd][] = $row;
if (!isset($byNEndIndex[$nEnd])) {
$byNEndIndex[$nEnd] = [];
}
$byNEndIndex[$nEnd][] = $row;
}
$minRealEv = empty($list) ? 0.0 : (float) min(array_column($list, 'real_ev'));
self::$instance = [