diff --git a/saiadmin-artd/package.json b/saiadmin-artd/package.json
index c438855..97947bd 100644
--- a/saiadmin-artd/package.json
+++ b/saiadmin-artd/package.json
@@ -99,6 +99,7 @@
"eslint-plugin-vue": "^9.27.0",
"globals": "^15.9.0",
"husky": "^9.1.5",
+ "iconv-lite": "^0.7.2",
"lint-staged": "^15.5.2",
"prettier": "^3.5.3",
"rollup-plugin-visualizer": "^5.12.0",
diff --git a/saiadmin-artd/pnpm-lock.yaml b/saiadmin-artd/pnpm-lock.yaml
index dcf6da0..32fbe95 100644
--- a/saiadmin-artd/pnpm-lock.yaml
+++ b/saiadmin-artd/pnpm-lock.yaml
@@ -144,6 +144,9 @@ importers:
husky:
specifier: ^9.1.5
version: 9.1.7
+ iconv-lite:
+ specifier: ^0.7.2
+ version: 0.7.2
lint-staged:
specifier: ^15.5.2
version: 15.5.2
@@ -2549,6 +2552,10 @@ packages:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
+ iconv-lite@0.7.2:
+ resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
+ engines: {node: '>=0.10.0'}
+
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@@ -6767,6 +6774,10 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
+ iconv-lite@0.7.2:
+ dependencies:
+ safer-buffer: 2.1.2
+
ieee754@1.2.1: {}
ignore@5.3.2: {}
diff --git a/saiadmin-artd/src/views/plugin/dice/reward/index/modules/weight-ratio-dialog.vue b/saiadmin-artd/src/views/plugin/dice/reward/index/modules/weight-ratio-dialog.vue
index 45835f8..8584415 100644
--- a/saiadmin-artd/src/views/plugin/dice/reward/index/modules/weight-ratio-dialog.vue
+++ b/saiadmin-artd/src/views/plugin/dice/reward/index/modules/weight-ratio-dialog.vue
@@ -12,8 +12,8 @@
1-10000,档位内按权重比抽取。
-
-
+
+
@@ -21,6 +21,7 @@
{
- const items: Array<{ id: number; weight: number }> = []
+ /** 按 DiceReward 主键 id 收集:每条记录一条 { id, reward_id, weight },后端按 id 更新(reward_id 作回退) */
+ function collectItems(): Array<{ id: number; reward_id: number; weight: number }> {
+ const items: Array<{ id: number; reward_id: number; weight: number }> = []
for (const t of TIER_KEYS) {
const tierData = grouped.value[t]
if (!tierData) continue
@@ -482,7 +484,7 @@
const rid = row.reward_id != null ? Number(row.reward_id) : 0
if (rid <= 0) continue
const w = isWeightDisabled(row, t) ? 10000 : toWeightPrecision(row.weight ?? 1)
- items.push({ id: rid, weight: w })
+ items.push({ id: rid, reward_id: rid, weight: w })
}
}
}
@@ -536,6 +538,7 @@
}
.chart-wrap {
margin-bottom: 12px;
+ min-height: 200px;
}
.weight-sum {
margin-bottom: 12px;
diff --git a/server/app/dice/controller/reward/DiceRewardController.php b/server/app/dice/controller/reward/DiceRewardController.php
index d0a2452..043f8a6 100644
--- a/server/app/dice/controller/reward/DiceRewardController.php
+++ b/server/app/dice/controller/reward/DiceRewardController.php
@@ -69,10 +69,12 @@ class DiceRewardController extends BaseController
/**
* 权重编辑弹窗:按档位分组获取配置+顺时针/逆时针权重(dice_reward 双方向)
* 返回与 reward_config 权重配比一致结构,供奖励对照页弹窗同时编辑 direction=0/1
+ * 拉取前先刷新缓存,保证与列表页(直查 DB)数据一致,避免表格与弹窗权重不一致
*/
#[Permission('奖励对照列表', 'dice:reward:index:index')]
public function weightRatioListWithDirection(Request $request): Response
{
+ DiceReward::refreshCache();
$logic = new DiceRewardLogic();
$data = $logic->getListGroupedByTierWithDirection();
return $this->success($data);
diff --git a/server/app/dice/logic/reward/DiceRewardLogic.php b/server/app/dice/logic/reward/DiceRewardLogic.php
index f23a3eb..6bb9e3e 100644
--- a/server/app/dice/logic/reward/DiceRewardLogic.php
+++ b/server/app/dice/logic/reward/DiceRewardLogic.php
@@ -195,12 +195,19 @@ class DiceRewardLogic
continue;
}
$id = isset($item['id']) ? (int) $item['id'] : 0;
- $weight = isset($item['weight']) ? (int) $item['weight'] : self::WEIGHT_MIN;
+ if ($id <= 0) {
+ $id = isset($item['reward_id']) ? (int) $item['reward_id'] : 0;
+ }
if ($id <= 0) {
throw new ApiException('存在无效的 DiceReward id');
}
+ $weight = isset($item['weight']) ? (int) $item['weight'] : self::WEIGHT_MIN;
$weight = max(self::WEIGHT_MIN, min(self::WEIGHT_MAX, $weight));
- DiceReward::where('id', $id)->update(['weight' => $weight]);
+ $model = DiceReward::find($id);
+ if ($model !== null) {
+ $model->weight = $weight;
+ $model->save();
+ }
}
DiceReward::refreshCache();
}
diff --git a/server/app/dice/logic/reward_config_record/DiceRewardConfigRecordLogic.php b/server/app/dice/logic/reward_config_record/DiceRewardConfigRecordLogic.php
index 8d3e6e2..21c349e 100644
--- a/server/app/dice/logic/reward_config_record/DiceRewardConfigRecordLogic.php
+++ b/server/app/dice/logic/reward_config_record/DiceRewardConfigRecordLogic.php
@@ -152,6 +152,7 @@ class DiceRewardConfigRecordLogic extends BaseLogic
->where('grid_number', $gridNumber)
->update(['weight' => $weight]);
}
+ DiceRewardConfig::refreshCache();
}
$tiers = ['T1', 'T2', 'T3', 'T4', 'T5'];
diff --git a/server/app/dice/logic/reward_config_record/WeightTestRunner.php b/server/app/dice/logic/reward_config_record/WeightTestRunner.php
index 376b633..d39c781 100644
--- a/server/app/dice/logic/reward_config_record/WeightTestRunner.php
+++ b/server/app/dice/logic/reward_config_record/WeightTestRunner.php
@@ -7,6 +7,8 @@ use app\api\logic\PlayStartLogic;
use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
use app\dice\model\play_record_test\DicePlayRecordTest;
use app\dice\model\reward_config_record\DiceRewardConfigRecord;
+use app\dice\model\reward\DiceReward;
+use app\dice\model\reward_config\DiceRewardConfig;
use support\Log;
/**
@@ -82,6 +84,10 @@ class WeightTestRunner
}
}
+ // 每次测试开始前清空进程内静态缓存,强制从共享缓存读取最新 BIGWIN/奖励配置,与数据库一致
+ DiceRewardConfig::clearRequestInstance();
+ DiceReward::clearRequestInstance();
+
$playLogic = new PlayStartLogic();
$resultCounts = [];
$tierCounts = [];
diff --git a/server/app/dice/model/reward/DiceReward.php b/server/app/dice/model/reward/DiceReward.php
index 7da990e..02ba353 100644
--- a/server/app/dice/model/reward/DiceReward.php
+++ b/server/app/dice/model/reward/DiceReward.php
@@ -46,18 +46,19 @@ class DiceReward extends BaseModel
/**
* 获取奖励对照实例(按档位+方向索引,用于抽奖与权重配比)
+ * 优先从共享缓存读取,保证多进程(如一键测试 worker)与数据库一致
* @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;
}
+ if (self::$instance !== null) {
+ return self::$instance;
+ }
self::refreshCache();
$instance = Cache::get(self::CACHE_KEY_INSTANCE);
self::$instance = is_array($instance) ? $instance : self::buildEmptyInstance();
diff --git a/server/app/dice/model/reward_config/DiceRewardConfig.php b/server/app/dice/model/reward_config/DiceRewardConfig.php
index 4f1544a..92889f0 100644
--- a/server/app/dice/model/reward_config/DiceRewardConfig.php
+++ b/server/app/dice/model/reward_config/DiceRewardConfig.php
@@ -42,18 +42,19 @@ class DiceRewardConfig extends BaseModel
/**
* 获取彩金池实例(含 list / by_tier / by_tier_grid),无则从库加载并写入缓存
+ * 优先从共享缓存读取,保证多进程(如一键测试 worker)能拿到最新配置,与数据库一致
* @return array{list: array, by_tier: array, by_tier_grid: array, min_real_ev: float}
*/
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;
}
+ if (self::$instance !== null) {
+ return self::$instance;
+ }
self::refreshCache();
$instance = Cache::get(self::CACHE_KEY_INSTANCE);
self::$instance = is_array($instance) ? $instance : self::buildEmptyInstance();