setName('scheme:make') ->addOption('table', 't', Option::VALUE_REQUIRED, "The table name (without prefix)") ->addArgument('table', Argument::OPTIONAL, "The table name (without prefix)") ->setDescription('Generate Scheme class from Database table'); } protected function execute(Input $input, Output $output) { $table = $input->getOption('table') ?: $input->getArgument('table'); $service = new DbToSchemeService(); $compare = new SchemeToDbService(); $tables = []; if ($table) { $tables[] = $table; } else { // 获取所有表 $allTables = Db::getTables(); // 过滤掉忽略的表 $config = Config::get('scheme.ignore_tables', []); $connection = Config::get('database.default', 'mysql'); $prefix = Config::get('database.connections.' . $connection . '.prefix', ''); $backupPrefix = Config::get('scheme.backup_prefix', 'backup'); foreach ($allTables as $t) { if ($this->isBackupTable($t, $prefix, $backupPrefix)) { continue; } // 如果有前缀,去除前缀后再判断 $shortName = $t; if ($prefix && str_starts_with($t, $prefix)) { $shortName = substr($t, strlen($prefix)); } if (!in_array($shortName, $config) && !in_array($t, $config)) { $tables[] = $shortName; } } } foreach ($tables as $t) { $output->writeln("Processing table: $t"); try { $code = $service->generate($t); // 提取类名以确定文件名 if (preg_match('/class\s+(\w+)/', $code, $matches)) { $className = $matches[1]; $path = app()->getAppPath() . 'admin/scheme/' . $className . '.php'; if (is_file($path)) { require_once $path; $schemeClass = 'app\\admin\\scheme\\' . $className; if (class_exists($schemeClass)) { $diffs = $compare->diff($schemeClass); if (empty($diffs)) { $output->writeln("Skipping (no schema changes): $path"); continue; } } } // 确保目录存在 if (!is_dir(dirname($path))) { mkdir(dirname($path), 0755, true); } file_put_contents($path, $code); $output->writeln("Generated: $path"); } } catch (\Exception $e) { $output->error("Error processing $t: " . $e->getMessage()); } } } protected function isBackupTable(string $tableName, string $prefix, string $backupPrefix): bool { $basePrefix = $prefix . $backupPrefix; if ($basePrefix === '') { return false; } $pattern = '/^' . preg_quote($basePrefix, '/') . '_?\\d{14}(?:_.*)?$/'; return preg_match($pattern, $tableName) === 1; } }