GenerateConfigDbCommand.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Module\Farm\Models\FarmFruitGrowthCycle;
  4. use App\Module\Farm\Models\FarmGodBuff;
  5. use App\Module\Farm\Models\FarmLandType;
  6. use App\Module\Farm\Models\FarmLandUpgradeConfig;
  7. use App\Module\Farm\Models\FarmMysterySeeLandEffect;
  8. use App\Module\Farm\Models\FarmSeed;
  9. use App\Module\Farm\Models\FarmSeedOutput;
  10. use App\Module\Farm\Models\FarmShrineConfig;
  11. use App\Module\Fund\Models\FundConfigModel;
  12. use App\Module\Fund\Models\FundCurrencyModel;
  13. use App\Module\Fund\Models\FundModel;
  14. use App\Module\GameItems\Models\ItemCategory;
  15. use App\Module\Mex\Models\MexPriceConfig;
  16. use App\Module\Pet\Models\PetLevelConfig;
  17. use App\Module\Pet\Models\PetSkill;
  18. use App\Module\Point\Models\PointAdminModel;
  19. use App\Module\Point\Models\PointConfigModel;
  20. use App\Module\Point\Models\PointCurrencyModel;
  21. use App\Module\Point\Models\PointModel;
  22. use App\Module\Shop\Models\ShopCategory;
  23. use App\Module\Shop\Models\ShopItem;
  24. use App\Module\ThirdParty\Models\ThirdPartyCredential;
  25. use App\Module\ThirdParty\Models\ThirdPartyLog;
  26. use App\Module\ThirdParty\Models\ThirdPartyQuota;
  27. use App\Module\ThirdParty\Models\ThirdPartyService;
  28. use App\Module\Transfer\Models\TransferApp;
  29. use App\Module\Transfer\Services\TransferService;
  30. use App\Module\UrsPromotion\Models\UrsTalentConfig;
  31. use App\Module\UrsPromotion\Models\UrsTransferFeeConfig;
  32. use Illuminate\Console\Command;
  33. use Illuminate\Support\Facades\File;
  34. use Illuminate\Support\Str;
  35. /**
  36. * 生成配置表的 数据库备份文件
  37. *
  38. * php artisan generate:configdb
  39. *
  40. */
  41. class GenerateConfigDbCommand extends Command
  42. {
  43. protected $signature = 'generate:configdb';
  44. protected $description = '生成配置表的 数据库备份文件,包含创建语句和插入语句';
  45. protected $outFile = 'database/sql/configdb.sql';
  46. protected $modelList = [
  47. // 系统
  48. \App\Module\System\Models\SysConfig::class,
  49. // 物品
  50. \App\Module\GameItems\Models\Item::class,
  51. \App\Module\GameItems\Models\ItemCategory::class,
  52. \App\Module\GameItems\Models\ItemChestConfig::class,
  53. \App\Module\GameItems\Models\ItemDismantleRule::class,
  54. \App\Module\GameItems\Models\ItemGroup::class,
  55. \App\Module\GameItems\Models\ItemGroupItem::class,
  56. \App\Module\GameItems\Models\ItemOutputLimit::class,
  57. \App\Module\GameItems\Models\ItemRecipe::class,
  58. // Game模块
  59. \App\Module\Game\Models\GameConditionGroup::class,
  60. \App\Module\Game\Models\GameConditionItem::class,
  61. \App\Module\Game\Models\GameConsumeGroup::class,
  62. \App\Module\Game\Models\GameConsumeItem::class,
  63. \App\Module\Game\Models\GameRewardGroup::class,
  64. \App\Module\Game\Models\GameRewardGroupPityCount::class,
  65. \App\Module\Game\Models\GameRewardItem::class,
  66. \App\Module\Game\Models\GameTag::class,
  67. \App\Module\Game\Models\GameTagRelation::class,
  68. // 农场
  69. \App\Module\Farm\Models\FarmConfig::class,
  70. \App\Module\Farm\Models\FarmShrineConfig::class,
  71. \App\Module\Farm\Models\FarmHouseConfig::class,
  72. FarmFruitGrowthCycle::class,
  73. FarmGodBuff::class,
  74. FarmLandType::class,
  75. FarmLandUpgradeConfig::class,
  76. FarmMysterySeeLandEffect::class,
  77. FarmSeed::class,
  78. FarmSeedOutput::class,
  79. FarmShrineConfig::class,
  80. // mex
  81. MexPriceConfig::class,
  82. // 宠物
  83. \App\Module\Pet\Models\PetConfig::class,
  84. PetLevelConfig::class,
  85. PetSkill::class,
  86. // urs 推广
  87. UrsTalentConfig::class,
  88. UrsTransferFeeConfig::class,
  89. // Fund 模块
  90. FundModel::class,
  91. FundConfigModel::class,
  92. FundCurrencyModel::class,
  93. // Point 模块
  94. PointModel::class,
  95. PointConfigModel::class,
  96. PointCurrencyModel::class,
  97. // 三方模块
  98. ThirdPartyService::class,
  99. ThirdPartyCredential::class,
  100. ThirdPartyQuota::class,
  101. // 划转模块
  102. TransferApp::class,
  103. // 商店模块
  104. ShopItem::class,
  105. ShopCategory::class,
  106. ];
  107. public function handle()
  108. {
  109. $this->info('开始生成配置表数据库备份文件...');
  110. // 确保输出目录存在
  111. $outputDir = dirname($this->outFile);
  112. if (!File::exists($outputDir)) {
  113. File::makeDirectory($outputDir, 0755, true);
  114. $this->info("创建输出目录: {$outputDir}");
  115. }
  116. $sqlContent = '';
  117. $sqlContent .= "-- ******************************************************************\n";
  118. $sqlContent .= "-- 配置表数据库备份文件\n";
  119. $sqlContent .= "-- 生成时间: " . now()->toDateTimeString() . "\n";
  120. $sqlContent .= "-- 警告: 此文件由系统自动生成,禁止修改!\n";
  121. $sqlContent .= "-- ******************************************************************\n\n";
  122. $totalTables = 0;
  123. $totalRecords = 0;
  124. // 遍历每个模型
  125. foreach ($this->modelList as $modelClass) {
  126. try {
  127. $this->info("处理模型: {$modelClass}");
  128. // 实例化模型
  129. $model = new $modelClass();
  130. $connection = $model->getConnection();
  131. $tablePrefix = $connection->getTablePrefix();
  132. $tableName = $tablePrefix . $model->getTable();
  133. $this->info(" 表名: {$tableName}");
  134. // 获取表的创建语句
  135. $createTableResult = $connection->select("SHOW CREATE TABLE `{$tableName}`");
  136. if (empty($createTableResult)) {
  137. $this->error(" 无法获取表 {$tableName} 的创建语句");
  138. continue;
  139. }
  140. $createTableSQL = $createTableResult[0]->{'Create Table'};
  141. // 移除当前自增值
  142. $createTableSQL = preg_replace('/\s+AUTO_INCREMENT=\d+/', '', $createTableSQL);
  143. // 添加表的创建语句
  144. $sqlContent .= "-- ==========================================\n";
  145. $sqlContent .= "-- 表: {$tableName}\n";
  146. $sqlContent .= "-- 模型: {$modelClass}\n";
  147. $sqlContent .= "-- ==========================================\n\n";
  148. $sqlContent .= "DROP TABLE IF EXISTS `{$tableName}`;\n";
  149. $sqlContent .= "{$createTableSQL};\n\n";
  150. // 获取表数据
  151. $records = $connection->table($model->getTable())->get();
  152. $recordCount = $records->count();
  153. $this->info(" 记录数: {$recordCount}");
  154. if ($recordCount > 0) {
  155. // 生成INSERT语句
  156. $sqlContent .= "-- 数据插入\n";
  157. // 获取字段名
  158. $firstRecord = (array)$records->first();
  159. $columns = array_keys($firstRecord);
  160. $columnList = '`' . implode('`, `', $columns) . '`';
  161. $sqlContent .= "INSERT INTO `{$tableName}` ({$columnList}) VALUES\n";
  162. $values = [];
  163. foreach ($records as $record) {
  164. $recordArray = (array)$record;
  165. $escapedValues = array_map(function ($value) {
  166. if ($value === null) {
  167. return 'NULL';
  168. } elseif (is_numeric($value)) {
  169. return $value;
  170. } else {
  171. return "'" . addslashes($value) . "'";
  172. }
  173. }, $recordArray);
  174. $values[] = '(' . implode(', ', $escapedValues) . ')';
  175. }
  176. $sqlContent .= implode(",\n", $values) . ";\n\n";
  177. } else {
  178. $sqlContent .= "-- 该表无数据记录\n\n";
  179. }
  180. $totalTables++;
  181. $totalRecords += $recordCount;
  182. } catch (\Exception $e) {
  183. $this->error("处理模型 {$modelClass} 时出错: " . $e->getMessage());
  184. continue;
  185. }
  186. }
  187. // 添加统计信息
  188. $sqlContent .= "-- ==========================================\n";
  189. $sqlContent .= "-- 备份统计\n";
  190. $sqlContent .= "-- 总表数: {$totalTables}\n";
  191. $sqlContent .= "-- 总记录数: {$totalRecords}\n";
  192. $sqlContent .= "-- 生成完成时间: " . now()->toDateTimeString() . "\n";
  193. $sqlContent .= "-- ==========================================\n";
  194. // 写入文件
  195. File::put($this->outFile, $sqlContent);
  196. $this->info("配置表数据库备份文件生成完成!");
  197. $this->info("输出文件: {$this->outFile}");
  198. $this->info("处理表数: {$totalTables}");
  199. $this->info("总记录数: {$totalRecords}");
  200. $this->info("文件大小: " . $this->formatBytes(File::size($this->outFile)));
  201. return self::SUCCESS;
  202. }
  203. /**
  204. * 格式化字节大小
  205. *
  206. * @param int $bytes
  207. * @return string
  208. */
  209. private function formatBytes(int $bytes): string
  210. {
  211. $units = [ 'B', 'KB', 'MB', 'GB' ];
  212. $bytes = max($bytes, 0);
  213. $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
  214. $pow = min($pow, count($units) - 1);
  215. $bytes /= 1 << 10 * $pow;
  216. return round($bytes, 2) . ' ' . $units[$pow];
  217. }
  218. }