mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 23:42:48 +08:00
145 lines
4.4 KiB
PHP
145 lines
4.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace base\common\command\admin;
|
||
|
||
use think\console\Command;
|
||
use think\console\Input;
|
||
use think\console\input\Option;
|
||
use think\console\Output;
|
||
use think\facade\Db;
|
||
|
||
class MigrateFileDataBase extends Command
|
||
{
|
||
/**
|
||
* 要检测的模型路径,一般以app开头或其他模块开头,不支持多级目录.
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $modelPath = [
|
||
'app/admin/model',
|
||
];
|
||
|
||
/**
|
||
* 老的域名,准备替换的域名,如果不以http:// 或 https:// 开头,会自动添加并尝试替换两种协议
|
||
* 一般只填写域名或者IP端口.
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $fromDomain = [
|
||
'127.0.0.1:8000',
|
||
];
|
||
|
||
/**
|
||
* 新的文件域名,必须以http:// 或 https:// 开头.
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $toDomain = '';
|
||
|
||
protected function configure()
|
||
{
|
||
// 指令配置
|
||
$this->setName('admin:migrate:file:data')
|
||
->addOption('exec', null, Option::VALUE_NONE, '确认执行')
|
||
->setDescription('将数据库中的文件地址从老地址更新到新地址,只处理数据库数据,不会实际迁移文件');
|
||
}
|
||
|
||
protected function execute(Input $input, Output $output)
|
||
{
|
||
if (empty($this->toDomain)) {
|
||
$output->error('请指定新的文件域名');
|
||
|
||
return;
|
||
}
|
||
|
||
$this->fromDomain = array_filter($this->fromDomain, function ($domain) {
|
||
return !empty($domain);
|
||
});
|
||
|
||
if (empty($this->fromDomain)) {
|
||
$output->error('请指定老的域名');
|
||
|
||
return;
|
||
}
|
||
|
||
// 指令输出
|
||
$model_files = [];
|
||
|
||
foreach ($this->modelPath as $model_path) {
|
||
$model_files = array_merge($model_files, glob($model_path . '/*.php'));
|
||
}
|
||
|
||
$model_class = [];
|
||
|
||
foreach ($model_files as $file) {
|
||
$class_name = str_replace('.php', '', $file);
|
||
$class_name = str_replace('/', '\\', $class_name);
|
||
$model_class[] = $class_name;
|
||
}
|
||
|
||
$field_map = [];
|
||
|
||
foreach ($model_class as $class_name) {
|
||
if (!isset($field_map[$class_name])) {
|
||
$field_map[$class_name] = [];
|
||
}
|
||
$field_list_file = $class_name::FIELD_LIST_FILE;
|
||
if (!empty($field_list_file)) {
|
||
$field_map[$class_name] = array_merge($field_map[$class_name], $field_list_file);
|
||
}
|
||
|
||
$field_list_content = $class_name::FIELD_LIST_CONTENT;
|
||
if (!empty($field_list_content)) {
|
||
$field_map[$class_name] = array_merge($field_map[$class_name], $field_list_content);
|
||
}
|
||
}
|
||
|
||
$from_domain_list = $this->getFromDomainList();
|
||
$to_domain = $this->toDomain;
|
||
|
||
$exec = $input->hasOption('exec');
|
||
if(!$exec) {
|
||
$output->writeln("输出模式,生成即将使用的sql,但不执行。");
|
||
$output->writeln("需要确认执行: php think admin:migrate:file:data --exec");
|
||
}
|
||
|
||
$field_map = array_filter($field_map);
|
||
foreach ($field_map as $model_class => $field_list) {
|
||
$output->writeln("# process model {$model_class}");
|
||
foreach ($field_list as $field_name) {
|
||
$output->writeln("# update field: {$field_name}");
|
||
foreach ($from_domain_list as $domain) {
|
||
$result = $model_class::whereLike($field_name, "%$domain%")
|
||
->fetchSql(!$exec)
|
||
->update([
|
||
$field_name => Db::raw("REPLACE({$field_name}, '{$domain}', '{$to_domain}')"),
|
||
]);
|
||
if($exec){
|
||
$output->writeln("exec affect rows: $result");
|
||
}else{
|
||
$output->writeln($result);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private function getFromDomainList()
|
||
{
|
||
$from_domain_list = [];
|
||
foreach ($this->fromDomain as $from_domain) {
|
||
if (!str_starts_with($from_domain, 'http://') && !str_starts_with($from_domain, 'https://')) {
|
||
$from_domain_list[] = 'http://' . $from_domain;
|
||
$from_domain_list[] = 'https://' . $from_domain;
|
||
} else {
|
||
$from_domain_list[] = $from_domain;
|
||
}
|
||
}
|
||
|
||
return $from_domain_list;
|
||
}
|
||
|
||
}
|