重新优化中奖权重计算方式

This commit is contained in:
2026-03-11 15:40:15 +08:00
parent bb166350fd
commit 2af7fedcce
13 changed files with 330 additions and 322 deletions

View File

@@ -13,49 +13,61 @@ use app\dice\model\reward_config\DiceRewardConfig;
use support\Log;
/**
* 奖励配置逻辑层
* weight 仅 tier=BIGWIN 时可设定,保存时非 BIGWIN 强制 weight=0
* 奖励配置逻辑层DiceRewardConfig
* weight 1-10000各档位权重和不限制
*/
class DiceRewardConfigLogic extends BaseLogic
{
/**
* 构造函数
*/
/** weight 取值范围 */
private const WEIGHT_MIN = 1;
private const WEIGHT_MAX = 10000;
public function __construct()
{
$this->model = new DiceRewardConfig();
}
/**
* 新增前:非 BIGWIN 时强制 weight=0
* 新增weight 限制 1-10000保存后刷新缓存
*/
public function add(array $data): mixed
{
$data = $this->normalizeWeightByTier($data);
return parent::add($data);
$data = $this->normalizeWeight($data);
$result = parent::add($data);
DiceRewardConfig::refreshCache();
return $result;
}
/**
* 修改前:非 BIGWIN 时强制 weight=0
* 修改weight 限制 1-10000保存后刷新缓存
*/
public function edit($id, array $data): mixed
{
$data = $this->normalizeWeightByTier($data);
return parent::edit($id, $data);
$data = $this->normalizeWeight($data);
$result = parent::edit($id, $data);
DiceRewardConfig::refreshCache();
return $result;
}
/**
* 仅 tier=BIGWIN 时保留 weight且限制 0-100否则强制为 0
* 删除后刷新缓存
*/
private function normalizeWeightByTier(array $data): array
public function destroy($ids): bool
{
$tier = isset($data['tier']) ? (string) $data['tier'] : '';
if ($tier !== 'BIGWIN') {
$data['weight'] = 0;
return $data;
$result = parent::destroy($ids);
if ($result) {
DiceRewardConfig::refreshCache();
}
$w = isset($data['weight']) ? (float) $data['weight'] : 0;
$data['weight'] = max(0, min(100, $w));
return $result;
}
/**
* weight 限制 1-10000
*/
private function normalizeWeight(array $data): array
{
$w = isset($data['weight']) ? (int) $data['weight'] : self::WEIGHT_MIN;
$data['weight'] = max(self::WEIGHT_MIN, min(self::WEIGHT_MAX, $w));
return $data;
}
@@ -81,9 +93,9 @@ class DiceRewardConfigLogic extends BaseLogic
}
/**
* 批量更新权重:T1-T5 同档位权重之和必须等于 100BIGWIN 为豹子权重单独设定,不校验合计
* @param array<int, array{id: int, weight: float}> $items 元素为 [ id => 配置ID, weight => 0-100 ]
* @throws ApiException 当单条 weight 非法或 T1-T5 某档位权重和≠100
* 批量更新权重:单条 weight 1-10000各档位权重和不限制
* @param array<int, array{id: int, weight: int}> $items 元素为 [ id => 配置ID, weight => 1-10000 ]
* @throws ApiException 当单条 weight 非法时
*/
public function batchUpdateWeights(array $items): void
{
@@ -98,16 +110,15 @@ class DiceRewardConfigLogic extends BaseLogic
continue;
}
$id = isset($item['id']) ? (int) $item['id'] : 0;
$w = isset($item['weight']) ? (float) $item['weight'] : 0;
$w = isset($item['weight']) ? (int) $item['weight'] : self::WEIGHT_MIN;
if ($id < 0) {
throw new ApiException('存在无效的配置ID');
}
if ($w < 0 || $w > 100) {
throw new ApiException('权重必须在 0-100 之间');
if ($w < self::WEIGHT_MIN || $w > self::WEIGHT_MAX) {
throw new ApiException('权重必须在 ' . self::WEIGHT_MIN . '-' . self::WEIGHT_MAX . ' 之间');
}
$ids[] = $id;
$w = max(0, min(100, $w));
$weightById[$id] = isset($weightById[$id]) ? min(100, $weightById[$id] + $w) : $w;
$weightById[$id] = $w;
}
$list = $this->model->whereIn('id', array_unique($ids))->field('id,tier,grid_number')->select()->toArray();
$idToTier = [];
@@ -115,26 +126,11 @@ class DiceRewardConfigLogic extends BaseLogic
$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();