249 lines
8.3 KiB
PHP
249 lines
8.3 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace app\admin\controller;
|
||
|
|
||
|
use app\common\controller\Backend;
|
||
|
use think\Config;
|
||
|
use think\console\Input;
|
||
|
use think\Db;
|
||
|
use think\Exception;
|
||
|
|
||
|
/**
|
||
|
* 在线命令管理
|
||
|
*
|
||
|
* @icon fa fa-circle-o
|
||
|
*/
|
||
|
class Command extends Backend
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* Command模型对象
|
||
|
*/
|
||
|
protected $model = null;
|
||
|
protected $noNeedRight = ['get_controller_list', 'get_field_list'];
|
||
|
|
||
|
public function _initialize()
|
||
|
{
|
||
|
parent::_initialize();
|
||
|
$this->model = new \app\admin\model\Command;
|
||
|
$this->view->assign("statusList", $this->model->getStatusList());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 添加
|
||
|
*/
|
||
|
public function add()
|
||
|
{
|
||
|
|
||
|
$tableList = [];
|
||
|
$list = \think\Db::query("SHOW TABLES");
|
||
|
foreach ($list as $key => $row) {
|
||
|
$tableList[reset($row)] = reset($row);
|
||
|
}
|
||
|
|
||
|
$this->view->assign("tableList", $tableList);
|
||
|
return $this->view->fetch();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取字段列表
|
||
|
* @internal
|
||
|
*/
|
||
|
public function get_field_list()
|
||
|
{
|
||
|
$dbname = Config::get('database.database');
|
||
|
$prefix = Config::get('database.prefix');
|
||
|
$table = $this->request->request('table');
|
||
|
//从数据库中获取表字段信息
|
||
|
$sql = "SELECT * FROM `information_schema`.`columns` "
|
||
|
. "WHERE TABLE_SCHEMA = ? AND table_name = ? "
|
||
|
. "ORDER BY ORDINAL_POSITION";
|
||
|
//加载主表的列
|
||
|
$columnList = Db::query($sql, [$dbname, $table]);
|
||
|
$fieldlist = [];
|
||
|
foreach ($columnList as $index => $item) {
|
||
|
$fieldlist[] = $item['COLUMN_NAME'];
|
||
|
}
|
||
|
$this->success("", null, ['fieldlist' => $fieldlist]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取控制器列表
|
||
|
* @internal
|
||
|
*/
|
||
|
public function get_controller_list()
|
||
|
{
|
||
|
//搜索关键词,客户端输入以空格分开,这里接收为数组
|
||
|
$word = (array)$this->request->request("q_word/a");
|
||
|
$word = implode('', $word);
|
||
|
|
||
|
$adminPath = dirname(__DIR__) . DS;
|
||
|
$controllerDir = $adminPath . 'controller' . DS;
|
||
|
$files = new \RecursiveIteratorIterator(
|
||
|
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
|
||
|
);
|
||
|
$list = [];
|
||
|
foreach ($files as $name => $file) {
|
||
|
if (!$file->isDir()) {
|
||
|
$filePath = $file->getRealPath();
|
||
|
$name = str_replace($controllerDir, '', $filePath);
|
||
|
$name = str_replace(DS, "/", $name);
|
||
|
if (!preg_match("/(.*)\.php\$/", $name)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (!$word || stripos($name, $word) !== false) {
|
||
|
$list[] = ['id' => $name, 'name' => $name];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$pageNumber = $this->request->request("pageNumber");
|
||
|
$pageSize = $this->request->request("pageSize");
|
||
|
return json(['list' => array_slice($list, ($pageNumber - 1) * $pageSize, $pageSize), 'total' => count($list)]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 详情
|
||
|
*/
|
||
|
public function detail($ids)
|
||
|
{
|
||
|
$row = $this->model->get($ids);
|
||
|
if (!$row) {
|
||
|
$this->error(__('No Results were found'));
|
||
|
}
|
||
|
$this->view->assign("row", $row);
|
||
|
return $this->view->fetch();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 执行
|
||
|
*/
|
||
|
public function execute($ids)
|
||
|
{
|
||
|
$row = $this->model->get($ids);
|
||
|
if (!$row) {
|
||
|
$this->error(__('No Results were found'));
|
||
|
}
|
||
|
$result = $this->doexecute($row['type'], json_decode($row['params'], true));
|
||
|
$this->success("", null, ['result' => $result]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 生成命令
|
||
|
*/
|
||
|
public function command($action = '')
|
||
|
{
|
||
|
$commandtype = $this->request->request("commandtype");
|
||
|
$params = $this->request->request();
|
||
|
$allowfields = [
|
||
|
'crud' => 'table,controller,model,fields,force,local,delete,menu',
|
||
|
'menu' => 'controller,delete,force',
|
||
|
'min' => 'module,resource,optimize',
|
||
|
'api' => 'url,module,output,template,force,title,author,class,language,addon',
|
||
|
];
|
||
|
$argv = [];
|
||
|
$allowfields = isset($allowfields[$commandtype]) ? explode(',', $allowfields[$commandtype]) : [];
|
||
|
$allowfields = array_filter(array_intersect_key($params, array_flip($allowfields)));
|
||
|
if (isset($params['local']) && !$params['local']) {
|
||
|
$allowfields['local'] = $params['local'];
|
||
|
} else {
|
||
|
unset($allowfields['local']);
|
||
|
}
|
||
|
foreach ($allowfields as $key => $param) {
|
||
|
$argv[] = "--{$key}=" . (is_array($param) ? implode(',', $param) : $param);
|
||
|
}
|
||
|
if ($commandtype == 'crud') {
|
||
|
$extend = 'setcheckboxsuffix,enumradiosuffix,imagefield,filefield,intdatesuffix,switchsuffix,citysuffix,selectpagesuffix,selectpagessuffix,ignorefields,sortfield,editorsuffix,headingfilterfield,tagsuffix,jsonsuffix,fixedcolumns';
|
||
|
$extendArr = explode(',', $extend);
|
||
|
foreach ($params as $index => $item) {
|
||
|
if (in_array($index, $extendArr)) {
|
||
|
foreach (explode(',', $item) as $key => $value) {
|
||
|
if ($value) {
|
||
|
$argv[] = "--{$index}={$value}";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$isrelation = (int)$this->request->request('isrelation');
|
||
|
if ($isrelation && isset($params['relation'])) {
|
||
|
foreach ($params['relation'] as $index => $relation) {
|
||
|
foreach ($relation as $key => $value) {
|
||
|
$argv[] = "--{$key}=" . (is_array($value) ? implode(',', $value) : $value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if ($commandtype == 'menu') {
|
||
|
if (isset($params['allcontroller']) && $params['allcontroller']) {
|
||
|
$argv[] = "--controller=all-controller";
|
||
|
} else {
|
||
|
foreach (explode(',', $params['controllerfile']) as $index => $param) {
|
||
|
if ($param) {
|
||
|
$argv[] = "--controller=" . substr($param, 0, -4);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if ($commandtype == 'min') {
|
||
|
|
||
|
} else {
|
||
|
if ($commandtype == 'api') {
|
||
|
|
||
|
} else {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ($action == 'execute') {
|
||
|
if (stripos(implode(' ', $argv), '--controller=all-controller') !== false) {
|
||
|
$this->error("只允许在命令行执行该命令,执行前请做好菜单规则备份!!!");
|
||
|
}
|
||
|
if (config('app_debug')) {
|
||
|
$result = $this->doexecute($commandtype, $argv);
|
||
|
$this->success("", null, ['result' => $result]);
|
||
|
} else {
|
||
|
$this->error("只允许在开发环境下执行命令");
|
||
|
}
|
||
|
} else {
|
||
|
$this->success("", null, ['command' => "php think {$commandtype} " . implode(' ', $argv)]);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
protected function doexecute($commandtype, $argv)
|
||
|
{
|
||
|
if (!config('app_debug')) {
|
||
|
$this->error("只允许在开发环境下执行命令");
|
||
|
}
|
||
|
if (preg_match("/([;\|&]+)/", implode(' ', $argv))) {
|
||
|
$this->error("不支持的命令参数");
|
||
|
}
|
||
|
$commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);
|
||
|
$input = new Input($argv);
|
||
|
$output = new \addons\command\library\Output();
|
||
|
$command = new $commandName($commandtype);
|
||
|
$data = [
|
||
|
'type' => $commandtype,
|
||
|
'params' => json_encode($argv),
|
||
|
'command' => "php think {$commandtype} " . implode(' ', $argv),
|
||
|
'executetime' => time(),
|
||
|
];
|
||
|
$this->model->save($data);
|
||
|
try {
|
||
|
$command->run($input, $output);
|
||
|
$result = implode("\n", $output->getMessage());
|
||
|
$this->model->status = 'successed';
|
||
|
} catch (Exception $e) {
|
||
|
$result = implode("\n", $output->getMessage()) . "\n";
|
||
|
$result .= $e->getMessage();
|
||
|
$this->model->status = 'failured';
|
||
|
}
|
||
|
$result = trim($result);
|
||
|
$this->model->content = $result;
|
||
|
$this->model->save();
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
}
|