where('type', ITEM_TYPE::CHEST) ->with([ 'chest_contents' => function ($query) { $query->select([ 'id', 'chest_id', 'item_id', 'group_id', 'min_quantity', 'max_quantity', 'weight' ]) ->where('weight', '>', 0) ->with([ 'item' => function ($query) { $query->select(['id', 'name']); }, 'group' => function ($query) { $query->select(['id', 'name']) ->with(['groupItems' => function ($query) { $query->with(['item' => function ($query) { $query->select(['id', 'name']); }]); }]); } ]); }, 'chest_costs' => function ($query) { $query->select([ 'id', 'chest_id', 'cost_type', 'cost_id', 'cost_quantity' ]) ->where('is_active', true) ->with([ 'costItem' => function ($query) { $query->select(['id', 'name']); } ]); } ]) ->select(['id', 'name','numeric_attributes']) ->get(); // 处理数据,去除不必要的字段 $processedChests = $chests->map(function ($chest) { // 检查宝箱是否有内容数据 if ($chest->chest_contents->isEmpty()) { return null; // 跳过没有内容的宝箱 } $chestData = [ 'id' => $chest->id, 'name' => $chest->name, ]; // 添加宝箱数值属性中的必要字段,使用白名单过滤 if (!empty($chest->numeric_attributes)) { $numericAttrs = NumericAttributesWhitelist::filter($chest->numeric_attributes); if (!empty($numericAttrs)) { foreach ($numericAttrs as $key => $value) { $chestData[$key] = $value; } } } // 处理宝箱内容 $contents = $chest->chest_contents->flatMap(function ($content) { // 根据是物品还是物品组处理 if ($content->item_id && $content->item) { // 单个物品 $contentData = [ 'id' => $content->id, 'weight' => $content->weight, 'min_quantity' => $content->min_quantity, 'max_quantity' => $content->max_quantity, 'item_id' => $content->item_id, 'item_name' => $content->item->name, 'type' => 'item', ]; // 使用白名单过滤内容数据 return [ChestContentWhitelist::filter($contentData)]; } elseif ($content->group_id && $content->group && $content->group->groupItems) { // 物品组 - 将每个物品组中的物品展开为单独的内容项 $groupItems = []; $totalGroupWeight = $content->group->groupItems->sum('weight'); foreach ($content->group->groupItems as $groupItem) { if (!$groupItem->item) { continue; } // 计算组内物品的实际权重(组权重 * 物品在组内的权重比例) $itemWeight = $totalGroupWeight > 0 ? $content->weight * ($groupItem->weight / $totalGroupWeight) : $content->weight; $itemContentData = [ 'id' => $content->id . '_' . $groupItem->id, // 创建唯一ID 'weight' => round($itemWeight, 3), 'min_quantity' => $content->min_quantity, 'max_quantity' => $content->max_quantity, 'item_id' => $groupItem->item->id, 'item_name' => $groupItem->item->name, 'type' => 'item', 'from_group' => true, 'group_id' => $content->group_id, 'group_name' => $content->group->name, ]; // 使用白名单过滤内容数据 $groupItems[] = ChestContentWhitelist::filter($itemContentData); } return $groupItems; } return []; })->toArray(); // 检查处理后的内容是否为空 if (empty($contents)) { return null; // 如果没有有效的内容,跳过这个宝箱 } $chestData['contents'] = $contents; // 处理宝箱开启消耗 $chestData['costs'] = $chest->chest_costs->map(function ($cost) { $costData = [ 'cost_type' => $cost->cost_type, 'cost_id' => $cost->cost_id, 'cost_quantity' => $cost->cost_quantity, ]; // 如果是物品消耗,添加物品名称 if ($cost->cost_type == CHEST_COST_TYPE::ITEM->value && $cost->costItem) { $costData['item_name'] = $cost->costItem->name; } // 使用白名单过滤消耗数据 return ChestCostWhitelist::filter($costData); })->toArray(); return $chestData; }) ->filter() // 过滤掉返回值为null的宝箱 ->toArray(); // 准备完整数据,包含生成时间 $data = [ 'generated_ts' => time(), 'chests' => $processedChests ]; return $data; } catch (\Exception $e) { // 不使用Log,直接输出到控制台 echo 'Generate chest.json failed: ' . $e->getMessage() . "\n"; echo $e->getTraceAsString() . "\n"; return false; } } /** * 执行命令 * * @return int */ public function handle() { $this->info('Generating chest JSON data...'); $result = ChestJsonConfig::getData([], true); if ($result && isset($result['chests'])) { $chestCount = count($result['chests']); $contentCount = 0; $costCount = 0; foreach ($result['chests'] as $chest) { $contentCount += count($chest['contents'] ?? []); $costCount += count($chest['costs'] ?? []); } $this->info('Successfully generated chest.json with timestamp'); $this->info("Processed {$chestCount} chests with {$contentCount} content items and {$costCount} cost items"); return 0; // 成功 } else { $this->error('Failed to generate chest.json'); return 1; // 失败 } } }