SyncDatabaseCommand.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Support\Facades\Config;
  5. use Illuminate\Support\Facades\DB;
  6. use App\Facades\Servers\Logs\Log;
  7. class SyncDatabaseCommand extends Command
  8. {
  9. /**
  10. * 任务名称
  11. *
  12. * @var string
  13. */
  14. protected $signature = 'sync:database';
  15. /**
  16. * 任务描述
  17. *
  18. * @var string
  19. */
  20. protected $description = '开邻的数据复制到Saas';
  21. /**
  22. * Create a new command instance.
  23. *
  24. * @return void
  25. */
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. }
  30. public function handle()
  31. {
  32. $dataBaseInfos = [
  33. //kailin
  34. 'remote' => [
  35. 'host' => '39.108.116.125',
  36. 'port' => 3306,
  37. 'db_name' => 'kailin_migrate_test',
  38. 'db_username' => 'kailin_migrate_test',
  39. 'db_password' => '4bCtNLjfsLJ5Fhbw'
  40. ],
  41. //saas-system
  42. 'system' => [
  43. 'host' => '120.24.49.2',
  44. 'port' => 3306,
  45. 'db_name' => 'system',
  46. 'db_username' => 'system',
  47. 'db_password' => 'tCDnjKmRRPsHikZw'
  48. ],
  49. //saas-company
  50. 'company' => [
  51. 'host' => '120.24.49.2',
  52. 'port' => 3306,
  53. 'db_name' => 'company',
  54. 'db_username' => 'company',
  55. 'db_password' => 'ifAJ7XaDGBZBpLdc'
  56. ]
  57. //测试用 start
  58. // 'system' => [
  59. // //'host' => '127.0.0.1',
  60. // 'host' => '39.108.116.125',
  61. // 'port' => 3306,
  62. // 'db_name' => 'system_migrate_test',
  63. // 'db_username' => 'system_migrate_test',
  64. // 'db_password' => 'wwaxK4AxTkZe3tBa'
  65. // ],
  66. //
  67. // 'company' => [
  68. // 'host' => '39.108.116.125',
  69. // 'port' => 3306,
  70. // 'db_name' => 'company_migrate_0620',
  71. // 'db_username' => 'company_migrate_0620',
  72. // 'db_password' => 'JhbycESDw7HDMfh2'
  73. // ]
  74. //测试用 end
  75. ];
  76. $remoteConnectionConfig = [
  77. 'driver' => 'mysql',
  78. 'host' => $dataBaseInfos['remote']['host'],
  79. 'port' => $dataBaseInfos['remote']['port'],
  80. 'database' => $dataBaseInfos['remote']['db_name'],
  81. 'username' => $dataBaseInfos['remote']['db_username'],
  82. 'password' => $dataBaseInfos['remote']['db_password'],
  83. 'charset' => 'utf8mb4',
  84. 'collation' => 'utf8mb4_unicode_ci',
  85. 'unix_socket' => env('DB_SOCKET', ''),
  86. 'prefix' => env('DB_PREFIX', ''),
  87. 'strict' => false,
  88. 'sticky' => true,
  89. 'engine' => null,
  90. 'options' => [],
  91. ];
  92. Config::set("database.connections.remote", $remoteConnectionConfig);
  93. $systemConnectionConfig = [
  94. 'driver' => 'mysql',
  95. 'host' => $dataBaseInfos['system']['host'],
  96. 'port' => $dataBaseInfos['system']['port'],
  97. 'database' => $dataBaseInfos['system']['db_name'],
  98. 'username' => $dataBaseInfos['system']['db_username'],
  99. 'password' => $dataBaseInfos['system']['db_password'],
  100. 'charset' => 'utf8mb4',
  101. 'collation' => 'utf8mb4_unicode_ci',
  102. 'unix_socket' => env('DB_SOCKET', ''),
  103. 'prefix' => env('DB_PREFIX', ''),
  104. 'strict' => false,
  105. 'sticky' => true,
  106. 'engine' => null,
  107. 'options' => [],
  108. ];
  109. Config::set("database.connections.system", $systemConnectionConfig);
  110. $companyConnectionConfig = [
  111. 'driver' => 'mysql',
  112. 'host' => $dataBaseInfos['company']['host'],
  113. 'port' => $dataBaseInfos['company']['port'],
  114. 'database' => $dataBaseInfos['company']['db_name'],
  115. 'username' => $dataBaseInfos['company']['db_username'],
  116. 'password' => $dataBaseInfos['company']['db_password'],
  117. 'charset' => 'utf8mb4',
  118. 'collation' => 'utf8mb4_unicode_ci',
  119. 'unix_socket' => env('DB_SOCKET', ''),
  120. 'prefix' => env('DB_PREFIX', ''),
  121. 'strict' => false,
  122. 'sticky' => true,
  123. 'engine' => null,
  124. 'options' => [],
  125. ];
  126. Config::set("database.connections.company", $companyConnectionConfig);
  127. // 获取远程数据库的表名
  128. $tables = DB::connection('remote')->select('SHOW TABLES');
  129. $systemTables = ['kailin_business']; // 远端是kailin_business 在系统库中是kailin_shop
  130. $notExecuteTables = [
  131. //'kailin_article', 'kailin_article_event',
  132. //'kailin_lottery_recruitment', 'kailin_lottery_recruitment_record',
  133. //'kailin_lottery_recruitment_reward', 'kailin_redpacket_active', 'kailin_redpacket_active_record',
  134. //'kailin_redpacket_active_reward',
  135. 'kailin_short_link', 'kailin_video_answer',
  136. 'kailin_video_course', 'kailin_video_course_service', 'kailin_video_course_type',
  137. 'kailin_video_exam_answer', 'kailin_video_exam_question', 'kailin_video_exam_record',
  138. 'kailin_video_learn_answer', 'kailin_video_learn_question', 'kailin_video_learn_record',
  139. 'kailin_video_question', 'kailin_video_vip', 'kailin_weiban_external',
  140. 'kailin_work_external', 'kailin_weiban_follow', 'kailin_weiban_qrcode',
  141. 'kailin_weiban_sync', 'kailin_weiban_taglist', 'kailin_weiban_tags',
  142. 'kailin_work_state', 'kailin_work_sync', 'kailin_work_tag',
  143. 'kailin_work_user',
  144. 'kailin_admin', 'kailin_admin_history', 'kailin_admin_rule',
  145. 'kailin_auth_group', 'kailin_auth_group_access', 'kailin_auth_rule',
  146. 'kailin_city', 'kailin_company', 'kailin_menu',
  147. 'kailin_score_orders_product', 'kailin_pay_city'
  148. ];
  149. $dataCount = count($tables);
  150. $this->info("总共有数据表:{$dataCount} 个");
  151. $this->info('开始处理...');
  152. $bar = $this->output->createProgressBar($dataCount);
  153. foreach ($tables as $table) {
  154. $tableName = (array) $table;
  155. $tableName = array_values($tableName)[0];
  156. //测试代码start
  157. // if ($tableName == 'kailin_business') {
  158. // // 获取远程表的数据
  159. // $data = DB::connection('remote')->table($tableName)->get();
  160. //
  161. // foreach ($data as $row) {
  162. // $insertData = (array)$row;
  163. // $insertData['id'] = $row['id'];
  164. //
  165. // DB::connection('system')->table('kailin_shop')->updateOrInsert(
  166. // ['id' => $row['id']], // 检查是否存在的条件
  167. // $insertData // 需要插入或更新的数据
  168. // );
  169. // Log::info('sync_database', "Synced data from remote table {$tableName} to local system database: " . json_encode($row));
  170. // }
  171. // } else {
  172. // $bar->advance();
  173. // }
  174. //测试代码end
  175. if (!in_array($tableName, $notExecuteTables)) {
  176. // 获取远程表的数据
  177. $data = DB::connection('remote')->table($tableName)->get();
  178. $this->info("\n");
  179. $this->info("当前处理的数据表:{$tableName} ");
  180. // 删除本地数据库中的数据
  181. if (in_array($tableName, $systemTables)) {
  182. if ($tableName == 'kailin_business') {
  183. //kailin_shop表的数据不删除
  184. //$this->truncateTable('kailin_shop', 'system');
  185. } else {
  186. $this->truncateTable($tableName, 'system');
  187. }
  188. } else {
  189. $this->truncateTable($tableName, 'company');
  190. }
  191. // 同步到本地数据库
  192. $tableCountData = count($data);
  193. $this->info("当前数据表的数据条数:{$tableCountData} ");
  194. $bar1 = $this->output->createProgressBar($tableCountData);
  195. foreach ($data as $row) {
  196. try {
  197. if (in_array($tableName, $systemTables)) {
  198. if ($tableName == 'kailin_business') {
  199. //DB::connection('system')->table('kailin_shop')->insert((array)$row);
  200. $insertData = (array)$row;
  201. $insertData['id'] = $row['id'];
  202. DB::connection('system')->table('kailin_shop')->updateOrInsert(
  203. ['id' => $row['id']], // 检查是否存在的条件
  204. $insertData // 需要插入或更新的数据
  205. );
  206. } else {
  207. DB::connection('system')->table($tableName)->insert((array)$row);
  208. }
  209. Log::info('sync_database', "Synced data from remote table {$tableName} to local system database: " . json_encode($row));
  210. } else {
  211. DB::connection('company')->table($tableName)->insert((array) $row);
  212. Log::info('sync_database',"Synced data from remote table {$tableName} to local company database: " . json_encode($row));
  213. }
  214. } catch (\Exception $e) {
  215. Log::error('sync_database_error',"Failed to sync data from remote table {$tableName}: " . $e->getMessage());
  216. }
  217. $bar1->advance();
  218. }
  219. $bar1->finish();
  220. $bar->advance();
  221. } else {
  222. $bar->advance();
  223. }
  224. }
  225. $bar->finish();
  226. $this->info('');
  227. $this->info('处理完成');
  228. }
  229. protected function truncateTable($tableName, $connection)
  230. {
  231. try {
  232. DB::connection($connection)->table($tableName)->truncate();
  233. Log::info('sync_database',"Truncated table {$tableName} in {$connection} database.");
  234. } catch (\Exception $e) {
  235. Log::error('sync_database',"Failed to truncate table {$tableName} in {$connection} database: " . $e->getMessage());
  236. }
  237. }
  238. }