diff --git a/application/admin/command/Install/install.lock b/application/admin/command/Install/install.lock new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/application/admin/command/Install/install.lock @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/application/admin/controller/Arc.php b/application/admin/controller/Arc.php new file mode 100644 index 0000000..b2cc4d9 --- /dev/null +++ b/application/admin/controller/Arc.php @@ -0,0 +1,37 @@ +model = new \app\admin\model\Arc; + + } + + + + /** + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 + * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 + */ + + +} diff --git a/application/admin/controller/Command.php b/application/admin/controller/Command.php new file mode 100644 index 0000000..8fa84ad --- /dev/null +++ b/application/admin/controller/Command.php @@ -0,0 +1,316 @@ +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() + { + if (!$this->request->isPost()) { + $this->error(__('请求方式不正确')); + } + $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() + { + if (!$this->request->isPost()) { + $this->error(__('请求方式不正确')); + } + //搜索关键词,客户端输入以空格分开,这里接收为数组 + $word = (array)$this->request->post("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')); + } + $row['params'] = (array)json_decode($row['params'], true); + $this->view->assign("row", $row); + return $this->view->fetch(); + } + + /** + * 执行 + */ + public function execute($ids) + { + if (!$this->request->isPost()) { + $this->error(__('请求方式不正确')); + } + $row = $this->model->get($ids); + if (!$row) { + $this->error(__('No Results were found')); + } + $params = (array)json_decode($row['params'], true); + if (!isset($params['commandtype'])) { + $this->error('不支持1.1.3之前版本的旧命令'); + } + $this->request->post($params); + $this->command('execute'); + } + + /** + * 生成命令 + */ + public function command($action = '') + { + if (!$this->request->isPost()) { + $this->error(__('请求方式不正确')); + } + $commandtype = $this->request->post("commandtype"); + $params = $this->request->post(); + $allowfields = [ + 'crud' => 'table,controller,model,fields,force,local,delete,menu', + 'menu' => 'delete,force', + 'min' => 'module,resource,optimize', + 'api' => 'url,module,output,template,force,title,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) { + if (is_string($param) && in_array($param, ['force', 'delete', 'local'])) { + $param = (int)$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); + } + } + } + } elseif ($commandtype == 'menu') { + + if (isset($params['allcontroller']) && $params['allcontroller']) { + $argv[] = "--controller=all-controller"; + } else { + foreach (explode(',', $params['controllerfile']) as $index => $param) { + if ($param) { + if (!preg_match("/^([a-zA-Z0-9\/]+)\.php$/", $param)) { + $this->error("请输入正确的控制器名称"); + } + $argv[] = "--controller=" . substr($param, 0, -4); + } + } + } + } elseif ($commandtype == 'min') { + $module = $params['module'] ?? ''; + if ($module && !in_array($module, ['all', 'backend', 'frontend'])) { + $this->error("请选择压缩模块"); + } + $resource = $params['resource'] ?? ''; + if ($resource && !in_array($resource, ['all', 'js', 'css'])) { + $this->error("请选择压缩资源"); + } + $optimize = $params['optimize'] ?? ''; + if ($optimize && !in_array($optimize, ['uglify', 'closure'])) { + $this->error("请选择压缩模式"); + } + } elseif ($commandtype == 'api') { + $url = $params['url'] ?? ''; + if ($url && !filter_var($url, FILTER_VALIDATE_URL)) { + $this->error("接口地址格式错误"); + } + $template = $params['template'] ?? ''; + if ($template && !preg_match("/([a-zA-Z0-9\-_]+)\.html/", $template)) { + $this->error("模板文件错误"); + } + $output = $params['output'] ?? ''; + if ($output && !preg_match("/([a-zA-Z0-9\-_]+)\.html/", $output)) { + $this->error("接口生成文件只支持HTML后缀"); + } + $title = $params['title'] ?? ''; + $author = $params['author'] ?? ''; + $language = $params['language'] ?? ''; + $module = $params['module'] ?? ''; + $addon = $params['addon'] ?? ''; + if (($title && !$this->validateString($title))) { + $this->error("请填写正确的标题"); + } + if (($author && !$this->validateString($author))) { + $this->error("请填写正确的作者"); + } + if ($language && !in_array($language, ['zh-cn', 'en'])) { + $this->error("请选择正确的语言"); + } + if ($module && !preg_match("/[a-zA-Z0-9]+/", $module)) { + $this->error("请填写正确的模块名称"); + } + if ($addon && !preg_match("/[a-zA-Z0-9]+/", $addon)) { + $this->error("请填写正确的插件名称"); + } + } else { + $this->error('参数类型错误'); + } + 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)]); + } + } + + protected function doexecute($commandtype, $argv) + { + if (!config('app_debug')) { + $this->error("只允许在开发环境下执行命令"); + } + if (preg_match("/([;\|&]+)/", implode(' ', $argv))) { + $this->error("不支持的命令参数"); + } + if (!$this->auth->isSuperAdmin()) { + $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($this->request->post()), + '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; + } + + protected function validateString($string) + { + // 匹配中文、英文、数字、下划线、连字符、空格和感叹号 + $pattern = '/^[a-zA-Z0-9_\-\.\s\x{4e00}-\x{9fa5}!]+$/u'; + return preg_match($pattern, $string); + } + +} diff --git a/application/admin/lang/zh-cn/arc.php b/application/admin/lang/zh-cn/arc.php new file mode 100644 index 0000000..60ce921 --- /dev/null +++ b/application/admin/lang/zh-cn/arc.php @@ -0,0 +1,6 @@ + '设备imei号', + 'Active_key' => '激活码' +]; diff --git a/application/admin/lang/zh-cn/command.php b/application/admin/lang/zh-cn/command.php new file mode 100644 index 0000000..b010250 --- /dev/null +++ b/application/admin/lang/zh-cn/command.php @@ -0,0 +1,16 @@ + 'ID', + 'Type' => '类型', + 'Params' => '参数', + 'Command' => '命令', + 'Content' => '返回结果', + 'Executetime' => '执行时间', + 'Createtime' => '创建时间', + 'Updatetime' => '更新时间', + 'Execute again' => '再次执行', + 'Successed' => '成功', + 'Failured' => '失败', + 'Status' => '状态' +]; diff --git a/application/admin/model/Arc.php b/application/admin/model/Arc.php new file mode 100644 index 0000000..e98cb2a --- /dev/null +++ b/application/admin/model/Arc.php @@ -0,0 +1,41 @@ + __('Successed'), 'failured' => __('Failured')]; + } + + + public function getExecutetimeTextAttr($value, $data) + { + $value = $value ? $value : $data['executetime']; + return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value; + } + + public function getTypeTextAttr($value, $data) + { + $value = $value ? $value : $data['type']; + $list = ['crud' => '一键生成CRUD', 'menu' => '一键生成菜单', 'min' => '一键压缩打包', 'api' => '一键生成文档']; + return $list[$value] ?? ''; + } + + public function getStatusTextAttr($value, $data) + { + $value = $value ? $value : $data['status']; + $list = $this->getStatusList(); + return $list[$value] ?? ''; + } + + protected function setExecutetimeAttr($value) + { + return $value && !is_numeric($value) ? strtotime($value) : $value; + } + + +} diff --git a/application/admin/validate/Arc.php b/application/admin/validate/Arc.php new file mode 100644 index 0000000..527ff74 --- /dev/null +++ b/application/admin/validate/Arc.php @@ -0,0 +1,27 @@ + [], + 'edit' => [], + ]; + +} diff --git a/application/admin/validate/Command.php b/application/admin/validate/Command.php new file mode 100644 index 0000000..9da8fa6 --- /dev/null +++ b/application/admin/validate/Command.php @@ -0,0 +1,27 @@ + [], + 'edit' => [], + ]; + +} diff --git a/application/admin/view/arc/add.html b/application/admin/view/arc/add.html new file mode 100644 index 0000000..c6e0bbb --- /dev/null +++ b/application/admin/view/arc/add.html @@ -0,0 +1,33 @@ +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
diff --git a/application/admin/view/arc/edit.html b/application/admin/view/arc/edit.html new file mode 100644 index 0000000..b61140e --- /dev/null +++ b/application/admin/view/arc/edit.html @@ -0,0 +1,33 @@ +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
diff --git a/application/admin/view/arc/index.html b/application/admin/view/arc/index.html new file mode 100644 index 0000000..46987bf --- /dev/null +++ b/application/admin/view/arc/index.html @@ -0,0 +1,29 @@ +
+ {:build_heading()} + +
+ +
+
diff --git a/application/admin/view/arc/recyclebin.html b/application/admin/view/arc/recyclebin.html new file mode 100644 index 0000000..ac30644 --- /dev/null +++ b/application/admin/view/arc/recyclebin.html @@ -0,0 +1,25 @@ +
+ {:build_heading()} + +
+
+
+ +
+ +
+
+
diff --git a/application/admin/view/command/add.html b/application/admin/view/command/add.html new file mode 100644 index 0000000..27fc47b --- /dev/null +++ b/application/admin/view/command/add.html @@ -0,0 +1,416 @@ + +
+
+ +
+
+
+
+
+
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ 主表设置 +
+
+ + {:build_select('table',$tableList,null,['class'=>'form-control selectpicker', 'data-live-search'=>'true']);} +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ +
+ 关联表设置 + + +
+ +
+
+ 字段识别设置 (与之匹配的字段都将生成相应组件) +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ +
+ 生成命令行 + +
+ +
+ 返回结果 + +
+ +
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+ 基础设置 +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ 生成命令行 + +
+ +
+ 返回结果 + +
+ +
+ + +
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + +
+
+
+
+ 文档设置 +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ 生成命令行 + +
+ +
+ 返回结果 + +
+ +
+ + +
+ +
+
+
+
+
+
+
+ diff --git a/application/admin/view/command/detail.html b/application/admin/view/command/detail.html new file mode 100644 index 0000000..19b7b3f --- /dev/null +++ b/application/admin/view/command/detail.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{:__('Title')}{:__('Content')}
{:__('Type')}{$row.type}({$row.type_text})
{:__('Params')} + + {foreach name="row.params" id="item"} + + {/foreach} +
{$key|htmlentities}{$item|htmlentities}
+
{:__('Command')}{$row.command|htmlentities}
{:__('Content')} + +
{:__('Executetime')}{$row.executetime|datetime}
{:__('Status')}{$row.status_text}
+ \ No newline at end of file diff --git a/application/admin/view/command/index.html b/application/admin/view/command/index.html new file mode 100644 index 0000000..3b4f823 --- /dev/null +++ b/application/admin/view/command/index.html @@ -0,0 +1,25 @@ +
+ {:build_heading()} + +
+
+
+ +
+ +
+
+
diff --git a/application/api/controller/Arc.php b/application/api/controller/Arc.php new file mode 100644 index 0000000..51a32ee --- /dev/null +++ b/application/api/controller/Arc.php @@ -0,0 +1,86 @@ + 'Mysql', // 缓存前缀 - 'key' => 'i3d6o32wo8fvs1fvdpwens', + 'key' => 'QwtOszK18yC4xYfGvDugcFTalpkUhqEH', // 加密方式 'hashalgo' => 'ripemd160', // 缓存有效期 0表示永久缓存 diff --git a/application/extra/addons.php b/application/extra/addons.php index 2177468..6cbb3f9 100644 --- a/application/extra/addons.php +++ b/application/extra/addons.php @@ -1,9 +1,15 @@ false, - 'hooks' => [], - 'route' => [], - 'priority' => [], - 'domain' => '', -]; +return array ( + 'autoload' => false, + 'hooks' => + array ( + ), + 'route' => + array ( + ), + 'priority' => + array ( + ), + 'domain' => '', +); diff --git a/application/extra/site.php b/application/extra/site.php index 9f282bb..47c903f 100644 --- a/application/extra/site.php +++ b/application/extra/site.php @@ -1,40 +1,44 @@ '我的网站', - 'beian' => '', - 'cdnurl' => '', - 'version' => '1.0.1', - 'timezone' => 'Asia/Shanghai', - 'forbiddenip' => '', - 'languages' => [ - 'backend' => 'zh-cn', - 'frontend' => 'zh-cn', - ], - 'fixedpage' => 'dashboard', - 'categorytype' => [ - 'default' => 'Default', - 'page' => 'Page', - 'article' => 'Article', - 'test' => 'Test', - ], - 'configgroup' => [ - 'basic' => 'Basic', - 'email' => 'Email', - 'dictionary' => 'Dictionary', - 'user' => 'User', - 'example' => 'Example', - ], - 'attachmentcategory' => [ - 'category1' => 'Category1', - 'category2' => 'Category2', - 'custom' => 'Custom', - ], - 'mail_type' => '1', - 'mail_smtp_host' => 'smtp.qq.com', - 'mail_smtp_port' => '465', - 'mail_smtp_user' => '', - 'mail_smtp_pass' => '', - 'mail_verify_type' => '2', - 'mail_from' => '', -]; +return array ( + 'name' => '夏芮智能芬太尼类专用智能柜', + 'beian' => '', + 'cdnurl' => '', + 'version' => '1.0.1', + 'timezone' => 'Asia/Shanghai', + 'forbiddenip' => '', + 'languages' => + array ( + 'backend' => 'zh-cn', + 'frontend' => 'zh-cn', + ), + 'fixedpage' => 'dashboard', + 'categorytype' => + array ( + 'default' => 'Default', + 'page' => 'Page', + 'article' => 'Article', + 'test' => 'Test', + ), + 'configgroup' => + array ( + 'basic' => 'Basic', + 'email' => 'Email', + 'dictionary' => 'Dictionary', + 'user' => 'User', + 'example' => 'Example', + ), + 'attachmentcategory' => + array ( + 'category1' => 'Category1', + 'category2' => 'Category2', + 'custom' => 'Custom', + ), + 'mail_type' => '1', + 'mail_smtp_host' => 'smtp.qq.com', + 'mail_smtp_port' => '465', + 'mail_smtp_user' => '', + 'mail_smtp_pass' => '', + 'mail_verify_type' => '2', + 'mail_from' => '', +); diff --git a/public/assets/js/backend/arc.js b/public/assets/js/backend/arc.js new file mode 100644 index 0000000..846a7ea --- /dev/null +++ b/public/assets/js/backend/arc.js @@ -0,0 +1,116 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'arc/index' + location.search, + add_url: 'arc/add', + edit_url: 'arc/edit', + del_url: 'arc/del', + multi_url: 'arc/multi', + import_url: 'arc/import', + table: 'arc', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: 'id', + sortName: 'id', + columns: [ + [ + {checkbox: true}, + {field: 'id', title: __('Id')}, + {field: 'imei', title: __('Imei'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'app_id', title: __('App_id'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'sdk_key', title: __('Sdk_key'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'active_key', title: __('Active_key'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, + {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + recyclebin: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + 'dragsort_url': '' + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: 'arc/recyclebin' + location.search, + pk: 'id', + sortName: 'id', + columns: [ + [ + {checkbox: true}, + {field: 'id', title: __('Id')}, + { + field: 'deletetime', + title: __('Deletetime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'operate', + width: '140px', + title: __('Operate'), + table: table, + events: Table.api.events.operate, + buttons: [ + { + name: 'Restore', + text: __('Restore'), + classname: 'btn btn-xs btn-info btn-ajax btn-restoreit', + icon: 'fa fa-rotate-left', + url: 'arc/restore', + refresh: true + }, + { + name: 'Destroy', + text: __('Destroy'), + classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit', + icon: 'fa fa-times', + url: 'arc/destroy', + refresh: true + } + ], + formatter: Table.api.formatter.operate + } + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + + add: function () { + Controller.api.bindevent(); + }, + edit: function () { + Controller.api.bindevent(); + }, + api: { + bindevent: function () { + Form.api.bindevent($("form[role=form]")); + } + } + }; + return Controller; +}); diff --git a/public/assets/js/backend/command.js b/public/assets/js/backend/command.js new file mode 100644 index 0000000..3df5515 --- /dev/null +++ b/public/assets/js/backend/command.js @@ -0,0 +1,234 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'command/index', + add_url: 'command/add', + edit_url: '', + del_url: 'command/del', + multi_url: 'command/multi', + table: 'command', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: 'id', + sortName: 'id', + columns: [ + [ + {checkbox: true}, + {field: 'id', title: __('Id')}, + {field: 'type', title: __('Type'), formatter: Table.api.formatter.search}, + {field: 'type_text', title: __('Type')}, + { + field: 'command', title: __('Command'), renderDefault: false, formatter: function (value, row, index) { + return ''; + } + }, + { + field: 'executetime', + title: __('Executetime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'createtime', + title: __('Createtime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'updatetime', + title: __('Updatetime'), + operate: 'RANGE', + addclass: 'datetimerange', + formatter: Table.api.formatter.datetime + }, + { + field: 'status', + title: __('Status'), + table: table, + custom: {"successed": 'success', "failured": 'danger'}, + searchList: {"successed": __('Successed'), "failured": __('Failured')}, + formatter: Table.api.formatter.status + }, + { + field: 'operate', + title: __('Operate'), + buttons: [ + { + name: 'execute', + title: __('Execute again'), + text: __('Execute again'), + url: 'command/execute', + icon: 'fa fa-repeat', + classname: 'btn btn-success btn-xs btn-execute btn-ajax', + success: function (data) { + Layer.alert("", { + title: __("执行结果"), + shadeClose: true + }); + table.bootstrapTable('refresh'); + return false; + } + }, + { + name: 'execute', + title: __('Detail'), + text: __('Detail'), + url: 'command/detail', + icon: 'fa fa-list', + classname: 'btn btn-info btn-xs btn-execute btn-dialog' + } + ], + table: table, + events: Table.api.events.operate, + formatter: Table.api.formatter.operate + } + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + add: function () { + require(['bootstrap-select', 'bootstrap-select-lang']); + var mainfields = []; + var relationfields = {}; + var maintable = []; + var relationtable = []; + var relationmode = ["belongsto", "hasone"]; + + var renderselect = function (select, data) { + var html = []; + for (var i = 0; i < data.length; i++) { + html.push(""); + } + $(select).html(html.join("")); + select.trigger("change"); + if (select.data("selectpicker")) { + select.selectpicker('refresh'); + } + return select; + }; + + $("select[name=table] option").each(function () { + maintable.push($(this).val()); + }); + $(document).on('change', "input[name='isrelation']", function () { + $("#relation-zone").toggleClass("hide", !$(this).prop("checked")); + }); + $(document).on('change', "select[name='table']", function () { + var that = this; + Fast.api.ajax({ + url: "command/get_field_list", + data: {table: $(that).val()}, + }, function (data, ret) { + mainfields = data.fieldlist; + $("#relation-zone .relation-item").remove(); + renderselect($("#fields"), mainfields); + return false; + }); + return false; + }); + $(document).on('click', "a.btn-newrelation", function () { + var that = this; + var index = parseInt($(that).data("index")) + 1; + var content = Template("relationtpl", {index: index}); + content = $(content.replace(/\[index\]/, index)); + $(this).data("index", index); + $(content).insertBefore($(that).closest(".row")); + $('select', content).selectpicker(); + var exists = [$("select[name='table']").val()]; + $("select.relationtable").each(function () { + exists.push($(this).val()); + }); + relationtable = []; + $.each(maintable, function (i, j) { + if ($.inArray(j, exists) < 0) { + relationtable.push(j); + } + }); + renderselect($("select.relationtable", content), relationtable); + $("select.relationtable", content).trigger("change"); + }); + $(document).on('click', "a.btn-removerelation", function () { + $(this).closest(".row").remove(); + }); + $(document).on('change', "#relation-zone select.relationmode", function () { + var table = $("select.relationtable", $(this).closest(".row")).val(); + var that = this; + Fast.api.ajax({ + url: "command/get_field_list", + data: {table: table}, + }, function (data, ret) { + renderselect($(that).closest(".row").find("select.relationprimarykey"), $(that).val() == 'belongsto' ? data.fieldlist : mainfields); + renderselect($(that).closest(".row").find("select.relationforeignkey"), $(that).val() == 'hasone' ? data.fieldlist : mainfields); + return false; + }); + }); + $(document).on('change', "#relation-zone select.relationtable", function () { + var that = this; + Fast.api.ajax({ + url: "command/get_field_list", + data: {table: $(that).val()}, + }, function (data, ret) { + renderselect($(that).closest(".row").find("select.relationmode"), relationmode); + renderselect($(that).closest(".row").find("select.relationfields"), mainfields) + renderselect($(that).closest(".row").find("select.relationforeignkey"), data.fieldlist) + renderselect($(that).closest(".row").find("select.relationfields"), data.fieldlist) + return false; + }); + }); + $(document).on('click', ".btn-command", function () { + var form = $(this).closest("form"); + var textarea = $("textarea[rel=command]", form); + textarea.val(''); + Fast.api.ajax({ + url: "command/command/action/command", + data: form.serialize(), + }, function (data, ret) { + textarea.val(data.command); + return false; + }); + }); + $(document).on('click', ".btn-execute", function () { + var form = $(this).closest("form"); + var textarea = $("textarea[rel=result]", form); + textarea.val(''); + Fast.api.ajax({ + url: "command/command/action/execute", + data: form.serialize(), + }, function (data, ret) { + textarea.val(data.result); + window.parent.$(".toolbar .btn-refresh").trigger('click'); + top.window.Fast.api.refreshmenu(); + return false; + }, function () { + window.parent.$(".toolbar .btn-refresh").trigger('click'); + }); + }); + $("select[name='table']").trigger("change"); + Controller.api.bindevent(); + }, + edit: function () { + Controller.api.bindevent(); + }, + api: { + bindevent: function () { + Form.api.bindevent($("form[role=form]")); + } + } + }; + return Controller; +}); diff --git a/public/install.php b/public/install.php deleted file mode 100644 index 57d7b68..0000000 --- a/public/install.php +++ /dev/null @@ -1,30 +0,0 @@ - -// +---------------------------------------------------------------------- -// [ 安装文件 ] -// 建议安装完成后移除此文件 -// 定义应用目录 -define('APP_PATH', __DIR__ . '/../application/'); - -// 加载框架引导文件 -require __DIR__ . '/../thinkphp/base.php'; - -// 绑定到安装控制器 -\think\Route::bind('\app\admin\command\Install', 'controller'); - -// 开启路由 -\think\App::route(true); - -// 设置根url -\think\Url::root(''); - -// 执行应用 -\think\App::run()->send(); diff --git a/public/admin.php b/public/jnalOSiBsd.php similarity index 100% rename from public/admin.php rename to public/jnalOSiBsd.php