最后更新时间:2024年5月
为了提高系统的灵活性和可维护性,我们将 FarmLandUpgradeConfig 模型中的 materials JSON 字段改为关联 Game 模块中的消耗组(GameConsumeGroup)。这样做的好处是:
在 farm_land_upgrade_configs 表中添加了 consume_group_id 字段,用于关联 game_consume_groups 表:
ALTER TABLE `kku_farm_land_upgrade_configs`
ADD COLUMN `consume_group_id` int(10) unsigned DEFAULT NULL COMMENT '消耗组ID,关联game_consume_groups表' AFTER `to_type_id`,
ADD INDEX `idx_consume_group_id` (`consume_group_id`);
在 FarmLandUpgradeConfig 模型中添加了与消耗组的关联:
/**
* 获取关联的消耗组
*
* @return BelongsTo
*/
public function consumeGroup(): BelongsTo
{
return $this->belongsTo(GameConsumeGroup::class, 'consume_group_id', 'id');
}
同时,添加了 getUpgradeMaterials 方法,用于获取升级所需材料:
/**
* 获取升级所需材料
*
* 兼容旧版本,优先使用消耗组,如果没有则使用 materials 字段
*
* @return array
*/
public function getUpgradeMaterials(): array
{
// 如果有关联的消耗组,则使用消耗组中的消耗项
if ($this->consume_group_id && $this->consumeGroup) {
$consumeItems = $this->consumeGroup->consumeItems;
$materials = [];
foreach ($consumeItems as $item) {
if ($item->consume_type == \App\Module\Game\Enums\CONSUME_TYPE::ITEM->value) {
$materials[] = [
'item_id' => $item->target_id,
'amount' => $item->quantity
];
}
}
return $materials;
}
// 否则使用 materials 字段
if (is_string($this->materials)) {
return json_decode($this->materials, true)['materials'] ?? [];
}
return $this->materials['materials'] ?? [];
}
在 LandLogic 类中添加了 getUpgradeMaterials 方法,用于获取升级所需材料:
/**
* 获取升级所需材料
*
* @param int $currentType 当前土地类型
* @param int $targetType 目标土地类型
* @return array 升级所需材料
*/
public function getUpgradeMaterials(int $currentType, int $targetType): array
{
try {
// 从数据库中获取升级配置
$upgradeConfig = FarmLandUpgradeConfig::where('from_type_id', $currentType)
->where('to_type_id', $targetType)
->first();
if (!$upgradeConfig) {
return [];
}
// 使用模型的 getUpgradeMaterials 方法获取材料
return $upgradeConfig->getUpgradeMaterials();
} catch (\Exception $e) {
Log::error('获取升级所需材料失败', [
'current_type' => $currentType,
'target_type' => $targetType,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [];
}
}
同时,修改了 getAvailableUpgradePaths 方法,使用 getUpgradeMaterials 方法获取材料:
// 格式化返回结果
return $availablePaths->map(function ($path) {
// 获取升级所需材料
$materials = $path->getUpgradeMaterials();
return [
'from_type_id' => $path->from_type_id,
'to_type_id' => $path->to_type_id,
'to_type_name' => $path->toType->name,
'materials' => ['materials' => $materials], // 保持与旧版本兼容的格式
'conditions' => $path->conditions,
'consume_group_id' => $path->consume_group_id,
];
})->values()->toArray();
在 FarmLandUpgradeConfigController 类中添加了消耗组选择字段:
// 添加消耗组选择
$form->select('consume_group_id', '消耗组')
->options(function () {
return GameConsumeGroup::pluck('name', 'id')->toArray();
})
->help('选择消耗组后,将使用消耗组中的消耗项作为升级所需材料,而不使用 materials 字段');
为了将现有的 materials 字段数据转换为消耗组,我们创建了一个迁移命令:
php artisan farm:migrate-land-upgrade-materials [--dry-run]
该命令会执行以下操作:
materials 字段中的物品添加到消耗组中consume_group_id 字段使用 --dry-run 参数可以查看将要执行的操作,而不实际执行。
materials 字段materials 字段materials 字段中的物品添加到消耗组中,不会处理其他类型的消耗--dry-run 参数查看将要执行的操作,确保没有问题后再执行实际迁移