From e6b443043a9cd620918a5324bd94dd611872e7e2 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Mon, 9 Dec 2019 09:58:52 +0800 Subject: [PATCH 01/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../permissions/controller/Permissions.php | 1 + catchAdmin/permissions/controller/Roles.php | 1 + .../migrations/20191208125722_roles.php | 40 +++++++++++++++ .../migrations/20191208125726_permissions.php | 44 ++++++++++++++++ .../20191208131107_user_has_roles.php | 36 +++++++++++++ .../20191208131115_role_has_permissions.php | 36 +++++++++++++ .../permissions/model/HasRolesTrait.php | 50 +++++++++++++++++++ catchAdmin/permissions/view/roles/create.html | 10 ++++ catchAdmin/permissions/view/roles/index.html | 10 ++++ extend/catcher/Form.php | 7 --- 11 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 catchAdmin/permissions/controller/Permissions.php create mode 100644 catchAdmin/permissions/controller/Roles.php create mode 100644 catchAdmin/permissions/database/migrations/20191208125722_roles.php create mode 100644 catchAdmin/permissions/database/migrations/20191208125726_permissions.php create mode 100644 catchAdmin/permissions/database/migrations/20191208131107_user_has_roles.php create mode 100644 catchAdmin/permissions/database/migrations/20191208131115_role_has_permissions.php create mode 100644 catchAdmin/permissions/model/HasRolesTrait.php create mode 100644 catchAdmin/permissions/view/roles/create.html create mode 100644 catchAdmin/permissions/view/roles/index.html delete mode 100644 extend/catcher/Form.php diff --git a/.gitignore b/.gitignore index d465120..0c60eea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /.idea /.vscode /vendor +/database *.log .env \ No newline at end of file diff --git a/catchAdmin/permissions/controller/Permissions.php b/catchAdmin/permissions/controller/Permissions.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/catchAdmin/permissions/controller/Permissions.php @@ -0,0 +1 @@ +table('roles',['engine'=>'Innodb', 'comment' => '角色表', 'signed' => false]); + $table->addColumn('name', 'string',['limit' => 15,'default'=>'','comment'=>'角色名']) + ->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false]) + ->addColumn('description', 'string',['default'=> '','comment'=>'角色备注']) + ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false )) + ->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false)) + ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) + ->create(); + } +} diff --git a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php new file mode 100644 index 0000000..373297b --- /dev/null +++ b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php @@ -0,0 +1,44 @@ +table('roles',['engine'=>'Innodb', 'comment' => '菜单表', 'signed' => false]); + $table->addColumn('name', 'string',['limit' => 15,'default'=>'','comment'=>'菜单名称']) + ->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false]) + ->addColumn('route', 'string', ['default' => '', 'comment' => '路由', 'limit' => 50]) + ->addColumn('permission_mark', 'string', ['null' => false, 'comment' => '权限标识', 'limit' => 50]) + ->addColumn('type', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 菜单 2 按钮']) + ->addColumn('sort', 'integer',['default'=> 0,'comment'=>'排序字段']) + ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false )) + ->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false)) + ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,null 未删除 timestamp 已删除', 'signed' => false)) + ->create(); + + } +} diff --git a/catchAdmin/permissions/database/migrations/20191208131107_user_has_roles.php b/catchAdmin/permissions/database/migrations/20191208131107_user_has_roles.php new file mode 100644 index 0000000..55d8450 --- /dev/null +++ b/catchAdmin/permissions/database/migrations/20191208131107_user_has_roles.php @@ -0,0 +1,36 @@ +table('user_has_roles',['engine'=>'Innodb', 'comment' => '用户角色表', 'signed' => false]); + $table->addColumn('uid', 'integer',['comment'=>'用户ID', 'signed' => false]) + ->addColumn('role_id', 'integer', ['comment'=>'角色ID', 'signed' => false]) + ->create(); + } +} diff --git a/catchAdmin/permissions/database/migrations/20191208131115_role_has_permissions.php b/catchAdmin/permissions/database/migrations/20191208131115_role_has_permissions.php new file mode 100644 index 0000000..c31c58b --- /dev/null +++ b/catchAdmin/permissions/database/migrations/20191208131115_role_has_permissions.php @@ -0,0 +1,36 @@ +table('role_has_permissions',['engine'=>'Innodb', 'comment' => '角色权限表', 'signed' => false]); + $table->addColumn('role_id', 'integer',['comment'=>'角色ID', 'signed' => false]) + ->addColumn('permission_id', 'integer', ['comment'=>'权限ID', 'signed' => false]) + ->create(); + } +} diff --git a/catchAdmin/permissions/model/HasRolesTrait.php b/catchAdmin/permissions/model/HasRolesTrait.php new file mode 100644 index 0000000..aa5800b --- /dev/null +++ b/catchAdmin/permissions/model/HasRolesTrait.php @@ -0,0 +1,50 @@ +belongsToMany(Roles::class, 'user_has_roles', 'user_id', 'role_id'); + } + + /** + * + * @time 2019年12月08日 + * @param $uid + * @return mixed + */ + public function getRoles($uid) + { + return $this->findBy($uid)->roles()->get(); + } + + /** + * + * @time 2019年12月08日 + * @param $uid + * @param array $roles + * @return mixed + */ + public function attach($uid, array $roles) + { + return $this->findBy($uid)->roles()->attach($roles); + } + + /** + * + * @time 2019年12月08日 + * @param $uid + * @param array $roles + * @return mixed + */ + public function detach($uid, array $roles) + { + return $this->findBy($uid)->roles()->detach($roles); + } +} \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/create.html b/catchAdmin/permissions/view/roles/create.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/catchAdmin/permissions/view/roles/create.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/index.html b/catchAdmin/permissions/view/roles/index.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/catchAdmin/permissions/view/roles/index.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/extend/catcher/Form.php b/extend/catcher/Form.php deleted file mode 100644 index 383c8eb..0000000 --- a/extend/catcher/Form.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Mon, 9 Dec 2019 16:22:00 +0800 Subject: [PATCH 02/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/view/index.html | 2 +- catchAdmin/permissions/controller/Roles.php | 78 ++++++++ .../migrations/20191208125726_permissions.php | 2 +- .../permissions/model/HasRolesTrait.php | 2 +- catchAdmin/permissions/model/Permissions.php | 28 +++ catchAdmin/permissions/model/Roles.php | 83 +++++++++ catchAdmin/permissions/route.php | 3 + catchAdmin/permissions/view/roles/create.html | 11 +- catchAdmin/permissions/view/roles/index.html | 167 +++++++++++++++++- catchAdmin/user/model/Users.php | 13 +- config/route.php | 4 +- ...20191128114204_any_class_name_you_want.php | 33 ---- database/seeds/Abc.php | 19 -- extend/catcher/CatchAdmin.php | 2 +- extend/catcher/command/InstallCommand.php | 54 ++---- .../catcher/command/ModelGeneratorCommand.php | 4 +- 16 files changed, 383 insertions(+), 122 deletions(-) create mode 100644 catchAdmin/permissions/model/Permissions.php create mode 100644 catchAdmin/permissions/model/Roles.php delete mode 100644 database/migrations/20191128114204_any_class_name_you_want.php delete mode 100644 database/seeds/Abc.php diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index 0d59d0d..fa6325a 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -84,7 +84,7 @@ 权限管理
用户管理
-
角色管理
+
角色管理
菜单管理
登录日志
diff --git a/catchAdmin/permissions/controller/Roles.php b/catchAdmin/permissions/controller/Roles.php index b3d9bbc..02b4c0a 100644 --- a/catchAdmin/permissions/controller/Roles.php +++ b/catchAdmin/permissions/controller/Roles.php @@ -1 +1,79 @@ role = $role; + } + + /** + * + * @time 2019年12月09日 + * @throws \Exception + * @return string + */ + public function index() + { + return $this->fetch(); + } + + public function roles() + { + + } + + public function create() + { + $form = new CatchForm(); + $form->formId('roles'); + $form->text('name', '角色名称'); + $form->formBtn('submitRoles'); + + return $this->fetch([ + 'form' => $form->render() + ]); + } + + public function save() + {} + + public function read($id) + { + + } + + public function edit($id) + { + $form = new CatchForm(); + $form->formId('roles'); + $form->text('name', '角色名称'); + $form->formBtn('submitRoles'); + + return $this->fetch([ + 'form' => $form->render() + ]); + } + + public function update($id, UpdateRequest $request) + { + } + + public function delete($id) + { + return CatchResponse::success($this->role->deleteBy($id)); + } + + public function list(Request $request) + { + return CatchResponse::paginate($this->role->getList($request->param())); + } +} \ No newline at end of file diff --git a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php index 373297b..5db13c9 100644 --- a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php +++ b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php @@ -28,7 +28,7 @@ class Permissions extends Migrator */ public function change() { - $table = $this->table('roles',['engine'=>'Innodb', 'comment' => '菜单表', 'signed' => false]); + $table = $this->table('permissions',['engine'=>'Innodb', 'comment' => '菜单表', 'signed' => false]); $table->addColumn('name', 'string',['limit' => 15,'default'=>'','comment'=>'菜单名称']) ->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false]) ->addColumn('route', 'string', ['default' => '', 'comment' => '路由', 'limit' => 50]) diff --git a/catchAdmin/permissions/model/HasRolesTrait.php b/catchAdmin/permissions/model/HasRolesTrait.php index aa5800b..03ec27b 100644 --- a/catchAdmin/permissions/model/HasRolesTrait.php +++ b/catchAdmin/permissions/model/HasRolesTrait.php @@ -1,7 +1,7 @@ belongsToMany(Roles::class, 'role_has_permissions'); + } +} \ No newline at end of file diff --git a/catchAdmin/permissions/model/Roles.php b/catchAdmin/permissions/model/Roles.php new file mode 100644 index 0000000..f17b2ea --- /dev/null +++ b/catchAdmin/permissions/model/Roles.php @@ -0,0 +1,83 @@ +0 已删除 + + ]; + + public function getList($search) + { + return $this->when($search['name'] ?? false, function ($query) use ($search){ + $query->whereLike('name', $search['name']); + })->paginate($search['limit'] ?? $this->limit); + } + + /** + * + * @time 2019年12月08日 + * @return \think\model\relation\BelongsToMany + */ + public function users(): \think\model\relation\BelongsToMany + { + return $this->belongsToMany(Users::class, 'user_has_roles'); + } + + /** + * + * @time 2019年12月09日 + * @return \think\model\relation\BelongsToMany + */ + public function permissions(): \think\model\relation\BelongsToMany + { + return $this->belongsToMany(Permissions::class, 'role_has_permissions', 'role_id', 'permission_id'); + } + + /** + * + * @time 2019年12月08日 + * @param $rid + * @return mixed + */ + public function getRoles($rid) + { + return $this->findBy($rid)->permissions()->get(); + } + + /** + * + * @time 2019年12月08日 + * @param $rid + * @param array $roles + * @return mixed + */ + public function attach($rid, array $roles) + { + return $this->findBy($rid)->permissions()->attach($roles); + } + + /** + * + * @time 2019年12月08日 + * @param $rid + * @param array $roles + * @return mixed + */ + public function detach($rid, array $roles) + { + return $this->findBy($rid)->permissions()->detach($roles); + } +} \ No newline at end of file diff --git a/catchAdmin/permissions/route.php b/catchAdmin/permissions/route.php index b3d9bbc..1aab024 100644 --- a/catchAdmin/permissions/route.php +++ b/catchAdmin/permissions/route.php @@ -1 +1,4 @@ resource('role', '\catchAdmin\permissions\controller\Roles'); +// 用户列表 +$router->get('roles', '\catchAdmin\permissions\controller\Roles/list'); diff --git a/catchAdmin/permissions/view/roles/create.html b/catchAdmin/permissions/view/roles/create.html index 566549b..590c7a1 100644 --- a/catchAdmin/permissions/view/roles/create.html +++ b/catchAdmin/permissions/view/roles/create.html @@ -1,10 +1 @@ - - - - - Title - - - - - \ No newline at end of file +{$form|raw} \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/index.html b/catchAdmin/permissions/view/roles/index.html index 566549b..d14b400 100644 --- a/catchAdmin/permissions/view/roles/index.html +++ b/catchAdmin/permissions/view/roles/index.html @@ -1,10 +1,159 @@ - - - - - Title - - +{extend name="../../../view/layout"} +{block name="title"}角色管理{/block} +{block name="search"} +
+
+
+ +
+ +
+
+
+ + + +
+
+ +
+
+
+{/block} +{block name="table"} +
+ + +{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/catchAdmin/user/model/Users.php b/catchAdmin/user/model/Users.php index db8450f..db2b8f0 100644 --- a/catchAdmin/user/model/Users.php +++ b/catchAdmin/user/model/Users.php @@ -1,10 +1,13 @@ when($search['username'] ?? false, function ($query) use ($search){ return $query->whereLike('username', $search['username']); diff --git a/config/route.php b/config/route.php index 955eeec..8d9b272 100644 --- a/config/route.php +++ b/config/route.php @@ -7,11 +7,11 @@ return [ // pathinfo分隔符 'pathinfo_depr' => '/', // URL伪静态后缀 - 'url_html_suffix' => 'html', + 'url_html_suffix' => '', // URL普通方式参数 用于自动生成 'url_common_param' => true, // 是否开启路由延迟解析 - 'url_lazy_route' => false, + 'url_lazy_route' => true, // 是否强制使用路由 'url_route_must' => false, // 合并路由规则 diff --git a/database/migrations/20191128114204_any_class_name_you_want.php b/database/migrations/20191128114204_any_class_name_you_want.php deleted file mode 100644 index 67a90d7..0000000 --- a/database/migrations/20191128114204_any_class_name_you_want.php +++ /dev/null @@ -1,33 +0,0 @@ -app->getRootPath() . '.env')) { return false; @@ -140,33 +141,16 @@ class InstallCommand extends Command */ protected function secondStep(): void { - $modulePaths = glob(root_path('module') . '*'); + $php = getenv('_'); - $this->checkRootDatabase(); + $think = root_path() . DIRECTORY_SEPARATOR . 'think'; - foreach ($modulePaths as $path) { - if (is_dir($path)) { - $moduleDatabasePath = $path . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR; - if (is_dir($moduleDatabasePath)) { - if (is_dir($moduleDatabasePath . 'migrations' . DIRECTORY_SEPARATOR)) { - $migrationFiles = glob($moduleDatabasePath . 'migrations' . DIRECTORY_SEPARATOR . '*.php'); - foreach ($migrationFiles as $file) { - copy($file, - root_path('database') . 'migrations'. DIRECTORY_SEPARATOR . - pathinfo($file, PATHINFO_BASENAME)); - } - } + foreach (CatchAdmin::getModulesDirectory() as $directory) { + $moduleInfo = CatchAdmin::getModuleInfo($directory); - if (is_dir($moduleDatabasePath . 'seeds' . DIRECTORY_SEPARATOR)) { - $seedFiles = glob($moduleDatabasePath . 'seeds' . DIRECTORY_SEPARATOR . '*.php'); - foreach ($seedFiles as $file) { - copy($file, - root_path('database') . 'seeds' . DIRECTORY_SEPARATOR . - pathinfo($file, PATHINFO_BASENAME)); - } - } - } - } + $this->output->info( + sprintf('module [%s] migrations ', $moduleInfo['alias']) . + exec(sprintf('%s %s catch-migrate:run %s', $php, $think, $moduleInfo['alias']))); } } @@ -190,9 +174,7 @@ class InstallCommand extends Command protected function finished(): void { // todo something - if ($this->dataInstall) { - rmdir($this->app->getRootPath() . 'database'); - } + } /** @@ -241,23 +223,11 @@ class InstallCommand extends Command if ($this->getEnvFile()) { $this->output->info('env file has been generated'); } - if ((new \mysqli($host, $username, $password, null, $port))->query(sprintf('CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARSET %s COLLATE %s_general_ci;', $database, $charset, $charset))) { $this->output->info(sprintf('🎉 create database %s successfully', $database)); - - exec(sprintf('%s %s migrate:run', getenv('_'), root_path() . DIRECTORY_SEPARATOR . 'think')); - - $this->output->info('🎉 database table install successfully'); - - exec(sprintf('%s %s seed:run', getenv('_'),root_path() . DIRECTORY_SEPARATOR . 'think')); - - $this->output->info('🎉 Fill database table successfully '); } else { - $this->dataInstall = false; - $this->output->warning(sprintf('create database %s failed, you should create it by yourself', $database)); - $this->output->warning('you should use `php think migrate:run` to create tables'); - $this->output->warning('you should use `php think seed:run` to fill tables data'); + $this->output->warning(sprintf('create database %s failed,you need create database first by yourself', $database)); } } diff --git a/extend/catcher/command/ModelGeneratorCommand.php b/extend/catcher/command/ModelGeneratorCommand.php index 66e68e1..4595a71 100644 --- a/extend/catcher/command/ModelGeneratorCommand.php +++ b/extend/catcher/command/ModelGeneratorCommand.php @@ -80,9 +80,9 @@ class ModelGeneratorCommand extends Command Date: Mon, 9 Dec 2019 16:48:09 +0800 Subject: [PATCH 03/99] =?UTF-8?q?=E6=96=B0=E5=A2=9Etheme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/controller/Index.php | 5 + catchAdmin/index/route.php | 1 + catchAdmin/index/view/theme.html | 259 ++++++++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 catchAdmin/index/view/theme.html diff --git a/catchAdmin/index/controller/Index.php b/catchAdmin/index/controller/Index.php index cd6e2d8..fdacc9d 100644 --- a/catchAdmin/index/controller/Index.php +++ b/catchAdmin/index/controller/Index.php @@ -10,4 +10,9 @@ class Index extends BaseController { return $this->fetch(); } + + public function theme() + { + return $this->fetch(); + } } \ No newline at end of file diff --git a/catchAdmin/index/route.php b/catchAdmin/index/route.php index ebbd5d7..56b9e99 100644 --- a/catchAdmin/index/route.php +++ b/catchAdmin/index/route.php @@ -1,3 +1,4 @@ get('/', '\catchAdmin\index\controller\index/index'); +$router->get('theme', '\catchAdmin\index\controller\index/theme'); diff --git a/catchAdmin/index/view/theme.html b/catchAdmin/index/view/theme.html new file mode 100644 index 0000000..f4e53a2 --- /dev/null +++ b/catchAdmin/index/view/theme.html @@ -0,0 +1,259 @@ + + + + 设置 + + + + + + + + + + + +
+
+ +
+
+ +
设置主题
+
+ +
+ + + + + +
+
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+
+
+ +
+ + + +
+
+
+ +
+ + + + + + \ No newline at end of file From 7ac37e235b257c5a9b5948e160bd24874cc620bd Mon Sep 17 00:00:00 2001 From: zhangfayuan <1137494466@qq.com> Date: Tue, 10 Dec 2019 14:03:28 +0800 Subject: [PATCH 04/99] catch-seed:run --- catchAdmin/CatchAdminService.php | 2 + catchAdmin/user/database/seeds/Abc.php | 19 ------ catchAdmin/user/database/seeds/UserSeeder.php | 30 +++++++++ extend/catcher/command/SeedRunCommand.php | 64 +++++++++++++++++++ 4 files changed, 96 insertions(+), 19 deletions(-) delete mode 100644 catchAdmin/user/database/seeds/Abc.php create mode 100644 catchAdmin/user/database/seeds/UserSeeder.php create mode 100644 extend/catcher/command/SeedRunCommand.php diff --git a/catchAdmin/CatchAdminService.php b/catchAdmin/CatchAdminService.php index cb46296..f9ac0c4 100644 --- a/catchAdmin/CatchAdminService.php +++ b/catchAdmin/CatchAdminService.php @@ -5,6 +5,7 @@ use catcher\command\InstallCommand; use catcher\command\MigrateRunCommand; use catcher\command\ModelGeneratorCommand; use catcher\command\ModuleCacheCommand; +use catcher\command\SeedRunCommand; use catcher\validates\Sometimes; use think\facade\Validate; use think\Service; @@ -23,6 +24,7 @@ class CatchAdminService extends Service ModuleCacheCommand::class, MigrateRunCommand::class, ModelGeneratorCommand::class, + SeedRunCommand::class ]); $this->registerValidates(); diff --git a/catchAdmin/user/database/seeds/Abc.php b/catchAdmin/user/database/seeds/Abc.php deleted file mode 100644 index 83cbbc5..0000000 --- a/catchAdmin/user/database/seeds/Abc.php +++ /dev/null @@ -1,19 +0,0 @@ - 'wuyanwen', + 'password' => password_hash('password',PASSWORD_DEFAULT), + 'email' => 'njphper@gmail.com', + 'status' => 1, + 'last_login_ip' => ip2long('127.0.0.1'), + 'last_login_time' => time(), + 'created_at' => time(), + 'updated_at' => time(), + 'deleted_at' => '', + ]; + $this->table('users')->insert($row)->save(); + } +} \ No newline at end of file diff --git a/extend/catcher/command/SeedRunCommand.php b/extend/catcher/command/SeedRunCommand.php new file mode 100644 index 0000000..c9b756b --- /dev/null +++ b/extend/catcher/command/SeedRunCommand.php @@ -0,0 +1,64 @@ +setName('catch-seed:run') + ->setDescription('the catch-seed:run command to Run database seeders') + ->addArgument('module', Argument::REQUIRED, 'seed the module database') + ->addOption('--seed', '-s', InputOption::VALUE_REQUIRED, 'What is the name of the seeder?') + ->setHelp(<<catch-seed:run command runs all available or individual seeders +php think catch-seed:run module +php think catch-seed:run -s UserSeeder +php think catch-seed:run -v + +EOT + ); + + } + + protected function execute(Input $input, Output $output) + { + $this->module = strtolower($input->getArgument('module')); + $seed = $input->getOption('seed'); + + // run the seed(ers) + $start = microtime(true); + $this->seed($seed); + $end = microtime(true); + + $output->writeln(CatchAdmin::moduleSeedsDirectory($this->module)); + $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); + + } + + /** + * + * 获取 seeder path + * @return string + * @param $module + * @date: 2019/12/10 14:01 + */ + protected function getPath() + { + return CatchAdmin::moduleSeedsDirectory($this->module); + } + + +} From 22064c61788d4ceb503afaaa008ed9175ec474cc Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Wed, 11 Dec 2019 20:59:59 +0800 Subject: [PATCH 05/99] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permissions/PermissionsMiddleware.php | 1 + .../permissions/view/permissions/create.html | 26 + .../permissions/view/permissions/edit.html | 25 + .../permissions/view/permissions/index.html | 178 +++++ catchAdmin/permissions/view/roles/edit.html | 10 + catchAdmin/user/controller/User.php | 40 +- catchAdmin/user/model/Users.php | 8 +- catchAdmin/user/request/CreateRequest.php | 4 +- catchAdmin/user/request/UpdateRequest.php | 4 +- catchAdmin/user/route.php | 1 + catchAdmin/user/validate/CreateValidate.php | 17 - catchAdmin/user/validate/UpdateValidate.php | 18 - catchAdmin/user/view/create.html | 22 +- catchAdmin/user/view/edit.html | 18 +- extend/catcher/Tree.php | 1 + ...BaseController.php => CatchController.php} | 0 .../base/{BaseModel.php => CatchModel.php} | 0 .../{BaseRequest.php => CatchRequest.php} | 0 .../{BaseValidate.php => CatchValidate.php} | 0 extend/catcher/exceptions/FailedException.php | 1 + .../assets/module/authtree/authtree.js | 731 ++++++++++++++++++ .../tree_themes/auth-skin-default.css | 108 +++ .../tree_themes/auth-skin-universal.css | 127 +++ .../module/authtree/tree_themes/template.css | 16 + .../assets/module/treetable-lay/treetable.css | 18 - .../assets/module/treetable-lay/treetable.js | 206 ----- 26 files changed, 1306 insertions(+), 274 deletions(-) create mode 100644 catchAdmin/permissions/PermissionsMiddleware.php create mode 100644 catchAdmin/permissions/view/permissions/create.html create mode 100644 catchAdmin/permissions/view/permissions/edit.html create mode 100644 catchAdmin/permissions/view/permissions/index.html create mode 100644 catchAdmin/permissions/view/roles/edit.html delete mode 100644 catchAdmin/user/validate/CreateValidate.php delete mode 100644 catchAdmin/user/validate/UpdateValidate.php create mode 100644 extend/catcher/Tree.php rename extend/catcher/base/{BaseController.php => CatchController.php} (100%) rename extend/catcher/base/{BaseModel.php => CatchModel.php} (100%) rename extend/catcher/base/{BaseRequest.php => CatchRequest.php} (100%) rename extend/catcher/base/{BaseValidate.php => CatchValidate.php} (100%) create mode 100644 extend/catcher/exceptions/FailedException.php create mode 100755 public/catch-admin/assets/module/authtree/authtree.js create mode 100755 public/catch-admin/assets/module/authtree/tree_themes/auth-skin-default.css create mode 100755 public/catch-admin/assets/module/authtree/tree_themes/auth-skin-universal.css create mode 100755 public/catch-admin/assets/module/authtree/tree_themes/template.css delete mode 100755 public/catch-admin/assets/module/treetable-lay/treetable.css delete mode 100755 public/catch-admin/assets/module/treetable-lay/treetable.js diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -0,0 +1 @@ + + layui.use(['layer', 'form', 'admin', 'formX'], function () { + var $ = layui.jquery; + var layer = layui.layer; + var form = layui.form; + var admin = layui.admin; + var mUser = admin.getLayerData('#role'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可 + // 回显数据 + form.val('role', mUser); + // 表单提交事件 + form.on('submit(submitRole)', function (data) { + admin.req('{:url("role")}', data.field, function (response) { + layer.closeAll('loading'); + if (response.code === 10000) { + layer.msg(response.msg, {icon: 1}); + admin.putLayerData('formOk', true, '#role'); // 设置操作成功的标识,#modelUserForm这个只要写弹窗内任意一个元素的id即可 + admin.closeDialog('#role'); // 关闭页面层弹窗 + } else { + layer.msg(response.msg, {icon: 2}); + } + }, 'post'); + return false; + }); + }); + \ No newline at end of file diff --git a/catchAdmin/permissions/view/permissions/edit.html b/catchAdmin/permissions/view/permissions/edit.html new file mode 100644 index 0000000..d8669bc --- /dev/null +++ b/catchAdmin/permissions/view/permissions/edit.html @@ -0,0 +1,25 @@ +{$form|raw} + \ No newline at end of file diff --git a/catchAdmin/permissions/view/permissions/index.html b/catchAdmin/permissions/view/permissions/index.html new file mode 100644 index 0000000..938e029 --- /dev/null +++ b/catchAdmin/permissions/view/permissions/index.html @@ -0,0 +1,178 @@ +{extend name="../../../view/layout"} +{block name="title"}角色管理{/block} +{block name="search"} +
+
+ + + +
+
+{/block} +{block name="table"} +
+ + +{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/edit.html b/catchAdmin/permissions/view/roles/edit.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/catchAdmin/permissions/view/roles/edit.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/catchAdmin/user/controller/User.php b/catchAdmin/user/controller/User.php index 0f570ca..6fe2b42 100644 --- a/catchAdmin/user/controller/User.php +++ b/catchAdmin/user/controller/User.php @@ -2,14 +2,16 @@ namespace catchAdmin\user\controller; use app\Request; +use catchAdmin\permissions\model\Roles; use catchAdmin\user\model\Users; use catchAdmin\user\request\CreateRequest; use catchAdmin\user\request\UpdateRequest; -use catcher\base\BaseController; +use catcher\base\CatchController; use catcher\CatchForm; use catcher\CatchResponse; +use catcher\Tree; -class User extends BaseController +class User extends CatchController { protected $user; @@ -49,6 +51,7 @@ class User extends BaseController $form->text('email', '邮箱')->verify('email')->placeholder('请输入邮箱'); $form->password('password', '密码')->id('pwd')->verify('required|psw')->placeholder('请输入密码'); $form->password('passwordConfirm', '确认密码')->verify('required|equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码'); + $form->dom('
', '角色'); $form->formBtn('submitUser'); return $this->fetch([ @@ -64,7 +67,12 @@ class User extends BaseController */ public function save(CreateRequest $request) { - return CatchResponse::success($this->user->storeBy($request->post())); + $uid = $this->user->storeBy($request->post()); + + if (!empty($request->param('roleids'))) { + $this->user->attach($request->param('roleids')); + } + return CatchResponse::success(); } /** @@ -88,6 +96,7 @@ class User extends BaseController $form->text('email', '邮箱')->verify('email')->default($user->email)->placeholder('请输入邮箱'); $form->password('password', '密码')->id('pwd')->placeholder('请输入密码'); $form->password('passwordConfirm', '确认密码')->verify('equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码'); + $form->dom('
', '角色'); $form->formBtn('submitUser'); return $this->fetch([ @@ -152,4 +161,29 @@ class User extends BaseController return CatchResponse::success($this->user->recover($id)); } + + /** + * + * @time 2019年12月11日 + * @param Request $request + * @param Roles $roles + * @return \think\response\Json + */ + public function getRoles(Request $request, Roles $roles): \think\response\Json + { + $roles = Tree::done($roles->getList()); + + $roleIds = []; + if ($request->param('uid')) { + $userHasRoles = $this->user->findBy($request->param('uid'))->getRoles(); + foreach ($userHasRoles as $role) { + $roleIds[] = $role->pivot->role_id; + } + } + + return CatchResponse::success([ + 'roles' => $roles, + 'hasRoles' => $roleIds, + ]); + } } \ No newline at end of file diff --git a/catchAdmin/user/model/Users.php b/catchAdmin/user/model/Users.php index db2b8f0..1d6b3d7 100644 --- a/catchAdmin/user/model/Users.php +++ b/catchAdmin/user/model/Users.php @@ -2,9 +2,9 @@ namespace catchAdmin\user\model; use catchAdmin\permissions\model\HasRolesTrait; -use catcher\base\BaseModel; +use catcher\base\CatchModel; -class Users extends BaseModel +class Users extends CatchModel { use HasRolesTrait; @@ -46,7 +46,9 @@ class Users extends BaseModel */ public function getList($search): \think\Paginator { - return (($search['trash'] ?? false) ? static::onlyTrashed() : $this)->when($search['username'] ?? false, function ($query) use ($search){ + return (($search['trash'] ?? false) ? static::onlyTrashed() : $this) + ->field(['id', 'username', 'email', 'status','last_login_time','last_login_ip', 'created_at', 'updated_at']) + ->when($search['username'] ?? false, function ($query) use ($search){ return $query->whereLike('username', $search['username']); }) ->when($search['email'] ?? false, function ($query) use ($search){ diff --git a/catchAdmin/user/request/CreateRequest.php b/catchAdmin/user/request/CreateRequest.php index 89b6f7a..23abb95 100644 --- a/catchAdmin/user/request/CreateRequest.php +++ b/catchAdmin/user/request/CreateRequest.php @@ -2,9 +2,9 @@ namespace catchAdmin\user\request; use catchAdmin\user\model\Users; -use catcher\base\BaseRequest; +use catcher\base\CatchRequest; -class CreateRequest extends BaseRequest +class CreateRequest extends CatchRequest { protected function rules(): array diff --git a/catchAdmin/user/request/UpdateRequest.php b/catchAdmin/user/request/UpdateRequest.php index 992720e..b82758b 100644 --- a/catchAdmin/user/request/UpdateRequest.php +++ b/catchAdmin/user/request/UpdateRequest.php @@ -2,9 +2,9 @@ namespace catchAdmin\user\request; use catchAdmin\user\model\Users; -use catcher\base\BaseRequest; +use catcher\base\CatchRequest; -class UpdateRequest extends BaseRequest +class UpdateRequest extends CatchRequest { protected function rules(): array { diff --git a/catchAdmin/user/route.php b/catchAdmin/user/route.php index 0dc963b..cf9137a 100644 --- a/catchAdmin/user/route.php +++ b/catchAdmin/user/route.php @@ -6,3 +6,4 @@ $router->get('users', '\catchAdmin\user\controller\User/list'); // 切换状态 $router->put('user/switch/status/', '\catchAdmin\user\controller\User/switchStatus'); $router->put('user/recover/', '\catchAdmin\user\controller\User/recover'); +$router->get('user/get/roles', '\catchAdmin\user\controller\User/getRoles'); diff --git a/catchAdmin/user/validate/CreateValidate.php b/catchAdmin/user/validate/CreateValidate.php deleted file mode 100644 index 59b1666..0000000 --- a/catchAdmin/user/validate/CreateValidate.php +++ /dev/null @@ -1,17 +0,0 @@ - 'require|max:20', - 'password|密码' => 'require|max:20', - 'email|邮箱' => 'require|email' - ]; - } -} diff --git a/catchAdmin/user/validate/UpdateValidate.php b/catchAdmin/user/validate/UpdateValidate.php deleted file mode 100644 index c7b7d78..0000000 --- a/catchAdmin/user/validate/UpdateValidate.php +++ /dev/null @@ -1,18 +0,0 @@ - 'require|max:20', - 'password|密码' => 'require|max:20', - 'email|邮箱' => 'require|email|unique:'.Users::class.',email,'.request()->route('user').',id', - ]; - } -} diff --git a/catchAdmin/user/view/create.html b/catchAdmin/user/view/create.html index 0f2bdb1..a0a6480 100644 --- a/catchAdmin/user/view/create.html +++ b/catchAdmin/user/view/create.html @@ -1,28 +1,42 @@ {$form|raw} \ No newline at end of file diff --git a/catchAdmin/user/view/edit.html b/catchAdmin/user/view/edit.html index c709ea9..1aafbe0 100644 --- a/catchAdmin/user/view/edit.html +++ b/catchAdmin/user/view/edit.html @@ -1,14 +1,30 @@ {$form|raw} {/block} @@ -53,22 +53,33 @@ } } }, - elem: '#tableRole', + elem: '#tablePermission', cellMinWidth: 100, cols: [ {type: 'numbers', title: '#'}, - {field: 'role_name', title: '角色名称', minWidth: 100}, - {field: 'description', title: '角色描述'}, + {field: 'permission_name', title: '菜单名称', minWidth: 200}, + {field: 'route', title: '菜单路由', templet: function (d) { + return escapeChars(d.route); + } + }, + {field: 'method', title: '请求方法', width: 90}, + {field: 'permission_mark', title: '权限标识'}, + {field: 'type', title: '菜单类型', templet: function (d) { + return d.type == 1 ? '' : + '' + }, width: 90, align: 'center' + }, + {field: 'sort', title: '排序', width:60, align: 'center'}, { field: 'created_at', sort: true, templet: function (d) { return util.toDateString(d.created_at); }, title: '创建时间', maxWidth: 100 }, - {templet: '#tableBarAuth', title: '操作', align: 'center', minWidth: 120} + {templet: '#tableBarAuth', title: '操作', align: 'center', minWidth: 150} ], reqData: function(data, callback) { // 在这里写ajax请求,通过callback方法回调数据 - $.get('{:url("roles")}', function (res) { + $.get('{:url("permissions")}', function (res) { callback(res.data); // 参数是数组类型 }); } @@ -78,9 +89,17 @@ $('#btnAddAuth').click(function () { showEditModel(); }); - + function escapeChars(str) { + str = str.replace(/&/g, '&'); + str = str.replace(//g, '>'); + str = str.replace(/'/g, '´'); + str = str.replace(/"/g, '"'); + str = str.replace(/\|/g, '¦'); + return str; + } // 工具条点击事件 - treeTable.on('tool(tableRole)', function (obj) { + treeTable.on('tool(tablePermission)', function (obj) { var data = obj.data; var layEvent = obj.event; if (layEvent === 'edit') { // 修改 @@ -91,15 +110,19 @@ showEditModel(data, true); } }); - + treeTable.on('row(tablePermission)', function(obj){ + console.log(obj.value); //得到修改后的值 + console.log(obj.field); //当前编辑的字段名 + console.log(obj.data); //所在行的所有相关数据 + }); // 删除 function doDel(obj) { - layer.confirm('确定要删除“' + obj.data.role_name + '”吗?', { + layer.confirm('确定要删除“' + obj.data.permission_name + '”吗?', { skin: 'layui-layer-admin', shade: .1 }, function (index) { layer.close(index); - admin.req('/role/'+ obj.data.id, {}, function (response) { + admin.req('/permission/'+ obj.data.id, {}, function (response) { if (response.code === 10000) { layer.msg(response.msg, {icon: 1}); obj.del() @@ -112,24 +135,23 @@ // 显示表单弹窗 // 显示表单弹窗 - function showEditModel(mRole, addRole = false) { + function showEditModel(permission, addPermission= false) { var layIndex = admin.open({ - title: addRole ? '新增子角色' : ((mRole ? '修改' : '添加') + '角色'), - url: addRole ? '/role/create' + '?id='+mRole.id : (mRole ? '/role/'+mRole.id + '/edit': '/role/create'), - data: addRole ? '' : mRole, // 传递数据到表单页面 + title: addPermission ? '新增子菜单' : ((permission ? '修改' : '添加') + '菜单'), + url: addPermission ? '/permission/create' + '?id='+permission.id : (permission ? '/permission/'+permission.id + '/edit': '/permission/create'), + data: addPermission ? '' : permission, // 传递数据到表单页面 end: function () { if (admin.getLayerData(layIndex, 'formOk')) { // 判断表单操作成功标识 - if (addRole) { + if (addPermission) { treeTb.reload(); setTimeout(function () { - treeTb.expand(mRole.id) + treeTb.expand(permission.id) }, 200) - } else { - if (mRole) { + if (permission) { treeTb.reload(); setTimeout(function () { - treeTb.expand(mRole.id) + treeTb.expand(permission.id) }, 200) } else { treeTb.reload(); // 成功刷新表格 diff --git a/catchAdmin/permissions/view/roles/create.html b/catchAdmin/permissions/view/roles/create.html index 590c7a1..6474fe4 100644 --- a/catchAdmin/permissions/view/roles/create.html +++ b/catchAdmin/permissions/view/roles/create.html @@ -1 +1,40 @@ -{$form|raw} \ No newline at end of file +{$form|raw} + \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/edit.html b/catchAdmin/permissions/view/roles/edit.html index 566549b..d8669bc 100644 --- a/catchAdmin/permissions/view/roles/edit.html +++ b/catchAdmin/permissions/view/roles/edit.html @@ -1,10 +1,25 @@ - - - - - Title - - - - - \ No newline at end of file +{$form|raw} + \ No newline at end of file diff --git a/catchAdmin/permissions/view/roles/index.html b/catchAdmin/permissions/view/roles/index.html index d14b400..63cc948 100644 --- a/catchAdmin/permissions/view/roles/index.html +++ b/catchAdmin/permissions/view/roles/index.html @@ -3,61 +3,76 @@ {block name="search"}
-
- + - -
-
- -
+
{/block} {block name="table"} -
+
{/block} {block name="script"} {/block} \ No newline at end of file From c48d9154adad9a4dd1fc24dd399adc3345eb9acf Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Wed, 11 Dec 2019 21:00:24 +0800 Subject: [PATCH 07/99] =?UTF-8?q?=E9=A6=96=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/controller/Index.php | 19 +++++++++++++++---- catchAdmin/index/view/index.html | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/catchAdmin/index/controller/Index.php b/catchAdmin/index/controller/Index.php index fdacc9d..6112225 100644 --- a/catchAdmin/index/controller/Index.php +++ b/catchAdmin/index/controller/Index.php @@ -1,17 +1,28 @@ fetch(); } - public function theme() + /** + * + * @time 2019年12月11日 + * @throws \Exception + * @return string + */ + public function theme(): string { return $this->fetch(); } diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index fa6325a..af758f3 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -85,7 +85,7 @@
用户管理
角色管理
-
菜单管理
+
菜单管理
登录日志
From 7a6628a95fc9b3184cf85f25ff8fd7a1de20dfb5 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 09:13:29 +0800 Subject: [PATCH 08/99] =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permissions/controller/Permissions.php | 2 + catchAdmin/permissions/controller/Roles.php | 67 ++++++++++++++++--- .../permissions/model/HasRolesTrait.php | 4 ++ catchAdmin/permissions/model/Permissions.php | 4 +- catchAdmin/permissions/model/Roles.php | 5 +- catchAdmin/permissions/route.php | 3 +- catchAdmin/permissions/view/roles/create.html | 6 +- catchAdmin/permissions/view/roles/edit.html | 18 ++++- catchAdmin/permissions/view/roles/index.html | 2 +- 9 files changed, 91 insertions(+), 20 deletions(-) diff --git a/catchAdmin/permissions/controller/Permissions.php b/catchAdmin/permissions/controller/Permissions.php index 6b0047b..c1430c0 100644 --- a/catchAdmin/permissions/controller/Permissions.php +++ b/catchAdmin/permissions/controller/Permissions.php @@ -155,6 +155,8 @@ class Permissions extends CatchController throw new FailedException('存在子菜单,无法删除'); } + $this->permissions->findBy($id)->roles()->detach(); + return CatchResponse::success($this->permissions->deleteBy($id)); } } diff --git a/catchAdmin/permissions/controller/Roles.php b/catchAdmin/permissions/controller/Roles.php index b6a0228..f9dae32 100644 --- a/catchAdmin/permissions/controller/Roles.php +++ b/catchAdmin/permissions/controller/Roles.php @@ -7,6 +7,7 @@ use catcher\CatchForm; use catcher\CatchResponse; use catcher\exceptions\FailedException; use catcher\Tree; +use think\response\Json; class Roles extends CatchController { @@ -53,13 +54,18 @@ class Roles extends CatchController * * @time 2019年12月11日 * @param Request $request - * @return \think\response\Json + * @return Json + * @throws \think\db\exception\DbException */ public function save(Request $request) { + $this->role->storeBy($request->param()); + + if (!empty($request->param('permissionids'))) { + $this->role->attach($request->param('permissionids')); + } // 添加角色 - dd($request->param('roleids')); - return CatchResponse::success($this->role->storeBy($request->param())); + return CatchResponse::success(); } public function read($id) @@ -83,6 +89,7 @@ class Roles extends CatchController $form->hidden('parent_id')->default($role->parent_id); $form->text('role_name', '角色名称', true)->default($role->name)->verify('required')->placeholder('请输入角色名称'); $form->textarea('description', '角色描述')->default($role->description)->placeholder('请输入角色描述'); + $form->dom('
', '权限'); $form->formBtn('submitRole'); return $this->fetch([ @@ -96,11 +103,22 @@ class Roles extends CatchController * @time 2019年12月11日 * @param $id * @param Request $request - * @return \think\response\Json + * @return Json + * @throws \think\db\exception\DbException */ public function update($id, Request $request) { - return CatchResponse::success($this->role->updateBy($id, $request->param())); + $this->role->updateBy($id, $request->param()); + + $role = $this->role->findBy($id); + + $role->detach(); + + if (!empty($request->param('permissionids'))) { + $role->attach($request->param('permissionids')); + } + + return CatchResponse::success(); } /** @@ -111,26 +129,57 @@ class Roles extends CatchController * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException - * @return \think\response\Json + * @return Json */ public function delete($id) { if ($this->role->where('parent_id', $id)->find()) { throw new FailedException('存在子角色,无法删除'); } - + $role = $this->role->findBy($id); // 删除权限 - return CatchResponse::success($this->role->deleteBy($id)); + $role->detach(); + // 删除用户关联 + $role->users()->detach(); + // 删除 + $this->role->deleteBy($id); + + return CatchResponse::success(); } /** * * @time 2019年12月11日 * @param Request $request - * @return \think\response\Json + * @return Json */ public function list(Request $request) { return CatchResponse::success(Tree::done($this->role->getList($request->param()))); } + + /** + * + * @time 2019年12月11日 + * @param Request $request + * @param \catchAdmin\permissions\model\Permissions $permission + * @return Json + */ + public function getPermissions(Request $request, \catchAdmin\permissions\model\Permissions $permission): Json + { + $permissions = Tree::done($permission->getList()); + + $permissionIds = []; + if ($request->param('role_id')) { + $roleHasPermissions = $this->role->findBy($request->param('role_id'))->getPermissions(); + foreach ($roleHasPermissions as $_permission) { + $permissionIds[] = $_permission->pivot->permission_id; + } + } + + return CatchResponse::success([ + 'permissions' => $permissions, + 'hasPermissions' => $permissionIds, + ]); + } } \ No newline at end of file diff --git a/catchAdmin/permissions/model/HasRolesTrait.php b/catchAdmin/permissions/model/HasRolesTrait.php index 9667d09..edd8228 100644 --- a/catchAdmin/permissions/model/HasRolesTrait.php +++ b/catchAdmin/permissions/model/HasRolesTrait.php @@ -31,6 +31,10 @@ trait HasRolesTrait */ public function attach(array $roles) { + if (empty($roles)) { + return true; + } + return $this->roles()->attach($roles); } diff --git a/catchAdmin/permissions/model/Permissions.php b/catchAdmin/permissions/model/Permissions.php index 464d463..dea4225 100644 --- a/catchAdmin/permissions/model/Permissions.php +++ b/catchAdmin/permissions/model/Permissions.php @@ -30,7 +30,7 @@ class Permissions extends CatchModel public const PUT = 'put'; public const DELETE = 'delete'; - public function getList($search) + public function getList($search = []) { return $this->when($search['name'] ?? false, function ($query) use ($search){ $query->whereLike('name', $search['name']); @@ -47,6 +47,6 @@ class Permissions extends CatchModel public function roles(): \think\model\relation\BelongsToMany { - return $this->belongsToMany(Roles::class, 'role_has_permissions'); + return $this->belongsToMany(Roles::class, 'role_has_permissions', 'role_id', 'permission_id'); } } \ No newline at end of file diff --git a/catchAdmin/permissions/model/Roles.php b/catchAdmin/permissions/model/Roles.php index 10e04fe..eac71fc 100644 --- a/catchAdmin/permissions/model/Roles.php +++ b/catchAdmin/permissions/model/Roles.php @@ -40,7 +40,7 @@ class Roles extends CatchModel */ public function users(): \think\model\relation\BelongsToMany { - return $this->belongsToMany(Users::class, 'user_has_roles'); + return $this->belongsToMany(Users::class, 'user_has_roles', 'uid', 'role_id'); } /** @@ -56,10 +56,9 @@ class Roles extends CatchModel /** * * @time 2019年12月08日 - * @param $rid * @return mixed */ - public function getRoles($rid) + public function getPermissions() { return $this->permissions()->select(); } diff --git a/catchAdmin/permissions/route.php b/catchAdmin/permissions/route.php index f92c20a..1052bbb 100644 --- a/catchAdmin/permissions/route.php +++ b/catchAdmin/permissions/route.php @@ -3,8 +3,9 @@ $router->resource('role', '\catchAdmin\permissions\controller\Roles'); // 角色列表 $router->get('roles', '\catchAdmin\permissions\controller\Roles/list'); +$router->get('/role/get/permissions', '\catchAdmin\permissions\controller\Roles/getPermissions'); // 权限 $router->resource('permission', '\catchAdmin\permissions\controller\Permissions'); // 权限列表 -$router->get('permissions', '\catchAdmin\permissions\controller\Permissions/list'); \ No newline at end of file +$router->get('permissions', '\catchAdmin\permissions\controller\Permissions/list'); diff --git a/catchAdmin/permissions/view/roles/create.html b/catchAdmin/permissions/view/roles/create.html index 6474fe4..e27f062 100644 --- a/catchAdmin/permissions/view/roles/create.html +++ b/catchAdmin/permissions/view/roles/create.html @@ -23,9 +23,9 @@ }, 'post'); return false; }); - admin.req('{:url("permissions")}',{}, function (response) { - var inst1 = authtree.render('#permissions', response.data,{ - inputname: 'authids[]', + admin.req('{:url("/role/get/permissions")}',{}, function (response) { + authtree.render('#permissions', response.data.permissions,{ + inputname: 'permissionids[]', layfilter: 'lay-check-auth', autowidth: true, nameKey: 'permission_name', diff --git a/catchAdmin/permissions/view/roles/edit.html b/catchAdmin/permissions/view/roles/edit.html index d8669bc..ce1d7d0 100644 --- a/catchAdmin/permissions/view/roles/edit.html +++ b/catchAdmin/permissions/view/roles/edit.html @@ -1,13 +1,29 @@ {$form|raw} + + + + \ No newline at end of file diff --git a/catchAdmin/login/validate/LoginValidate.php b/catchAdmin/login/validate/LoginValidate.php deleted file mode 100644 index d4b7099..0000000 --- a/catchAdmin/login/validate/LoginValidate.php +++ /dev/null @@ -1,18 +0,0 @@ - 'require|max:25', - 'password|密码' => 'require', - 'captcha|验证码' => 'require|captcha' - ]; - } -} \ No newline at end of file diff --git a/catchAdmin/permissions/controller/Permissions.php b/catchAdmin/permissions/controller/Permission.php similarity index 92% rename from catchAdmin/permissions/controller/Permissions.php rename to catchAdmin/permissions/controller/Permission.php index c1430c0..5defd2d 100644 --- a/catchAdmin/permissions/controller/Permissions.php +++ b/catchAdmin/permissions/controller/Permission.php @@ -4,13 +4,14 @@ namespace catchAdmin\permissions\controller; use app\Request; use catcher\base\CatchController; +use catcher\CatchAdmin; use catcher\CatchForm; use catcher\CatchResponse; use catcher\exceptions\FailedException; use catcher\Tree; use catchAdmin\permissions\model\Permissions as Permission; -class Permissions extends CatchController +class Permission extends CatchController { protected $permissions; @@ -50,10 +51,10 @@ class Permissions extends CatchController public function create() { $form = new CatchForm(); - $form->formId('permission'); $form->text('permission_name', '菜单名称', true)->verify('required')->placeholder('请输入菜单名称'); $form->hidden('parent_id')->default(\request()->param('id') ?? 0); + $form->select('module', '模块', true)->verify('required')->options(CatchAdmin::getModulesInfo()); $form->text('route', '路由')->placeholder('请输入路由'); $form->radio('method', '请求方法', true)->default(Permission::GET)->options([ ['value' => Permission::GET, 'title' => 'get'], @@ -104,8 +105,9 @@ class Permissions extends CatchController ->verify('required') ->placeholder('请输入菜单名称'); $form->hidden('parent_id')->default($permission->parent_id); + $form->select('module', '模块', true)->default($permission->module)->options(CatchAdmin::getModulesInfo()); $form->text('route', '路由')->default($permission->route)->placeholder('请输入路由'); - $form->radio('method', '请求方法', true)->default($permission->method)->options([ + $form->radio('method', '请求方法', true)->verify('required')->default($permission->method)->options([ ['value' => Permission::GET, 'title' => 'get'], ['value' => Permission::POST, 'title' => 'post'], ['value' => Permission::PUT, 'title' => 'put'], diff --git a/catchAdmin/permissions/controller/Roles.php b/catchAdmin/permissions/controller/Role.php similarity index 88% rename from catchAdmin/permissions/controller/Roles.php rename to catchAdmin/permissions/controller/Role.php index f9dae32..43b81ae 100644 --- a/catchAdmin/permissions/controller/Roles.php +++ b/catchAdmin/permissions/controller/Role.php @@ -46,7 +46,8 @@ class Roles extends CatchController $form->formBtn('submitRole'); return $this->fetch([ - 'form' => $form->render() + 'form' => $form->render(), + 'parent_id' => \request()->param('id') ?? 0, ]); } @@ -95,6 +96,7 @@ class Roles extends CatchController return $this->fetch([ 'form' => $form->render(), 'role_id' => $role->id, + 'parent_id' => $role->parent_id ]); } @@ -167,7 +169,17 @@ class Roles extends CatchController */ public function getPermissions(Request $request, \catchAdmin\permissions\model\Permissions $permission): Json { - $permissions = Tree::done($permission->getList()); + $parentRoleHasPermissionIds = null; + if ($request->param('parent_id')) { + $permissions = $this->role->findBy($request->param('parent_id'))->getPermissions(); + foreach ($permissions as $_permission) { + $parentRoleHasPermissionIds[] = $_permission->pivot->permission_id; + } + } + + $permissions = Tree::done($permission->getList([ + 'permission_ids' => $parentRoleHasPermissionIds + ])); $permissionIds = []; if ($request->param('role_id')) { diff --git a/catchAdmin/permissions/view/permissions/create.html b/catchAdmin/permissions/view/permission/create.html similarity index 100% rename from catchAdmin/permissions/view/permissions/create.html rename to catchAdmin/permissions/view/permission/create.html diff --git a/catchAdmin/permissions/view/permissions/edit.html b/catchAdmin/permissions/view/permission/edit.html similarity index 100% rename from catchAdmin/permissions/view/permissions/edit.html rename to catchAdmin/permissions/view/permission/edit.html diff --git a/catchAdmin/permissions/view/permissions/index.html b/catchAdmin/permissions/view/permission/index.html similarity index 98% rename from catchAdmin/permissions/view/permissions/index.html rename to catchAdmin/permissions/view/permission/index.html index 77ec12b..2327f54 100644 --- a/catchAdmin/permissions/view/permissions/index.html +++ b/catchAdmin/permissions/view/permission/index.html @@ -21,7 +21,7 @@ {/block} diff --git a/catchAdmin/permissions/view/roles/create.html b/catchAdmin/permissions/view/role/create.html similarity index 94% rename from catchAdmin/permissions/view/roles/create.html rename to catchAdmin/permissions/view/role/create.html index e27f062..9325b59 100644 --- a/catchAdmin/permissions/view/roles/create.html +++ b/catchAdmin/permissions/view/role/create.html @@ -23,7 +23,7 @@ }, 'post'); return false; }); - admin.req('{:url("/role/get/permissions")}',{}, function (response) { + admin.req('{:url("/role/get/permissions")}',{parent_id:"{$parent_id}"}, function (response) { authtree.render('#permissions', response.data.permissions,{ inputname: 'permissionids[]', layfilter: 'lay-check-auth', diff --git a/catchAdmin/permissions/view/roles/edit.html b/catchAdmin/permissions/view/role/edit.html similarity index 96% rename from catchAdmin/permissions/view/roles/edit.html rename to catchAdmin/permissions/view/role/edit.html index ce1d7d0..ceaa644 100644 --- a/catchAdmin/permissions/view/roles/edit.html +++ b/catchAdmin/permissions/view/role/edit.html @@ -10,7 +10,7 @@ // 回显数据 form.val('role', mUser); - admin.req('{:url("/role/get/permissions")}',{role_id:"{$role_id}"}, function (response) { + admin.req('{:url("/role/get/permissions")}',{role_id:"{$role_id}", parent_id:"{$parent_id}"}, function (response) { console.log(response.data) authtree.render('#permissions', response.data.permissions,{ inputname: 'permissionids[]', diff --git a/catchAdmin/permissions/view/roles/index.html b/catchAdmin/permissions/view/role/index.html similarity index 98% rename from catchAdmin/permissions/view/roles/index.html rename to catchAdmin/permissions/view/role/index.html index e1da354..5687279 100644 --- a/catchAdmin/permissions/view/roles/index.html +++ b/catchAdmin/permissions/view/role/index.html @@ -21,7 +21,7 @@ {/block} @@ -125,7 +125,6 @@ setTimeout(function () { treeTb.expand(mRole.id) }, 200) - } else { if (mRole) { treeTb.reload(); diff --git a/catchAdmin/login/Auth.php b/catchAdmin/user/Auth.php similarity index 100% rename from catchAdmin/login/Auth.php rename to catchAdmin/user/Auth.php diff --git a/config/catch.php b/config/catch.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/config/catch.php @@ -0,0 +1 @@ + Date: Thu, 12 Dec 2019 18:52:24 +0800 Subject: [PATCH 13/99] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/user/Auth.php | 40 ++++++++++++++++++++------------- catchAdmin/user/model/Users.php | 22 ++++++++++++++++++ catchAdmin/user/route.php | 8 +++---- catchAdmin/user/view/index.html | 2 +- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/catchAdmin/user/Auth.php b/catchAdmin/user/Auth.php index 9472f02..31fbbcb 100644 --- a/catchAdmin/user/Auth.php +++ b/catchAdmin/user/Auth.php @@ -1,21 +1,14 @@ loginUser = md5($this->loginUser); - } + protected const USER_KEY = 'admin_user'; /** * 登陆 @@ -25,9 +18,14 @@ class Auth * @throws LoginFailedException * @return bool */ - public function login($params) + public static function login($params) { - $user = Users::where('username', $params['name'])->find(); + $user = Users::where('email', $params['email'])->find(); + + if (!$user) { + throw new LoginFailedException('登陆失败, 请检查用户名和密码'); + } + if (!password_verify($params['password'], $user->password)) { throw new LoginFailedException('登陆失败, 请检查用户名和密码'); } @@ -41,7 +39,7 @@ class Auth $user->last_login_time = time(); $user->save(); - Session::set($this->loginUser, $user); + Session::set(self::getLoginUserKey(), $user); return true; } @@ -52,10 +50,20 @@ class Auth * @time 2019年11月28日 * @return bool */ - public function logout() + public static function logout(): bool { - Session::delete($this->loginUser); + Session::delete(self::getLoginUserKey()); return true; } + + public static function user() + { + return Session::get(self::getLoginUserKey(), null); + } + + protected static function getLoginUserKey(): string + { + return md5(self::USER_KEY); + } } diff --git a/catchAdmin/user/model/Users.php b/catchAdmin/user/model/Users.php index 1d6b3d7..e7dd220 100644 --- a/catchAdmin/user/model/Users.php +++ b/catchAdmin/user/model/Users.php @@ -58,4 +58,26 @@ class Users extends CatchModel return $query->where('status', $search['status']); })->paginate($search['limit'] ?? $this->limit); } + + /** + * 获取权限 + * + * @time 2019年12月12日 + * @param $uid + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @return array + */ + public function getPermissionsBy($uid = 0): array + { + $roles = $uid ? $this->findBy($uid)->getRoles() : $this->getRoles(); + + $permissionIds = []; + foreach ($roles as $role) { + $permissionIds = array_merge($permissionIds, $role->getPermissions()->column('id')); + } + + return array_unique($permissionIds); + } } \ No newline at end of file diff --git a/catchAdmin/user/route.php b/catchAdmin/user/route.php index cf9137a..8cc80ca 100644 --- a/catchAdmin/user/route.php +++ b/catchAdmin/user/route.php @@ -2,8 +2,8 @@ $router->resource('user', '\catchAdmin\user\controller\User'); // 用户列表 -$router->get('users', '\catchAdmin\user\controller\User/list'); +$router->get('users', '\catchAdmin\user\controller\User@list'); // 切换状态 -$router->put('user/switch/status/', '\catchAdmin\user\controller\User/switchStatus'); -$router->put('user/recover/', '\catchAdmin\user\controller\User/recover'); -$router->get('user/get/roles', '\catchAdmin\user\controller\User/getRoles'); +$router->put('user/switch/status/', '\catchAdmin\user\controller\User@switchStatus'); +$router->put('user/recover/', '\catchAdmin\user\controller\User@recover'); +$router->get('user/get/roles', '\catchAdmin\user\controller\User@getRoles'); diff --git a/catchAdmin/user/view/index.html b/catchAdmin/user/view/index.html index 32d8805..39d23c2 100644 --- a/catchAdmin/user/view/index.html +++ b/catchAdmin/user/view/index.html @@ -122,7 +122,6 @@ }); function recover(uid, username) { - console.log(username) layer.confirm('确定要恢复“' + username + '”吗?', { skin: 'layui-layer-admin', shade: .1 @@ -145,6 +144,7 @@ title: (mUser ? '修改' : '添加') + '用户', url: mUser ? '/user/'+mUser.id + '/edit':'/user/create', data: mUser, // 传递数据到表单页面 + area: '500px', end: function () { if (admin.getLayerData(layIndex, 'formOk')) { // 判断表单操作成功标识 insTb.reload(); // 成功刷新表格 From 5c7c976869e5154fb3527e958e6bfc521cacda2e Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:52:33 +0800 Subject: [PATCH 14/99] =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permissions/PermissionsMiddleware.php | 64 ++++++++++++++++++- .../permissions/controller/Permission.php | 28 ++++---- catchAdmin/permissions/controller/Role.php | 2 +- .../migrations/20191208125726_permissions.php | 1 + .../permissions/model/HasRolesTrait.php | 2 + catchAdmin/permissions/model/Permissions.php | 4 ++ catchAdmin/permissions/model/Roles.php | 10 +-- catchAdmin/permissions/route.php | 10 +-- 8 files changed, 95 insertions(+), 26 deletions(-) diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php index af032cf..ba0168e 100644 --- a/catchAdmin/permissions/PermissionsMiddleware.php +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -1,14 +1,74 @@ user()) { + throw new PermissionForbiddenException('Login is invalid', 10006); + } // toad + if (($permission = $this->getPermission($request->rule()->getName())) && in_array($permission->id, $request->user()->getPermissionsBy())) { + throw new PermissionForbiddenException(); + } return $next($request); } + + /** + * + * @time 2019年12月12日 + * @param $rule + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @return array|bool|\think\Model|null + */ + protected function getPermission($rule) + { + if (!$rule) { + return false; + } + + [$controller, $action] = explode(Str::contains($rule, '@') ? '@' : '/', $rule); + + $controller = explode('\\', $controller); + + $controllerName = strtolower(array_pop($controller)); + + array_pop($controller); + + $module = array_pop($controller); + + $ignore = config('catch.ignore'); + + if (in_array($module, $ignore['module'])) { + return false; + } + + $permissionMark = sprintf('%s:%s:%s', $module, $controllerName, $action); + + if (in_array($permissionMark, $ignore['route'])) { + return false; + } + + return Permissions::where('permission_mark', $permissionMark)->find(); + } } \ No newline at end of file diff --git a/catchAdmin/permissions/controller/Permission.php b/catchAdmin/permissions/controller/Permission.php index 5defd2d..6a24072 100644 --- a/catchAdmin/permissions/controller/Permission.php +++ b/catchAdmin/permissions/controller/Permission.php @@ -9,13 +9,13 @@ use catcher\CatchForm; use catcher\CatchResponse; use catcher\exceptions\FailedException; use catcher\Tree; -use catchAdmin\permissions\model\Permissions as Permission; +use catchAdmin\permissions\model\Permissions as Permissions; class Permission extends CatchController { protected $permissions; - public function __construct(Permission $permissions) + public function __construct(Permissions $permissions) { $this->permissions = $permissions; } @@ -57,15 +57,15 @@ class Permission extends CatchController $form->select('module', '模块', true)->verify('required')->options(CatchAdmin::getModulesInfo()); $form->text('route', '路由')->placeholder('请输入路由'); $form->radio('method', '请求方法', true)->default(Permission::GET)->options([ - ['value' => Permission::GET, 'title' => 'get'], - ['value' => Permission::POST, 'title' => 'post'], - ['value' => Permission::PUT, 'title' => 'put'], - ['value' => Permission::DELETE, 'title' => 'delete'], + ['value' => Permissions::GET, 'title' => 'get'], + ['value' => Permissions::POST, 'title' => 'post'], + ['value' => Permissions::PUT, 'title' => 'put'], + ['value' => Permissions::DELETE, 'title' => 'delete'], ]); $form->text('permission_mark', '权限标识', true)->verify('required')->placeholder('请输入权限标识controller:action'); $form->radio('type', '类型', true)->default(Permission::BTN_TYPE)->options([ - ['value' => Permission::MENU_TYPE, 'title' => '菜单'], - ['value' => Permission::BTN_TYPE, 'title' => '按钮'], + ['value' => Permissions::MENU_TYPE, 'title' => '菜单'], + ['value' => Permissions::BTN_TYPE, 'title' => '按钮'], ]); $form->text('sort', '排序')->verify('numberX')->default(1)->placeholder('倒叙排序'); $form->formBtn('submitPermission'); @@ -108,17 +108,17 @@ class Permission extends CatchController $form->select('module', '模块', true)->default($permission->module)->options(CatchAdmin::getModulesInfo()); $form->text('route', '路由')->default($permission->route)->placeholder('请输入路由'); $form->radio('method', '请求方法', true)->verify('required')->default($permission->method)->options([ - ['value' => Permission::GET, 'title' => 'get'], - ['value' => Permission::POST, 'title' => 'post'], - ['value' => Permission::PUT, 'title' => 'put'], - ['value' => Permission::DELETE, 'title' => 'delete'], + ['value' => Permissions::GET, 'title' => 'get'], + ['value' => Permissions::POST, 'title' => 'post'], + ['value' => Permissions::PUT, 'title' => 'put'], + ['value' => Permissions::DELETE, 'title' => 'delete'], ]); $form->text('permission_mark', '权限标识', true) ->default($permission->permission_mark) ->verify('required')->placeholder('请输入权限标识controller:action'); $form->radio('type', '类型', true)->default($permission->type)->options([ - ['value' => Permission::MENU_TYPE, 'title' => '菜单'], - ['value' => Permission::BTN_TYPE, 'title' => '按钮'], + ['value' => Permissions::MENU_TYPE, 'title' => '菜单'], + ['value' => Permissions::BTN_TYPE, 'title' => '按钮'], ]); $form->text('sort', '排序')->verify('numberX')->default($permission->sort)->placeholder('倒叙排序'); $form->formBtn('submitPermission'); diff --git a/catchAdmin/permissions/controller/Role.php b/catchAdmin/permissions/controller/Role.php index 43b81ae..d583340 100644 --- a/catchAdmin/permissions/controller/Role.php +++ b/catchAdmin/permissions/controller/Role.php @@ -9,7 +9,7 @@ use catcher\exceptions\FailedException; use catcher\Tree; use think\response\Json; -class Roles extends CatchController +class Role extends CatchController { protected $role; diff --git a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php index e2ed573..ab252a1 100644 --- a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php +++ b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php @@ -32,6 +32,7 @@ class Permissions extends Migrator $table->addColumn('permission_name', 'string',['limit' => 15,'default'=>'','comment'=>'菜单名称']) ->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false]) ->addColumn('route', 'string', ['default' => '', 'comment' => '路由', 'limit' => 50]) + ->addColumn('module', 'string', ['default' => '', 'comment' => '模块', 'limit' => 20]) ->addColumn('method', 'string', ['default' => 'get', 'comment' => '路由请求方法', 'limit' => 15]) ->addColumn('permission_mark', 'string', ['null' => false, 'comment' => '权限标识', 'limit' => 50]) ->addColumn('type', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 菜单 2 按钮']) diff --git a/catchAdmin/permissions/model/HasRolesTrait.php b/catchAdmin/permissions/model/HasRolesTrait.php index edd8228..f9219c8 100644 --- a/catchAdmin/permissions/model/HasRolesTrait.php +++ b/catchAdmin/permissions/model/HasRolesTrait.php @@ -35,6 +35,8 @@ trait HasRolesTrait return true; } + sort($roles); + return $this->roles()->attach($roles); } diff --git a/catchAdmin/permissions/model/Permissions.php b/catchAdmin/permissions/model/Permissions.php index dea4225..880b11e 100644 --- a/catchAdmin/permissions/model/Permissions.php +++ b/catchAdmin/permissions/model/Permissions.php @@ -11,6 +11,7 @@ class Permissions extends CatchModel 'id', // 'permission_name', // 菜单名称 'parent_id', // 父级ID + 'module', // 模块 'route', // 路由 'method', // 请求方法 'permission_mark', // 权限标识 @@ -39,6 +40,9 @@ class Permissions extends CatchModel $query->where('parent_id', $search['id']) ->whereOr('id', $search['id']); }) + ->when($search['permission_ids'] ?? false, function ($query) use ($search){ + $query->whereIn('id', $search['permission_ids']); + }) ->order('sort', 'desc') ->order('id', 'desc') ->select() diff --git a/catchAdmin/permissions/model/Roles.php b/catchAdmin/permissions/model/Roles.php index eac71fc..02bc203 100644 --- a/catchAdmin/permissions/model/Roles.php +++ b/catchAdmin/permissions/model/Roles.php @@ -66,17 +66,19 @@ class Roles extends CatchModel /** * * @time 2019年12月08日 - * @param array $roles + * @param array $permissions * @return mixed * @throws \think\db\exception\DbException */ - public function attach(array $roles) + public function attach(array $permissions) { - if (empty($roles)) { + if (empty($permissions)) { return true; } - return $this->permissions()->attach($roles); + sort($permissions); + + return $this->permissions()->attach($permissions); } /** diff --git a/catchAdmin/permissions/route.php b/catchAdmin/permissions/route.php index 1052bbb..1a3aaf9 100644 --- a/catchAdmin/permissions/route.php +++ b/catchAdmin/permissions/route.php @@ -1,11 +1,11 @@ resource('role', '\catchAdmin\permissions\controller\Roles'); +$router->resource('role', '\catchAdmin\permissions\controller\Role'); // 角色列表 -$router->get('roles', '\catchAdmin\permissions\controller\Roles/list'); -$router->get('/role/get/permissions', '\catchAdmin\permissions\controller\Roles/getPermissions'); +$router->get('roles', '\catchAdmin\permissions\controller\Role@list'); +$router->get('/role/get/permissions', '\catchAdmin\permissions\controller\Role@getPermissions'); // 权限 -$router->resource('permission', '\catchAdmin\permissions\controller\Permissions'); +$router->resource('permission', '\catchAdmin\permissions\controller\Permission'); // 权限列表 -$router->get('permissions', '\catchAdmin\permissions\controller\Permissions/list'); +$router->get('permissions', '\catchAdmin\permissions\controller\Permission@list'); From a0a62b5640e0a4d390cdfe4e415117ab201bae0f Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:52:44 +0800 Subject: [PATCH 15/99] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/controller/Index.php | 34 +++- catchAdmin/index/route.php | 5 +- catchAdmin/index/view/dashboard.html | 217 +++++++++++++++++++++++++- catchAdmin/index/view/error.html | 16 +- catchAdmin/index/view/index.html | 159 ++----------------- 5 files changed, 266 insertions(+), 165 deletions(-) diff --git a/catchAdmin/index/controller/Index.php b/catchAdmin/index/controller/Index.php index 6112225..36636e7 100644 --- a/catchAdmin/index/controller/Index.php +++ b/catchAdmin/index/controller/Index.php @@ -1,19 +1,35 @@ fetch(); + $permissionIds = Auth::user()->getPermissionsBy(); + + $menus = Permissions::whereIn('id', $permissionIds) + ->where('type', Permissions::MENU_TYPE) + ->field(['id', 'parent_id', 'permission_name', 'route']) + ->select()->toArray(); + + return $this->fetch([ + 'menus' => Tree::done($menus), + 'username' => Auth::user()->username, + ]); } /** @@ -26,4 +42,18 @@ class Index extends CatchController { return $this->fetch(); } + + /** + * + * @time 2019年12月12日 + * @throws \Exception + * @return string + */ + public function dashboard(): string + { + $mysqlVersion = Db::query('select version() as version'); + return $this->fetch([ + 'mysql_version' => $mysqlVersion['0']['version'], + ]); + } } \ No newline at end of file diff --git a/catchAdmin/index/route.php b/catchAdmin/index/route.php index 56b9e99..a3c0e5e 100644 --- a/catchAdmin/index/route.php +++ b/catchAdmin/index/route.php @@ -1,4 +1,5 @@ get('/', '\catchAdmin\index\controller\index/index'); -$router->get('theme', '\catchAdmin\index\controller\index/theme'); +$router->get('/', '\catchAdmin\index\controller\index@index'); +$router->get('theme', '\catchAdmin\index\controller\index@theme'); +$router->get('dashboard', '\catchAdmin\index\controller\index@dashboard'); diff --git a/catchAdmin/index/view/dashboard.html b/catchAdmin/index/view/dashboard.html index 566549b..38a2c62 100644 --- a/catchAdmin/index/view/dashboard.html +++ b/catchAdmin/index/view/dashboard.html @@ -1,10 +1,221 @@ - + - - Title + + + + CatchAdmin 后台开发框架 + + + + + + +
+
+ +
+
+ + +
+
+
+
+
+ 访问量 +
+
+

99,666

+

总计访问量88万

+
+
+
+
+
+
+ 下载 +
+
+

33,555

+

新下载10%

+
+
+
+
+
+
+ Start +
+
+

99,666

+

总Start数88万

+
+
+
+
+
+
+ 活跃用户 +
+
+

66,666

+

最近一个月15%

+
+
+
+
+ +
+
+
+
更新日志
+
+
    +
  • + +
    +

    + V1.0 + catchAdmin 后台框架  + 2019-11-14 +

    +
      +
    • 基于 Thinkphp6 & layui 开发
    • +
    • 完整的权限管理
    • +
    • 模块化开发方式
    • +
    • ...
    • +
    +
    +
  • +
  • + +
    +
    + CatchAdmin 开发中... 更早 +
    +
    +
  • +
+
+
+
+
+
+
后台框架
+
+ + + + + + + + + + + + + + + + + + + + + + + + + {if condition="function_exists('opcache_get_configuration')"} + + {else/} + + {/if} + + + + + + + + + + + + + + + + + + +
PHP 版本{$Think.PHP_VERSION}
MYSQL 版本{$mysql_version}
WEB 服务器{$_SERVER['SERVER_SOFTWARE']}
操作系统{$Think.PHP_OS}
opcache (建议开启){:opcache_get_configuration()['directives']['opcache.enable'] ? '开启' : '关闭' }未开启
最大执行时间{:get_cfg_var("max_execution_time")} s
上传限制大小(M){:get_cfg_var ("upload_max_filesize")}
当前时间{:date("Y-m-d H:i:s")}
核心框架Thinkphp v6
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/catchAdmin/index/view/error.html b/catchAdmin/index/view/error.html index 7a7a87d..eb66fb3 100644 --- a/catchAdmin/index/view/error.html +++ b/catchAdmin/index/view/error.html @@ -15,19 +15,12 @@ - -
-
- -
-
-

403

-
抱歉,你无权访问此页面
+
{$msg}
@@ -37,12 +30,5 @@ - \ No newline at end of file diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index af758f3..b15d846 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -45,7 +45,7 @@
  • - 管理员 + {$username}
    @@ -56,7 +56,7 @@

    - 退出 + 退出
  • @@ -71,147 +71,20 @@
    @@ -220,7 +93,7 @@
    @@ -242,7 +115,7 @@ // 默认加载主页 index.loadHome({ - menuPath: 'page/console/console.html', + menuPath: '{:url("dashboard")}', menuName: '' }); From 109cb7279a49f6e5c998f0d0f36eb061d00268c6 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:52:56 +0800 Subject: [PATCH 16/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/login/controller/Index.php | 19 +++++++++++++--- catchAdmin/login/request/LoginRequest.php | 2 +- catchAdmin/login/route.php | 9 +++++--- catchAdmin/login/view/index.html | 27 ++++++++++++++--------- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/catchAdmin/login/controller/Index.php b/catchAdmin/login/controller/Index.php index e45d367..ed339f9 100644 --- a/catchAdmin/login/controller/Index.php +++ b/catchAdmin/login/controller/Index.php @@ -1,10 +1,11 @@ login($request->param()) ? + return Auth::login($request->param()) ? CatchResponse::success('', '登录成功') : CatchResponse::success('', '登录失败'); } @@ -43,10 +44,22 @@ class Index extends CatchController */ public function logout(): bool { - if ((new Auth())->logout()) { + if (Auth::logout()) { return redirect(url('login')); } return false; } + + /** + * + * @time 2019年12月12日 + * @param Captcha $captcha + * @param null $config + * @return \think\Response + */ + public function captcha(Captcha $captcha, $config = null): \think\Response + { + return $captcha->create($config); + } } \ No newline at end of file diff --git a/catchAdmin/login/request/LoginRequest.php b/catchAdmin/login/request/LoginRequest.php index 392d3c5..a8b709d 100644 --- a/catchAdmin/login/request/LoginRequest.php +++ b/catchAdmin/login/request/LoginRequest.php @@ -9,7 +9,7 @@ class LoginRequest extends CatchRequest { // TODO: Implement rules() method. return [ - 'name|用户名' => 'require|max:25', + 'email|用户名' => 'email', 'password|密码' => 'require', // 'captcha|验证码' => 'require|captcha' ]; diff --git a/catchAdmin/login/route.php b/catchAdmin/login/route.php index 669d695..10665ea 100644 --- a/catchAdmin/login/route.php +++ b/catchAdmin/login/route.php @@ -1,8 +1,11 @@ get('login', '\catchAdmin\login\controller\Index/index'); +$router->get('login', '\catchAdmin\login\controller\Index@index'); # 登入 -$router->post('login', '\catchAdmin\login\controller\Index/login'); +$router->post('login', '\catchAdmin\login\controller\Index@login'); # 登出 -$router->post('logout', '\catchAdmin\login\controller\Index/logout'); +$router->post('logout', '\catchAdmin\login\controller\Index@logout'); +# 验证码 +$router->get('catch/captcha/[:config]','\catchAdmin\login\controller\Index@captcha'); + diff --git a/catchAdmin/login/view/index.html b/catchAdmin/login/view/index.html index 8e44f37..4307043 100644 --- a/catchAdmin/login/view/index.html +++ b/catchAdmin/login/view/index.html @@ -38,8 +38,8 @@
    - +
    @@ -58,7 +58,7 @@ autocomplete="off" lay-verType="tips" lay-verify="required" required/>
    - captcha + captcha
    @@ -106,13 +106,20 @@ type: 'post', data: obj.field, success: function(response) { - layer.msg(response.msg, { - icon: 1, - time: 2000 //2秒关闭(如果不配置,默认是3秒) - }, function(){ - //do something - window.location.href = '/'; - }) + if (response.code === 10000) { + layer.msg(response.msg, { + icon: 1, + time: 2000 //2秒关闭(如果不配置,默认是3秒) + }, function () { + //do something + window.location.href = '/'; + }) + } else { + layer.msg(response.msg, { + icon: 2, + time: 2000 //2秒关闭(如果不配置,默认是3秒) + }) + } } }); return false; From c8eedead0059e9fb84f191c513aa2d15b4a03d71 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:53:10 +0800 Subject: [PATCH 17/99] =?UTF-8?q?=E6=B3=A8=E5=86=8C=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/CatchAdminService.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/catchAdmin/CatchAdminService.php b/catchAdmin/CatchAdminService.php index f9ac0c4..8a338c1 100644 --- a/catchAdmin/CatchAdminService.php +++ b/catchAdmin/CatchAdminService.php @@ -1,6 +1,7 @@ registerValidates(); + $this->registerMiddleWares(); } /** @@ -46,6 +48,17 @@ class CatchAdminService extends Service $validate->extend($vali->type(), [$vali, 'verify'], $vali->message()); } }); + } + /** + * + * @time 2019年12月12日 + * @return void + */ + protected function registerMiddleWares(): void + { + $this->app->middleware->import([ + 'check_auth' => PermissionsMiddleware::class + ], 'route'); } } \ No newline at end of file From 67e79bfa190c646eac819606bafc6d2168a9c9c9 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:53:25 +0800 Subject: [PATCH 18/99] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/catch.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/config/catch.php b/config/catch.php index b3d9bbc..1cb9e39 100644 --- a/config/catch.php +++ b/config/catch.php @@ -1 +1,17 @@ [ + 'route' => [ + 'index:index:index', // 首页 + 'index:index:theme', // 主题选择 + ], + // 模块 + 'module' => [ + 'login', + ], + ], + + // 错误提示 + 'error' => root_path('catchAdmin/index/view/') . 'error.html', +]; From 4a5993160f4cea961812e5683b9d2985b1743419 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:53:34 +0800 Subject: [PATCH 19/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9session=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/session.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/session.php b/config/session.php index c1ef6e1..5ecfd2c 100644 --- a/config/session.php +++ b/config/session.php @@ -13,7 +13,7 @@ return [ // 存储连接标识 当type使用cache的时候有效 'store' => null, // 过期时间 - 'expire' => 1440, + 'expire' => 24 * 3600, // 前缀 - 'prefix' => '', + 'prefix' => 'catch_admin', ]; From d53b0bae73fbcd83a94fb90fc2afd2d12d31333f Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 18:54:07 +0800 Subject: [PATCH 20/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=85=AC=E5=85=B1=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 19 ++++++++++++ extend/catcher/CatchForm.php | 4 +-- extend/catcher/CatchResponse.php | 31 ++++++++++++------- extend/catcher/base/CatchController.php | 2 ++ .../exceptions/LoginFailedException.php | 6 ++-- .../PermissionForbiddenException.php | 8 +++++ 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index ac5a4b3..5ac548a 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -126,6 +126,25 @@ class CatchAdmin return $modules; } + /** + * + * @time 2019年12月12日 + * @return array + */ + public static function getModulesInfo(): array + { + $modules = []; + foreach (self::getModulesDirectory() as $module) { + $moduleInfo = self::getModuleInfo($module); + $modules[] = [ + 'value' => $moduleInfo['alias'], + 'title' => $moduleInfo['name'], + ]; + } + + return $modules; + } + /** * * @time 2019年11月30日 diff --git a/extend/catcher/CatchForm.php b/extend/catcher/CatchForm.php index c8f0fae..a850ae1 100644 --- a/extend/catcher/CatchForm.php +++ b/extend/catcher/CatchForm.php @@ -355,12 +355,12 @@ class CatchForm */ private function selectField($field) { - $select = sprintf('', $field['name'], $field['verify'] ?? ''); $default = $field['default'] ?? ''; foreach ($field['options'] as $key => $option) { - $select .= sprintf('', $key, $default == $key ? ' selected' : '',$option); + $select .= sprintf('', $option['value'], $default == $key ? ' selected' : '',$option['title']); } return $select . ''; diff --git a/extend/catcher/CatchResponse.php b/extend/catcher/CatchResponse.php index a748d06..e97f682 100644 --- a/extend/catcher/CatchResponse.php +++ b/extend/catcher/CatchResponse.php @@ -1,7 +1,9 @@ $code, - 'msg' => $msg, - 'data' => $data, - ]); + if (request()->isAjax()) { + return json([ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + ]); + } } /** @@ -47,13 +51,18 @@ class CatchResponse * @time 2019年12月02日 * @param string $msg * @param int $code - * @return \think\response\Json + * @return mixed + * @throws \Exception */ - public static function fail($msg = '', $code = 10001): \think\response\Json + public static function fail($msg = '', $code = 10001) { - return json([ - 'code' => $code, - 'msg' => $msg, - ]); + if (request()->isAjax()) { + return json([ + 'code' => $code, + 'msg' => $msg, + ]); + } + + return Response::create(config('catch.error'), 'view', $code)->assign(['msg' => $msg]); } } diff --git a/extend/catcher/base/CatchController.php b/extend/catcher/base/CatchController.php index 68bdf17..d895071 100644 --- a/extend/catcher/base/CatchController.php +++ b/extend/catcher/base/CatchController.php @@ -6,6 +6,8 @@ use think\facade\View; abstract class CatchController { + protected $middleware = ['check_auth']; + /** * * @time 2019年11月28日 diff --git a/extend/catcher/exceptions/LoginFailedException.php b/extend/catcher/exceptions/LoginFailedException.php index 1470ca7..df56dd9 100644 --- a/extend/catcher/exceptions/LoginFailedException.php +++ b/extend/catcher/exceptions/LoginFailedException.php @@ -1,7 +1,7 @@ Date: Thu, 12 Dec 2019 22:33:12 +0800 Subject: [PATCH 21/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/login/LoginLogListener.php | 79 +++++++++++++++++++ catchAdmin/permissions/OperateLogListener.php | 7 ++ catchAdmin/system/controller/LoginLog.php | 19 +++++ catchAdmin/system/controller/OperateLog.php | 25 ++++++ .../migrations/20191212110921_login_log.php | 40 ++++++++++ .../migrations/20191212110930_operate_log.php | 40 ++++++++++ catchAdmin/system/event/LoginLogEvent.php | 12 +++ catchAdmin/system/event/OperateLogEvent.php | 12 +++ catchAdmin/system/module.json | 11 +++ catchAdmin/system/route.php | 8 ++ catchAdmin/system/view/loginLog/index.html | 57 +++++++++++++ catchAdmin/system/view/operateLog/index.html | 53 +++++++++++++ 12 files changed, 363 insertions(+) create mode 100644 catchAdmin/login/LoginLogListener.php create mode 100644 catchAdmin/permissions/OperateLogListener.php create mode 100644 catchAdmin/system/controller/LoginLog.php create mode 100644 catchAdmin/system/controller/OperateLog.php create mode 100644 catchAdmin/system/database/migrations/20191212110921_login_log.php create mode 100644 catchAdmin/system/database/migrations/20191212110930_operate_log.php create mode 100644 catchAdmin/system/event/LoginLogEvent.php create mode 100644 catchAdmin/system/event/OperateLogEvent.php create mode 100644 catchAdmin/system/module.json create mode 100644 catchAdmin/system/route.php create mode 100644 catchAdmin/system/view/loginLog/index.html create mode 100644 catchAdmin/system/view/operateLog/index.html diff --git a/catchAdmin/login/LoginLogListener.php b/catchAdmin/login/LoginLogListener.php new file mode 100644 index 0000000..bf2b5be --- /dev/null +++ b/catchAdmin/login/LoginLogListener.php @@ -0,0 +1,79 @@ +params = $params; + } + + public function handle() + { + dd('ad'); + $agent = request()->header('user-agent'); + + $username = Users::where('email', $this->params['email'])->value('username'); + + Db::name('login_log')->insert([ + 'login_name' => $username ? : $this->params['email'], + 'login_ip' => ip2long(request()->ip()), + 'browser' => $this->getBrowser($agent), + 'os' => $this->getOs($agent), + 'login_at' => time(), + 'status' => $this->params['success'] ? 1 : 2, + ]); + } + + + private function getOs($agent) + { + if (false !== stripos($agent, 'win') && preg_match('/nt 6.1/i', $agent)) { + return 'Windows 7'; + } + if (false !== stripos($agent, 'win') && preg_match('/nt 6.2/i', $agent)) { + return 'Windows 8'; + } + if(false !== stripos($agent, 'win') && preg_match('/nt 10.0/i', $agent)) { + return 'Windows 10';#添加win10判断 + } + if (false !== stripos($agent, 'win') && preg_match('/nt 5.1/i', $agent)) { + return 'Windows XP'; + } + if (false !== stripos($agent, 'linux')) { + return 'Linux'; + } + if (false !== stripos($agent, 'mac')) { + return 'mac'; + } + + return '未知'; + } + + private function getBrowser($agent) + { + if (false !== stripos($agent, "MSIE")) { + return 'MSIE'; + } + if (false !== stripos($agent, "Firefox")) { + return 'Firefox'; + } + if (false !== stripos($agent, "Chrome")) { + return 'Chrome'; + } + if (false !== stripos($agent, "Safari")) { + return 'Safari'; + } + if (false !== stripos($agent, "Opera")) { + return 'Opera'; + } + + return '未知'; + } +} diff --git a/catchAdmin/permissions/OperateLogListener.php b/catchAdmin/permissions/OperateLogListener.php new file mode 100644 index 0000000..053457d --- /dev/null +++ b/catchAdmin/permissions/OperateLogListener.php @@ -0,0 +1,7 @@ +fetch(); + } + + public function list() + { + return CatchResponse::paginate(Db::name('login_log')->paginate(10)); + } +} diff --git a/catchAdmin/system/controller/OperateLog.php b/catchAdmin/system/controller/OperateLog.php new file mode 100644 index 0000000..b24f465 --- /dev/null +++ b/catchAdmin/system/controller/OperateLog.php @@ -0,0 +1,25 @@ +fetch(); + } + + public function list() + { + return CatchResponse::paginate( + Db::name('operate_log') + ->field(['operate_log.*', 'users.username as creator']) + ->join('users','users.id = operate_log.creator_id') + ->order('id', 'desc') + ->paginate(10) + ); + } +} diff --git a/catchAdmin/system/database/migrations/20191212110921_login_log.php b/catchAdmin/system/database/migrations/20191212110921_login_log.php new file mode 100644 index 0000000..45965d0 --- /dev/null +++ b/catchAdmin/system/database/migrations/20191212110921_login_log.php @@ -0,0 +1,40 @@ +table('login_log',['engine'=>'Myisam', 'comment' => '登录日志', 'signed' => false]); + $table->addColumn('login_name', 'string',['limit' => 50,'default'=>'','comment'=>'用户名']) + ->addColumn('login_ip', 'string',['default'=>0, 'limit' => 20, 'comment'=>'登录地点ip', 'signed' => false]) + ->addColumn('browser', 'string',['default'=> '','comment'=>'浏览器']) + ->addColumn('os', 'string',['default'=> '','comment'=>'操作系统']) + ->addColumn('login_at', 'integer', array('default'=>0,'comment'=>'登录时间', 'signed' => false )) + ->addColumn('status', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 成功 2 失败']) + ->create(); + } +} diff --git a/catchAdmin/system/database/migrations/20191212110930_operate_log.php b/catchAdmin/system/database/migrations/20191212110930_operate_log.php new file mode 100644 index 0000000..4e75d7e --- /dev/null +++ b/catchAdmin/system/database/migrations/20191212110930_operate_log.php @@ -0,0 +1,40 @@ +table('operate_log',['engine'=>'Myisam', 'comment' => '操作日志', 'signed' => false]); + $table->addColumn('module', 'string',['limit' => 50,'default'=>'','comment'=>'模块名称']) + ->addColumn('ip', 'string',['default'=>'', 'limit' => 20,'comment'=>'ip', 'signed' => false]) + ->addColumn('operate', 'string',['default'=> '','comment'=>'操作模块']) + ->addColumn('creator_id', 'integer',['default'=> 0,'comment'=>'创建人ID', 'signed' => false]) + ->addColumn('method', 'string',['default'=> '','comment'=>'请求方法']) + ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'登录时间', 'signed' => false )) + ->create(); + } +} diff --git a/catchAdmin/system/event/LoginLogEvent.php b/catchAdmin/system/event/LoginLogEvent.php new file mode 100644 index 0000000..9d33a1c --- /dev/null +++ b/catchAdmin/system/event/LoginLogEvent.php @@ -0,0 +1,12 @@ +params = $params; + } +} \ No newline at end of file diff --git a/catchAdmin/system/event/OperateLogEvent.php b/catchAdmin/system/event/OperateLogEvent.php new file mode 100644 index 0000000..cece388 --- /dev/null +++ b/catchAdmin/system/event/OperateLogEvent.php @@ -0,0 +1,12 @@ +params = $params; + } +} \ No newline at end of file diff --git a/catchAdmin/system/module.json b/catchAdmin/system/module.json new file mode 100644 index 0000000..e5d44e9 --- /dev/null +++ b/catchAdmin/system/module.json @@ -0,0 +1,11 @@ +{ + "name": "系统管理", + "alias": "system", + "description": "", + "keywords": [], + "order": 2, + "services": [], + "aliases": {}, + "files": [], + "requires": [] +} \ No newline at end of file diff --git a/catchAdmin/system/route.php b/catchAdmin/system/route.php new file mode 100644 index 0000000..d81abc8 --- /dev/null +++ b/catchAdmin/system/route.php @@ -0,0 +1,8 @@ +get('log/login', '\catchAdmin\system\controller\LoginLog@list'); +$router->get('loginLog/index', '\catchAdmin\system\controller\LoginLog@index'); +// 操作日志 +$router->get('log/operate', '\catchAdmin\system\controller\OperateLog@list'); +$router->get('operateLog/index', '\catchAdmin\system\controller\OperateLog@index'); + diff --git a/catchAdmin/system/view/loginLog/index.html b/catchAdmin/system/view/loginLog/index.html new file mode 100644 index 0000000..17d9a45 --- /dev/null +++ b/catchAdmin/system/view/loginLog/index.html @@ -0,0 +1,57 @@ +{extend name="../../../view/layout"} +{block name="title"}登录日志{/block} +{block name="search"} +
    +
    + + + +
    +
    +{/block} +{block name="table"} +
    +{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/catchAdmin/system/view/operateLog/index.html b/catchAdmin/system/view/operateLog/index.html new file mode 100644 index 0000000..57b5cad --- /dev/null +++ b/catchAdmin/system/view/operateLog/index.html @@ -0,0 +1,53 @@ +{extend name="../../../view/layout"} +{block name="title"}操作日志{/block} +{block name="search"} +
    +
    + + + +
    +
    +{/block} +{block name="table"} +
    +{/block} +{block name="script"} + +{/block} \ No newline at end of file From bdbf8129416df127b12dd7192f62f3adb7bb389f Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 22:33:28 +0800 Subject: [PATCH 22/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/view/index.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index b15d846..48a0954 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -77,7 +77,16 @@ {$menu['permission_name']}
    {foreach $menu['children'] as $m} -
    {$m['permission_name']}
    + {if (!empty($m['children']))} + {$menu['permission_name']} +
    + {foreach $m['children'] as $_m} +
    {$_m['permission_name']}
    + {/foreach} +
    + {else/} +
    {$m['permission_name']}
    + {/if} {/foreach}
    {else/} From 02b973d0b555ad0464879a3045d0b1a944aa38d1 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 22:33:45 +0800 Subject: [PATCH 23/99] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/login/LoginLogListener.php | 38 ++++++++++++++------------- catchAdmin/login/controller/Index.php | 17 ++++++++++-- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/catchAdmin/login/LoginLogListener.php b/catchAdmin/login/LoginLogListener.php index bf2b5be..dbcad95 100644 --- a/catchAdmin/login/LoginLogListener.php +++ b/catchAdmin/login/LoginLogListener.php @@ -4,35 +4,31 @@ namespace catchAdmin\login; use catchAdmin\user\model\Users; use think\facade\Db; -class LoginEvent +class LoginLogListener { - protected $params; - - public function __construct(array $params) + public function handle($params) { - - $this->params = $params; - } - - public function handle() - { - dd('ad'); $agent = request()->header('user-agent'); - $username = Users::where('email', $this->params['email'])->value('username'); + $username = Users::where('email', $params['email'])->value('username'); Db::name('login_log')->insert([ - 'login_name' => $username ? : $this->params['email'], - 'login_ip' => ip2long(request()->ip()), + 'login_name' => $username ? : $params['email'], + 'login_ip' => request()->ip(), 'browser' => $this->getBrowser($agent), 'os' => $this->getOs($agent), 'login_at' => time(), - 'status' => $this->params['success'] ? 1 : 2, + 'status' => $params['success'] ? 1 : 2, ]); } - - private function getOs($agent) + /** + * + * @time 2019年12月12日 + * @param $agent + * @return string + */ + private function getOs($agent): string { if (false !== stripos($agent, 'win') && preg_match('/nt 6.1/i', $agent)) { return 'Windows 7'; @@ -56,7 +52,13 @@ class LoginEvent return '未知'; } - private function getBrowser($agent) + /** + * + * @time 2019年12月12日 + * @param $agent + * @return string + */ + private function getBrowser($agent): string { if (false !== stripos($agent, "MSIE")) { return 'MSIE'; diff --git a/catchAdmin/login/controller/Index.php b/catchAdmin/login/controller/Index.php index ed339f9..38e96fb 100644 --- a/catchAdmin/login/controller/Index.php +++ b/catchAdmin/login/controller/Index.php @@ -1,11 +1,16 @@ param()) ? - CatchResponse::success('', '登录成功') : CatchResponse::success('', '登录失败'); + $params = $request->param(); + $isSucceed = Auth::login($params); + // 登录事件 + $params['success'] = $isSucceed; + event('log', $params); + + return $isSucceed ? CatchResponse::success('', '登录成功') : + + CatchResponse::success('', '登录失败'); } /** From 5976ebb23593297eee31edb88c56b52224cff606 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 22:33:58 +0800 Subject: [PATCH 24/99] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/permissions/OperateLogListener.php | 17 ++++++++-- .../permissions/PermissionsMiddleware.php | 33 ++++++++++--------- .../permissions/controller/Permission.php | 4 +-- catchAdmin/permissions/module.json | 4 +-- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/catchAdmin/permissions/OperateLogListener.php b/catchAdmin/permissions/OperateLogListener.php index 053457d..4945e49 100644 --- a/catchAdmin/permissions/OperateLogListener.php +++ b/catchAdmin/permissions/OperateLogListener.php @@ -1,7 +1,20 @@ insert([ + 'module' => $params['module'], + 'ip' => request()->ip(), + 'operate' => $params['operate'], + 'creator_id' => $params['uid'], + 'method' => $params['method'], + 'created_at' => time(), + ]); + } } diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php index ba0168e..df82c77 100644 --- a/catchAdmin/permissions/PermissionsMiddleware.php +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -3,6 +3,7 @@ namespace catchAdmin\permissions; use app\Request; use catchAdmin\permissions\model\Permissions; +use catcher\CatchAdmin; use catcher\exceptions\PermissionForbiddenException; use think\helper\Str; @@ -25,7 +26,8 @@ class PermissionsMiddleware throw new PermissionForbiddenException('Login is invalid', 10006); } // toad - if (($permission = $this->getPermission($request->rule()->getName())) && in_array($permission->id, $request->user()->getPermissionsBy())) { + if (($permission = $this->getPermission($request)) + && in_array($permission->id, $request->user()->getPermissionsBy())) { throw new PermissionForbiddenException(); } @@ -35,17 +37,15 @@ class PermissionsMiddleware /** * * @time 2019年12月12日 - * @param $rule + * @param $request * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @return array|bool|\think\Model|null */ - protected function getPermission($rule) + protected function getPermission(Request $request) { - if (!$rule) { - return false; - } + $rule = $request->rule()->getName(); [$controller, $action] = explode(Str::contains($rule, '@') ? '@' : '/', $rule); @@ -57,18 +57,21 @@ class PermissionsMiddleware $module = array_pop($controller); - $ignore = config('catch.ignore'); - - if (in_array($module, $ignore['module'])) { - return false; - } - $permissionMark = sprintf('%s:%s:%s', $module, $controllerName, $action); - if (in_array($permissionMark, $ignore['route'])) { - return false; + $permission = Permissions::where('permission_mark', $permissionMark)->find(); + + + $params['uid'] = $request->user()->id; + $params['module'] = $rule ? CatchAdmin::getModulesInfo(false)[$module] : '首页'; + $params['method'] = $request->method(); + $params['operate'] = sprintf('%s/%s', $controllerName, $action); + event('operateLog', $params); + + if (!$permission) { + return false; } - return Permissions::where('permission_mark', $permissionMark)->find(); + return $permission; } } \ No newline at end of file diff --git a/catchAdmin/permissions/controller/Permission.php b/catchAdmin/permissions/controller/Permission.php index 6a24072..3eed60f 100644 --- a/catchAdmin/permissions/controller/Permission.php +++ b/catchAdmin/permissions/controller/Permission.php @@ -56,14 +56,14 @@ class Permission extends CatchController $form->hidden('parent_id')->default(\request()->param('id') ?? 0); $form->select('module', '模块', true)->verify('required')->options(CatchAdmin::getModulesInfo()); $form->text('route', '路由')->placeholder('请输入路由'); - $form->radio('method', '请求方法', true)->default(Permission::GET)->options([ + $form->radio('method', '请求方法', true)->default(Permissions::GET)->options([ ['value' => Permissions::GET, 'title' => 'get'], ['value' => Permissions::POST, 'title' => 'post'], ['value' => Permissions::PUT, 'title' => 'put'], ['value' => Permissions::DELETE, 'title' => 'delete'], ]); $form->text('permission_mark', '权限标识', true)->verify('required')->placeholder('请输入权限标识controller:action'); - $form->radio('type', '类型', true)->default(Permission::BTN_TYPE)->options([ + $form->radio('type', '类型', true)->default(Permissions::BTN_TYPE)->options([ ['value' => Permissions::MENU_TYPE, 'title' => '菜单'], ['value' => Permissions::BTN_TYPE, 'title' => '按钮'], ]); diff --git a/catchAdmin/permissions/module.json b/catchAdmin/permissions/module.json index 05a46d1..82a671c 100644 --- a/catchAdmin/permissions/module.json +++ b/catchAdmin/permissions/module.json @@ -4,9 +4,7 @@ "description": "", "keywords": [], "order": 2, - "services": [ - "catchAdmin\\permissions\\PermissionService" - ], + "services": [], "aliases": {}, "files": [], "requires": [] From 86a198d66a887d78c8bd2ce45fb7edd3b93354b5 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 22:34:08 +0800 Subject: [PATCH 25/99] =?UTF-8?q?=E6=B3=A8=E5=86=8C=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/CatchAdminService.php | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/catchAdmin/CatchAdminService.php b/catchAdmin/CatchAdminService.php index 8a338c1..9df52e1 100644 --- a/catchAdmin/CatchAdminService.php +++ b/catchAdmin/CatchAdminService.php @@ -1,7 +1,11 @@ registerValidates(); $this->registerMiddleWares(); + $this->registerEvents(); + $this->registerListeners(); } /** @@ -61,4 +67,38 @@ class CatchAdminService extends Service 'check_auth' => PermissionsMiddleware::class ], 'route'); } + + /** + * + * @time 2019年12月12日 + * @return void + */ + protected function registerEvents(): void + { + $this->app->event->bind([ + 'loginLog' => LoginLogEvent::class, + 'operateLog' => OperateLogEvent::class, + ]); + + + } + + /** + * 注册监听者 + * + * @time 2019年12月12日 + * @return void + */ + protected function registerListeners(): void + { + $this->app->event->listenEvents([ + 'loginLog' => [ + LoginLogListener::class, + ], + 'operateLog' => [ + OperateLogListener::class, + ], + ]); + } + } \ No newline at end of file From 6f7e0d71c26af6036aa1370660ff18dd2c06a586 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Thu, 12 Dec 2019 22:34:27 +0800 Subject: [PATCH 26/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 21 ++++++++++++++------- extend/catcher/CatchResponse.php | 12 +++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index 5ac548a..f8c9f9f 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -131,15 +131,22 @@ class CatchAdmin * @time 2019年12月12日 * @return array */ - public static function getModulesInfo(): array + public static function getModulesInfo($select = true): array { $modules = []; - foreach (self::getModulesDirectory() as $module) { - $moduleInfo = self::getModuleInfo($module); - $modules[] = [ - 'value' => $moduleInfo['alias'], - 'title' => $moduleInfo['name'], - ]; + if ($select) { + foreach (self::getModulesDirectory() as $module) { + $moduleInfo = self::getModuleInfo($module); + $modules[] = [ + 'value' => $moduleInfo['alias'], + 'title' => $moduleInfo['name'], + ]; + } + } else { + foreach (self::getModulesDirectory() as $module) { + $moduleInfo = self::getModuleInfo($module); + $modules[$moduleInfo['alias']] = $moduleInfo['name']; + } } return $modules; diff --git a/extend/catcher/CatchResponse.php b/extend/catcher/CatchResponse.php index e97f682..58aa9a7 100644 --- a/extend/catcher/CatchResponse.php +++ b/extend/catcher/CatchResponse.php @@ -18,13 +18,11 @@ class CatchResponse */ public static function success($data = [], $msg = 'success', $code = 10000): \think\response\Json { - if (request()->isAjax()) { - return json([ - 'code' => $code, - 'msg' => $msg, - 'data' => $data, - ]); - } + return json([ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + ]); } /** From d40deeff606806886b4d0c9d2e366a314889a799 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:25:05 +0800 Subject: [PATCH 27/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/event.php | 8 +++----- catchAdmin/helper.php | 1 + catchAdmin/system/controller/DataDictionary.php | 1 + catchAdmin/system/view/dataDictionary/index.html | 10 ++++++++++ catchAdmin/system/view/dataDictionary/view.html | 10 ++++++++++ extend/catcher/command/BackupCommand.php | 1 + 6 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 catchAdmin/helper.php create mode 100644 catchAdmin/system/controller/DataDictionary.php create mode 100644 catchAdmin/system/view/dataDictionary/index.html create mode 100644 catchAdmin/system/view/dataDictionary/view.html create mode 100644 extend/catcher/command/BackupCommand.php diff --git a/app/event.php b/app/event.php index 37cbcb8..9983454 100644 --- a/app/event.php +++ b/app/event.php @@ -1,8 +1,8 @@ [ - ], + 'bind' => [], 'listen' => [ 'AppInit' => [], @@ -10,9 +10,7 @@ return [ 'HttpEnd' => [], 'LogLevel' => [], 'LogWrite' => [], - 'RouteLoaded' => [ - catcher\event\LoadModuleRoutes::class, - ], + 'RouteLoaded' => [], ], 'subscribe' => [ diff --git a/catchAdmin/helper.php b/catchAdmin/helper.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/catchAdmin/helper.php @@ -0,0 +1 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/catchAdmin/system/view/dataDictionary/view.html b/catchAdmin/system/view/dataDictionary/view.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/catchAdmin/system/view/dataDictionary/view.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/extend/catcher/command/BackupCommand.php b/extend/catcher/command/BackupCommand.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/extend/catcher/command/BackupCommand.php @@ -0,0 +1 @@ + Date: Fri, 13 Dec 2019 17:25:22 +0800 Subject: [PATCH 28/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/CatchAdminService.php | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/catchAdmin/CatchAdminService.php b/catchAdmin/CatchAdminService.php index 9df52e1..de12131 100644 --- a/catchAdmin/CatchAdminService.php +++ b/catchAdmin/CatchAdminService.php @@ -6,11 +6,13 @@ use catchAdmin\permissions\OperateLogListener; use catchAdmin\permissions\PermissionsMiddleware; use catchAdmin\system\event\LoginLogEvent; use catchAdmin\system\event\OperateLogEvent; +use catcher\command\BackupCommand; use catcher\command\InstallCommand; use catcher\command\MigrateRunCommand; use catcher\command\ModelGeneratorCommand; use catcher\command\ModuleCacheCommand; use catcher\command\SeedRunCommand; +use catcher\event\LoadModuleRoutes; use catcher\validates\Sometimes; use think\facade\Validate; use think\Service; @@ -24,20 +26,30 @@ class CatchAdminService extends Service */ public function boot() { - $this->commands([ - InstallCommand::class, - ModuleCacheCommand::class, - MigrateRunCommand::class, - ModelGeneratorCommand::class, - SeedRunCommand::class - ]); + $this->registerCommands(); $this->registerValidates(); $this->registerMiddleWares(); $this->registerEvents(); $this->registerListeners(); } + /** + * + * @time 2019年12月13日 + * @return void + */ + protected function registerCommands(): void + { + $this->commands([ + InstallCommand::class, + ModuleCacheCommand::class, + MigrateRunCommand::class, + ModelGeneratorCommand::class, + SeedRunCommand::class, + BackupCommand::class, + ]); + } /** * * @time 2019年12月07日 @@ -98,6 +110,9 @@ class CatchAdminService extends Service 'operateLog' => [ OperateLogListener::class, ], + 'RouteLoaded' => [ + LoadModuleRoutes::class + ] ]); } From a4a03857ac0da2349c69eb6303299e79553718fa Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:25:34 +0800 Subject: [PATCH 29/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/user/database/migrations/20191128114204_users.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catchAdmin/user/database/migrations/20191128114204_users.php b/catchAdmin/user/database/migrations/20191128114204_users.php index 905e6b0..e76d9eb 100644 --- a/catchAdmin/user/database/migrations/20191128114204_users.php +++ b/catchAdmin/user/database/migrations/20191128114204_users.php @@ -37,7 +37,7 @@ class Users extends Migrator ->addColumn('last_login_time', 'integer',array('default'=>0,'comment'=>'最后登录时间', 'signed' => false)) ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false )) ->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false)) - ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) + ->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) ->create(); } } From 17d30f1cc33208149e44d45f29052c07e863cc11 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:25:47 +0800 Subject: [PATCH 30/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/DataDictionary.php | 83 ++++++++++++ .../migrations/20191212110930_operate_log.php | 4 +- catchAdmin/system/route.php | 7 + .../system/view/dataDictionary/index.html | 121 ++++++++++++++++-- .../system/view/dataDictionary/view.html | 31 ++++- catchAdmin/system/view/loginLog/index.html | 27 ++-- catchAdmin/system/view/operateLog/index.html | 19 +-- 7 files changed, 260 insertions(+), 32 deletions(-) diff --git a/catchAdmin/system/controller/DataDictionary.php b/catchAdmin/system/controller/DataDictionary.php index b3d9bbc..caf642d 100644 --- a/catchAdmin/system/controller/DataDictionary.php +++ b/catchAdmin/system/controller/DataDictionary.php @@ -1 +1,84 @@ fetch(); + } + + /** + * + * @time 2019年12月13日 + * @param Request $request + * @return \think\response\Json + */ + public function tables(Request $request): \think\response\Json + { + $tables = Db::query('show table status'); + + return CatchResponse::paginate(Paginator::make($tables, $request->get('limit') ?? 10, $request->get('page'), count($tables), false, [])); + } + + /** + * + * @time 2019年12月13日 + * @param $table + * @throws \Exception + * @return string + */ + public function view($table): string + { + $this->table = Db::query('show full columns from ' . $table); + + return $this->fetch(); + } + + /** + * + * @time 2019年12月13日 + * @return \think\response\Json + */ + public function optimize(): \think\response\Json + { + $tables = \request()->post('data'); + + foreach ($tables as $table) { + Db::query(sprintf('optimize table %s', $table)); + } + + return CatchResponse::success([], '优化成功'); + } + + /** + * + * @time 2019年12月13日 + * @throws FailedException + * @return \think\response\Json + */ + public function backup(): \think\response\Json + { + try { + Console::call('backup:data', [trim(implode(',', \request()->post('data')), ',')]); + }catch (\Exception $e) { + throw new FailedException($e->getMessage()); + } + + return CatchResponse::success([], '备份成功'); + } +} diff --git a/catchAdmin/system/database/migrations/20191212110930_operate_log.php b/catchAdmin/system/database/migrations/20191212110930_operate_log.php index 4e75d7e..0fb31db 100644 --- a/catchAdmin/system/database/migrations/20191212110930_operate_log.php +++ b/catchAdmin/system/database/migrations/20191212110930_operate_log.php @@ -30,8 +30,10 @@ class OperateLog extends Migrator { $table = $this->table('operate_log',['engine'=>'Myisam', 'comment' => '操作日志', 'signed' => false]); $table->addColumn('module', 'string',['limit' => 50,'default'=>'','comment'=>'模块名称']) + ->addColumn('operate', 'string',['default'=> '', 'limit' => 20, 'comment'=>'操作模块']) + ->addColumn('route', 'string',['default'=> '','limit' => 20, 'comment'=>'路由']) + ->addColumn('params', 'string',['default'=> '','limit' => 1000, 'comment'=>'参数']) ->addColumn('ip', 'string',['default'=>'', 'limit' => 20,'comment'=>'ip', 'signed' => false]) - ->addColumn('operate', 'string',['default'=> '','comment'=>'操作模块']) ->addColumn('creator_id', 'integer',['default'=> 0,'comment'=>'创建人ID', 'signed' => false]) ->addColumn('method', 'string',['default'=> '','comment'=>'请求方法']) ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'登录时间', 'signed' => false )) diff --git a/catchAdmin/system/route.php b/catchAdmin/system/route.php index d81abc8..bf0f500 100644 --- a/catchAdmin/system/route.php +++ b/catchAdmin/system/route.php @@ -5,4 +5,11 @@ $router->get('loginLog/index', '\catchAdmin\system\controller\LoginLog@index'); // 操作日志 $router->get('log/operate', '\catchAdmin\system\controller\OperateLog@list'); $router->get('operateLog/index', '\catchAdmin\system\controller\OperateLog@index'); +// 数据字典 +$router->get('data/dictionary', '\catchAdmin\system\controller\DataDictionary@index'); +$router->get('tables', '\catchAdmin\system\controller\DataDictionary@tables'); +$router->get('table/view/', '\catchAdmin\system\controller\DataDictionary@view'); +$router->post('table/optimize', '\catchAdmin\system\controller\DataDictionary@optimize'); +$router->post('table/backup', '\catchAdmin\system\controller\DataDictionary@backup'); + diff --git a/catchAdmin/system/view/dataDictionary/index.html b/catchAdmin/system/view/dataDictionary/index.html index 566549b..6c41f31 100644 --- a/catchAdmin/system/view/dataDictionary/index.html +++ b/catchAdmin/system/view/dataDictionary/index.html @@ -1,10 +1,113 @@ - - - - - Title - - +{extend name="../../../view/layout"} +{block name="title"}登录日志{/block} +{block name="search"} +
    +
    + + + + +
    +
    +{/block} +{block name="table"} +
    + + +{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/catchAdmin/system/view/dataDictionary/view.html b/catchAdmin/system/view/dataDictionary/view.html index 566549b..f6ab66b 100644 --- a/catchAdmin/system/view/dataDictionary/view.html +++ b/catchAdmin/system/view/dataDictionary/view.html @@ -5,6 +5,35 @@ Title - +
    + + + + + + + + + + + + + + + {foreach $table as $field} + + + + + + + + + + + {/foreach} + +
    字段类型字符集Null索引默认值权限注释
    {$field['Field']}{$field['Type']}{$field['Collation']}{$field['Null']}{$field['Key']}{$field['Default']}{$field['Privileges']}{$field['Comment']}
    +
    \ No newline at end of file diff --git a/catchAdmin/system/view/loginLog/index.html b/catchAdmin/system/view/loginLog/index.html index 17d9a45..c28c0a9 100644 --- a/catchAdmin/system/view/loginLog/index.html +++ b/catchAdmin/system/view/loginLog/index.html @@ -3,16 +3,17 @@ {block name="search"}
    - - - + + +
    {/block} @@ -36,17 +37,19 @@ // toolbar: true, cellMinWidth: 100, cols: [[ - {type: 'id', title: '#', field: 'id'}, - {field: 'login_name', sort: true, title: '登录名'}, - {field: 'login_ip', sort: true, title: '登录IP'}, - {field: 'browser', sort: true, title: '浏览器'}, - {field: 'os', sort: true, title: '操作系统'}, - {field: 'status', sort: true, title: '状态', templet: function (d) { - return d.status === 1 ? '成功' : '失败' + {type: 'id', title: '序号', field: 'id'}, + {field: 'login_name', title: '登录名'}, + {field: 'login_ip', title: '登录IP'}, + {field: 'browser', title: '浏览器'}, + {field: 'os', title: '操作系统'}, + {field: 'status', title: '状态', templet: function (d) { + return d.status === 1 ? + '' : + '' } }, { - field: 'login_at', sort: true, templet: function (d) { + field: 'login_at', templet: function (d) { return util.toDateString(d.login_at); }, title: '登录时间' }, diff --git a/catchAdmin/system/view/operateLog/index.html b/catchAdmin/system/view/operateLog/index.html index 57b5cad..6563419 100644 --- a/catchAdmin/system/view/operateLog/index.html +++ b/catchAdmin/system/view/operateLog/index.html @@ -36,15 +36,16 @@ // toolbar: true, cellMinWidth: 100, cols: [[ - {type: 'id', title: '#', field: 'id'}, - {field: 'module', sort: true, title: '模块'}, - {field: 'ip', sort: true, title: 'IP'}, - {field: 'operate', sort: true, title: 'operate'}, - {field: 'creator', sort: true, title: '操作者'}, - {field: 'method', sort: true, title: '请求方法'}, - {field: 'created_at', sort: true, title: '创建时间', templet: function (d) { - return d.status === 1 ? '成功' : '失败' - } + {type: 'id', title: '序号', field: 'id'}, + {field: 'module', title: '模块'}, + {field: 'ip', title: 'IP'}, + {field: 'operate', title: 'operate'}, + {field: 'creator', title: '操作者'}, + {field: 'method', title: '请求方法'}, + { + field: 'created_at', sort: true, templet: function (d) { + return util.toDateString(d.created_at); + }, title: '创建时间' }, ]], }); From b5e90dd14fab3184eb8577af156f04e169fd7d10 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:26:09 +0800 Subject: [PATCH 31/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9D=83=E9=99=90?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/permissions/OperateLogListener.php | 17 ++++++++++++----- .../permissions/PermissionsMiddleware.php | 19 ++++++++----------- .../migrations/20191208125722_roles.php | 2 +- .../migrations/20191208125726_permissions.php | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/catchAdmin/permissions/OperateLogListener.php b/catchAdmin/permissions/OperateLogListener.php index 4945e49..0ea6041 100644 --- a/catchAdmin/permissions/OperateLogListener.php +++ b/catchAdmin/permissions/OperateLogListener.php @@ -2,19 +2,26 @@ namespace catchAdmin\permissions; +use catchAdmin\permissions\model\Permissions; +use catcher\CatchAdmin; use think\facade\Db; class OperateLogListener { public function handle($params) { + $request = $params['request']; + $permission = $params['permission']; + Db::name('operate_log')->insert([ - 'module' => $params['module'], - 'ip' => request()->ip(), - 'operate' => $params['operate'], - 'creator_id' => $params['uid'], - 'method' => $params['method'], + 'creator_id' => $request->user()->id, + 'module' => Permissions::where('id', $permission->parent_id)->value('permission_name'), + 'method' => $request->method(), + 'operate' => $permission->permission_name, + 'route' => $permission->route, + 'params' => json_encode($request->param()), 'created_at' => time(), + 'ip' => $request->ip(), ]); } } diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php index df82c77..2ef432d 100644 --- a/catchAdmin/permissions/PermissionsMiddleware.php +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -27,7 +27,7 @@ class PermissionsMiddleware } // toad if (($permission = $this->getPermission($request)) - && in_array($permission->id, $request->user()->getPermissionsBy())) { + && !in_array($permission->id, $request->user()->getPermissionsBy())) { throw new PermissionForbiddenException(); } @@ -57,21 +57,18 @@ class PermissionsMiddleware $module = array_pop($controller); - $permissionMark = sprintf('%s:%s:%s', $module, $controllerName, $action); - - $permission = Permissions::where('permission_mark', $permissionMark)->find(); - - - $params['uid'] = $request->user()->id; - $params['module'] = $rule ? CatchAdmin::getModulesInfo(false)[$module] : '首页'; - $params['method'] = $request->method(); - $params['operate'] = sprintf('%s/%s', $controllerName, $action); - event('operateLog', $params); + $permissionMark = sprintf('%s:%s', $controllerName, $action); + $permission = Permissions::where('module', $module)->where('permission_mark', $permissionMark)->find(); if (!$permission) { return false; } + event('operateLog', [ + 'request' => $request, + 'permission' => $permission, + ]); + return $permission; } } \ No newline at end of file diff --git a/catchAdmin/permissions/database/migrations/20191208125722_roles.php b/catchAdmin/permissions/database/migrations/20191208125722_roles.php index a794623..6c0412d 100644 --- a/catchAdmin/permissions/database/migrations/20191208125722_roles.php +++ b/catchAdmin/permissions/database/migrations/20191208125722_roles.php @@ -34,7 +34,7 @@ class Roles extends Migrator ->addColumn('description', 'string',['default'=> '','comment'=>'角色备注']) ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false )) ->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false)) - ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) + ->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) ->create(); } } diff --git a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php index ab252a1..50a6fbe 100644 --- a/catchAdmin/permissions/database/migrations/20191208125726_permissions.php +++ b/catchAdmin/permissions/database/migrations/20191208125726_permissions.php @@ -39,7 +39,7 @@ class Permissions extends Migrator ->addColumn('sort', 'integer',['default'=> 0,'comment'=>'排序字段']) ->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false )) ->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false)) - ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,null 未删除 timestamp 已删除', 'signed' => false)) + ->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态,null 未删除 timestamp 已删除', 'signed' => false)) ->create(); } From fad0f9770d2a3ad716ac1e8c5ddcb34309a3d375 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:26:19 +0800 Subject: [PATCH 32/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A9=E6=89=8B?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/helper.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/catchAdmin/helper.php b/catchAdmin/helper.php index b3d9bbc..7a1b907 100644 --- a/catchAdmin/helper.php +++ b/catchAdmin/helper.php @@ -1 +1,23 @@ %s', + $event, $name); +} + +function deleteButton($name = '删除', $event = 'del') +{ + return sprintf( + '%s', + $event, $name); +} + +function addButton($name = '新增', $event = 'add') +{ + return sprintf( + '%s', + $event, $name); +} + From dacf0051176c80583a9ee2fb128a9f8c2a57c2db Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:26:40 +0800 Subject: [PATCH 33/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A9=E6=89=8B?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9dcf858..bac6cd2 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,9 @@ "topthink/think-trace":"^1.0" }, "autoload": { - "files": [], + "files": [ + "catchAdmin/helper.php" + ], "psr-4": { "app\\": "app", "catchAdmin\\": "catchAdmin", From e35a76a80e7babe5fa4f0a3b43934f295cac6772 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Fri, 13 Dec 2019 17:26:54 +0800 Subject: [PATCH 34/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 17 +++ extend/catcher/base/CatchController.php | 29 ++++ extend/catcher/base/CatchModel.php | 2 + extend/catcher/base/CatchRequest.php | 6 +- extend/catcher/command/BackupCommand.php | 181 +++++++++++++++++++++++ 5 files changed, 230 insertions(+), 5 deletions(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index f8c9f9f..6044e6f 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -50,6 +50,23 @@ class CatchAdmin return $directory; } + /** + * 备份地址 + * + * @time 2019年12月13日 + * @return string + */ + public static function backupDirectory(): string + { + $directory = root_path('database/backup'); + + if (!is_dir($directory) && !mkdir($directory, 0777, true) && !is_dir($directory)) { + throw new \RuntimeException(sprintf('Directory "%s" was not created', $directory)); + } + + return $directory; + } + /** * * @time 2019年12月03日 diff --git a/extend/catcher/base/CatchController.php b/extend/catcher/base/CatchController.php index d895071..71f1211 100644 --- a/extend/catcher/base/CatchController.php +++ b/extend/catcher/base/CatchController.php @@ -8,6 +8,8 @@ abstract class CatchController { protected $middleware = ['check_auth']; + protected $data = []; + /** * * @time 2019年11月28日 @@ -26,6 +28,10 @@ abstract class CatchController 'view_path' => CatchAdmin::getViews()[$this->getModule($end['class'])] ]); + if (!empty($this->data)) { + $data = array_merge($this->data, $data); + } + return View::fetch($template ? : $this->getTemp($end['class'], $end['function']), $data); } @@ -62,4 +68,27 @@ abstract class CatchController { return explode('\\', $class)[1]; } + + /** + * + * @time 2019年12月13日 + * @param $name + * @param $value + * @return void + */ + public function __set($name, $value) + { + // TODO: Implement __set() method. + $this->data[$name] = $value; + } + + public function __get($name) + { + // TODO: Implement __get() method. + } + + public function __isset($name) + { + // TODO: Implement __isset() method. + } } diff --git a/extend/catcher/base/CatchModel.php b/extend/catcher/base/CatchModel.php index 5b5485a..4202d8f 100644 --- a/extend/catcher/base/CatchModel.php +++ b/extend/catcher/base/CatchModel.php @@ -17,6 +17,8 @@ abstract class CatchModel extends \think\Model protected $deleteTime = 'deleted_at'; + protected $defaultSoftDelete = 0; + protected $autoWriteTimestamp = true; protected $limit = 10; diff --git a/extend/catcher/base/CatchRequest.php b/extend/catcher/base/CatchRequest.php index 622fac1..fd2668f 100644 --- a/extend/catcher/base/CatchRequest.php +++ b/extend/catcher/base/CatchRequest.php @@ -5,7 +5,7 @@ use app\Request; use catcher\exceptions\ValidateFailedException; use think\Validate; -abstract class CatchRequest extends Request +class CatchRequest extends Request { /** * Request constructor. @@ -35,8 +35,4 @@ abstract class CatchRequest extends Request return true; } - - abstract protected function rules(): array; - - abstract protected function message(): array; } diff --git a/extend/catcher/command/BackupCommand.php b/extend/catcher/command/BackupCommand.php index b3d9bbc..18d904d 100644 --- a/extend/catcher/command/BackupCommand.php +++ b/extend/catcher/command/BackupCommand.php @@ -1 +1,182 @@ setName('backup:data') + ->addArgument('tables', Argument::REQUIRED, 'backup tables') + ->addOption('zip', 'z',Option::VALUE_REQUIRED, 'is need zip') + ->setDescription('backup data you need'); + } + + protected function execute(Input $input, Output $output) + { + $tables = $this->input->getArgument('tables'); + + $isZip = $this->input->getOption('zip') ?? true; + + $this->generator(explode(',', $tables), CatchAdmin::backupDirectory()); + + if ($isZip) { + $this->zip(); + } + + $output->info('succeed!'); + } + + + /** + * + * @time 2019年09月30日 + * @param $tables + * @param $format + * @param $path + * @return void + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\db\exception\DataNotFoundException + */ + public function generator($tables, $path) + { + foreach ($tables as $table) { + $this->table = $table; + + $this->createDataFile(); + } + } + + /** + * 创建数据文件 + * + * @time 2019年09月27日 + * @param $format + * @return void + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\db\exception\DataNotFoundException + */ + public function createDataFile(): void + { + $file = CatchAdmin::backupDirectory() . $this->table . '.sql'; + + $handle = fopen($file, 'wb+'); + + fwrite($handle, $begin = "BEGIN;\r\n", \strlen($begin)); + $this->createClass($this->table, $handle); + fwrite($handle, $end = 'COMMIT;', \strlen($end)); + + fclose($handle); + } + + /** + * 创建了临时模型 + * + * @time 2019年09月27日 + * @param $table + * @param $format + * @param $handle + * @return void + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\db\exception\DataNotFoundException + */ + protected function createClass($table, $handle) + { + $this->setUnbuffered(); + + // 防止 IO 多次写入 + $buffer = []; + + // 记录中记录 + $total = Db::table($table)->count(); + + $limit = 1000; + + // 生成器减少内存 + while ($total > 0) { + $items = Db::table($table)->limit($limit)->select(); + + $this->writeIn($handle, $items); + + $total -= $limit; + } + } + + /** + * sql 文件格式 + * + * @time 2019年09月27日 + * @param $handle + * @param $data + * @return void + */ + protected function writeIn($handle, $datas) + { + $values = ''; + $sql = ''; + foreach ($datas as $data) { + foreach ($data as $value) { + $values .= sprintf("'%s'", $value) . ','; + } + + $sql .= sprintf('INSERT INTO `%s` VALUE (%s);' . "\r\n", $this->table, rtrim($values, ',')); + $values = ''; + } + + fwrite($handle, $sql, strlen($sql)); + } + + + /** + * 设置未缓存模式 + * + * @time 2019年09月29日 + * @return void + */ + protected function setUnbuffered() + { + $connections = \config('database.connections'); + + $connections['mysql']['params'] = [ + \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false + ]; + + \config($connections,'database'); + + } + + protected function zip() + { + if (extension_loaded('zip')) { + $files = glob(CatchAdmin::backupDirectory() . '*.sql'); + $zip = new \ZipArchive(); + $zip->open(root_path('database/') . 'backup.zip', \ZipArchive::CREATE); + $zip->addEmptyDir('backup'); + foreach ($files as $file) { + $zip->addFile($file, 'backup/'. basename($file)); + } + $zip->close(); + + foreach ($files as $file) { + unlink($file); + } + rmdir(CatchAdmin::backupDirectory()); + } + } +} From 1ce4c7122a56e66b681fa2c5ac3958449838f38d Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 14:58:08 +0800 Subject: [PATCH 35/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/command/BackupCommand.php | 4 ++- extend/catcher/command/InstallCommand.php | 36 +++++++++++++++----- extend/catcher/command/MigrateRunCommand.php | 2 ++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/extend/catcher/command/BackupCommand.php b/extend/catcher/command/BackupCommand.php index 18d904d..f35bc27 100644 --- a/extend/catcher/command/BackupCommand.php +++ b/extend/catcher/command/BackupCommand.php @@ -157,7 +157,9 @@ class BackupCommand extends Command \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false ]; - \config($connections,'database'); + \config([ + 'connections' => $connections, + ],'database.connections'); } diff --git a/extend/catcher/command/InstallCommand.php b/extend/catcher/command/InstallCommand.php index 139df1c..cd5fb59 100644 --- a/extend/catcher/command/InstallCommand.php +++ b/extend/catcher/command/InstallCommand.php @@ -13,7 +13,7 @@ use think\facade\Db; class InstallCommand extends Command { - protected $dataInstall = true; + protected $databaseLink = []; protected function configure() { @@ -129,6 +129,8 @@ class InstallCommand extends Command } } + $this->databaseLink = [$host, $database, $username, $password, $port, $charset, $prefix]; + $this->generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix); } } @@ -141,16 +143,28 @@ class InstallCommand extends Command */ protected function secondStep(): void { - $php = getenv('_'); + $connections = \config('database.connections'); - $think = root_path() . DIRECTORY_SEPARATOR . 'think'; + [ + $connections['mysql']['hostname'], + $connections['mysql']['database'], + $connections['mysql']['username'], + $connections['mysql']['password'], + $connections['mysql']['hostport'], + $connections['mysql']['charset'], + $connections['mysql']['prefix'], + ] = $this->databaseLink; + + \config([ + 'connections' => $connections, + ],'database'); foreach (CatchAdmin::getModulesDirectory() as $directory) { $moduleInfo = CatchAdmin::getModuleInfo($directory); - - $this->output->info( - sprintf('module [%s] migrations ', $moduleInfo['alias']) . - exec(sprintf('%s %s catch-migrate:run %s', $php, $think, $moduleInfo['alias']))); + if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) { + $output = Console::call('catch-migrate:run', [$moduleInfo['alias']]); + $this->output->info(sprintf('module [%s] migrations %s', $moduleInfo['alias'], $output->fetch())); + } } } @@ -192,6 +206,7 @@ class InstallCommand extends Command */ protected function generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix): void { + try { $env = \parse_ini_file(root_path() . '.example.env', true); $env['DATABASE']['HOSTNAME'] = $host; @@ -218,7 +233,6 @@ class InstallCommand extends Command } } - file_put_contents(root_path() . '.env', $dotEnv); if ($this->getEnvFile()) { $this->output->info('env file has been generated'); @@ -229,6 +243,12 @@ class InstallCommand extends Command } else { $this->output->warning(sprintf('create database %s failed,you need create database first by yourself', $database)); } + } catch (\Exception $e) { + $this->output->error($e->getMessage()); + exit(0); + } + + file_put_contents(root_path() . '.env', $dotEnv); } /** diff --git a/extend/catcher/command/MigrateRunCommand.php b/extend/catcher/command/MigrateRunCommand.php index ba808b8..95bd6b4 100644 --- a/extend/catcher/command/MigrateRunCommand.php +++ b/extend/catcher/command/MigrateRunCommand.php @@ -46,6 +46,8 @@ EOT } $end = microtime(true); + // 重置 migrations 在循环冲无法重复使用 + $this->migrations = null; $output->writeln(''); $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); } From 8479522970b11195d8f238f9a6bdb31a6edb5696 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 15:03:39 +0800 Subject: [PATCH 36/99] =?UTF-8?q?=E5=AE=89=E8=A3=85=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/command/InstallCommand.php | 40 ++++++++++++----------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/extend/catcher/command/InstallCommand.php b/extend/catcher/command/InstallCommand.php index cd5fb59..78e2c0e 100644 --- a/extend/catcher/command/InstallCommand.php +++ b/extend/catcher/command/InstallCommand.php @@ -17,7 +17,7 @@ class InstallCommand extends Command protected function configure() { - $this->setName('install:project') + $this->setName('catch:install') // ->addArgument('module', Argument::REQUIRED, 'module name') ->setDescription('install project'); } @@ -143,27 +143,29 @@ class InstallCommand extends Command */ protected function secondStep(): void { - $connections = \config('database.connections'); + if (file_exists(root_path() . '.env')) { + $connections = \config('database.connections'); - [ - $connections['mysql']['hostname'], - $connections['mysql']['database'], - $connections['mysql']['username'], - $connections['mysql']['password'], - $connections['mysql']['hostport'], - $connections['mysql']['charset'], - $connections['mysql']['prefix'], - ] = $this->databaseLink; + [ + $connections['mysql']['hostname'], + $connections['mysql']['database'], + $connections['mysql']['username'], + $connections['mysql']['password'], + $connections['mysql']['hostport'], + $connections['mysql']['charset'], + $connections['mysql']['prefix'], + ] = $this->databaseLink; - \config([ - 'connections' => $connections, - ],'database'); + \config([ + 'connections' => $connections, + ], 'database'); - foreach (CatchAdmin::getModulesDirectory() as $directory) { - $moduleInfo = CatchAdmin::getModuleInfo($directory); - if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) { - $output = Console::call('catch-migrate:run', [$moduleInfo['alias']]); - $this->output->info(sprintf('module [%s] migrations %s', $moduleInfo['alias'], $output->fetch())); + foreach (CatchAdmin::getModulesDirectory() as $directory) { + $moduleInfo = CatchAdmin::getModuleInfo($directory); + if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) { + $output = Console::call('catch-migrate:run', [$moduleInfo['alias']]); + $this->output->info(sprintf('module [%s] migrations %s', $moduleInfo['alias'], $output->fetch())); + } } } } From d27b7442d8a4e0982d43fab318abb533bc52e56d Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 15:56:59 +0800 Subject: [PATCH 37/99] =?UTF-8?q?=E6=96=B0=E5=A2=9Eseed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/permissions/OperateLogListener.php | 3 +- .../database/seeds/PermissionSeed.php | 603 ++++++++++++++++++ catchAdmin/user/database/seeds/UserSeeder.php | 30 - catchAdmin/user/database/seeds/UsersSeed.php | 23 + 4 files changed, 628 insertions(+), 31 deletions(-) create mode 100644 catchAdmin/permissions/database/seeds/PermissionSeed.php delete mode 100644 catchAdmin/user/database/seeds/UserSeeder.php create mode 100644 catchAdmin/user/database/seeds/UsersSeed.php diff --git a/catchAdmin/permissions/OperateLogListener.php b/catchAdmin/permissions/OperateLogListener.php index 0ea6041..5cd5954 100644 --- a/catchAdmin/permissions/OperateLogListener.php +++ b/catchAdmin/permissions/OperateLogListener.php @@ -13,9 +13,10 @@ class OperateLogListener $request = $params['request']; $permission = $params['permission']; + $parentPermission = Permissions::where('id', $permission->parent_id)->value('permission_name'); Db::name('operate_log')->insert([ 'creator_id' => $request->user()->id, - 'module' => Permissions::where('id', $permission->parent_id)->value('permission_name'), + 'module' => $parentPermission ? : '', 'method' => $request->method(), 'operate' => $permission->permission_name, 'route' => $permission->route, diff --git a/catchAdmin/permissions/database/seeds/PermissionSeed.php b/catchAdmin/permissions/database/seeds/PermissionSeed.php new file mode 100644 index 0000000..83bd140 --- /dev/null +++ b/catchAdmin/permissions/database/seeds/PermissionSeed.php @@ -0,0 +1,603 @@ +roles(); + $this->createPermissions(); + } + + protected function roles() + { + \catchAdmin\permissions\model\Roles::create([ + 'role_name' => '超级管理员', + 'description' => 'super user', + ]); + + \think\facade\Db::name('user_has_roles')->insert([ + 'role_id' => 1, + 'uid' => 1, + ]); + + \think\facade\Db::name('role_has_permissions')->insertAll(array ( + 0 => + array ( + 'role_id' => 1, + 'permission_id' => 4, + ), + 1 => + array ( + 'role_id' => 1, + 'permission_id' => 6, + ), + 2 => + array ( + 'role_id' => 1, + 'permission_id' => 7, + ), + 3 => + array ( + 'role_id' => 1, + 'permission_id' => 8, + ), + 4 => + array ( + 'role_id' => 1, + 'permission_id' => 9, + ), + 5 => + array ( + 'role_id' => 1, + 'permission_id' => 10, + ), + 6 => + array ( + 'role_id' => 1, + 'permission_id' => 11, + ), + 7 => + array ( + 'role_id' => 1, + 'permission_id' => 12, + ), + 8 => + array ( + 'role_id' => 1, + 'permission_id' => 13, + ), + 9 => + array ( + 'role_id' => 1, + 'permission_id' => 14, + ), + 10 => + array ( + 'role_id' => 1, + 'permission_id' => 15, + ), + 11 => + array ( + 'role_id' => 1, + 'permission_id' => 16, + ), + 12 => + array ( + 'role_id' => 1, + 'permission_id' => 17, + ), + 13 => + array ( + 'role_id' => 1, + 'permission_id' => 18, + ), + 14 => + array ( + 'role_id' => 1, + 'permission_id' => 19, + ), + 15 => + array ( + 'role_id' => 1, + 'permission_id' => 20, + ), + 16 => + array ( + 'role_id' => 1, + 'permission_id' => 21, + ), + 17 => + array ( + 'role_id' => 1, + 'permission_id' => 22, + ), + 18 => + array ( + 'role_id' => 1, + 'permission_id' => 23, + ), + 19 => + array ( + 'role_id' => 1, + 'permission_id' => 24, + ), + 20 => + array ( + 'role_id' => 1, + 'permission_id' => 25, + ), + 21 => + array ( + 'role_id' => 1, + 'permission_id' => 26, + ), + 22 => + array ( + 'role_id' => 1, + 'permission_id' => 27, + ), + 23 => + array ( + 'role_id' => 1, + 'permission_id' => 28, + ), + 24 => + array ( + 'role_id' => 1, + 'permission_id' => 29, + ), + 25 => + array ( + 'role_id' => 1, + 'permission_id' => 30, + ), + 26 => + array ( + 'role_id' => 1, + 'permission_id' => 31, + ), + 27 => + array ( + 'role_id' => 1, + 'permission_id' => 32, + ), + 28 => + array ( + 'role_id' => 1, + 'permission_id' => 33, + ), + 29 => + array ( + 'role_id' => 1, + 'permission_id' => 34, + ), + 30 => + array ( + 'role_id' => 1, + 'permission_id' => 35, + ), + 31 => + array ( + 'role_id' => 1, + 'permission_id' => 36, + ), + )); + } + + + protected function createPermissions() + { + foreach (array ( + 0 => + array ( + 'id' => 4, + 'permission_name' => 'Dashboard', + 'parent_id' => 0, + 'module' => 'index', + 'route' => 'dashboard', + 'method' => 'get', + 'permission_mark' => 'index:dashboard', + 'type' => 1, + 'sort' => 10000, + ), + 1 => + array ( + 'id' => 5, + 'permission_name' => '主题', + 'parent_id' => 4, + 'module' => '', + 'route' => 'themes', + 'method' => 'get', + 'permission_mark' => 'index:theme', + 'type' => 2, + 'sort' => 0, + ), + 2 => + array ( + 'id' => 6, + 'permission_name' => '用户管理', + 'parent_id' => 16, + 'module' => 'user', + 'route' => 'user', + 'method' => 'get', + 'permission_mark' => 'user:index', + 'type' => 1, + 'sort' => 9999, + ), + 3 => + array ( + 'id' => 7, + 'permission_name' => '创建', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user', + 'method' => 'get', + 'permission_mark' => 'user:create', + 'type' => 2, + 'sort' => 0, + ), + 4 => + array ( + 'id' => 8, + 'permission_name' => '保存', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user', + 'method' => 'post', + 'permission_mark' => 'user:save', + 'type' => 2, + 'sort' => 0, + ), + 5 => + array ( + 'id' => 9, + 'permission_name' => '查看', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user//edit', + 'method' => 'get', + 'permission_mark' => 'user:edit', + 'type' => 2, + 'sort' => 0, + ), + 6 => + array ( + 'id' => 10, + 'permission_name' => '编辑', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user/', + 'method' => 'put', + 'permission_mark' => 'user:update', + 'type' => 2, + 'sort' => 0, + ), + 7 => + array ( + 'id' => 11, + 'permission_name' => '删除', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user/', + 'method' => 'delete', + 'permission_mark' => 'user:delete', + 'type' => 2, + 'sort' => 0, + ), + 8 => + array ( + 'id' => 12, + 'permission_name' => '列表', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'users', + 'method' => 'get', + 'permission_mark' => 'user:list', + 'type' => 2, + 'sort' => 0, + ), + 9 => + array ( + 'id' => 13, + 'permission_name' => '禁用/启用', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user/switch/status/', + 'method' => 'put', + 'permission_mark' => 'user:switchStatus', + 'type' => 2, + 'sort' => 0, + ), + 10 => + array ( + 'id' => 14, + 'permission_name' => '恢复', + 'parent_id' => 6, + 'module' => 'user', + 'route' => 'user/recover/', + 'method' => 'put', + 'permission_mark' => 'user:recover', + 'type' => 2, + 'sort' => 0, + ), + 11 => + array ( + 'id' => 15, + 'permission_name' => '角色管理', + 'parent_id' => 16, + 'module' => 'permissions', + 'route' => 'role', + 'method' => 'get', + 'permission_mark' => 'role:index', + 'type' => 1, + 'sort' => 1000, + ), + 12 => + array ( + 'id' => 16, + 'permission_name' => '权限管理', + 'parent_id' => 0, + 'module' => 'permissions', + 'route' => '', + 'method' => 'get', + 'permission_mark' => '@:@', + 'type' => 1, + 'sort' => 1, + ), + 13 => + array ( + 'id' => 17, + 'permission_name' => '菜单管理', + 'parent_id' => 16, + 'module' => 'permissions', + 'route' => 'permission', + 'method' => 'get', + 'permission_mark' => 'permission:index', + 'type' => 1, + 'sort' => 1, + ), + 14 => + array ( + 'id' => 18, + 'permission_name' => '创建', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role/create', + 'method' => 'get', + 'permission_mark' => 'role:create', + 'type' => 2, + 'sort' => 1, + ), + 15 => + array ( + 'id' => 19, + 'permission_name' => '保存', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role', + 'method' => 'post', + 'permission_mark' => 'role:save', + 'type' => 2, + 'sort' => 1, + ), + 16 => + array ( + 'id' => 20, + 'permission_name' => '查看', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role//edit', + 'method' => 'get', + 'permission_mark' => 'role:edit', + 'type' => 2, + 'sort' => 1, + ), + 17 => + array ( + 'id' => 21, + 'permission_name' => '更新', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role/', + 'method' => 'put', + 'permission_mark' => 'role:update', + 'type' => 2, + 'sort' => 1, + ), + 18 => + array ( + 'id' => 22, + 'permission_name' => '删除', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role/', + 'method' => 'delete', + 'permission_mark' => 'role:delete', + 'type' => 2, + 'sort' => 1, + ), + 19 => + array ( + 'id' => 23, + 'permission_name' => '列表', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'roles', + 'method' => 'get', + 'permission_mark' => 'role:list', + 'type' => 2, + 'sort' => 1, + ), + 20 => + array ( + 'id' => 24, + 'permission_name' => '获取权限', + 'parent_id' => 15, + 'module' => 'permissions', + 'route' => 'role/get/permissions', + 'method' => 'get', + 'permission_mark' => 'role:getPermissions', + 'type' => 2, + 'sort' => 1, + ), + 21 => + array ( + 'id' => 25, + 'permission_name' => '删除', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permission/', + 'method' => 'delete', + 'permission_mark' => 'permissions:delete', + 'type' => 2, + 'sort' => 1, + ), + 22 => + array ( + 'id' => 26, + 'permission_name' => '更新', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permission/', + 'method' => 'put', + 'permission_mark' => 'permission:update', + 'type' => 2, + 'sort' => 1, + ), + 23 => + array ( + 'id' => 27, + 'permission_name' => '查看', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permissions//edit', + 'method' => 'get', + 'permission_mark' => 'permission:edit', + 'type' => 2, + 'sort' => 1, + ), + 24 => + array ( + 'id' => 28, + 'permission_name' => '创建', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permission/create', + 'method' => 'get', + 'permission_mark' => 'permission:create', + 'type' => 2, + 'sort' => 1, + ), + 25 => + array ( + 'id' => 29, + 'permission_name' => '保存', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permission', + 'method' => 'post', + 'permission_mark' => 'permission', + 'type' => 2, + 'sort' => 1, + + ), + 26 => + array ( + 'id' => 30, + 'permission_name' => '列表', + 'parent_id' => 17, + 'module' => 'permissions', + 'route' => 'permissions', + 'method' => 'get', + 'permission_mark' => 'permission:list', + 'type' => 2, + 'sort' => 1, + ), + 27 => + array ( + 'id' => 31, + 'permission_name' => '系统管理', + 'parent_id' => 0, + 'module' => 'system', + 'route' => '', + 'method' => 'get', + 'permission_mark' => 's:s', + 'type' => 1, + 'sort' => 1, + ), + 28 => + array ( + 'id' => 32, + 'permission_name' => '日志管理', + 'parent_id' => 31, + 'module' => 'system', + 'route' => '', + 'method' => 'get', + 'permission_mark' => 'log:log', + 'type' => 1, + 'sort' => 1, + ), + 29 => + array ( + 'id' => 33, + 'permission_name' => '登录日志', + 'parent_id' => 32, + 'module' => 'system', + 'route' => 'loginLog/index', + 'method' => 'get', + 'permission_mark' => 'operateLog:index', + 'type' => 1, + 'sort' => 1, + ), + 30 => + array ( + 'id' => 34, + 'permission_name' => '操作日志', + 'parent_id' => 32, + 'module' => 'index', + 'route' => 'operateLog/index', + 'method' => 'get', + 'permission_mark' => 'loginLog:index', + 'type' => 1, + 'sort' => 1, + ), + 31 => + array ( + 'id' => 35, + 'permission_name' => '数据字典', + 'parent_id' => 31, + 'module' => 'system', + 'route' => 'data/dictionary', + 'method' => 'get', + 'permission_mark' => 'datadictory:index', + 'type' => 1, + 'sort' => 1, + ), + 32 => + array ( + 'id' => 36, + 'permission_name' => '查看表', + 'parent_id' => 35, + 'module' => 'system', + 'route' => 'table/view/', + 'method' => 'get', + 'permission_mark' => 'datadictionary:view', + 'type' => 2, + 'sort' => 1, + ), + ) as $permission) { + \catchAdmin\permissions\model\Permissions::create($permission); + } + } + +} \ No newline at end of file diff --git a/catchAdmin/user/database/seeds/UserSeeder.php b/catchAdmin/user/database/seeds/UserSeeder.php deleted file mode 100644 index ee442f5..0000000 --- a/catchAdmin/user/database/seeds/UserSeeder.php +++ /dev/null @@ -1,30 +0,0 @@ - 'wuyanwen', - 'password' => password_hash('password',PASSWORD_DEFAULT), - 'email' => 'njphper@gmail.com', - 'status' => 1, - 'last_login_ip' => ip2long('127.0.0.1'), - 'last_login_time' => time(), - 'created_at' => time(), - 'updated_at' => time(), - 'deleted_at' => '', - ]; - $this->table('users')->insert($row)->save(); - } -} \ No newline at end of file diff --git a/catchAdmin/user/database/seeds/UsersSeed.php b/catchAdmin/user/database/seeds/UsersSeed.php new file mode 100644 index 0000000..276acc5 --- /dev/null +++ b/catchAdmin/user/database/seeds/UsersSeed.php @@ -0,0 +1,23 @@ + 'admin', + 'password' => 'admin', + 'email' => 'admin@gmail.com', + ]); + } +} \ No newline at end of file From 6ac0562470bb7f3729ea769d89fefe1e863df9e9 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 15:57:15 +0800 Subject: [PATCH 38/99] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7seed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/user/database/seeds/UsersSeed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catchAdmin/user/database/seeds/UsersSeed.php b/catchAdmin/user/database/seeds/UsersSeed.php index 276acc5..c3f3b6d 100644 --- a/catchAdmin/user/database/seeds/UsersSeed.php +++ b/catchAdmin/user/database/seeds/UsersSeed.php @@ -2,7 +2,7 @@ use think\migration\Seeder; -class Users extends Seeder +class UsersSeed extends Seeder { /** * Run Method. From 5bcfe3c52d893c4af0e590911880a0898c32240e Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 15:57:32 +0800 Subject: [PATCH 39/99] =?UTF-8?q?=E5=AE=89=E8=A3=85=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A1=AB=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/command/InstallCommand.php | 3 +++ extend/catcher/command/SeedRunCommand.php | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extend/catcher/command/InstallCommand.php b/extend/catcher/command/InstallCommand.php index 78e2c0e..f8d5212 100644 --- a/extend/catcher/command/InstallCommand.php +++ b/extend/catcher/command/InstallCommand.php @@ -165,6 +165,9 @@ class InstallCommand extends Command if (is_dir(CatchAdmin::moduleMigrationsDirectory($moduleInfo['alias']))) { $output = Console::call('catch-migrate:run', [$moduleInfo['alias']]); $this->output->info(sprintf('module [%s] migrations %s', $moduleInfo['alias'], $output->fetch())); + + $seedOut = Console::call('catch-seed:run', [$moduleInfo['alias']]); + $this->output->info(sprintf('module [%s] seeds %s', $moduleInfo['alias'], $seedOut->fetch())); } } } diff --git a/extend/catcher/command/SeedRunCommand.php b/extend/catcher/command/SeedRunCommand.php index c9b756b..0daeb97 100644 --- a/extend/catcher/command/SeedRunCommand.php +++ b/extend/catcher/command/SeedRunCommand.php @@ -42,8 +42,7 @@ EOT $start = microtime(true); $this->seed($seed); $end = microtime(true); - - $output->writeln(CatchAdmin::moduleSeedsDirectory($this->module)); + $this->seeds = null; $output->writeln('All Done. Took ' . sprintf('%.4fs', $end - $start) . ''); } From 74841b07179862f5b677e51c344747756333bba4 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 15:57:55 +0800 Subject: [PATCH 40/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f6fc9b..8ce1b12 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - curl -sS http://install.phpcomposer.com/installer | php - composer config -g repo.packagist composer https://packagist.laravel-china.org - composer update -- php think install:project +- php think catch:install ### Use - 配置虚拟域名 OR 在根目录下执行 php think run From d3dfe38d6030a336c82e9310e578f7ff20b2eb0b Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 16:02:09 +0800 Subject: [PATCH 41/99] =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/view/dashboard.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/catchAdmin/index/view/dashboard.html b/catchAdmin/index/view/dashboard.html index 38a2c62..ccabf4a 100644 --- a/catchAdmin/index/view/dashboard.html +++ b/catchAdmin/index/view/dashboard.html @@ -114,8 +114,8 @@

    V1.0 - catchAdmin 后台框架  - 2019-11-14 + catchAdmin 后台框架发布  + 2019-12-15

    • 基于 Thinkphp6 & layui 开发
    • From 3ec10515fb5615f31b656a2617ada13ae710bfd3 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 16:54:56 +0800 Subject: [PATCH 42/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/permissions/PermissionsMiddleware.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php index 2ef432d..7945647 100644 --- a/catchAdmin/permissions/PermissionsMiddleware.php +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -22,9 +22,6 @@ class PermissionsMiddleware */ public function handle(Request $request, \Closure $next) { - if (!$request->user()) { - throw new PermissionForbiddenException('Login is invalid', 10006); - } // toad if (($permission = $this->getPermission($request)) && !in_array($permission->id, $request->user()->getPermissionsBy())) { @@ -38,10 +35,11 @@ class PermissionsMiddleware * * @time 2019年12月12日 * @param $request - * @throws \think\db\exception\DataNotFoundException + * @return array|bool|\think\Model|null * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException - * @return array|bool|\think\Model|null + * @throws PermissionForbiddenException + * @throws \think\db\exception\DataNotFoundException */ protected function getPermission(Request $request) { @@ -56,7 +54,11 @@ class PermissionsMiddleware array_pop($controller); $module = array_pop($controller); - + if ($module != 'login') { + if (!$request->user()) { + throw new PermissionForbiddenException('Login is invalid', 10006); + } + } $permissionMark = sprintf('%s:%s', $controllerName, $action); $permission = Permissions::where('module', $module)->where('permission_mark', $permissionMark)->find(); From 485432acfb6bf59f2a5c9b6b2f6fd30a83b8688f Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 16:56:59 +0800 Subject: [PATCH 43/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/route.php | 6 +++--- catchAdmin/index/view/index.html | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/catchAdmin/index/route.php b/catchAdmin/index/route.php index a3c0e5e..3f0cdef 100644 --- a/catchAdmin/index/route.php +++ b/catchAdmin/index/route.php @@ -1,5 +1,5 @@ get('/', '\catchAdmin\index\controller\index@index'); -$router->get('theme', '\catchAdmin\index\controller\index@theme'); -$router->get('dashboard', '\catchAdmin\index\controller\index@dashboard'); +$router->get('/', '\catchAdmin\index\controller\Index@index'); +$router->get('theme', '\catchAdmin\index\controller\Index@theme'); +$router->get('dashboard', '\catchAdmin\index\controller\Index@dashboard'); diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index 48a0954..9d0d613 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -49,14 +49,14 @@
      - 个人中心 + 个人中心
      修改密码

      - 退出 + 退出
      @@ -127,7 +127,9 @@ menuPath: '{:url("dashboard")}', menuName: '' }); - + window.logouts= function(){ + layer.msg('弹窗被成功打开了'); + }; }); From 0d0abf3ea004efb326fd103563841c0e7d88ca7a Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:08:21 +0800 Subject: [PATCH 44/99] tree-table --- public/catch-admin/assets/js/common.js | 5 +- public/catch-admin/assets/module/admin.js | 2 +- .../assets/module/authtree/authtree.js | 2 +- .../tree_themes/auth-skin-default.css | 4 +- .../assets/module/treetable-lay/treeTable.css | 275 ++++ .../assets/module/treetable-lay/treeTable.js | 1388 +++++++++++++++++ 6 files changed, 1670 insertions(+), 6 deletions(-) create mode 100755 public/catch-admin/assets/module/treetable-lay/treeTable.css create mode 100755 public/catch-admin/assets/module/treetable-lay/treeTable.js diff --git a/public/catch-admin/assets/js/common.js b/public/catch-admin/assets/js/common.js index 415e93e..7b8218c 100755 --- a/public/catch-admin/assets/js/common.js +++ b/public/catch-admin/assets/js/common.js @@ -6,7 +6,7 @@ layui.config({ base: getProjectUrl() + 'assets/module/' }).extend({ formSelects: 'formSelects/formSelects-v4', - treetable: 'treetable-lay/treetable', + treeTable: 'treetable-lay/treeTable', dropdown: 'dropdown/dropdown', notice: 'notice/notice', step: 'step-lay/step', @@ -21,7 +21,8 @@ layui.config({ Drag: 'Drag/Drag', CKEDITOR: 'ckeditor/ckeditor', Split: 'Split/Split', - cascader: 'cascader/cascader' + cascader: 'cascader/cascader', + authtree: 'authtree/authtree', }).use(['layer', 'admin'], function () { var $ = layui.jquery; var layer = layui.layer; diff --git a/public/catch-admin/assets/module/admin.js b/public/catch-admin/assets/module/admin.js index 4f72a5b..446e153 100755 --- a/public/catch-admin/assets/module/admin.js +++ b/public/catch-admin/assets/module/admin.js @@ -1,2 +1,2 @@ /** EasyWeb iframe v3.1.5 date:2019-10-05 License By http://easyweb.vip */ -layui.define(["layer"],function(f){var h=layui.jquery;var j=layui.layer;var a=".layui-layout-admin>.layui-body";var k=a+">.layui-tab";var e=".layui-layout-admin>.layui-side>.layui-side-scroll";var i=".layui-layout-admin>.layui-header";var b="admin-pagetabs";var d="admin-side-nav";var c="theme-admin";var m={version:"314",defaultTheme:"theme-admin",tableName:"easyweb",flexible:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.flexible(n);return}}var o=h(".layui-layout-admin").hasClass("admin-nav-mini");(n==undefined)&&(n=o);if(o==n){if(n){m.hideTableScrollBar();h(".layui-layout-admin").removeClass("admin-nav-mini")}else{h(".layui-layout-admin").addClass("admin-nav-mini")}}},activeNav:function(o){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.activeNav(o);return}}if(!o){o=window.location.pathname;o=o.substring(o.indexOf("/"))}if(o&&o!=""){h(e+">.layui-nav .layui-nav-item .layui-nav-child dd.layui-this").removeClass("layui-this");h(e+">.layui-nav .layui-nav-item.layui-this").removeClass("layui-this");var r=h(e+'>.layui-nav a[lay-href="'+o+'"]');if(r&&r.length>0){var q=h(".layui-layout-admin").hasClass("admin-nav-mini");if(h(e+">.layui-nav").attr("lay-accordion")=="true"){var n=r.parent("dd").parents(".layui-nav-child");if(q){h(e+">.layui-nav .layui-nav-itemed>.layui-nav-child").not(n).css("display","none")}else{h(e+">.layui-nav .layui-nav-itemed>.layui-nav-child").not(n).slideUp("fast")}h(e+">.layui-nav .layui-nav-itemed").not(n.parent()).removeClass("layui-nav-itemed")}r.parent().addClass("layui-this");var s=r.parent("dd").parents(".layui-nav-child").parent();if(q){s.not(".layui-nav-itemed").children(".layui-nav-child").css("display","block")}else{s.not(".layui-nav-itemed").children(".layui-nav-child").slideDown("fast",function(){var t=r.offset().top+r.outerHeight()+30-m.getPageHeight();var u=50+65-r.offset().top;if(t>0){h(e).animate({"scrollTop":h(e).scrollTop()+t},100)}else{if(u>0){h(e).animate({"scrollTop":h(e).scrollTop()-u},100)}}})}s.addClass("layui-nav-itemed");h('ul[lay-filter="'+d+'"]').addClass("layui-hide");var p=r.parents(".layui-nav");p.removeClass("layui-hide");h(i+">.layui-nav>.layui-nav-item").removeClass("layui-this");h(i+'>.layui-nav>.layui-nav-item>a[nav-bind="'+p.attr("nav-id")+'"]').parent().addClass("layui-this")}else{}}else{console.warn("active url is null")}},popupRight:function(n){if(n.title==undefined){n.title=false;n.closeBtn=false}if(n.fixed==undefined){n.fixed=true}n.anim=-1;n.offset="r";n.shadeClose=true;n.area||(n.area="336px");n.skin||(n.skin="layui-anim layui-anim-rl layui-layer-adminRight");n.move=false;return m.open(n)},open:function(q){if(!q.area){q.area=(q.type==2)?["360px","300px"]:"360px"}if(!q.skin){q.skin="layui-layer-admin"}if(!q.offset){if(m.getPageWidth()<768){q.offset="15px"}else{if(window==top){q.offset="70px"}else{q.offset="40px"}}}if(q.fixed==undefined){q.fixed=false}q.resize=q.resize!=undefined?q.resize:false;q.shade=q.shade!=undefined?q.shade:0.1;var o=q.end;q.end=function(){j.closeAll("tips");o&&o()};if(q.url){(q.type==undefined)&&(q.type=1);var p=q.success;q.success=function(r,s){m.showLoading(r,2);h(r).children(".layui-layer-content").load(q.url,function(){p?p(r,s):"";m.removeLoading(r,false)})}}var n=j.open(q);(q.data)&&(m.layerData["d"+n]=q.data);return n},layerData:{},getLayerData:function(n,o){if(n==undefined){n=parent.layer.getFrameIndex(window.name);return parent.layui.admin.getLayerData(n,o)}else{if(n.toString().indexOf("#")==0){n=h(n).parents(".layui-layer").attr("id").substring(11)}}var p=m.layerData["d"+n];if(o){return p?p[o]:p}return p},putLayerData:function(o,q,n){if(n==undefined){n=parent.layer.getFrameIndex(window.name);return parent.layui.admin.putLayerData(o,q,n)}else{if(n.toString().indexOf("#")==0){n=h(n).parents(".layui-layer").attr("id").substring(11)}}var p=m.getLayerData(n);p||(p={});p[o]=q;m.layerData["d"+n]=p},req:function(n,o,p,q){m.ajax({url:n,data:o,type:q,dataType:"json",success:p})},ajax:function(p){var o=p.header;p.dataType||(p.dataType="json");var n=p.success;p.success=function(q,r,t){var s;if("json"==p.dataType.toLowerCase()){s=q}else{s=m.parseJSON(q)}s&&(s=q);if(m.ajaxSuccessBefore(s,p.url)==false){return}n(q,r,t)};p.error=function(q){p.success({code:q.status,msg:q.statusText})};p.beforeSend=function(t){var s=m.getAjaxHeaders(p.url);for(var q=0;q
    ','
    ','
    '];h(r).addClass("page-no-scroll");var s=h(r).children(".page-loading");if(s.length<=0){h(r).append('
    '+n[q-1]+"
    ");s=h(r).children(".page-loading")}o&&s.css("background-color","rgba(255,255,255,"+o+")");s.show()},removeLoading:function(o,q,n){if(!o){o="body"}if(q==undefined){q=true}var p=h(o).children(".page-loading");if(n){p.remove()}else{q?p.fadeOut():p.hide()}h(o).removeClass("page-no-scroll")},putTempData:function(o,p){var n=m.tableName+"_tempData";if(p!=undefined&&p!=null){layui.sessionData(n,{key:o,value:p})}else{layui.sessionData(n,{key:o,remove:true})}},getTempData:function(o){var n=m.tableName+"_tempData";var p=layui.sessionData(n);if(p){return p[o]}else{return false}},rollPage:function(q){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.rollPage(q);return}}var o=h(k+">.layui-tab-title");var p=o.scrollLeft();if("left"===q){o.animate({"scrollLeft":p-120},100)}else{if("auto"===q){var n=0;o.children("li").each(function(){if(h(this).hasClass("layui-this")){return false}else{n+=h(this).outerWidth()}});o.animate({"scrollLeft":n-120},100)}else{o.animate({"scrollLeft":p+120},100)}}},refresh:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.refresh(n);return}}var p;if(!n){p=h(k+">.layui-tab-content>.layui-tab-item.layui-show>.admin-iframe");if(!p||p.length<=0){p=h(a+">div>.admin-iframe")}}else{p=h(k+'>.layui-tab-content>.layui-tab-item>.admin-iframe[lay-id="'+n+'"]');if(!p||p.length<=0){p=h(a+">.admin-iframe")}}if(p&&p[0]){try{p[0].contentWindow.location.reload(true)}catch(o){p.attr("src",p.attr("src"))}}else{console.warn(n+" is not found")}},closeThisTabs:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeThisTabs(n);return}}m.closeTabOperNav();var o=h(k+">.layui-tab-title");if(!n){if(o.find("li").first().hasClass("layui-this")){j.msg("主页不能关闭",{icon:2});return}o.find("li.layui-this").find(".layui-tab-close").trigger("click")}else{if(n==o.find("li").first().attr("lay-id")){j.msg("主页不能关闭",{icon:2});return}o.find('li[lay-id="'+n+'"]').find(".layui-tab-close").trigger("click")}},closeOtherTabs:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeOtherTabs(n);return}}if(!n){h(k+">.layui-tab-title li:gt(0):not(.layui-this)").find(".layui-tab-close").trigger("click")}else{h(k+">.layui-tab-title li:gt(0)").each(function(){if(n!=h(this).attr("lay-id")){h(this).find(".layui-tab-close").trigger("click")}})}m.closeTabOperNav()},closeAllTabs:function(){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeAllTabs();return}}h(k+">.layui-tab-title li:gt(0)").find(".layui-tab-close").trigger("click");h(k+">.layui-tab-title li:eq(0)").trigger("click");m.closeTabOperNav()},closeTabOperNav:function(){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeTabOperNav();return}}h(".layui-icon-down .layui-nav .layui-nav-child").removeClass("layui-show")},changeTheme:function(t){if(t){layui.data(m.tableName,{key:"theme",value:t});if(c==t){t=undefined}}else{layui.data(m.tableName,{key:"theme",remove:true})}try{m.removeTheme(top);(t&&top.layui)&&top.layui.link(m.getThemeDir()+t+m.getCssSuffix(),t);var u=top.window.frames;for(var p=0;p768){if(!p){var o=h(k+">.layui-tab-content>.layui-tab-item.layui-show>.admin-iframe");if(o.length<=0){o=h(a+">div>.admin-iframe")}if(o.length>0){p=o[0].contentWindow}}try{if(p&&p.layui&&p.layui.jquery){if(window.hsbTimer){clearTimeout(hsbTimer)}p.layui.jquery(".layui-table-body.layui-table-main").addClass("no-scrollbar");window.hsbTimer=setTimeout(function(){if(p&&p.layui&&p.layui.jquery){p.layui.jquery(".layui-table-body.layui-table-main").removeClass("no-scrollbar")}},500)}}catch(n){}}},modelForm:function(o,r,n){var q=h(o);q.addClass("layui-form");if(n){q.attr("lay-filter",n)}var p=q.find(".layui-layer-btn .layui-layer-btn0");p.attr("lay-submit","");p.attr("lay-filter",r)},btnLoading:function(o,p,q){if(p!=undefined&&(typeof p=="boolean")){q=p;p=undefined}(q==undefined)&&(q=true);var n=h(o);if(q){p&&n.html(p);n.find(".layui-icon").addClass("layui-hide");n.addClass("icon-btn");n.prepend('');n.prop("disabled","disabled")}else{n.find(".ew-btn-loading").remove();n.removeProp("disabled","disabled");if(n.find(".layui-icon.layui-hide").length<=0){n.removeClass("icon-btn")}n.find(".layui-icon").removeClass("layui-hide");p&&n.html(p)}},openSideAutoExpand:function(){h(".layui-layout-admin>.layui-side").off("mouseenter.openSideAutoExpand").on("mouseenter.openSideAutoExpand",function(){if(h(this).parent().hasClass("admin-nav-mini")){m.flexible(true);h(this).addClass("side-mini-hover")}});h(".layui-layout-admin>.layui-side").off("mouseleave.openSideAutoExpand").on("mouseleave.openSideAutoExpand",function(){if(h(this).hasClass("side-mini-hover")){m.flexible(false);h(this).removeClass("side-mini-hover")}})},openCellAutoExpand:function(){h("body").off("mouseenter.openCellAutoExpand").on("mouseenter.openCellAutoExpand",".layui-table-view td",function(){h(this).find(".layui-table-grid-down").trigger("click")});h("body").off("mouseleave.openCellAutoExpand").on("mouseleave.openCellAutoExpand",".layui-table-tips>.layui-layer-content",function(){h(".layui-table-tips-c").trigger("click")})},isTop:function(){return h(a).length>0},strToWin:function(q){var p=window;if(q){var n=q.split(".");for(var o=0;o';L+='
    '+I.name+"
    ";L+='
    '+I.address+"
    ";L+='
    ';L+=""}}h("#ew-map-select-pois").html(L)}})})};var n=function(){var C={resizeEnable:true,zoom:A};x&&(C.center=x);var D=new AMap.Map("ew-map-select-map",C);D.on("complete",function(){var E=D.getCenter();u(E.lat,E.lng)});D.on("moveend",function(){if(B){B=false}else{h("#ew-map-select-tips").addClass("layui-hide");h("#ew-map-select-center-img").removeClass("bounceInDown");setTimeout(function(){h("#ew-map-select-center-img").addClass("bounceInDown")});var E=D.getCenter();u(E.lat,E.lng)}});h("#ew-map-select-pois").off("click").on("click",".ew-map-select-search-list-item",function(){h("#ew-map-select-tips").addClass("layui-hide");h("#ew-map-select-pois .ew-map-select-search-list-item-icon-ok").addClass("layui-hide");h(this).find(".ew-map-select-search-list-item-icon-ok").removeClass("layui-hide");h("#ew-map-select-center-img").removeClass("bounceInDown");setTimeout(function(){h("#ew-map-select-center-img").addClass("bounceInDown")});var G=h(this).data("lng");var H=h(this).data("lat");var F=h(this).find(".ew-map-select-search-list-item-title").text();var E=h(this).find(".ew-map-select-search-list-item-address").text();y={name:F,address:E,lat:H,lng:G};B=true;D.setZoomAndCenter(t,[G,H])});h("#ew-map-select-btn-ok").click(function(){if(y==undefined){j.msg("请点击位置列表选择",{icon:2,anim:6})}else{if(w){if(q){var E=j.load(2);D.setCenter([y.lng,y.lat]);D.getCity(function(F){j.close(E);y.city=F;m.closeDialog("#ew-map-select-btn-ok");w(y)})}else{m.closeDialog("#ew-map-select-btn-ok");w(y)}}else{m.closeDialog("#ew-map-select-btn-ok")}}});h("#ew-map-select-input-search").off("input").on("input",function(){var E=h(this).val();if(!E){h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}AMap.plugin("AMap.Autocomplete",function(){var F=new AMap.Autocomplete({city:"全国"});F.search(E,function(I,H){if(H.tips){var G=H.tips;var K="";for(var J=0;J';K+=' ';K+='
    '+L.name+"
    ";K+='
    '+L.address+"
    ";K+=""}}h("#ew-map-select-tips").html(K);if(G.length==0){h("#ew-map-select-tips").addClass("layui-hide")}else{h("#ew-map-select-tips").removeClass("layui-hide")}}else{h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}})})});h("#ew-map-select-input-search").off("blur").on("blur",function(){var E=h(this).val();if(!E){h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}});h("#ew-map-select-input-search").off("focus").on("focus",function(){var E=h(this).val();if(E){h("#ew-map-select-tips").removeClass("layui-hide")}});h("#ew-map-select-tips").off("click").on("click",".ew-map-select-search-list-item",function(){h("#ew-map-select-tips").addClass("layui-hide");var E=h(this).data("lng");var F=h(this).data("lat");y=undefined;D.setZoomAndCenter(t,[E,F])})};var p='
    ';p+=' 搜索:';p+=' ';p+='
    ';p+="
    ";p+="
    ";p+='
    ';p+='
    ';p+='
    ';p+=' ';p+=' ';p+="
    ";p+='
    ';p+="
    ";p+="
    ";m.open({id:"ew-map-select",type:1,title:o,area:"750px",content:p,success:function(C,E){var D=h(C).children(".layui-layer-content");D.css("overflow","visible");m.showLoading(D);if(undefined==window.AMap){h.getScript(r,function(){n();m.removeLoading(D)})}else{n();m.removeLoading(D)}}})};m.cropImg=function(q){var o="image/jpeg";var v=q.aspectRatio;var w=q.imgSrc;var t=q.imgType;var r=q.onCrop;var s=q.limitSize;var u=q.acceptMime;var p=q.exts;var n=q.title;(v==undefined)&&(v=1/1);(n==undefined)&&(n="裁剪图片");t&&(o=t);layui.use(["Cropper","upload"],function(){var y=layui.Cropper;var x=layui.upload;function z(){var C,D=h("#ew-crop-img");var E={elem:"#ew-crop-img-upload",auto:false,drag:false,choose:function(F){F.preview(function(H,I,G){o=I.type;D.attr("src",G);if(!w||!C){w=G;z()}else{C.destroy();C=new y(D[0],B)}})}};(s!=undefined)&&(E.size=s);(u!=undefined)&&(E.acceptMime=u);(p!=undefined)&&(E.exts=p);x.render(E);if(!w){h("#ew-crop-img-upload").trigger("click");return}var B={aspectRatio:v,preview:"#ew-crop-img-preview"};C=new y(D[0],B);h(".ew-crop-tool").on("click","[data-method]",function(){var G=h(this).data(),H,F;if(!C||!G.method){return}G=h.extend({},G);H=C.cropped;switch(G.method){case"rotate":if(H&&B.viewMode>0){C.clear()}break;case"getCroppedCanvas":if(o==="image/jpeg"){if(!G.option){G.option={}}G.option.fillColor="#fff"}break}F=C[G.method](G.option,G.secondOption);switch(G.method){case"rotate":if(H&&B.viewMode>0){C.crop()}break;case"scaleX":case"scaleY":h(this).data("option",-G.option);break;case"getCroppedCanvas":if(F){r&&r(F.toDataURL(o));m.closeDialog("#ew-crop-img")}else{j.msg("裁剪失败",{icon:2,anim:6})}break}})}var A='
    ';A+='
    ';A+=' ';A+="
    ";A+='
    ';A+='
    ';A+="
    ";A+="
    ";A+='
    ';A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+=' ';A+="
    ";m.open({title:n,area:"665px",type:1,content:A,success:function(B,C){h(B).children(".layui-layer-content").css("overflow","visible");z()}})})};m.util={Convert_BD09_To_GCJ02:function(o){var q=(3.141592653589793*3000)/180;var n=o.lng-0.0065,s=o.lat-0.006;var r=Math.sqrt(n*n+s*s)-0.00002*Math.sin(s*q);var p=Math.atan2(s,n)-0.000003*Math.cos(n*q);o.lng=r*Math.cos(p);o.lat=r*Math.sin(p);return o},Convert_GCJ02_To_BD09:function(o){var q=(3.141592653589793*3000)/180;var n=o.lng,s=o.lat;var r=Math.sqrt(n*n+s*s)+0.00002*Math.sin(s*q);var p=Math.atan2(s,n)+0.000003*Math.cos(n*q);o.lng=r*Math.cos(p)+0.0065;o.lat=r*Math.sin(p)+0.006;return o},animateNum:function(D,x,F,v){var r=h(D);var s=r.text().replace(/,/g,"");x=x===null||x===undefined||x===true||x==="true";F=isNaN(F)?500:F;v=isNaN(v)?100:v;var z="INPUT,TEXTAREA".indexOf(r.get(0).tagName)>=0;var t=function(J){var H="";for(var I=0;I=0;I--){if(!isNaN(J.charAt(I))){return H}else{H=J.charAt(I)+H}}},C=function(I,H){if(!H){return I}if(!/^[0-9]+.?[0-9]*$/.test(I)){return I}I=I.toString();return I.replace(I.indexOf(".")>0?/(\d)(?=(\d{3})+(?:\.))/g:/(\d)(?=(\d{3})+(?:$))/g,"$1,")};var G=t(s.toString());var p=A(s.toString());var q=s.toString().replace(G,"").replace(p,"");if(isNaN(q)||q===0){z?r.val(s):r.html(s);console.error("非法数值!");return}var u=q.split(".");var o=u[1]?u[1].length:0;var n=0,y=q;if(Math.abs(y)>10){n=parseFloat(u[0].substring(0,u[0].length-1)+(u[1]?".0"+u[1]:""))}var w=(y-n)/v,E=0;var B=setInterval(function(){var H=G+C(n.toFixed(o),x)+p;z?r.val(H):r.html(H);n+=w;E++;if(Math.abs(n)>=Math.abs(y)||E>5000){H=G+C(y,x)+p;z?r.val(H):r.html(H);clearInterval(B)}},F/v)},deepClone:function(q){var n;var o=m.util.isClass(q);if(o==="Object"){n={}}else{if(o==="Array"){n=[]}else{return q}}for(var p in q){var r=q[p];if(m.util.isClass(r)=="Object"){n[p]=arguments.callee(r)}else{if(m.util.isClass(r)=="Array"){n[p]=arguments.callee(r)}else{n[p]=q[p]}}}return n},isClass:function(n){if(n===null){return"Null"}if(n===undefined){return"Undefined"}return Object.prototype.toString.call(n).slice(8,-1)},fullTextIsEmpty:function(q){if(!q){return true}var o=["img","audio","video","iframe","object"];for(var n=0;n-1){return false}}var p=q.replace(/\s*/g,"");if(!p){return true}p=p.replace(/ /ig,"");if(!p){return true}p=p.replace(/<[^>]+>/g,"");if(!p){return true}return false}};var l=".layui-layout-admin.admin-nav-mini>.layui-side .layui-nav .layui-nav-item";h(document).on("mouseenter",l+","+l+" .layui-nav-child>dd",function(){if(m.getPageWidth()>768){var o=h(this),q=o.find(">.layui-nav-child");if(q.length>0){o.addClass("admin-nav-hover");q.css("left",o.offset().left+o.outerWidth());var p=o.offset().top;if(p+q.outerHeight()>m.getPageHeight()){p=p-q.outerHeight()+o.outerHeight();(p<60)&&(p=60);q.addClass("show-top")}q.css("top",p);q.addClass("ew-anim-drop-in")}else{if(o.hasClass("layui-nav-item")){var n=o.find("cite").text();j.tips(n,o,{tips:[2,"#303133"],time:-1,success:function(r,s){h(r).css("margin-top","12px")}})}}}}).on("mouseleave",l+","+l+" .layui-nav-child>dd",function(){j.closeAll("tips");var o=h(this);o.removeClass("admin-nav-hover");var n=o.find(">.layui-nav-child");n.removeClass("show-top ew-anim-drop-in");n.css({"left":"unset","top":"unset"})});h(document).on("click","*[ew-event]",function(){var n=h(this).attr("ew-event");var o=m.events[n];o&&o.call(this,h(this))});h(document).on("mouseenter","*[lay-tips]",function(){var n=h(this).attr("lay-tips");var o=h(this).attr("lay-direction");var p=h(this).attr("lay-bg");var q=h(this).attr("lay-offset");j.tips(n,this,{tips:[o||1,p||"#303133"],time:-1,success:function(r,s){if(q){q=q.split(",");var u=q[0],t=q.length>1?q[1]:undefined;u&&(h(r).css("margin-top",u));t&&(h(r).css("margin-left",t))}}})}).on("mouseleave","*[lay-tips]",function(){j.closeAll("tips")});if(m.getPageWidth()<768){if(layui.device().os=="windows"){h("body").append("")}}h(document).on("click","*[ew-href]",function(){var n=h(this).attr("ew-href");var o=h(this).attr("ew-title");o||(o=h(this).text());if(top.layui&&top.layui.index){top.layui.index.openTab({title:o?o:"",url:n})}else{location.href=n}});var g=layui.data(m.tableName);if(g&&g.theme){(g.theme==c)||layui.link(m.getThemeDir()+g.theme+m.getCssSuffix(),g.theme)}else{if(c!=m.defaultTheme){layui.link(m.getThemeDir()+m.defaultTheme+m.getCssSuffix(),m.defaultTheme)}}if(!layui.contextMenu){h(document).off("click.ctxMenu").on("click.ctxMenu",function(){try{var q=top.window.frames;for(var n=0;n.ctxMenu").remove()}catch(p){}}try{(top.layui&&top.layui.jquery)&&top.layui.jquery("body>.ctxMenu").remove()}catch(p){}}catch(p){}})}f("admin",m)}); \ No newline at end of file +layui.define(["layer"],function(f){var h=layui.jquery;var j=layui.layer;var a=".layui-layout-admin>.layui-body";var k=a+">.layui-tab";var e=".layui-layout-admin>.layui-side>.layui-side-scroll";var i=".layui-layout-admin>.layui-header";var b="admin-pagetabs";var d="admin-side-nav";var c="theme-admin";var m={version:"314",defaultTheme:"theme-admin",tableName:"easyweb",flexible:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.flexible(n);return}}var o=h(".layui-layout-admin").hasClass("admin-nav-mini");(n==undefined)&&(n=o);if(o==n){if(n){m.hideTableScrollBar();h(".layui-layout-admin").removeClass("admin-nav-mini")}else{h(".layui-layout-admin").addClass("admin-nav-mini")}}},activeNav:function(o){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.activeNav(o);return}}if(!o){o=window.location.pathname;o=o.substring(o.indexOf("/"))}if(o&&o!=""){h(e+">.layui-nav .layui-nav-item .layui-nav-child dd.layui-this").removeClass("layui-this");h(e+">.layui-nav .layui-nav-item.layui-this").removeClass("layui-this");var r=h(e+'>.layui-nav a[lay-href="'+o+'"]');if(r&&r.length>0){var q=h(".layui-layout-admin").hasClass("admin-nav-mini");if(h(e+">.layui-nav").attr("lay-accordion")=="true"){var n=r.parent("dd").parents(".layui-nav-child");if(q){h(e+">.layui-nav .layui-nav-itemed>.layui-nav-child").not(n).css("display","none")}else{h(e+">.layui-nav .layui-nav-itemed>.layui-nav-child").not(n).slideUp("fast")}h(e+">.layui-nav .layui-nav-itemed").not(n.parent()).removeClass("layui-nav-itemed")}r.parent().addClass("layui-this");var s=r.parent("dd").parents(".layui-nav-child").parent();if(q){s.not(".layui-nav-itemed").children(".layui-nav-child").css("display","block")}else{s.not(".layui-nav-itemed").children(".layui-nav-child").slideDown("fast",function(){var t=r.offset().top+r.outerHeight()+30-m.getPageHeight();var u=50+65-r.offset().top;if(t>0){h(e).animate({"scrollTop":h(e).scrollTop()+t},100)}else{if(u>0){h(e).animate({"scrollTop":h(e).scrollTop()-u},100)}}})}s.addClass("layui-nav-itemed");h('ul[lay-filter="'+d+'"]').addClass("layui-hide");var p=r.parents(".layui-nav");p.removeClass("layui-hide");h(i+">.layui-nav>.layui-nav-item").removeClass("layui-this");h(i+'>.layui-nav>.layui-nav-item>a[nav-bind="'+p.attr("nav-id")+'"]').parent().addClass("layui-this")}else{}}else{console.warn("active url is null")}},popupRight:function(n){if(n.title==undefined){n.title=false;n.closeBtn=false}if(n.fixed==undefined){n.fixed=true}n.anim=-1;n.offset="r";n.shadeClose=true;n.area||(n.area="336px");n.skin||(n.skin="layui-anim layui-anim-rl layui-layer-adminRight");n.move=false;return m.open(n)},open:function(q){if(!q.area){q.area=(q.type==2)?["360px","300px"]:"360px"}if(!q.skin){q.skin="layui-layer-admin"}if(!q.offset){if(m.getPageWidth()<768){q.offset="15px"}else{if(window==top){q.offset="70px"}else{q.offset="40px"}}}if(q.fixed==undefined){q.fixed=false}q.resize=q.resize!=undefined?q.resize:false;q.shade=q.shade!=undefined?q.shade:0.1;var o=q.end;q.end=function(){j.closeAll("tips");o&&o()};if(q.url){(q.type==undefined)&&(q.type=1);var p=q.success;q.success=function(r,s){m.showLoading(r,2);h(r).children(".layui-layer-content").load(q.url,function(){p?p(r,s):"";m.removeLoading(r,false)})}}var n=j.open(q);(q.data)&&(m.layerData["d"+n]=q.data);return n},layerData:{},getLayerData:function(n,o){if(n==undefined){n=parent.layer.getFrameIndex(window.name);return parent.layui.admin.getLayerData(n,o)}else{if(n.toString().indexOf("#")==0){n=h(n).parents(".layui-layer").attr("id").substring(11)}}var p=m.layerData["d"+n];if(o){return p?p[o]:p}return p},putLayerData:function(o,q,n){if(n==undefined){n=parent.layer.getFrameIndex(window.name);return parent.layui.admin.putLayerData(o,q,n)}else{if(n.toString().indexOf("#")==0){n=h(n).parents(".layui-layer").attr("id").substring(11)}}var p=m.getLayerData(n);p||(p={});p[o]=q;m.layerData["d"+n]=p},req:function(n,o,p,q){m.ajax({url:n,data:o,type:q,dataType:"json",success:p})},ajax:function(p){var o=p.header;p.dataType||(p.dataType="json");var n=p.success;p.success=function(q,r,t){var s;if("json"==p.dataType.toLowerCase()){s=q}else{s=m.parseJSON(q)}s&&(s=q);if(m.ajaxSuccessBefore(s,p.url)==false){return}n(q,r,t)};p.error=function(q){p.success({code:q.status,msg:q.statusText})};p.beforeSend=function(t){var s=m.getAjaxHeaders(p.url);for(var q=0;q','
    ','
    '];h(r).addClass("page-no-scroll");var s=h(r).children(".page-loading");if(s.length<=0){h(r).append('
    '+n[q-1]+"
    ");s=h(r).children(".page-loading")}o&&s.css("background-color","rgba(255,255,255,"+o+")");s.show()},removeLoading:function(o,q,n){if(!o){o="body"}if(q==undefined){q=true}var p=h(o).children(".page-loading");if(n){p.remove()}else{q?p.fadeOut():p.hide()}h(o).removeClass("page-no-scroll")},putTempData:function(o,p){var n=m.tableName+"_tempData";if(p!=undefined&&p!=null){layui.sessionData(n,{key:o,value:p})}else{layui.sessionData(n,{key:o,remove:true})}},getTempData:function(o){var n=m.tableName+"_tempData";var p=layui.sessionData(n);if(p){return p[o]}else{return false}},rollPage:function(q){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.rollPage(q);return}}var o=h(k+">.layui-tab-title");var p=o.scrollLeft();if("left"===q){o.animate({"scrollLeft":p-120},100)}else{if("auto"===q){var n=0;o.children("li").each(function(){if(h(this).hasClass("layui-this")){return false}else{n+=h(this).outerWidth()}});o.animate({"scrollLeft":n-120},100)}else{o.animate({"scrollLeft":p+120},100)}}},refresh:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.refresh(n);return}}var p;if(!n){p=h(k+">.layui-tab-content>.layui-tab-item.layui-show>.admin-iframe");if(!p||p.length<=0){p=h(a+">div>.admin-iframe")}}else{p=h(k+'>.layui-tab-content>.layui-tab-item>.admin-iframe[lay-id="'+n+'"]');if(!p||p.length<=0){p=h(a+">.admin-iframe")}}if(p&&p[0]){try{p[0].contentWindow.location.reload(true)}catch(o){p.attr("src",p.attr("src"))}}else{console.warn(n+" is not found")}},closeThisTabs:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeThisTabs(n);return}}m.closeTabOperNav();var o=h(k+">.layui-tab-title");if(!n){if(o.find("li").first().hasClass("layui-this")){j.msg("主页不能关闭",{icon:2});return}o.find("li.layui-this").find(".layui-tab-close").trigger("click")}else{if(n==o.find("li").first().attr("lay-id")){j.msg("主页不能关闭",{icon:2});return}o.find('li[lay-id="'+n+'"]').find(".layui-tab-close").trigger("click")}},closeOtherTabs:function(n){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeOtherTabs(n);return}}if(!n){h(k+">.layui-tab-title li:gt(0):not(.layui-this)").find(".layui-tab-close").trigger("click")}else{h(k+">.layui-tab-title li:gt(0)").each(function(){if(n!=h(this).attr("lay-id")){h(this).find(".layui-tab-close").trigger("click")}})}m.closeTabOperNav()},closeAllTabs:function(){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeAllTabs();return}}h(k+">.layui-tab-title li:gt(0)").find(".layui-tab-close").trigger("click");h(k+">.layui-tab-title li:eq(0)").trigger("click");m.closeTabOperNav()},closeTabOperNav:function(){if(window!=top&&!m.isTop()){if(top.layui&&top.layui.admin){top.layui.admin.closeTabOperNav();return}}h(".layui-icon-down .layui-nav .layui-nav-child").removeClass("layui-show")},changeTheme:function(t){if(t){layui.data(m.tableName,{key:"theme",value:t});if(c==t){t=undefined}}else{layui.data(m.tableName,{key:"theme",remove:true})}try{m.removeTheme(top);(t&&top.layui)&&top.layui.link(m.getThemeDir()+t+m.getCssSuffix(),t);var u=top.window.frames;for(var p=0;p768){if(!p){var o=h(k+">.layui-tab-content>.layui-tab-item.layui-show>.admin-iframe");if(o.length<=0){o=h(a+">div>.admin-iframe")}if(o.length>0){p=o[0].contentWindow}}try{if(p&&p.layui&&p.layui.jquery){if(window.hsbTimer){clearTimeout(hsbTimer)}p.layui.jquery(".layui-table-body.layui-table-main").addClass("no-scrollbar");window.hsbTimer=setTimeout(function(){if(p&&p.layui&&p.layui.jquery){p.layui.jquery(".layui-table-body.layui-table-main").removeClass("no-scrollbar")}},500)}}catch(n){}}},modelForm:function(o,r,n){var q=h(o);q.addClass("layui-form");if(n){q.attr("lay-filter",n)}var p=q.find(".layui-layer-btn .layui-layer-btn0");p.attr("lay-submit","");p.attr("lay-filter",r)},btnLoading:function(o,p,q){if(p!=undefined&&(typeof p=="boolean")){q=p;p=undefined}(q==undefined)&&(q=true);var n=h(o);if(q){p&&n.html(p);n.find(".layui-icon").addClass("layui-hide");n.addClass("icon-btn");n.prepend('');n.prop("disabled","disabled")}else{n.find(".ew-btn-loading").remove();n.removeProp("disabled","disabled");if(n.find(".layui-icon.layui-hide").length<=0){n.removeClass("icon-btn")}n.find(".layui-icon").removeClass("layui-hide");p&&n.html(p)}},openSideAutoExpand:function(){h(".layui-layout-admin>.layui-side").off("mouseenter.openSideAutoExpand").on("mouseenter.openSideAutoExpand",function(){if(h(this).parent().hasClass("admin-nav-mini")){m.flexible(true);h(this).addClass("side-mini-hover")}});h(".layui-layout-admin>.layui-side").off("mouseleave.openSideAutoExpand").on("mouseleave.openSideAutoExpand",function(){if(h(this).hasClass("side-mini-hover")){m.flexible(false);h(this).removeClass("side-mini-hover")}})},openCellAutoExpand:function(){h("body").off("mouseenter.openCellAutoExpand").on("mouseenter.openCellAutoExpand",".layui-table-view td",function(){h(this).find(".layui-table-grid-down").trigger("click")});h("body").off("mouseleave.openCellAutoExpand").on("mouseleave.openCellAutoExpand",".layui-table-tips>.layui-layer-content",function(){h(".layui-table-tips-c").trigger("click")})},isTop:function(){return h(a).length>0},strToWin:function(q){var p=window;if(q){var n=q.split(".");for(var o=0;o';L+='
    '+I.name+"
    ";L+='
    '+I.address+"
    ";L+='
    ';L+=""}}h("#ew-map-select-pois").html(L)}})})};var n=function(){var C={resizeEnable:true,zoom:A};x&&(C.center=x);var D=new AMap.Map("ew-map-select-map",C);D.on("complete",function(){var E=D.getCenter();u(E.lat,E.lng)});D.on("moveend",function(){if(B){B=false}else{h("#ew-map-select-tips").addClass("layui-hide");h("#ew-map-select-center-img").removeClass("bounceInDown");setTimeout(function(){h("#ew-map-select-center-img").addClass("bounceInDown")});var E=D.getCenter();u(E.lat,E.lng)}});h("#ew-map-select-pois").off("click").on("click",".ew-map-select-search-list-item",function(){h("#ew-map-select-tips").addClass("layui-hide");h("#ew-map-select-pois .ew-map-select-search-list-item-icon-ok").addClass("layui-hide");h(this).find(".ew-map-select-search-list-item-icon-ok").removeClass("layui-hide");h("#ew-map-select-center-img").removeClass("bounceInDown");setTimeout(function(){h("#ew-map-select-center-img").addClass("bounceInDown")});var G=h(this).data("lng");var H=h(this).data("lat");var F=h(this).find(".ew-map-select-search-list-item-title").text();var E=h(this).find(".ew-map-select-search-list-item-address").text();y={name:F,address:E,lat:H,lng:G};B=true;D.setZoomAndCenter(t,[G,H])});h("#ew-map-select-btn-ok").click(function(){if(y==undefined){j.msg("请点击位置列表选择",{icon:2,anim:6})}else{if(w){if(q){var E=j.load(2);D.setCenter([y.lng,y.lat]);D.getCity(function(F){j.close(E);y.city=F;m.closeDialog("#ew-map-select-btn-ok");w(y)})}else{m.closeDialog("#ew-map-select-btn-ok");w(y)}}else{m.closeDialog("#ew-map-select-btn-ok")}}});h("#ew-map-select-input-search").off("input").on("input",function(){var E=h(this).val();if(!E){h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}AMap.plugin("AMap.Autocomplete",function(){var F=new AMap.Autocomplete({city:"全国"});F.search(E,function(I,H){if(H.tips){var G=H.tips;var K="";for(var J=0;J';K+=' ';K+='
    '+L.name+"
    ";K+='
    '+L.address+"
    ";K+=""}}h("#ew-map-select-tips").html(K);if(G.length==0){h("#ew-map-select-tips").addClass("layui-hide")}else{h("#ew-map-select-tips").removeClass("layui-hide")}}else{h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}})})});h("#ew-map-select-input-search").off("blur").on("blur",function(){var E=h(this).val();if(!E){h("#ew-map-select-tips").html("");h("#ew-map-select-tips").addClass("layui-hide")}});h("#ew-map-select-input-search").off("focus").on("focus",function(){var E=h(this).val();if(E){h("#ew-map-select-tips").removeClass("layui-hide")}});h("#ew-map-select-tips").off("click").on("click",".ew-map-select-search-list-item",function(){h("#ew-map-select-tips").addClass("layui-hide");var E=h(this).data("lng");var F=h(this).data("lat");y=undefined;D.setZoomAndCenter(t,[E,F])})};var p='
    ';p+=' 搜索:';p+=' ';p+='
    ';p+="
    ";p+="
    ";p+='
    ';p+='
    ';p+='
    ';p+=' ';p+=' ';p+="
    ";p+='
    ';p+="
    ";p+="
    ";m.open({id:"ew-map-select",type:1,title:o,area:"750px",content:p,success:function(C,E){var D=h(C).children(".layui-layer-content");D.css("overflow","visible");m.showLoading(D);if(undefined==window.AMap){h.getScript(r,function(){n();m.removeLoading(D)})}else{n();m.removeLoading(D)}}})};m.cropImg=function(q){var o="image/jpeg";var v=q.aspectRatio;var w=q.imgSrc;var t=q.imgType;var r=q.onCrop;var s=q.limitSize;var u=q.acceptMime;var p=q.exts;var n=q.title;(v==undefined)&&(v=1/1);(n==undefined)&&(n="裁剪图片");t&&(o=t);layui.use(["Cropper","upload"],function(){var y=layui.Cropper;var x=layui.upload;function z(){var C,D=h("#ew-crop-img");var E={elem:"#ew-crop-img-upload",auto:false,drag:false,choose:function(F){F.preview(function(H,I,G){o=I.type;D.attr("src",G);if(!w||!C){w=G;z()}else{C.destroy();C=new y(D[0],B)}})}};(s!=undefined)&&(E.size=s);(u!=undefined)&&(E.acceptMime=u);(p!=undefined)&&(E.exts=p);x.render(E);if(!w){h("#ew-crop-img-upload").trigger("click");return}var B={aspectRatio:v,preview:"#ew-crop-img-preview"};C=new y(D[0],B);h(".ew-crop-tool").on("click","[data-method]",function(){var G=h(this).data(),H,F;if(!C||!G.method){return}G=h.extend({},G);H=C.cropped;switch(G.method){case"rotate":if(H&&B.viewMode>0){C.clear()}break;case"getCroppedCanvas":if(o==="image/jpeg"){if(!G.option){G.option={}}G.option.fillColor="#fff"}break}F=C[G.method](G.option,G.secondOption);switch(G.method){case"rotate":if(H&&B.viewMode>0){C.crop()}break;case"scaleX":case"scaleY":h(this).data("option",-G.option);break;case"getCroppedCanvas":if(F){r&&r(F.toDataURL(o));m.closeDialog("#ew-crop-img")}else{j.msg("裁剪失败",{icon:2,anim:6})}break}})}var A='
    ';A+='
    ';A+=' ';A+="
    ";A+='
    ';A+='
    ';A+="
    ";A+="
    ";A+='
    ';A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+='
    ';A+=' ';A+=' ';A+="
    ";A+=' ';A+="
    ";m.open({title:n,area:"665px",type:1,content:A,success:function(B,C){h(B).children(".layui-layer-content").css("overflow","visible");z()}})})};m.util={Convert_BD09_To_GCJ02:function(o){var q=(3.141592653589793*3000)/180;var n=o.lng-0.0065,s=o.lat-0.006;var r=Math.sqrt(n*n+s*s)-0.00002*Math.sin(s*q);var p=Math.atan2(s,n)-0.000003*Math.cos(n*q);o.lng=r*Math.cos(p);o.lat=r*Math.sin(p);return o},Convert_GCJ02_To_BD09:function(o){var q=(3.141592653589793*3000)/180;var n=o.lng,s=o.lat;var r=Math.sqrt(n*n+s*s)+0.00002*Math.sin(s*q);var p=Math.atan2(s,n)+0.000003*Math.cos(n*q);o.lng=r*Math.cos(p)+0.0065;o.lat=r*Math.sin(p)+0.006;return o},animateNum:function(D,x,F,v){var r=h(D);var s=r.text().replace(/,/g,"");x=x===null||x===undefined||x===true||x==="true";F=isNaN(F)?500:F;v=isNaN(v)?100:v;var z="INPUT,TEXTAREA".indexOf(r.get(0).tagName)>=0;var t=function(J){var H="";for(var I=0;I=0;I--){if(!isNaN(J.charAt(I))){return H}else{H=J.charAt(I)+H}}},C=function(I,H){if(!H){return I}if(!/^[0-9]+.?[0-9]*$/.test(I)){return I}I=I.toString();return I.replace(I.indexOf(".")>0?/(\d)(?=(\d{3})+(?:\.))/g:/(\d)(?=(\d{3})+(?:$))/g,"$1,")};var G=t(s.toString());var p=A(s.toString());var q=s.toString().replace(G,"").replace(p,"");if(isNaN(q)||q===0){z?r.val(s):r.html(s);console.error("非法数值!");return}var u=q.split(".");var o=u[1]?u[1].length:0;var n=0,y=q;if(Math.abs(y)>10){n=parseFloat(u[0].substring(0,u[0].length-1)+(u[1]?".0"+u[1]:""))}var w=(y-n)/v,E=0;var B=setInterval(function(){var H=G+C(n.toFixed(o),x)+p;z?r.val(H):r.html(H);n+=w;E++;if(Math.abs(n)>=Math.abs(y)||E>5000){H=G+C(y,x)+p;z?r.val(H):r.html(H);clearInterval(B)}},F/v)},deepClone:function(q){var n;var o=m.util.isClass(q);if(o==="Object"){n={}}else{if(o==="Array"){n=[]}else{return q}}for(var p in q){var r=q[p];if(m.util.isClass(r)=="Object"){n[p]=arguments.callee(r)}else{if(m.util.isClass(r)=="Array"){n[p]=arguments.callee(r)}else{n[p]=q[p]}}}return n},isClass:function(n){if(n===null){return"Null"}if(n===undefined){return"Undefined"}return Object.prototype.toString.call(n).slice(8,-1)},fullTextIsEmpty:function(q){if(!q){return true}var o=["img","audio","video","iframe","object"];for(var n=0;n-1){return false}}var p=q.replace(/\s*/g,"");if(!p){return true}p=p.replace(/ /ig,"");if(!p){return true}p=p.replace(/<[^>]+>/g,"");if(!p){return true}return false}};var l=".layui-layout-admin.admin-nav-mini>.layui-side .layui-nav .layui-nav-item";h(document).on("mouseenter",l+","+l+" .layui-nav-child>dd",function(){if(m.getPageWidth()>768){var o=h(this),q=o.find(">.layui-nav-child");if(q.length>0){o.addClass("admin-nav-hover");q.css("left",o.offset().left+o.outerWidth());var p=o.offset().top;if(p+q.outerHeight()>m.getPageHeight()){p=p-q.outerHeight()+o.outerHeight();(p<60)&&(p=60);q.addClass("show-top")}q.css("top",p);q.addClass("ew-anim-drop-in")}else{if(o.hasClass("layui-nav-item")){var n=o.find("cite").text();j.tips(n,o,{tips:[2,"#303133"],time:-1,success:function(r,s){h(r).css("margin-top","12px")}})}}}}).on("mouseleave",l+","+l+" .layui-nav-child>dd",function(){j.closeAll("tips");var o=h(this);o.removeClass("admin-nav-hover");var n=o.find(">.layui-nav-child");n.removeClass("show-top ew-anim-drop-in");n.css({"left":"unset","top":"unset"})});h(document).on("click","*[ew-event]",function(){var n=h(this).attr("ew-event");var o=m.events[n];o&&o.call(this,h(this))});h(document).on("mouseenter","*[lay-tips]",function(){var n=h(this).attr("lay-tips");var o=h(this).attr("lay-direction");var p=h(this).attr("lay-bg");var q=h(this).attr("lay-offset");j.tips(n,this,{tips:[o||1,p||"#303133"],time:-1,success:function(r,s){if(q){q=q.split(",");var u=q[0],t=q.length>1?q[1]:undefined;u&&(h(r).css("margin-top",u));t&&(h(r).css("margin-left",t))}}})}).on("mouseleave","*[lay-tips]",function(){j.closeAll("tips")});if(m.getPageWidth()<768){if(layui.device().os=="windows"){h("body").append("")}}h(document).on("click","*[ew-href]",function(){var n=h(this).attr("ew-href");var o=h(this).attr("ew-title");o||(o=h(this).text());if(top.layui&&top.layui.index){top.layui.index.openTab({title:o?o:"",url:n})}else{location.href=n}});var g=layui.data(m.tableName);if(g&&g.theme){(g.theme==c)||layui.link(m.getThemeDir()+g.theme+m.getCssSuffix(),g.theme)}else{if(c!=m.defaultTheme){layui.link(m.getThemeDir()+m.defaultTheme+m.getCssSuffix(),m.defaultTheme)}}if(!layui.contextMenu){h(document).off("click.ctxMenu").on("click.ctxMenu",function(){try{var q=top.window.frames;for(var n=0;n.ctxMenu").remove()}catch(p){}}try{(top.layui&&top.layui.jquery)&&top.layui.jquery("body>.ctxMenu").remove()}catch(p){}}catch(p){}})}f("admin",m)}); \ No newline at end of file diff --git a/public/catch-admin/assets/module/authtree/authtree.js b/public/catch-admin/assets/module/authtree/authtree.js index a33181c..b18a46b 100755 --- a/public/catch-admin/assets/module/authtree/authtree.js +++ b/public/catch-admin/assets/module/authtree/authtree.js @@ -85,7 +85,7 @@ layui.define(['jquery', 'form'], function (exports) { opt.checkSkin = opt.checkSkin ? opt.checkSkin : 'primary'; // 主题定制 opt.theme = opt.theme ? opt.theme : ''; - opt.themePath = opt.themePath ? opt.themePath : 'layui_exts/tree_themes/'; + opt.themePath = opt.themePath ? opt.themePath : 'catch-admin/assets/module/authtree/tree_themes/'; // 展开、折叠节点的前显字符配置 opt.openIconContent = opt.openIconContent ? opt.openIconContent : ''; this.openIconContent = opt.openIconContent; diff --git a/public/catch-admin/assets/module/authtree/tree_themes/auth-skin-default.css b/public/catch-admin/assets/module/authtree/tree_themes/auth-skin-default.css index ad2d858..314e374 100755 --- a/public/catch-admin/assets/module/authtree/tree_themes/auth-skin-default.css +++ b/public/catch-admin/assets/module/authtree/tree_themes/auth-skin-default.css @@ -29,9 +29,9 @@ Version: v1.0.0 -webkit-border-radius: 5px; border-radius: 5px; display: inline-block; - padding: 3px 8px; + padding: 3px 3px; text-decoration: none; - + font-size: 12px; position: relative; top: -3px; } diff --git a/public/catch-admin/assets/module/treetable-lay/treeTable.css b/public/catch-admin/assets/module/treetable-lay/treeTable.css new file mode 100755 index 0000000..5743390 --- /dev/null +++ b/public/catch-admin/assets/module/treetable-lay/treeTable.css @@ -0,0 +1,275 @@ +/** + * 树形表格 2.x + * date:2019-11-08 License By https://easyweb.vip + */ +.ew-tree-table { + margin: 10px 0; + position: relative +} + +.ew-tree-table .layui-table { + margin: 0 +} + +.ew-tree-table .ew-tree-table-border { + position: absolute; + background-color: #e6e6e6 +} + +.ew-tree-table .ew-tree-table-border.top { + left: 0; + right: 0; + top: 0; + height: 1px +} + +.ew-tree-table .ew-tree-table-border.left { + top: 0; + left: 0; + bottom: 0; + width: 1px +} + +.ew-tree-table .ew-tree-table-border.right { + top: 0; + right: 0; + bottom: 0; + width: .52px +} + +.ew-tree-table .ew-tree-table-border.bottom { + left: 0; + right: 0; + bottom: 0; + height: .52px +} + +.ew-tree-table-group { + overflow: auto; + position: relative +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box { + overflow: auto; + position: relative; + box-sizing: border-box +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-head { + position: relative; + box-sizing: border-box; + background-color: #f2f2f2 +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box > .layui-table, .ew-tree-table > .ew-tree-table-group > .ew-tree-table-head > .layui-table { + table-layout: fixed +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box > .ew-tree-table-loading { + padding: 10px 0; + text-align: center +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box > .ew-tree-table-loading > i { + color: #999; + font-size: 30px +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box > .ew-tree-table-loading.ew-loading-float { + position: absolute; + left: 0; + right: 0; + top: 0 +} + +.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box > .ew-tree-table-empty { + color: #666; + font-size: 14px; + text-align: center +} + +.ew-tree-table .ew-tree-table-arrow { + margin-right: 5px; + vertical-align: middle +} + +.ew-tree-table .ew-tree-table-arrow:before { + content: "\e623" +} + +.ew-tree-table .ew-tree-table-open .ew-tree-table-arrow:before { + content: "\e625" +} + +.ew-tree-table .ew-tree-table-arrow.arrow2 { + font-size: 13px; + font-weight: 600; + line-height: 16px; + height: 16px; + width: 16px; + display: inline-block; + text-align: center; + color: #888 +} + +.ew-tree-table .ew-tree-table-arrow.arrow2:before { + content: "\e602" +} + +.ew-tree-table .ew-tree-table-open .ew-tree-table-arrow.arrow2:before { + content: "\e61a" +} + +.ew-tree-table-arrow.ew-tree-table-arrow-hide { + visibility: hidden +} + +.ew-tree-table .ew-tree-table-loading > td > .ew-tree-pack > .ew-tree-table-arrow:before { + content: "\e63d" !important +} + +.ew-tree-table .ew-tree-table-loading > td > .ew-tree-pack > .ew-tree-table-arrow { + margin-right: 0 +} + +.ew-tree-table .ew-tree-table-loading > td > .ew-tree-pack > .ew-tree-table-arrow + * { + margin-left: 5px +} + +.ew-tree-table tr.ew-tree-table-loading > * { + pointer-events: none !important +} + +.ew-tree-table .ew-tree-pack { + cursor: pointer; + line-height: 16px; + display: inline-block; + vertical-align: middle +} + +.ew-tree-table .ew-tree-pack > span { + height: 16px; + line-height: 16px; + display: inline-block; + vertical-align: middle +} + +.ew-tree-table .ew-tree-tb-hide { + display: none +} + +.ew-tree-table .ew-tree-table-indent { + margin-right: 5px; + padding-left: 16px +} + +.ew-tree-table .ew-tree-icon { + margin-right: 5px; + display: inline-block; + vertical-align: middle +} + +.ew-tree-table .ew-tree-icon-folder, .ew-tree-table .ew-tree-icon-file { + width: 22px; + height: 16px; + line-height: 16px; + position: relative +} + +.ew-tree-table .ew-tree-icon-folder:after, .ew-tree-table .ew-tree-icon-file:after { + content: ""; + width: 22px; + height: 22px; + position: absolute; + left: 0; + top: -3px; + background-size: cover; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyMzE3MTQ3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIxNTgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNjQiIGhlaWdodD0iNjQiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTE4MSA4MjNoLTMxLjFjLTI4LjYgMC01MS45LTIzLjItNTEuOS01MS45VjI1Mi40YzAtMjguNiAyMy4yLTUxLjkgNTEuOS01MS45SDQzMGw4MyA3Ny44aDMzMmM0NS42IDAgODMgMzUgODMgNzcuOHYzODkuMWMwIDQyLjgtMzcuMyA3Ny44LTgzIDc3LjhIMTgxeiIgcC1pZD0iMjE1OSIgZmlsbD0iI0ZGQTUwMCI+PC9wYXRoPjwvc3ZnPg==") +} + +.ew-tree-table tr.ew-tree-table-open > td > .ew-tree-pack .ew-tree-icon-folder:after { + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyMzA5MDQwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE5NzciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNjQiIGhlaWdodD0iNjQiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTMyNi40IDQ2MC4xSDkyOGwtODIuMyAzMjRjLTUuOCAyMy0yNi42IDM5LjEtNTAuMyAzOS4xSDE0OS45Yy0yOC42IDAtNTEuOS0yMy4yLTUxLjktNTEuOVYyNTIuNmMwLTI4LjYgMjMuMi01MS45IDUxLjktNTEuOUg0MTNsMTA1IDEwMy43aDI5MS44YzE0LjMgMCAyNS45IDExLjYgMjUuOSAyNS45djc3LjhoLTUyN0wyMDMuNCA1NjMuOWg1Mi43bDcwLjMtMTAzLjh6IiBwLWlkPSIxOTc4IiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PC9zdmc+") +} + +.ew-tree-table .ew-tree-icon-file:after { + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc0MDYyNTE1MDUxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEzNTE4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0Ij48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwvc3R5bGU+PC9kZWZzPjxwYXRoIGQ9Ik03NDEuMyAxNjEuNmgtNDIuNGMtMTAuNSAwLTE5LjEgOC42LTE5LjEgMTkuMXM4LjYgMTkuMSAxOS4xIDE5LjFoNDIuNGM0MiAwIDc2LjIgMzQuMiA3Ni4yIDc2LjN2NDc3LjRjMCA0Mi4xLTM0LjMgNzYuMy03Ni40IDc2LjNIMjgyLjljLTQyLjEgMC03Ni4zLTM0LjItNzYuMy03Ni4zVjI3Ni4xYzAtNDIuMSAzNC4yLTc2LjMgNzYuMy03Ni4zaDQ0LjljMTAuNSAwIDE5LjEtOC42IDE5LjEtMTkuMXMtOC42LTE5LjEtMTkuMS0xOS4xaC00NC45Yy02My4xIDAtMTE0LjUgNTEuNC0xMTQuNSAxMTQuNXY0NzcuNGMwIDYzLjEgNTEuNCAxMTQuNSAxMTQuNSAxMTQuNWg0NTguM2M2My4xIDAgMTE0LjUtNTEuNCAxMTQuNS0xMTQuNVYyNzYuMWMtMC4xLTYzLjEtNTEuNC0xMTQuNS0xMTQuNC0xMTQuNXoiIHAtaWQ9IjEzNTE5IiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PHBhdGggZD0iTTY4MC42IDUwNS4zSDM0My40Yy0xMi4zIDAtMjIuMyA4LjYtMjIuMyAxOS4xczEwIDE5LjEgMjIuMyAxOS4xaDMzNy4yYzEyLjMgMCAyMi4zLTguNiAyMi4zLTE5LjEgMC0xMC42LTEwLTE5LjEtMjIuMy0xOS4xek00MzkuMyAyMTMuM2gxNDQuNmMxOSAwIDM0LjQtMTIuOCAzNC40LTI4LjZzLTE1LjQtMjguNi0zNC40LTI4LjZINDM5LjNjLTE5IDAtMzQuNCAxMi44LTM0LjQgMjguNi0wLjEgMTUuNyAxNS4zIDI4LjYgMzQuNCAyOC42ek02ODAuNiA2NThIMzQzLjRjLTEyLjMgMC0yMi4zIDguNS0yMi4zIDE5LjEgMCAxMC41IDEwIDE5LjEgMjIuMyAxOS4xaDMzNy4yYzEyLjMgMCAyMi4zLTguNiAyMi4zLTE5LjEgMC0xMC42LTEwLTE5LjEtMjIuMy0xOS4xek02ODAuNiAzNTIuNUgzNDMuNGMtMTIuMyAwLTIyLjMgOC42LTIyLjMgMTkuMXMxMCAxOS4xIDIyLjMgMTkuMWgzMzcuMmMxMi4zIDAgMjIuMy04LjYgMjIuMy0xOS4xIDAtMTAuNS0xMC0xOS4xLTIyLjMtMTkuMXoiIHAtaWQ9IjEzNTIwIiBmaWxsPSIjRkZBNTAwIj48L3BhdGg+PC9zdmc+") +} + +.ew-tree-table .layui-form-switch { + margin-top: 0 +} + +.ew-tree-table .layui-form-radio { + margin: 0 +} + +.ew-tree-table-checkbox + .layui-form-checkbox { + padding: 0 +} + +.ew-tree-table-checkbox + .layui-form-checkbox > .layui-icon { + color: transparent; + transition: background-color .1s linear +} + +.ew-tree-table-checkbox + .layui-form-checkbox.layui-form-checked > .layui-icon { + color: #fff +} + +.ew-tree-table-radio + .layui-form-radio { + padding: 0; + height: 20px; + line-height: 20px +} + +.ew-tree-table-radio + .layui-form-radio > i { + margin: 0; + height: 20px; + font-size: 20px; + line-height: 20px +} + +.ew-tree-table .layui-form-checked.ew-form-indeterminate > .layui-icon:before { + content: ""; + width: 9px; + height: 2px; + display: inline-block; + background-color: #eee; + vertical-align: middle +} + +.ew-tree-table .layui-form-checked.ew-form-indeterminate > .layui-icon { + line-height: 14px +} + +.ew-tree-table .layui-table td[data-edit] { + cursor: text +} + +.ew-tree-table .ew-tree-table-edit { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + border-radius: 0; + box-shadow: 1px 1px 20px rgba(0, 0, 0, .15) +} + +.ew-tree-table .ew-tree-table-edit:focus { + border-color: #5fb878 !important +} + +.ew-tree-table .ew-tree-table-edit.layui-form-danger { + border-color: #ff5722 !important +} + +.ew-tree-table td[data-type="numbers"] { + padding-left: 0; + padding-right: 0; + text-align: center +} + +.ew-tree-table tr.ew-tree-table-filter-hide { + display: none !important +} \ No newline at end of file diff --git a/public/catch-admin/assets/module/treetable-lay/treeTable.js b/public/catch-admin/assets/module/treetable-lay/treeTable.js new file mode 100755 index 0000000..6a84e98 --- /dev/null +++ b/public/catch-admin/assets/module/treetable-lay/treeTable.js @@ -0,0 +1,1388 @@ +/** + * 树形表格 2.x + * date:2019-11-08 License By http://easyweb.vip + */ +layui.define(['layer', 'laytpl', 'form'], function (exports) { + var $ = layui.jquery; + var layer = layui.layer; + var laytpl = layui.laytpl; + var form = layui.form; + var device = layui.device(); + var MOD_NAME = 'treeTable'; // 绑定事件的模块名 + layui.link(layui.cache.base + 'treetable-lay/treeTable.css'); + + /** TreeTable类构造方法 */ + var TreeTable = function (options) { + // 表格默认参数 + var defaultOption = { + elem: undefined, // table容器 + data: [], // 数据 + cols: [], // 列配置 + reqData: undefined, // 异步加载数据的方法 + width: undefined, // 容器宽度 + height: undefined, // 容器高度 + cellMinWidth: 100, // 单元格最小宽度 + skin: undefined, // 表格风格 + size: undefined, // 表格尺寸 + even: undefined, // 是否开启隔行变色 + style: undefined, // 容器样式 + getThead: function () { // 获取表头 + return getThead(this); + }, + getAllChooseBox: function () { // 获取全选按钮 + return getAllChooseBox(this); + }, + getColgroup: function () { // 获取colgroup + return getColgroup(this); + }, + getTbWidth: function () { // 计算table的宽度 + return getTbWidth(this); + }, + tree: {}, + text: {} + }; + // 默认tree参数 + var treeDefaultOption = { + idName: 'id', // id的字段名 + pidName: 'pid', // pid的字段名 + childName: 'children', // children的字段名 + haveChildName: 'haveChild', // 是否有children标识的字段名 + openName: 'open', // 是否默认展开的字段名 + isPidData: false, // 是否是pid形式的数据 + iconIndex: 0, // 图标列的索引 + arrowType: undefined, // 箭头类型 + onlyIconControl: false, // 仅允许点击图标折叠 + getIcon: function (d) { // 自定义图标 + return getIcon(d, this); + } + }; + // 默认提示文本 + var textDefaultOption = { + none: '
    暂无数据
    ' // 空文本提示文字 + }; + this.options = $.extend(defaultOption, options); + this.options.tree = $.extend(treeDefaultOption, options.tree); + this.options.text = $.extend(textDefaultOption, options.text); + for (var i = 0; i < options.cols.length; i++) { + // 列默认参数 + var colDefaultOption = { + field: undefined, // 字段名 + title: undefined, // 标题 + align: undefined, // 对齐方式 + templet: undefined, // 自定义模板 + toolbar: undefined, // 工具列 + width: undefined, // 宽度 + type: undefined, // 列类型 + style: undefined, // 单元格样式 + fixed: undefined, // 固定列 + unresize: false // 关闭拖拽列宽 + }; + this.options.cols[i] = $.extend(colDefaultOption, options.cols[i]); + } + this.init(); // 初始化表格 + this.bindEvents(); // 绑定事件 + }; + + /** 初始化表格 */ + TreeTable.prototype.init = function () { + var options = this.options; + var tbFilter = options.elem.substring(1); // 树表格的filter + var $elem = $(options.elem); // 原始表格 + + // 生成树表格dom + $elem.removeAttr('lay-filter'); + $elem.next('.ew-tree-table').remove(); + var viewHtml = '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += ' '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += ' '; + viewHtml += '
    '; + viewHtml += ' '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += '
    '; + viewHtml += ' '; + $elem.after(viewHtml); + + // 获取各个组件 + var components = this.getComponents(); + var $view = components.$view; // 容器 + $view.attr('lay-filter', tbFilter); + var $group = components.$group; // 表格容器 + var $tbBox = components.$tbBox; // 表格主体部分容器 + var $table = components.$table; // 主体表格 + var $headTb = components.$headTb; // 表头表格 + var $tbEmpty = components.$tbEmpty; // 空视图 + var $tbLoading = components.$tbLoading; // 空视图 + + // 基础参数设置 + options.width && $view.css('width', options.width); + options.skin && $table.attr('lay-skin', options.skin); + options.size && $table.attr('lay-size', options.size); + options.even && $table.attr('lay-even', options.even); + + // 容器边框调整 + if (device.ie) { + $view.find('.ew-tree-table-border.bottom').css('height', '1px'); + $view.find('.ew-tree-table-border.right').css('width', '1px'); + } + + // 计算表格宽度 + var tbWidth = options.getTbWidth(); + $tbBox.css('min-width', tbWidth.minWidth); + $headTb.parent().css('min-width', tbWidth.minWidth); + if (tbWidth.setWidth) { + $tbBox.css('width', tbWidth.width); + $headTb.parent().css('width', tbWidth.width); + } + + // 渲染表结构及表头 + var colgroupHtmlStr = options.getColgroup(); + var headHtmlStr = colgroupHtmlStr + '' + options.getThead() + ''; + if (options.height) { // 固定表头 + $table.html(colgroupHtmlStr + ''); + $headTb.html(headHtmlStr); + $table.css('margin-top', '-1px'); + if (options.height.indexOf('full-') == 0) { // 差值高度 + var h = parseFloat(options.height.substring(5)); + var cssStr = ''; + $tbBox.after(cssStr); + $tbBox.attr('ew-tree-full', h); + } else { // 固定高度 + $tbBox.css('height', options.height); + } + } else { + $table.html(headHtmlStr + ''); + } + form.render('checkbox', tbFilter); // 渲染表头的表单元素 + + // 渲染数据 + if (options.reqData) { // 异步加载 + this.renderBodyAsync(); + } else { // 一次性渲染 + if (options.data && options.data.length > 0) { + // 处理数据 + if (options.tree.isPidData) { // pid形式数据 + treeTb.pidToChildren(options.data, options.tree.idName, options.tree.pidName, options.tree.childName); + } else { // children形式数据 + addPidField(options.data, options.tree); + } + $table.children('tbody').html(this.renderBody(options.data)); + $tbLoading.hide(); + this.renderNumberCol(); // 渲染序号列 + form.render(null, tbFilter); // 渲染表单元素 + this.checkChooseAllCB(); // 联动全选框 + updateFixedTbHead($view); + } else { + $tbLoading.hide(); + $tbEmpty.show(); + } + } + }; + + /** 绑定各项事件 */ + TreeTable.prototype.bindEvents = function () { + var that = this; + var options = this.options; + var components = this.getComponents(); + var $view = components.$view; + var $table = components.$table; + var $tbEmpty = components.$tbEmpty; + var tbFilter = components.tbFilter; + var checkboxFilter = components.checkboxFilter; + var radioFilter = components.radioFilter; + var cbAllFilter = components.cbAllFilter; + var $tbody = $table.children('tbody'); + + /** 行事件公共返回对象 */ + var commonMember = function (ext) { + var $tr = $(this); + if (!$tr.is('tr')) { + $tr = $tr.parentsUntil('tr[data-id]').parent(); + } + var id = $tr.data('id'); + var data = getDataById(options.data, id, options.tree); + var obj = { + tr: $tr, // 当前行 + data: data, //当前行数据 + del: function () { // 删除行 + var indent = parseInt(this.tr.data('indent')); + this.tr.nextAll('tr').each(function () { + if (parseInt($(this).data('indent')) <= indent) { + return false; + } + $(this).remove(); + }); + var $parentTr = this.tr.prevAll('tr'); + this.tr.remove(); + delDataById(options.data, id, options.tree); + if (!options.data || options.data.length <= 0) { + $tbEmpty.show(); + } + that.renderNumberCol(); // 渲染序号列 + // 联动父级 + $parentTr.each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < indent) { + that.checkParentCB($(this)); + indent = tInd; + } + }); + that.checkChooseAllCB(); // 联动全选框 + }, + update: function (fields) { // 修改行 + data = $.extend(data, fields); + var indent = parseInt(this.tr.data('indent')); + that.renderBodyTr(data, indent, undefined, this.tr); + form.render(null, tbFilter); // 渲染表单元素 + that.checkIndeterminateCB(); // 恢复半选框状态 + that.checkChooseAllCB(); // 联动全选框 + } + }; + return $.extend(obj, ext); + }; + + // 绑定折叠展开事件 + $tbody.off('click.fold').on('click.fold', '.ew-tree-pack', function (e) { + layui.stope(e); + var $tr = $(this).parent().parent(); + if ($tr.hasClass('ew-tree-table-loading')) { // 已是加载中 + return; + } + var haveChild = $tr.data('have-child'); + if (haveChild != true && haveChild != 'true') { // 子节点 + return; + } + var id = $tr.data('id'); + var isOpen = $tr.hasClass('ew-tree-table-open'); + var data = getDataById(options.data, id, options.tree); + if (!isOpen && (!data[options.tree.childName] || data[options.tree.childName].length <= 0)) { + that.renderBodyAsync(data, $tr); + } else { + toggleRow($tr); + } + }); + + // 绑定lay-event事件 + $tbody.off('click.tool').on('click.tool', '*[lay-event]', function (e) { + layui.stope(e); + var $this = $(this); + layui.event.call(this, MOD_NAME, 'tool(' + tbFilter + ')', commonMember.call(this, { + event: $this.attr('lay-event') + })); + }); + + // 绑定单选框事件 + form.on('radio(' + radioFilter + ')', function (data) { + var d = getDataById(options.data, data.value, options.tree); + that.removeAllChecked(); + d.LAY_CHECKED = true; // 同时更新数据 + layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', {checked: true, data: d, type: 'one'}); + }); + + // 绑定复选框事件 + form.on('checkbox(' + checkboxFilter + ')', function (data) { + var checked = data.elem.checked; + var $cb = $(data.elem); + var $layCb = $cb.next('.layui-form-checkbox'); + // 如果是半选状态,点击全选 + if (!checked && $layCb.hasClass('ew-form-indeterminate')) { + checked = true; + $cb.prop('checked', checked); + $cb.data('indeterminate', 'false'); + $layCb.addClass('layui-form-checked'); + $layCb.removeClass('ew-form-indeterminate'); + } + var d = getDataById(options.data, data.value, options.tree); + d.LAY_CHECKED = checked; // 同时更新数据 + // 联动操作 + var $tr = $cb.parentsUntil('tr').parent(); + if (d[options.tree.childName] && d[options.tree.childName].length > 0) { + that.checkSubCB($tr, checked); // 联动子级 + } + var indent = parseInt($tr.data('indent')); + $tr.prevAll('tr').each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < indent) { + that.checkParentCB($(this)); // 联动父级 + indent = tInd; + } + }); + that.checkChooseAllCB(); // 联动全选框 + // 回调事件 + layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', { + checked: checked, + data: d, + type: 'one' + }); + }); + + // 绑定全选复选框事件 + form.on('checkbox(' + cbAllFilter + ')', function (data) { + var checked = data.elem.checked; + var $cb = $(data.elem); + var $layCb = $cb.next('.layui-form-checkbox'); + if (!options.data || options.data.length <= 0) { // 如果数据为空 + $cb.prop('checked', false); + $cb.data('indeterminate', 'false'); + $layCb.removeClass('layui-form-checked ew-form-indeterminate'); + return; + } + // 如果是半选状态,点击全选 + if (!checked && $layCb.hasClass('ew-form-indeterminate')) { + checked = true; + $cb.prop('checked', checked); + $cb.data('indeterminate', 'false'); + $layCb.addClass('layui-form-checked'); + $layCb.removeClass('ew-form-indeterminate'); + } + layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', { + checked: checked, + data: undefined, + type: 'all' + }); + that.checkSubCB($table.children('tbody'), checked); // 联动操作 + }); + + // 绑定行单击事件 + $tbody.off('click.row').on('click.row', 'tr', function () { + layui.event.call(this, MOD_NAME, 'row(' + tbFilter + ')', commonMember.call(this, {})); + }); + + // 绑定行双击事件 + $tbody.off('dblclick.rowDouble').on('dblclick.rowDouble', 'tr', function () { + layui.event.call(this, MOD_NAME, 'rowDouble(' + tbFilter + ')', commonMember.call(this, {})); + }); + + // 绑定单元格点击事件 + $tbody.off('click.cell').on('click.cell', 'td', function (e) { + var $td = $(this); + var type = $td.data('type'); + // 判断是否是复选框、单选框列 + if (type == 'checkbox' || type == 'radio') { + layui.stope(e); + return; + } + var edit = $td.data('edit'); + var field = $td.data('field'); + if (edit) { // 开启了单元格编辑 + layui.stope(e); + if ($tbody.find('.ew-tree-table-edit').length > 0) { + return; + } + var index = $td.data('index'); + var indentSize = $td.children('.ew-tree-table-indent').length; + var id = $td.parent().data('id'); + var d = getDataById(options.data, id, options.tree); + if ('text' == edit || 'number' == edit) { // 文本框 + var $input = $(''); + $input[0].value = d[field]; + $td.append($input); + $input.focus(); + $input.blur(function () { + var value = $(this).val(); + if (value == d[field]) { + $(this).remove(); + return; + } + var rs = layui.event.call(this, MOD_NAME, 'edit(' + tbFilter + ')', commonMember.call(this, { + value: value, + field: field + })); + if (rs == false) { + $(this).addClass('layui-form-danger'); + $(this).focus(); + } else { + d[field] = value; // 同步更新数据 + that.renderBodyTd(d, indentSize, index, $td); // 更新单元格 + } + }); + } else { + console.error('不支持的单元格编辑类型:' + edit); + } + } else { // 回调单元格点击事件 + var rs = layui.event.call(this, MOD_NAME, 'cell(' + tbFilter + ')', commonMember.call(this, { + td: $td, + field: field + })); + if (rs == false) { + layui.stope(e); + } + } + }); + + // 绑定单元格双击事件 + $tbody.off('dblclick.cellDouble').on('dblclick.cellDouble', 'td', function (e) { + var $td = $(this); + var type = $td.data('type'); + // 判断是否是复选框、单选框列 + if (type == 'checkbox' || type == 'radio') { + layui.stope(e); + return; + } + var edit = $td.data('edit'); + var field = $td.data('field'); + if (edit) { // 开启了单元格编辑 + layui.stope(e); + } else { // 回调单元格双击事件 + var rs = layui.event.call(this, MOD_NAME, 'cellDouble(' + tbFilter + ')', commonMember.call(this, { + td: $td, + field: field + })); + if (rs == false) { + layui.stope(e); + } + } + }); + + // 列宽拖拽调整 + /*$view.off('mousedown.resize').on('mousedown.resize', '.ew-tb-resize', function (e) { + layui.stope(e); + var index = $(this).parent().data('index'); + $(this).data('move', 'true'); + $(this).data('x', e.clientX); + var w = $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width'); + $(this).data('width', w); + }); + $view.off('mousemove.resize').on('mousemove.resize', '.ew-tb-resize', function (e) { + layui.stope(e); + var move = $(this).data('move'); + if ('true' == move) { + var x = $(this).data('x'); + var w = $(this).data('width'); + var index = $(this).parent().data('index'); + var nw = parseFloat(w) + e.clientX - parseFloat(x); + $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width', nw); + } + }); + $view.off('mouseup.resize').on('mouseup.resize', '.ew-tb-resize', function (e) { + layui.stope(e); + $(this).data('move', 'false'); + }); + $view.off('mouseleave.resize').on('mouseleave.resize', '.ew-tb-resize', function (e) { + layui.stope(e); + $(this).data('move', 'false'); + });*/ + + }; + + /** 获取各个组件 */ + TreeTable.prototype.getComponents = function () { + var $view = $(this.options.elem).next(); // 容器 + var $group = $view.children('.ew-tree-table-group'); // 表格容器 + var $tbBox = $group.children('.ew-tree-table-box'); // 表格主体部分容器 + var $table = $tbBox.children('.layui-table'); // 主体表格 + var $headTb = $group.children('.ew-tree-table-head').children('.layui-table'); // 表头表格 + var $tbEmpty = $tbBox.children('.ew-tree-table-empty'); // 空视图 + var $tbLoading = $tbBox.children('.ew-tree-table-loading'); // 加载视图 + var tbFilter = $view.attr('lay-filter'); // 容器filter + var checkboxFilter = 'ew_tb_checkbox_' + tbFilter; // 复选框filter + var radioFilter = 'ew_tb_radio_' + tbFilter; // 单选框filter + var cbAllFilter = 'ew_tb_choose_all_' + tbFilter; // 全选按钮filter + return { + $view: $view, + $group: $group, + $tbBox: $tbBox, + $table: $table, + $headTb: $headTb, + $tbEmpty: $tbEmpty, + $tbLoading: $tbLoading, + tbFilter: tbFilter, + checkboxFilter: checkboxFilter, + radioFilter: radioFilter, + cbAllFilter: cbAllFilter + }; + }; + + /** + * 递归渲染表格主体部分 + * @param data 数据列表 + * @param indentSize 缩进大小 + * @param isHide 是否默认隐藏 + * @returns {string} + */ + TreeTable.prototype.renderBody = function (data, indentSize, isHide) { + var options = this.options; + var treeOption = options.tree; + indentSize || (indentSize = 0); + var htmlStr = ''; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + htmlStr += this.renderBodyTr(d, indentSize, isHide); + // 递归渲染子集 + var children = d[treeOption.childName]; + if (children && children.length > 0) { + htmlStr += this.renderBody(children, indentSize + 1, !d[treeOption.openName]); + } + } + return htmlStr; + }; + + /** + * 渲染一行数据 + * @param d 行数据 + * @param option 配置 + * @param indentSize 缩进大小 + * @param isHide 是否隐藏 + * @param $tr + * @returns {string} + */ + TreeTable.prototype.renderBodyTr = function (d, indentSize, isHide, $tr) { + var options = this.options; + var cols = options.cols; + var treeOption = options.tree; + indentSize || (indentSize = 0); + var htmlStr = ''; + var haveChild = getHaveChild(d, treeOption); + if ($tr) { + $tr.data('pid', d[treeOption.pidName] || ''); + $tr.data('have-child', haveChild); + $tr.data('indent', indentSize); + $tr.removeClass('ew-tree-table-loading'); + } else { + var classNames = ''; + if (haveChild && d[treeOption.openName]) { + classNames += 'ew-tree-table-open'; + } + if (isHide) { + classNames += 'ew-tree-tb-hide'; + } + htmlStr += ''; + } + for (var j = 0; j < cols.length; j++) { + var $td; + if ($tr) { + $td = $tr.children('td').eq(j); + } + htmlStr += this.renderBodyTd(d, indentSize, j, $td); + } + htmlStr += ''; + return htmlStr; + }; + + /** + * 渲染每一个单元格数据 + * @param d 行数据 + * @param indentSize 缩进大小 + * @param index 第几列 + * @param $td + * @returns {string} + */ + TreeTable.prototype.renderBodyTd = function (d, indentSize, index, $td) { + var options = this.options; + var col = options.cols[index]; + var treeOption = options.tree; + var components = this.getComponents(); + var checkboxFilter = components.checkboxFilter; + var radioFilter = components.radioFilter; + indentSize || (indentSize = 0); + // 内容填充 + var fieldStr = ''; + if (col.type == 'numbers') { // 序号列 + fieldStr += ''; + } else if (col.type == 'checkbox') { // 复选框列 + var attrStr = 'name="' + checkboxFilter + '" lay-filter="' + checkboxFilter + '" value="' + d[treeOption.idName] + '"'; + attrStr += d.LAY_CHECKED ? ' checked="checked"' : ''; + fieldStr += ''; + } else if (col.type == 'radio') { // 单选框列 + var attrStr = 'name="' + radioFilter + '" lay-filter="' + radioFilter + '" value="' + d[treeOption.idName] + '"'; + attrStr += d.LAY_CHECKED ? ' checked="checked"' : ''; + fieldStr += ''; + } else if (col.templet) { // 自定义模板 + if (typeof col.templet == 'function') { + fieldStr += col.templet(d); + } else if (typeof col.templet == 'string') { + laytpl($(col.templet).html()).render(d, function (html) { + fieldStr += html; + }); + } + } else if (col.toolbar) { // 工具列 + laytpl($(col.toolbar).html()).render(d, function (html) { + fieldStr += html; + }); + } else if (col.field && d[col.field] != undefined && d[col.field] != null) { // 普通字段 + fieldStr += d[col.field]; + } + var tdStr = ''; + // 图标列处理 + if (index == treeOption.iconIndex) { + // 缩进 + for (var k = 0; k < indentSize; k++) { + tdStr += ''; + } + tdStr += ''; + // 加箭头 + var haveChild = getHaveChild(d, treeOption); + tdStr += (''); + // 加图标 + tdStr += treeOption.getIcon(d); + if (options.tree.onlyIconControl) { + tdStr += ''; + tdStr += ('' + fieldStr + ''); + } else { + tdStr += ('' + fieldStr + ''); + tdStr += ''; + } + } else { + tdStr += fieldStr; + } + if ($td && col.type != 'numbers') { + $td.html(tdStr); + } + var htmlStr = ''); + return htmlStr; + }; + + /** + * 异步加载渲染 + * @param data 父级数据 + * @param $tr 父级dom + */ + TreeTable.prototype.renderBodyAsync = function (d, $tr) { + var that = this; + var options = this.options; + var components = this.getComponents(); + var $tbEmpty = components.$tbEmpty; + var $tbLoading = components.$tbLoading; + // 显示loading + if ($tr) { + $tr.addClass('ew-tree-table-loading'); + $tr.children('td').children('.ew-tree-pack').children('.ew-tree-table-arrow').addClass('layui-anim layui-anim-rotate layui-anim-loop'); + } else { + if (options.data && options.data.length > 0) { + $tbLoading.addClass('ew-loading-float'); + } + $tbLoading.show(); + } + // 请求数据 + options.reqData(d, function (res) { + if (options.tree.isPidData) { + res = treeTb.pidToChildren(res, options.tree.idName, options.tree.pidName, options.tree.childName); + } + that.renderBodyData(res, d, $tr); // 渲染内容 + // 移除loading + if ($tr) { + $tr.removeClass('ew-tree-table-loading'); + $tr.children('td').children('.ew-tree-pack').children('.ew-tree-table-arrow').removeClass('layui-anim layui-anim-rotate layui-anim-loop'); + } else { + $tbLoading.hide(); + $tbLoading.removeClass('ew-loading-float'); + } + // 是否为空 + if ((!res || res.length == 0) && !$tr) { + $tbEmpty.show(); + } + }); + }; + + /** + * 根据数据渲染body + * @param data 数据集合 + * @param option 配置项 + * @param d 父级数据 + * @param $tr 父级dom + */ + TreeTable.prototype.renderBodyData = function (data, d, $tr) { + var that = this; + var options = this.options; + var components = this.getComponents(); + var $view = components.$view; + var $table = components.$table; + var tbFilter = components.tbFilter; + addPidField(data, options.tree, d); // 补充pid字段 + // 更新到数据 + if (d == undefined) { + options.data = data; + } else { + d[options.tree.childName] = data; + } + var indent; + if ($tr) { + indent = parseInt($tr.data('indent')) + 1; + } + var htmlStr = this.renderBody(data, indent); + if ($tr) { + // 移除旧dom + $tr.nextAll('tr').each(function () { + if (parseInt($(this).data('indent')) <= (indent - 1)) { + return false; + } + $(this).remove(); + }); + // 渲染新dom + $tr.after(htmlStr); + $tr.addClass('ew-tree-table-open'); + } else { + $table.children('tbody').html(htmlStr); + } + form.render(null, tbFilter); // 渲染表单元素 + this.renderNumberCol(); // 渲染序号列 + this.checkIndeterminateCB(); // 恢复复选框半选状态 + if ($tr) { + // 更新父级复选框状态 + this.checkParentCB($tr); + $tr.prevAll('tr').each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < (indent - 1)) { + that.checkParentCB($(this)); + indent = tInd + 1; + } + }); + } + this.checkChooseAllCB(); // 联动全选框 + updateFixedTbHead($view); + }; + + /** + * 联动子级复选框状态 + * @param $tr 当前tr的dom + * @param checked + */ + TreeTable.prototype.checkSubCB = function ($tr, checked) { + var that = this; + var components = this.getComponents(); + var cbFilter = components.checkboxFilter; + var indent = -1, $trList; + if ($tr.is('tbody')) { + $trList = $tr.children('tr'); + } else { + indent = parseInt($tr.data('indent')); + $trList = $tr.nextAll('tr') + } + $trList.each(function () { + if (parseInt($(this).data('indent')) <= indent) { + return false; + } + var $cb = $(this).children('td').children('input[name="' + cbFilter + '"]'); + $cb.prop('checked', checked); + if (checked) { + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); + $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); + } else { + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); + } + that.update($(this).data('id'), {LAY_CHECKED: checked}); // 同步更新数据 + }); + }; + + /** + * 联动父级复选框状态 + * @param $tr 父级的dom + */ + TreeTable.prototype.checkParentCB = function ($tr) { + var that = this; + var components = this.getComponents(); + var cbFilter = components.checkboxFilter; + var indent = parseInt($tr.data('indent')); + var ckNum = 0, unCkNum = 0; + $tr.nextAll('tr').each(function () { + if (parseInt($(this).data('indent')) <= indent) { + return false; + } + var $cb = $(this).children('td').children('input[name="' + cbFilter + '"]'); + if ($cb.prop('checked')) { + ckNum++; + } else { + unCkNum++; + } + }); + var $cb = $tr.children('td').children('input[name="' + cbFilter + '"]'); + if (ckNum > 0 && unCkNum == 0) { // 全选 + $cb.prop('checked', true); + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); + $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); + that.update($tr.data('id'), {LAY_CHECKED: true}); // 同步更新数据 + } else if (ckNum == 0 && unCkNum > 0) { // 全不选 + $cb.prop('checked', false); + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); + that.update($tr.data('id'), {LAY_CHECKED: false}); // 同步更新数据 + } else if (ckNum > 0 && unCkNum > 0) { // 半选 + $cb.prop('checked', true); + $cb.data('indeterminate', 'true'); + $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate'); + that.update($tr.data('id'), {LAY_CHECKED: true}); // 同步更新数据 + } + }; + + /** 联动全选复选框 */ + TreeTable.prototype.checkChooseAllCB = function () { + var components = this.getComponents(); + var cbAllFilter = components.cbAllFilter; + var cbFilter = components.checkboxFilter; + var $tbody = components.$table.children('tbody'); + var ckNum = 0, unCkNum = 0; + $tbody.children('tr').each(function () { + var $cb = $(this).children('td').children('input[name="' + cbFilter + '"]'); + if ($cb.prop('checked')) { + ckNum++; + } else { + unCkNum++; + } + }); + var $cb = $('input[lay-filter="' + cbAllFilter + '"]'); + if (ckNum > 0 && unCkNum == 0) { // 全选 + $cb.prop('checked', true); + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').addClass('layui-form-checked'); + $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate'); + } else if ((ckNum == 0 && unCkNum > 0) || (ckNum == 0 && unCkNum == 0)) { // 全不选 + $cb.prop('checked', false); + $cb.data('indeterminate', 'false'); + $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate'); + } else if (ckNum > 0 && unCkNum > 0) { // 半选 + $cb.prop('checked', true); + $cb.data('indeterminate', 'true'); + $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate'); + } + }; + + /** 填充序号列 */ + TreeTable.prototype.renderNumberCol = function () { + var components = this.getComponents(); + var $tbody = components.$table.children('tbody'); + $tbody.children('tr').each(function (index) { + $(this).children('td').children('.ew-tree-table-numbers').text(index + 1); + }); + }; + + /* 解决form.render之后半选框被重置的问题 */ + TreeTable.prototype.checkIndeterminateCB = function () { + var components = this.getComponents(); + var cbFilter = components.checkboxFilter; + $('input[lay-filter="' + cbFilter + '"]').each(function () { + var $cb = $(this); + if ($cb.data('indeterminate') == 'true' && $cb.prop('checked')) { + $cb.next('.layui-form-checkbox').addClass('ew-form-indeterminate'); + } + }); + }; + + /** + * 搜索数据 + * @param ids 关键字或数据id集合 + */ + TreeTable.prototype.filterData = function (ids) { + var components = this.getComponents(); + var $trList = components.$table.children('tbody').children('tr'); + if (typeof ids == 'string') { // 关键字 + var keyword = ids; + ids = []; + $trList.each(function () { + var id = $(this).data('id'); + $(this).children('td').each(function () { + if ($(this).text().indexOf(keyword) != -1) { + ids.push(id); + return false; + } + }); + }); + } + $trList.addClass('ew-tree-table-filter-hide'); + for (var i = 0; i < ids.length; i++) { + var $tr = $trList.filter('[data-id="' + ids[i] + '"]'); + $tr.removeClass('ew-tree-table-filter-hide'); + // 联动父级 + var indent = parseInt($tr.data('indent')); + $tr.prevAll('tr').each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < indent) { + $(this).removeClass('ew-tree-table-filter-hide'); // 联动父级 + if (!$(this).hasClass('ew-tree-table-open')) { + toggleRow($(this)); + } + indent = tInd; + } + }); + } + }; + + /** 重置搜索 */ + TreeTable.prototype.clearFilter = function () { + var components = this.getComponents(); + var $trList = components.$table.children('tbody').children('tr'); + $trList.removeClass('ew-tree-table-filter-hide'); + }; + + /** 展开指定行 */ + TreeTable.prototype.expand = function (id, cascade) { + var components = this.getComponents(); + var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]'); + if (!$tr.hasClass('ew-tree-table-open')) { + $tr.children('td').children('.ew-tree-pack').trigger('click'); + } + if (cascade == false) { + return; + } + // 联动父级 + var indent = parseInt($tr.data('indent')); + $tr.prevAll('tr').each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < indent) { + if (!$(this).hasClass('ew-tree-table-open')) { + $(this).children('td').children('.ew-tree-pack').trigger('click'); + } + indent = tInd; + } + }); + }; + + /** 折叠指定行 */ + TreeTable.prototype.fold = function (id, cascade) { + var components = this.getComponents(); + var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]'); + if ($tr.hasClass('ew-tree-table-open')) { + $tr.children('td').children('.ew-tree-pack').trigger('click'); + } + if (cascade == false) { + return; + } + // 联动父级 + var indent = parseInt($tr.data('indent')); + $tr.prevAll('tr').each(function () { + var tInd = parseInt($(this).data('indent')); + if (tInd < indent) { + if ($(this).hasClass('ew-tree-table-open')) { + $(this).children('td').children('.ew-tree-pack').trigger('click'); + } + indent = tInd; + } + }); + }; + + /** 全部展开 */ + TreeTable.prototype.expandAll = function () { + var that = this; + var components = this.getComponents(); + var $trList = components.$table.children('tbody').children('tr'); + $trList.each(function () { + that.expand($(this).data('id'), false); + }); + }; + + /** 全部折叠 */ + TreeTable.prototype.foldAll = function () { + var that = this; + var components = this.getComponents(); + var $trList = components.$table.children('tbody').children('tr'); + $trList.each(function () { + that.fold($(this).data('id'), false); + }); + }; + + /** 获取当前数据 */ + TreeTable.prototype.getData = function () { + return this.options.data; + }; + + /** 重载表格 */ + TreeTable.prototype.reload = function (opt) { + treeTb.render($.extend(this.options, opt)); + }; + + /** 根据id更新数据 */ + TreeTable.prototype.update = function (id, fields) { + var data = getDataById(this.getData(), id, this.options.tree); + $.extend(data, fields); + }; + + /** 根据id删除数据 */ + TreeTable.prototype.del = function (id) { + delDataById(this.getData(), id, this.options.tree); + }; + + /** 获取当前选中行 */ + TreeTable.prototype.checkStatus = function () { + var that = this; + var components = this.getComponents(); + var $table = components.$table; + var checkboxFilter = components.checkboxFilter; + var radioFilter = components.radioFilter; + var list = []; + // 获取单选框选中数据 + var $radio = $table.find('input[name="' + radioFilter + '"]'); + if ($radio.length > 0) { + var id = $radio.filter(':checked').val(); + var d = getDataById(this.getData(), id, this.options.tree); + if (d) { + list.push(d); + } + } else { // 获取复选框数据 + $table.find('input[name="' + checkboxFilter + '"]:checked').each(function () { + var id = $(this).val(); + var d = getDataById(that.getData(), id, that.options.tree); + if (d) { + list.push(d); + } + }); + } + return list; + }; + + /** 设置复/单选框选中 */ + TreeTable.prototype.setChecked = function (ids) { + var components = this.getComponents(); + var $table = components.$table; + var checkboxFilter = components.checkboxFilter; + var radioFilter = components.radioFilter; + var $radio = $table.find('input[name="' + radioFilter + '"]'); + if ($radio.length > 0) { // 开启了单选框 + $radio.each(function () { + if (ids[ids.length - 1] == $(this).val()) { + $(this).next('.layui-form-radio').trigger('click'); + return false; + } + }); + } else { // 开启了复选框 + $table.find('input[name="' + checkboxFilter + '"]').each(function () { + var $cb = $(this); + var value = $cb.val(); + var $layCb = $cb.next('.layui-form-checkbox'); + for (var i = 0; i < ids.length; i++) { + if (value == ids[i]) { + var checked = $cb.prop('checked'); + var indeterminate = $layCb.hasClass('ew-form-indeterminate'); + if (!checked || indeterminate) { + $layCb.trigger('click'); + } + } + } + }); + } + }; + + /** 移除全部选中 */ + TreeTable.prototype.removeAllChecked = function () { + var components = this.getComponents(); + var $table = components.$table; + var checkboxFilter = components.checkboxFilter; + this.checkSubCB($table.children('tbody'), false); + }; + + /** + * 刷新指定父级下的节点 + * @param id 父级id,空则全部刷新 + * @param data 非异步模式替换的数据 + */ + TreeTable.prototype.refresh = function (id, data) { + var components = this.getComponents().$table; + var $table = components.$table; + var d, $tr; + if (id != undefined) { + d = getDataById(this.getData(), id, this.options.tree); + $tr = $table.children('tbody').children('tr[data-id="' + id + '"]'); + } + if (data) { // 数据模式 + components.$tbLoading.addClass('ew-loading-float'); + components.$tbLoading.show(); + this.renderBodyData(data, d, $tr); + components.$tbLoading.hide(); + components.$tbLoading.removeClass('ew-loading-float'); + } else { // 异步模式 + this.renderBodyAsync(d, $tr); + } + }; + + /** 生成表头 */ + function getThead(options) { + var htmlStr = ''; + for (var i = 0; i < options.cols.length; i++) { + var col = options.cols[i]; + htmlStr += ''; + } + + /** 获取列图标 */ + function getIcon(d, treeOption) { + if (getHaveChild(d, treeOption)) { + return ''; + } else { + return ''; + } + } + + /** 折叠/展开行 */ + function toggleRow($tr) { + var indent = parseInt($tr.data('indent')); + var isOpen = $tr.hasClass('ew-tree-table-open'); + if (isOpen) { // 折叠 + $tr.removeClass('ew-tree-table-open'); + $tr.nextAll('tr').each(function () { + if (parseInt($(this).data('indent')) <= indent) { + return false; + } + $(this).addClass('ew-tree-tb-hide'); + }); + } else { // 展开 + $tr.addClass('ew-tree-table-open'); + var hideInd; + $tr.nextAll('tr').each(function () { + var ind = parseInt($(this).data('indent')); + if (ind <= indent) { + return false; + } + if (hideInd != undefined && ind > hideInd) { + return true; + } + $(this).removeClass('ew-tree-tb-hide'); + if (!$(this).hasClass('ew-tree-table-open')) { + hideInd = parseInt($(this).data('indent')); + } else { + hideInd = undefined; + } + }); + } + updateFixedTbHead($tr.parent().parent().parent().parent().parent()); + } + + /** 固定表头减去滚动条 */ + function updateFixedTbHead($view) { + var $group = $view.children('.ew-tree-table-group'); + var $tbBox = $group.children('.ew-tree-table-box'); + var sWidth = $tbBox.width() - $tbBox.prop('clientWidth'); + if (sWidth > 0) { + if (!(device.ie && device.ie < 9)) { + sWidth = sWidth - 0.48; + } + $group.children('.ew-tree-table-head').css('padding-right', sWidth); + } else { + $group.children('.ew-tree-table-head').css('padding-right', 0); + } + } + + // 监听窗口大小改变 + $(window).resize(function () { + $('.ew-tree-table').each(function () { + updateFixedTbHead($(this)); + var $tbBox = $(this).children('.ew-tree-table-group').children('.ew-tree-table-box'); + var full = $tbBox.attr('ew-tree-full'); + if (full && device.ie && device.ie < 10) { + $tbBox.css('height', getPageHeight() - full); + } + }); + }); + + /** 判断是否还有子节点 */ + function getHaveChild(d, treeOption) { + var haveChild = false; + if (d[treeOption.haveChildName] != undefined) { + haveChild = d[treeOption.haveChildName]; + haveChild = haveChild == true || haveChild == 'true'; + } else if (d[treeOption.childName]) { + haveChild = d[treeOption.childName].length > 0; + } + return haveChild; + } + + /** 补充pid字段 */ + function addPidField(data, treeOption, parent) { + for (var i = 0; i < data.length; i++) { + if (parent) { + data[i][treeOption.pidName] = parent[treeOption.idName]; + } + if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { + addPidField(data[i][treeOption.childName], treeOption, data[i]); + } + } + } + + /** 根据id获取数据 */ + function getDataById(data, id, treeOption) { + for (var i = 0; i < data.length; i++) { + if (data[i][treeOption.idName] == id) { + return data[i]; + } + if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { + var d = getDataById(data[i][treeOption.childName], id, treeOption); + if (d != undefined) { + return d; + } + } + } + } + + /** 根据id删除数据 */ + function delDataById(data, id, treeOption) { + for (var i = 0; i < data.length; i++) { + if (data[i][treeOption.idName] == id) { + data.splice(i, 1); + return true; + } + if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) { + var rs = delDataById(data[i][treeOption.childName], id, treeOption); + if (rs) { + return true; + } + } + } + } + + /** 获取顶级的pId */ + function getPids(list, idName, pidName) { + var pids = []; + for (var i = 0; i < list.length; i++) { + var hasPid = false; + for (var j = 0; j < list.length; j++) { + if (i != j && list[j][idName] == list[i][pidName]) { + hasPid = true; + } + } + if (!hasPid) { + pids.push(list[i][pidName]); + } + } + return pids; + } + + /** 判断pId是否相等 */ + function pidEquals(pId, pIds) { + if (isClass(pIds) == 'Array') { + for (var i = 0; i < pIds.length; i++) { + if (pId == pIds[i]) { + return true; + } + } + } else { + return pId == pIds; + } + return false; + } + + /** 获取变量类型 */ + function isClass(o) { + if (o === null) + return 'Null'; + if (o === undefined) + return 'Undefined'; + return Object.prototype.toString.call(o).slice(8, -1); + } + + /* 获取浏览器高度 */ + function getPageHeight() { + return document.documentElement.clientHeight || document.body.clientHeight; + } + + /** 对外提供的方法 */ + var treeTb = { + /* 渲染 */ + render: function (options) { + return new TreeTable(options); + }, + /* 事件监听 */ + on: function (events, callback) { + return layui.onevent.call(this, MOD_NAME, events, callback); + }, + /* pid转children形式 */ + pidToChildren: function (data, idName, pidName, childName, pId) { + childName || (childName = 'children'); + var newList = []; + for (var i = 0; i < data.length; i++) { + (pId == undefined) && (pId = getPids(data, idName, pidName)); + if (pidEquals(data[i][pidName], pId)) { + var children = this.pidToChildren(data, idName, pidName, childName, data[i][idName]); + (children.length > 0) && (data[i][childName] = children); + newList.push(data[i]); + } + } + return newList; + } + }; + + exports('treeTable', treeTb); +}); From 722b8cfa7f7fed0ce6139a545e8cc5c40ae070b3 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:37:00 +0800 Subject: [PATCH 45/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index 6044e6f..87178f7 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -280,8 +280,11 @@ class CatchAdmin { $routeFiles = []; foreach (self::getModulesDirectory() as $module) { - if (file_exists($module . 'route.php')) { - $routeFiles[] = $module . 'route.php'; + $moduleInfo = self::getModuleInfo($module); + if (!in_array($moduleInfo['alias'], ['login'])) { + if (file_exists($module . 'route.php')) { + $routeFiles[] = $module . 'route.php'; + } } } $routes = ''; From d3e0c64b585df0d3110a4dd1d80087583ccb9704 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:37:45 +0800 Subject: [PATCH 46/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9D=83=E9=99=90?= =?UTF-8?q?=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/permissions/PermissionsMiddleware.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/catchAdmin/permissions/PermissionsMiddleware.php b/catchAdmin/permissions/PermissionsMiddleware.php index 7945647..bb55ef0 100644 --- a/catchAdmin/permissions/PermissionsMiddleware.php +++ b/catchAdmin/permissions/PermissionsMiddleware.php @@ -3,7 +3,6 @@ namespace catchAdmin\permissions; use app\Request; use catchAdmin\permissions\model\Permissions; -use catcher\CatchAdmin; use catcher\exceptions\PermissionForbiddenException; use think\helper\Str; @@ -22,6 +21,10 @@ class PermissionsMiddleware */ public function handle(Request $request, \Closure $next) { + if (!$request->user()) { + throw new PermissionForbiddenException('Login is invalid', 10006); + } + // toad if (($permission = $this->getPermission($request)) && !in_array($permission->id, $request->user()->getPermissionsBy())) { @@ -54,11 +57,6 @@ class PermissionsMiddleware array_pop($controller); $module = array_pop($controller); - if ($module != 'login') { - if (!$request->user()) { - throw new PermissionForbiddenException('Login is invalid', 10006); - } - } $permissionMark = sprintf('%s:%s', $controllerName, $action); $permission = Permissions::where('module', $module)->where('permission_mark', $permissionMark)->find(); From 6724da9e8fe7f1d2da56eb366dcb6e3754d4226a Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:50:54 +0800 Subject: [PATCH 47/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9F=BA=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/base/CatchController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extend/catcher/base/CatchController.php b/extend/catcher/base/CatchController.php index 71f1211..86c2ec5 100644 --- a/extend/catcher/base/CatchController.php +++ b/extend/catcher/base/CatchController.php @@ -49,7 +49,7 @@ abstract class CatchController $class = explode('\\', $class); - $className = strtolower(end($class)); + $className = lcfirst(end($class)); if (is_dir($viewPath . $className)) { return sprintf('%s/%s', $className, $func); From 1bcc0f217e17d3ebe5b5028f8f8151f71a02a422 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:53:40 +0800 Subject: [PATCH 48/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index 87178f7..6094dd7 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -58,7 +58,7 @@ class CatchAdmin */ public static function backupDirectory(): string { - $directory = root_path('database/backup'); + $directory = self::cacheDirectory(); if (!is_dir($directory) && !mkdir($directory, 0777, true) && !is_dir($directory)) { throw new \RuntimeException(sprintf('Directory "%s" was not created', $directory)); From eb2fd14f07ceaf89ed2193c62ea5083fbd81ab66 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:54:06 +0800 Subject: [PATCH 49/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/CatchAdmin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extend/catcher/CatchAdmin.php b/extend/catcher/CatchAdmin.php index 6094dd7..878a492 100644 --- a/extend/catcher/CatchAdmin.php +++ b/extend/catcher/CatchAdmin.php @@ -58,7 +58,7 @@ class CatchAdmin */ public static function backupDirectory(): string { - $directory = self::cacheDirectory(); + $directory = self::cacheDirectory() . 'backup' .DIRECTORY_SEPARATOR; if (!is_dir($directory) && !mkdir($directory, 0777, true) && !is_dir($directory)) { throw new \RuntimeException(sprintf('Directory "%s" was not created', $directory)); From e6d15174296b51e8a26227115e079cbd6bc808f0 Mon Sep 17 00:00:00 2001 From: wuyanwen Date: Sat, 14 Dec 2019 17:59:11 +0800 Subject: [PATCH 50/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/login/controller/Index.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/catchAdmin/login/controller/Index.php b/catchAdmin/login/controller/Index.php index 38e96fb..1ff1667 100644 --- a/catchAdmin/login/controller/Index.php +++ b/catchAdmin/login/controller/Index.php @@ -1,16 +1,11 @@ Date: Sat, 14 Dec 2019 18:02:09 +0800 Subject: [PATCH 51/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- catchAdmin/index/view/index.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index 9d0d613..ba7a403 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -30,15 +30,15 @@