feat(scheme): 增强 Scheme 与数据库同步机制并添加严格校验

This commit is contained in:
augushong
2026-01-12 12:37:37 +08:00
parent 2f7ec93f89
commit ee40374732
5 changed files with 612 additions and 128 deletions

View File

@@ -9,7 +9,6 @@ use think\console\Output;
use think\facade\Config;
use think\facade\Db;
use app\common\service\scheme\SchemeToDbService;
use app\common\service\scheme\DbToSchemeService;
use app\common\scheme\attribute\Table;
use ReflectionClass;
@@ -28,7 +27,6 @@ class Sync extends Command
$skipData = $input->getOption('skip-data');
$service = new SchemeToDbService();
$generator = new DbToSchemeService();
$schemeDir = app()->getAppPath() . 'admin/scheme/';
$ignoreTables = Config::get('scheme.ignore_tables', []);
$connection = Config::get('database.default', 'mysql');
@@ -63,19 +61,21 @@ class Sync extends Command
continue;
}
if ($this->checkTableExists($connection, $fullTableName)) {
try {
$expectedClass = basename($file, '.php');
$generated = $generator->generate($fullTableName, $expectedClass);
$existing = (string)file_get_contents($file);
if ($this->normalizeCode($generated) === $this->normalizeCode($existing)) {
$output->writeln("Skipping $className (no schema changes)");
continue;
}
} catch (\Exception $e) {
$output->writeln("<error>Check failed for $className: " . $e->getMessage() . "</error>");
continue;
}
try {
$diffs = $service->diff($className);
} catch (\Throwable $e) {
$output->writeln("<error>Check failed for $className: " . $e->getMessage() . "</error>");
continue;
}
if (count($diffs) === 1 && str_starts_with($diffs[0], '无法读取数据库表结构')) {
$output->writeln("<error>Check failed for $className: {$diffs[0]}</error>");
continue;
}
if (empty($diffs)) {
$output->writeln("Skipping $className (no schema changes)");
continue;
}
$output->writeln("Syncing $className...");