Files
2026-03-26 20:22:34 +08:00

111 lines
3.8 KiB
PHP

<?php
namespace base\common\command\scheme;
use app\common\console\Command;
use think\console\Input;
use think\console\Input\Option;
use think\console\Input\Argument;
use think\console\Output;
use think\facade\Db;
use think\facade\Config;
use app\common\service\scheme\DbToSchemeService;
use app\common\service\scheme\SchemeToDbService;
use app\common\service\scheme\attribute\Table;
use ReflectionClass;
class Make extends Command
{
protected function configure()
{
parent::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->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("<info>Skipping (no schema changes): $path</info>");
continue;
}
}
}
// 确保目录存在
if (!is_dir(dirname($path))) {
mkdir(dirname($path), 0755, true);
}
file_put_contents($path, $code);
$output->writeln("<info>Generated: $path</info>");
}
} 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;
}
}