mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-07 10:32:48 +08:00
feat(scheme): 增强 Scheme 与数据库同步机制并添加严格校验
This commit is contained in:
@@ -5,24 +5,28 @@ namespace base\common\command\scheme;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\facade\Db;
|
||||
use think\facade\Config;
|
||||
use app\common\service\scheme\DbToSchemeService;
|
||||
use app\common\service\scheme\SchemeToDbService;
|
||||
|
||||
class Make extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->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->getArgument('table');
|
||||
$table = $input->getOption('table') ?: $input->getArgument('table');
|
||||
$service = new DbToSchemeService();
|
||||
$compare = new SchemeToDbService();
|
||||
|
||||
$tables = [];
|
||||
if ($table) {
|
||||
@@ -62,6 +66,18 @@ class Make extends Command
|
||||
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("<info>Skipping (no schema changes): $path</info>");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保目录存在
|
||||
if (!is_dir(dirname($path))) {
|
||||
|
||||
@@ -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...");
|
||||
|
||||
Reference in New Issue
Block a user