Files
dafuweng-saiadmin6.x/server/plugin/saiadmin/command/SaiOrm.php
2026-03-03 10:06:12 +08:00

183 lines
5.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace plugin\saiadmin\command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Question\ChoiceQuestion;
/**
* SaiAdmin ORM 切换命令
* 用于切换 saiadmin 插件的 ORM 实现 (think / eloquent)
*/
class SaiOrm extends Command
{
protected static $defaultName = 'sai:orm';
protected static $defaultDescription = '切换 SaiAdmin 使用的 ORM';
/**
* ORM 源文件目录
*/
protected string $ormSourcePath;
/**
* 目标插件目录
*/
protected string $pluginAppPath;
/**
* ORM 选项配置
*/
protected array $ormOptions = [
'think' => '1. ThinkORM (TopThink)',
'eloquent' => '2. Eloquent ORM (Laravel)',
'exit' => '3. 退出,什么也不做',
];
protected function configure(): void
{
$this->setName('sai:orm')
->setDescription('切换 SaiAdmin 使用的 ORM');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('SaiAdmin ORM 切换工具');
$io->text('此命令只切换 saiadmin 框架核心使用的 ORM, 不影响其他模块功能, 多种 ORM 可以同时使用!');
$io->newLine();
// 创建选择问题编号从1开始
$helper = $this->getHelper('question');
$choices = [
1 => '1. ThinkORM (TopThink)',
2 => '2. Eloquent ORM (Laravel)',
3 => '3. 退出,什么也不做',
];
$question = new ChoiceQuestion(
'请选择要使用的 ORM 框架:',
$choices,
1 // 默认选中第一个
);
$question->setErrorMessage('选项 %s 无效');
// 获取用户选择
$selected = $helper->ask($input, $output, $question);
// 根据选择的文本反查 key
$selectedKey = array_search($selected, $choices);
// 如果选择退出
if ($selectedKey == 3) {
$io->newLine();
$io->info('已退出,什么也没做。');
return Command::SUCCESS;
}
// 映射选项到 ORM 类型
$ormMap = [1 => 'think', 2 => 'eloquent'];
$orm = $ormMap[$selectedKey];
$io->newLine();
$io->section("您选择了: {$selected}");
// 确认操作
if (!$io->confirm('确定要切换吗?这将覆盖 saiadmin 核心代码文件', true)) {
$io->warning('操作已取消');
return Command::SUCCESS;
}
// 设置路径
$this->ormSourcePath = BASE_PATH . '/vendor/saithink/saiadmin/src/orm/' . $orm . '/app';
$this->pluginAppPath = BASE_PATH . '/plugin/saiadmin/app';
// 检查源目录是否存在
if (!is_dir($this->ormSourcePath)) {
$io->error("ORM 源目录不存在: {$this->ormSourcePath}");
return Command::FAILURE;
}
$io->section('开始复制文件...');
try {
$copiedFiles = $this->copyDirectory($this->ormSourcePath, $this->pluginAppPath, $io);
$io->newLine();
$io->success([
"ORM 切换成功!",
"已切换到: {$selected}",
"复制文件数: {$copiedFiles}"
]);
$io->note([
'请重启 webman 服务使更改生效',
'命令: php webman restart 或 php windows.php'
]);
return Command::SUCCESS;
} catch (\Exception $e) {
$io->error("切换失败: " . $e->getMessage());
return Command::FAILURE;
}
}
/**
* 递归复制目录
* @param string $source 源目录
* @param string $dest 目标目录
* @param SymfonyStyle $io 输出接口
* @return int 复制的文件数量
*/
protected function copyDirectory(string $source, string $dest, SymfonyStyle $io): int
{
$count = 0;
if (!is_dir($dest)) {
mkdir($dest, 0755, true);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST
);
// 先计算文件总数用于进度条
$files = [];
foreach ($iterator as $item) {
if (!$item->isDir()) {
$files[] = $item;
}
}
// 创建进度条
$io->progressStart(count($files));
// 重新遍历并复制
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
$destPath = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName();
if ($item->isDir()) {
if (!is_dir($destPath)) {
mkdir($destPath, 0755, true);
}
} else {
copy($item->getPathname(), $destPath);
$count++;
$io->progressAdvance();
}
}
$io->progressFinish();
return $count;
}
}