Files
ulthon_admin/extend/base/common/command/admin/stack/AdminStackModeBase.php
augushong b44fcfd86c feat(stack): 新增 stack 模式管理功能
- 新增 `php think admin:stack:mode` 命令,支持 list/use/current/rollback 操作
- 新增 StackModeService 服务,负责模式切换、备份与回滚逻辑
- 在 source/stack/ 目录下添加 default、full、base-build 三种模式的配置文件
- 更新 UlthonAdminService 以注册新的命令行工具
2026-04-24 23:20:13 +08:00

136 lines
4.8 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 base\common\command\admin\stack;
use app\common\console\Command;
use app\common\service\stack\StackModeService;
use RuntimeException;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class AdminStackModeBase extends Command
{
protected function configure()
{
parent::configure();
$this->setName('admin:stack:mode')
->setDescription('管理 Stack 模式list/use/current/rollback')
->addArgument('action', Argument::OPTIONAL, '操作list|use|current|rollback', 'list')
->addArgument('value', Argument::OPTIONAL, 'mode 或 backup_id')
->addOption('force', 'f', Option::VALUE_NONE, '跳过确认步骤');
}
protected function execute(Input $input, Output $output)
{
$action = strtolower((string)$input->getArgument('action'));
$value = (string)$input->getArgument('value');
$force = (bool)$input->getOption('force');
try {
/** @var StackModeService $service */
$service = app(StackModeService::class);
switch ($action) {
case 'list':
$this->handleList($service, $output);
break;
case 'current':
$this->handleCurrent($service, $output);
break;
case 'use':
$this->handleUse($service, $input, $output, $value, $force);
break;
case 'rollback':
$this->handleRollback($service, $input, $output, $value, $force);
break;
default:
throw new RuntimeException('不支持的 action' . $action);
}
} catch (\Throwable $e) {
$output->error($e->getMessage());
}
}
protected function handleList(StackModeService $service, Output $output): void
{
$modes = $service->listModes();
if (empty($modes)) {
$output->warning('未发现可用模式');
return;
}
$output->writeln('可用模式:');
foreach ($modes as $item) {
$mode = (string)$item['mode'];
$desc = (string)$item['description'];
$authorOnly = (bool)$item['author_only'] ? 'yes' : 'no';
$output->writeln("- {$mode} | author_only={$authorOnly} | {$desc}");
}
}
protected function handleCurrent(StackModeService $service, Output $output): void
{
$state = $service->getCurrentState();
$output->writeln('当前模式:' . ((string)$state['mode'] === '' ? '未记录' : (string)$state['mode']));
$output->writeln('切换时间:' . ((string)$state['switched_at'] === '' ? '未记录' : (string)$state['switched_at']));
$output->writeln('备份ID' . ((string)$state['backup_id'] === '' ? '未记录' : (string)$state['backup_id']));
}
protected function handleUse(
StackModeService $service,
Input $input,
Output $output,
string $mode,
bool $force
): void {
$mode = trim($mode);
if ($mode === '') {
throw new RuntimeException('请提供 mode例如admin:stack:mode use base-build');
}
$planData = $service->getModePlan($mode);
$output->writeln("将切换到模式:{$mode}");
foreach ($planData['plan'] as $item) {
$file = (string)$item['file'];
$sourceMode = (string)$item['source_mode'];
$output->writeln("- {$file} <= {$sourceMode}");
}
if (!$force && !$output->confirm($input, '确认执行覆盖切换?', true)) {
$output->warning('已取消');
return;
}
$result = $service->applyMode($mode, get_current_user() ?: 'cli');
$output->info('模式切换完成');
$output->writeln('mode=' . $result['mode']);
$output->writeln('backup_id=' . $result['backup_id']);
}
protected function handleRollback(
StackModeService $service,
Input $input,
Output $output,
string $backupId,
bool $force
): void {
$backupId = trim($backupId);
if ($backupId === '') {
throw new RuntimeException('请提供 backup_id例如admin:stack:mode rollback 20260424120000-abcd1234');
}
if (!$force && !$output->confirm($input, "确认回滚到备份 {$backupId}", true)) {
$output->warning('已取消');
return;
}
$result = $service->rollback($backupId, get_current_user() ?: 'cli');
$output->info('回滚完成');
$output->writeln('backup_id=' . $result['backup_id']);
$output->writeln('restored_files=' . count($result['restored_files']));
}
}