diff --git a/catchAdmin/CatchAdminService.php b/catchAdmin/CatchAdminService.php index 606f99f..cb46296 100644 --- a/catchAdmin/CatchAdminService.php +++ b/catchAdmin/CatchAdminService.php @@ -5,6 +5,8 @@ use catcher\command\InstallCommand; use catcher\command\MigrateRunCommand; use catcher\command\ModelGeneratorCommand; use catcher\command\ModuleCacheCommand; +use catcher\validates\Sometimes; +use think\facade\Validate; use think\Service; class CatchAdminService extends Service @@ -22,5 +24,26 @@ class CatchAdminService extends Service MigrateRunCommand::class, ModelGeneratorCommand::class, ]); + + $this->registerValidates(); + } + + /** + * + * @time 2019年12月07日 + * @return void + */ + protected function registerValidates(): void + { + $validates = [ + new Sometimes(), + ]; + + Validate::maker(function($validate) use ($validates){ + foreach ($validates as $vali) { + $validate->extend($vali->type(), [$vali, 'verify'], $vali->message()); + } + }); + } } \ No newline at end of file diff --git a/catchAdmin/index/view/index.html b/catchAdmin/index/view/index.html index eed4d46..0d59d0d 100644 --- a/catchAdmin/index/view/index.html +++ b/catchAdmin/index/view/index.html @@ -220,8 +220,8 @@
diff --git a/catchAdmin/user/controller/User.php b/catchAdmin/user/controller/User.php index 7ed8bdc..0f570ca 100644 --- a/catchAdmin/user/controller/User.php +++ b/catchAdmin/user/controller/User.php @@ -1,6 +1,7 @@ fetch(); + } + + public function list(Request $request) + { + return CatchResponse::paginate($this->user->getList($request->param())); + } + + /** + * + * @time 2019年12月06日 + * @throws \Exception + * @return string + */ + public function create() { $form = new CatchForm(); - $form->text('name', '用户名')->id('id')->class('class'); - $form->select('names', '性别')->options(['请选择性别', '男', '女'])->default(1); - //$form->select('namess', '用户名'); + $form->formId('userForm'); + $form->text('username', '用户名')->verify('required')->placeholder('请输入用户名'); + $form->text('email', '邮箱')->verify('email')->placeholder('请输入邮箱'); + $form->password('password', '密码')->id('pwd')->verify('required|psw')->placeholder('请输入密码'); + $form->password('passwordConfirm', '确认密码')->verify('required|equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码'); + $form->formBtn('submitUser'); - $form->render(); return $this->fetch([ - 'form' => $form->render() + 'form' => $form->render(), ]); } /** * - * @time 2019年12月04日 * @param CreateRequest $request + * @time 2019年12月06日 * @return \think\response\Json */ - public function create(CreateRequest $request) + public function save(CreateRequest $request) { return CatchResponse::success($this->user->storeBy($request->post())); } - public function save() - {} - /** * * @time 2019年12月04日 @@ -62,8 +78,23 @@ class User extends BaseController return CatchResponse::success($this->user->findBy($id)); } - public function edit() - {} + public function edit($id) + { + $user = $this->user->findBy($id, ['id','username', 'email']); + $form = new CatchForm(); + + $form->formId('userForm'); + $form->text('username', '用户名')->verify('required')->default($user->username)->placeholder('请输入用户名'); + $form->text('email', '邮箱')->verify('email')->default($user->email)->placeholder('请输入邮箱'); + $form->password('password', '密码')->id('pwd')->placeholder('请输入密码'); + $form->password('passwordConfirm', '确认密码')->verify('equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码'); + $form->formBtn('submitUser'); + + return $this->fetch([ + 'form' => $form->render(), + 'uid' => $user->id, + ]); + } /** * @@ -88,4 +119,37 @@ class User extends BaseController return CatchResponse::success($this->user->deleteBy($id)); } + /** + * + * @time 2019年12月07日 + * @param $id + * @return \think\response\Json + */ + public function switchStatus($id): \think\response\Json + { + $user = $this->user->findBy($id); + return CatchResponse::success($this->user->updateBy($id, [ + 'status' => $user->status == Users::ENABLE ? Users::DISABLE : Users::ENABLE, + ])); + } + + /** + * + * @time 2019年12月07日 + * @param $id + * @return \think\response\Json + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\db\exception\DataNotFoundException + */ + public function recover($id): \think\response\Json + { + $trashedUser = $this->user->findBy($id, ['*'], true); + + if ($this->user->where('email', $trashedUser->email)->find()) { + return CatchResponse::fail(sprintf('该恢复用户的邮箱 [%s] 已被占用', $trashedUser->email)); + } + + return CatchResponse::success($this->user->recover($id)); + } } \ No newline at end of file diff --git a/catchAdmin/user/database/migrations/20191128114204_users.php b/catchAdmin/user/database/migrations/20191128114204_users.php index 6d48155..905e6b0 100644 --- a/catchAdmin/user/database/migrations/20191128114204_users.php +++ b/catchAdmin/user/database/migrations/20191128114204_users.php @@ -37,8 +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('delete_at', 'integer', array('null'=>true,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) - ->addIndex(array('email'), array('unique' => true)) + ->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态,0未删除 >0 已删除', 'signed' => false)) ->create(); } } diff --git a/catchAdmin/user/model/Users.php b/catchAdmin/user/model/Users.php index f38b0fc..db8450f 100644 --- a/catchAdmin/user/model/Users.php +++ b/catchAdmin/user/model/Users.php @@ -6,7 +6,7 @@ use catcher\base\BaseModel; class Users extends BaseModel { protected $name = 'users'; - + protected $field = [ 'id', // 'username', // 用户名 @@ -17,7 +17,32 @@ class Users extends BaseModel 'last_login_time', // 最后登录时间 'created_at', // 创建时间 'updated_at', // 更新时间 - 'delete_at', // 删除状态,0未删除 >0 已删除 + 'deleted_at', // 删除状态,0未删除 >0 已删除 - ]; + ]; + + /** + * set password + * + * @time 2019年12月07日 + * @param $value + * @return false|string + */ + public function setPasswordAttr($value) + { + return password_hash($value, PASSWORD_DEFAULT); + } + + public function getList($search) + { + return (($search['trash'] ?? false) ? static::onlyTrashed() : $this)->when($search['username'] ?? false, function ($query) use ($search){ + return $query->whereLike('username', $search['username']); + }) + ->when($search['email'] ?? false, function ($query) use ($search){ + return $query->whereLike('email', $search['email']); + }) + ->when($search['status'] ?? false, function ($query) use ($search){ + return $query->where('status', $search['status']); + })->paginate($search['limit'] ?? $this->limit); + } } \ No newline at end of file diff --git a/catchAdmin/user/request/CreateRequest.php b/catchAdmin/user/request/CreateRequest.php index d2bba2e..89b6f7a 100644 --- a/catchAdmin/user/request/CreateRequest.php +++ b/catchAdmin/user/request/CreateRequest.php @@ -1,15 +1,24 @@ 'require|max:20', + 'password|密码' => 'require|min:5|max:12', + 'email|邮箱' => 'require|email|unique:'.Users::class, + ]; + } + + protected function message(): array + { + // TODO: Implement message() method. } } \ No newline at end of file diff --git a/catchAdmin/user/request/UpdateRequest.php b/catchAdmin/user/request/UpdateRequest.php index eada0ce..992720e 100644 --- a/catchAdmin/user/request/UpdateRequest.php +++ b/catchAdmin/user/request/UpdateRequest.php @@ -1,14 +1,24 @@ 'require|max:20', + 'password|密码' => 'sometimes|min:5|max:12', + 'passwordConfirm|密码' => 'sometimes|confirm:password', + 'email|邮箱' => 'require|email|unique:'.Users::class, + ]; + } + + protected function message(): array + { + // TODO: Implement message() method. } } diff --git a/catchAdmin/user/route.php b/catchAdmin/user/route.php index 10fa64a..0dc963b 100644 --- a/catchAdmin/user/route.php +++ b/catchAdmin/user/route.php @@ -1,3 +1,8 @@ resource('user', '\catchAdmin\user\controller\User'); \ No newline at end of file +$router->resource('user', '\catchAdmin\user\controller\User'); +// 用户列表 +$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'); diff --git a/catchAdmin/user/view/create.html b/catchAdmin/user/view/create.html index 566549b..0f2bdb1 100644 --- a/catchAdmin/user/view/create.html +++ b/catchAdmin/user/view/create.html @@ -1,10 +1,28 @@ - - - - - Title - - - - - \ No newline at end of file +{$form|raw} + \ No newline at end of file diff --git a/catchAdmin/user/view/edit.html b/catchAdmin/user/view/edit.html index 566549b..c709ea9 100644 --- a/catchAdmin/user/view/edit.html +++ b/catchAdmin/user/view/edit.html @@ -1,10 +1,27 @@ - - - - - Title - - - - - \ No newline at end of file +{$form|raw} + \ No newline at end of file diff --git a/catchAdmin/user/view/index.html b/catchAdmin/user/view/index.html index 49ad0b9..32d8805 100644 --- a/catchAdmin/user/view/index.html +++ b/catchAdmin/user/view/index.html @@ -3,26 +3,34 @@ {block name="search"}
- {php}echo $form{/php} -
- -
- -
-
-
- +
+
- +
- +
+
+
+ +
+ +
+
+
+ +
+
@@ -36,7 +44,17 @@
{/block} {block name="table"} -
+
+ + + + {/block} {block name="script"} {/block} \ No newline at end of file diff --git a/extend/catcher/CatchForm.php b/extend/catcher/CatchForm.php index 576c59b..ee6747a 100644 --- a/extend/catcher/CatchForm.php +++ b/extend/catcher/CatchForm.php @@ -6,11 +6,12 @@ namespace catcher; * @package catcher * * - * @method text($column, $label = ''): self - * @method image($column, $label = ''): self - * @method radio($column, $label = ''): self - * @method select($column, $label = ''): self - * @method textarea($column, $label = ''): self + * @method CatchForm text($column, $label = '') + * @method CatchForm image($column, $label = '') + * @method CatchForm radio($column, $label = '') + * @method CatchForm select($column, $label = '') + * @method CatchForm textarea($column, $label = '') + * @method CatchForm password($column, $label = '') * */ class CatchForm @@ -19,10 +20,48 @@ class CatchForm private $fields = []; + protected $action; + + protected $method; + + protected $enctype; + + protected $formId; + + protected $btn; + + public function action($acton) + { + $this->action = $acton; + + return $this; + } + + public function method($method) + { + $this->method = $method; + + return $this; + } + + public function formId($formId) + { + $this->formId = $formId; + + return $this; + } + + public function enctype($enctype ="multipart/form-data") + { + $this->enctype = $enctype; + + return $this; + } + public function id($id) { $this->fields[$this->name] = array_merge($this->fields[$this->name], [ - 'id' => $id, + 'id' => sprintf('id="%s"', $id), ]); return $this; } @@ -57,6 +96,7 @@ class CatchForm return $this; } + public function disabled() { $this->fields[$this->name] = array_merge($this->fields[$this->name], [ @@ -87,19 +127,28 @@ class CatchForm public function render() { - $form = ''; + $form = sprintf('
', $this->formId, $this->formId); + foreach ($this->fields as $field) { $form .= sprintf($this->baseField(), $field['labelClass'] ?? '', $field['label'], $field['inlineClass'] ?? '', - $this->{$field['type'].'Field'}($field)); + $this->{$field['type'].'Field'}($field)) ; } - return $form; + return $form . $this->btn. '
'; } + public function append($append) + { + $this->fields[$this->name] = array_merge($this->fields[$this->name], [ + 'append' => $append, + ]); + + return $this; + } public function __call($method, $arguments) { @@ -111,6 +160,7 @@ class CatchForm 'name' => $this->name, 'type' => $method, 'label' => $label, + 'inline' => false, ]; return $this; @@ -128,23 +178,62 @@ class CatchForm private function baseField() { return - '
- -
+ '
+ +
%s
'; } + + /** + * form btn + * + * @time 2019年12月06日 + * @param $filter + * @param string $position + * @return string + */ + public function formBtn($filter, $position = 'text-right') + { + $this->btn = sprintf('
+ + +
', $position, $filter); + + return $this; + } + + public function verify($rule, $equalTo = []) + { + if (empty($equalTo)) { + $this->fields[$this->name] = array_merge($this->fields[$this->name], [ + 'verify' => sprintf('lay-verType="tips" lay-verify="%s"', $rule), + ]); + } else { + [$id, $msg] = $equalTo; + + $this->fields[$this->name] = array_merge($this->fields[$this->name], [ + 'verify' => sprintf(' lay-verType="tips" lay-verify="%s" lay-equalTo="#%s" + lay-equalToText="%s" ', $rule, $id, $msg), + ]); + } + + return $this; + } + private function textField($field) { return - sprintf('', + sprintf('', $field['name'], - $field['class'], + $field['id'] ?? '', + $field['class'] ?? '', $field['default'] ?? '', $field['readonly'] ?? '', $field['placeholder'] ?? '', - $field['disabled'] ?? '' + $field['disabled'] ?? '', + $field['verify'] ?? '' ); } @@ -162,6 +251,16 @@ class CatchForm return $select . ''; } + private function passwordField($field) + { + return sprintf('', + $field['name'], + $field['id'] ?? '', + $field['verify'] ?? '', + $field['placeholder'] ?? '' + ); + } + private function radioField() {} diff --git a/extend/catcher/base/BaseModel.php b/extend/catcher/base/BaseModel.php index ad4e984..0098352 100644 --- a/extend/catcher/base/BaseModel.php +++ b/extend/catcher/base/BaseModel.php @@ -11,10 +11,18 @@ abstract class BaseModel extends \think\Model use TransTrait; use BaseOptionsTrait; - protected $createTime = 'create_at'; + protected $createTime = 'created_at'; - protected $updateTime = 'update_at'; + protected $updateTime = 'updated_at'; - protected $deleteTime = 'delete_at'; + protected $deleteTime = 'deleted_at'; + protected $autoWriteTimestamp = true; + + protected $limit = 10; + + // 开启 + public const ENABLE = 1; + // 禁用 + public const DISABLE = 2; } diff --git a/extend/catcher/base/BaseValidate.php b/extend/catcher/base/BaseValidate.php index db644e2..d4f3465 100644 --- a/extend/catcher/base/BaseValidate.php +++ b/extend/catcher/base/BaseValidate.php @@ -1,7 +1,7 @@ newValidates())) { foreach ($this->newValidates() as $validate) { @@ -28,10 +32,15 @@ abstract class BaseValidate extends Validate } } - - private function newValidates() + /** + * + * @time 2019年12月07日 + * @return array + */ + private function newValidates(): array { return [ + new Sometimes(), ]; } } diff --git a/extend/catcher/traits/db/BaseOptionsTrait.php b/extend/catcher/traits/db/BaseOptionsTrait.php index 380e5d8..8371038 100644 --- a/extend/catcher/traits/db/BaseOptionsTrait.php +++ b/extend/catcher/traits/db/BaseOptionsTrait.php @@ -19,7 +19,7 @@ trait BaseOptionsTrait } if ($this->save()) { - return $this->id; + return $this->{$this->getPk()}; } return false; @@ -42,7 +42,7 @@ trait BaseOptionsTrait } if ($model->save()) { - $model->id; + return $model->id; } return false; @@ -53,21 +53,37 @@ trait BaseOptionsTrait * @time 2019年12月03日 * @param $id * @param array $field + * @param bool $trash * @return mixed */ - public function findBy($id, array $field = ['*']) + public function findBy($id, array $field = ['*'], $trash = false) { - return static::where($this->getPk(), $id)->select($field)->find(); + if ($trash) { + return static::onlyTrashed()->find($id); + } + + return static::where($this->getPk(), $id)->field($field)->find(); } /** * * @time 2019年12月03日 * @param $id + * @param $force * @return mixed */ - public function deleteBy($id) + public function deleteBy($id, $force = false) { - return static::destory($id); + return static::destroy($id, $force); + } + + /** + * @time 2019年12月07日 + * @param $id + * @return mixed + */ + public function recover($id) + { + return static::onlyTrashed()->find($id)->restore(); } } diff --git a/extend/catcher/validates/Sometimes.php b/extend/catcher/validates/Sometimes.php new file mode 100644 index 0000000..2025cdc --- /dev/null +++ b/extend/catcher/validates/Sometimes.php @@ -0,0 +1,28 @@ + 'module', + + /* + |-------------------------------------------------------------------------- + | Module Stubs + |-------------------------------------------------------------------------- + | + | Default module stubs. + | + */ + + 'stubs' => [ + 'enabled' => false, + 'path' => base_path() . '/vendor/nwidart/laravel-modules/src/Commands/stubs', + 'files' => [ + 'routes/web' => 'Routes/web.php', + 'routes/api' => 'Routes/api.php', + 'views/index' => 'Resources/views/index.blade.php', + 'views/master' => 'Resources/views/layouts/master.blade.php', + 'scaffold/config' => 'Config/config.php', + 'composer' => 'composer.json', + 'assets/js/app' => 'Resources/assets/js/app.js', + 'assets/sass/app' => 'Resources/assets/sass/app.scss', + 'webpack' => 'webpack.mix.js', + 'package' => 'package.json', + ], + 'replacements' => [ + 'routes/web' => ['LOWER_NAME', 'STUDLY_NAME'], + 'routes/api' => ['LOWER_NAME'], + 'webpack' => ['LOWER_NAME'], + 'json' => ['LOWER_NAME', 'STUDLY_NAME', 'MODULE_NAMESPACE', 'PROVIDER_NAMESPACE'], + 'views/index' => ['LOWER_NAME'], + 'views/master' => ['LOWER_NAME', 'STUDLY_NAME'], + 'scaffold/config' => ['STUDLY_NAME'], + 'composer' => [ + 'LOWER_NAME', + 'STUDLY_NAME', + 'VENDOR', + 'AUTHOR_NAME', + 'AUTHOR_EMAIL', + 'MODULE_NAMESPACE', + 'PROVIDER_NAMESPACE', + ], + ], + 'gitkeep' => true, + ], + 'paths' => [ + /* + |-------------------------------------------------------------------------- + | Modules path + |-------------------------------------------------------------------------- + | + | This path used for save the generated module. This path also will be added + | automatically to list of scanned folders. + | + */ + + 'module' => root_path('module'), + /* + |-------------------------------------------------------------------------- + | Modules assets path + |-------------------------------------------------------------------------- + | + | Here you may update the modules assets path. + | + */ + + 'assets' => public_path('module'), + /* + |-------------------------------------------------------------------------- + | The migrations path + |-------------------------------------------------------------------------- + | + | Where you run 'module:publish-migration' command, where do you publish the + | the migration files? + | + */ + + 'migration' => root_path('database/migrations'), + /* + |-------------------------------------------------------------------------- + | Generator path + |-------------------------------------------------------------------------- + | Customise the paths where the folders will be generated. + | Set the generate key to false to not generate that folder + */ + 'generator' => [ + 'config' => ['path' => 'Config', 'generate' => true], + 'command' => ['path' => 'Console', 'generate' => true], + 'migration' => ['path' => 'Database/Migrations', 'generate' => true], + 'seeder' => ['path' => 'Database/Seeders', 'generate' => true], + 'factory' => ['path' => 'Database/factories', 'generate' => true], + 'model' => ['path' => 'Entities', 'generate' => true], + 'routes' => ['path' => 'Routes', 'generate' => true], + 'controller' => ['path' => 'Http/Controllers', 'generate' => true], + 'filter' => ['path' => 'Http/Middleware', 'generate' => true], + 'request' => ['path' => 'Http/Requests', 'generate' => true], + 'provider' => ['path' => 'Providers', 'generate' => true], + 'assets' => ['path' => 'Resources/assets', 'generate' => true], + 'lang' => ['path' => 'Resources/lang', 'generate' => true], + 'views' => ['path' => 'Resources/views', 'generate' => true], + 'test' => ['path' => 'Tests/Unit', 'generate' => true], + 'test-feature' => ['path' => 'Tests/Feature', 'generate' => true], + 'repository' => ['path' => 'Repositories', 'generate' => false], + 'event' => ['path' => 'Events', 'generate' => false], + 'listener' => ['path' => 'Listeners', 'generate' => false], + 'policies' => ['path' => 'Policies', 'generate' => false], + 'rules' => ['path' => 'Rules', 'generate' => false], + 'jobs' => ['path' => 'Jobs', 'generate' => false], + 'emails' => ['path' => 'Emails', 'generate' => false], + 'notifications' => ['path' => 'Notifications', 'generate' => false], + 'resource' => ['path' => 'Transformers', 'generate' => false], + ], + ], + /* + |-------------------------------------------------------------------------- + | Scan Path + |-------------------------------------------------------------------------- + | + | Here you define which folder will be scanned. By default will scan vendor + | directory. This is useful if you host the package in packagist website. + | + */ + + 'scan' => [ + 'enabled' => false, + 'paths' => [ + base_path('vendor/*/*'), + ], + ], + /* + |-------------------------------------------------------------------------- + | Composer File Template + |-------------------------------------------------------------------------- + | + | Here is the config for composer.json file, generated by this package + | + */ + + 'composer' => [ + 'vendor' => 'nwidart', + 'author' => [ + 'name' => 'Nicolas Widart', + 'email' => 'n.widart@gmail.com', + ], + ], + /* + |-------------------------------------------------------------------------- + | Caching + |-------------------------------------------------------------------------- + | + | Here is the config for setting up caching feature. + | + */ + 'cache' => [ + 'enabled' => false, + 'key' => 'laravel-modules', + 'lifetime' => 60, + ], + /* + |-------------------------------------------------------------------------- + | Choose what laravel-modules will register as custom namespaces. + | Setting one to false will require you to register that part + | in your own Service Provider class. + |-------------------------------------------------------------------------- + */ + 'register' => [ + 'translations' => true, + /** + * load files on boot or register method + * + * Note: boot not compatible with asgardcms + * + * @example boot|register + */ + 'files' => 'register', + ], + + /* + |-------------------------------------------------------------------------- + | Activators + |-------------------------------------------------------------------------- + | + | You can define new types of activators here, file, database etc. The only + | required parameter is 'class'. + | The file activator will store the activation status in storage/installed_modules + */ + 'activators' => [ + 'file' => [ + 'class' => FileActivator::class, + 'statuses-file' => base_path('modules_statuses.json'), + 'cache-key' => 'activator.installed', + 'cache-lifetime' => 604800, + ], + ], + + 'activator' => 'file', +]; diff --git a/extend/think-module/src/ThinkModuleService.php b/extend/think-module/src/ThinkModuleService.php new file mode 100644 index 0000000..b83c46f --- /dev/null +++ b/extend/think-module/src/ThinkModuleService.php @@ -0,0 +1,17 @@ +commands([ + CreateModuleCommand::class, + DiscoverModuleServiceCommand::class, + ]); + } +} diff --git a/extend/think-module/src/command/CreateModuleCommand.php b/extend/think-module/src/command/CreateModuleCommand.php new file mode 100644 index 0000000..02d118e --- /dev/null +++ b/extend/think-module/src/command/CreateModuleCommand.php @@ -0,0 +1,131 @@ +setName('module:create') + ->addArgument('module', Argument::REQUIRED, 'module name') + ->setDescription('create module service'); + } + + protected function execute(Input $input, Output $output) + { + $this->module = strtolower($input->getArgument('module')); + + $this->moduleDir = CatchAdmin::moduleDirectory($this->module); + + $this->namespaces = CatchAdmin::NAME . '\\\\' . $this->module . '\\\\'; + + $this->createController(); + $this->createRequest(); + $this->createModel(); + // $this->createService(); + $this->createView(); + $this->createValidate(); + $this->createRoute(); + $this->moduleJson(); + + $output->warning('module created'); + } + + + protected function createController() + { + mkdir($this->moduleDir . 'controller' . DIRECTORY_SEPARATOR); + return file_put_contents($this->moduleDir . 'controller' . DIRECTORY_SEPARATOR . 'Index.php', str_replace( + ['{CLASS}', '{NAMESPACE}', '{MODULE}'], + ['Index', $this->namespaces . 'controller', $this->module], + file_get_contents(__DIR__ . DIRECTORY_SEPARATOR .'stubs'.DIRECTORY_SEPARATOR. 'controller.stub') + )); + } + + + protected function createModel() + { + + } + + protected function createView() + { + mkdir($this->moduleDir . DIRECTORY_SEPARATOR . 'view'); + + file_put_contents($this->moduleDir . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'index.html', ''); + file_put_contents($this->moduleDir . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'create.html', ''); + file_put_contents($this->moduleDir . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'edit.html', ''); + } + + protected function createValidate() + { + $validatePath = $this->moduleDir . DIRECTORY_SEPARATOR . 'validate' . DIRECTORY_SEPARATOR; + mkdir($validatePath); + file_put_contents($validatePath . 'CreateValidate.php', str_replace( + ['{Namespace}', '{Class}'], + [$this->namespaces . 'validate', 'Create'], + file_get_contents(__DIR__ . 'stubs' . DIRECTORY_SEPARATOR . 'validate.stub'))); + + file_put_contents($validatePath . 'UpdateValidate.php', str_replace( + ['{Namespace}', '{Class}'], + [$this->namespaces . 'validate', 'Update'], + file_get_contents(__DIR__ . 'stubs' . DIRECTORY_SEPARATOR . 'validate.stub'))); + } + + protected function createRequest() + { + $requestPath = $this->moduleDir . DIRECTORY_SEPARATOR . 'request' . DIRECTORY_SEPARATOR; + mkdir($requestPath); + file_put_contents($validatePath . 'CreateRequest.php', str_replace( + ['{Namespace}', '{Class}'], + [$this->namespaces . 'request', 'Create'], + file_get_contents(__DIR__ . 'stubs' . DIRECTORY_SEPARATOR . 'request.stub'))); + + file_put_contents($validatePath . 'UpdateRequest.php', str_replace( + ['{Namespace}', '{Class}'], + [$this->namespaces . 'request', 'Update'], + file_get_contents(__DIR__ . 'stubs' . DIRECTORY_SEPARATOR . 'request.stub'))); + } + + protected function database() + { + mkdir($this->moduleDir . DIRECTORY_SEPARATOR . 'database'); + mkdir($this->moduleDir . DIRECTORY_SEPARATOR . 'database'.DIRECTORY_SEPARATOR.'migrations'); + mkdir($this->moduleDir . DIRECTORY_SEPARATOR . 'database'.DIRECTORY_SEPARATOR . 'seeds'); + } + + protected function moduleJson() + { + file_put_contents($this->moduleDir.DIRECTORY_SEPARATOR .'module.json', str_replace( + ['{MODULE}', '{SERVICE}'], + [$this->module, $this->namespaces. ucfirst($this->module) . 'Service'], + file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'module.stub'))); + } + + protected function createRoute() + { + file_put_contents($this->moduleDir.DIRECTORY_SEPARATOR .'route.php', + file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'route.stub')); + } + + protected function createService() + { + file_put_contents($this->moduleDir.DIRECTORY_SEPARATOR . ucfirst($this->module) . 'Service.php', str_replace( + ['{CLASS}', '{NAMESPACE}'], + [ucfirst($this->module), $this->namespaces . '\\' . $this->module], + file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'provider.stub'))); + } + + +} diff --git a/extend/think-module/src/command/DiscoverModuleServiceCommand.php b/extend/think-module/src/command/DiscoverModuleServiceCommand.php new file mode 100644 index 0000000..090eced --- /dev/null +++ b/extend/think-module/src/command/DiscoverModuleServiceCommand.php @@ -0,0 +1,83 @@ +setName('module:service') + ->setDescription('discover module service'); + } + + protected function execute(Input $input, Output $output) + { + $this->getModuleServices(); + + $output->writeln('module service generator succeed!'); + } + + /** + * 获取模块 + * + * @time 2019年11月27日 + * @return bool + * @throws \ReflectionException + */ + protected function getModuleServices(): bool + { + $modules = glob(root_path('module') .'*'); + $moduleServices = []; + + foreach ($modules as $module) { + if (file_exists($module . DIRECTORY_SEPARATOR . 'module.json')) { + $moduleJson = file_get_contents($module . DIRECTORY_SEPARATOR . 'module.json'); + $moduleServices = array_merge($moduleServices, \json_decode($moduleJson, true)['services']); + } + } + + $moduleServices = $this->checkModuleService($moduleServices); + + $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL; + + $content = + 'app->getRootPath() . 'module/services.php', $content); + + return true; + } + + /** + * + * @time 2019年11月29日 + * @param $moduleServices + * @throws \ReflectionException + * @return mixed + */ + protected function checkModuleService($moduleServices) + { + $new = []; + + foreach ($moduleServices as $key => $service) { + $selfReflection = new \ReflectionClass($service); + // if service set property 'cache' && set cache => false + // the service will not be cached + // finally will boot it + if ($selfReflection->hasProperty('cache') && !$selfReflection->getProperty('cache')) { + $new[$service] = true; + } else { + $new[$service] = false; + } + } + + return $new; + } +} diff --git a/extend/think-module/src/command/stubs/command.stub b/extend/think-module/src/command/stubs/command.stub new file mode 100644 index 0000000..367b248 --- /dev/null +++ b/extend/think-module/src/command/stubs/command.stub @@ -0,0 +1,21 @@ +setName('') + ->setDescription(''); + } + + protected function execute(Input $input, Output $output) + { + } +} diff --git a/extend/think-module/src/command/stubs/composer.stub b/extend/think-module/src/command/stubs/composer.stub new file mode 100644 index 0000000..c482da5 --- /dev/null +++ b/extend/think-module/src/command/stubs/composer.stub @@ -0,0 +1,25 @@ +{ + "name": "$VENDOR$/$LOWER_NAME$", + "description": "", + "authors": [ + { + "name": "$AUTHOR_NAME$", + "email": "$AUTHOR_EMAIL$" + } + ], + "extra": { + "laravel": { + "providers": [ + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\$PROVIDER_NAMESPACE$\\$STUDLY_NAME$ServiceProvider" + ], + "aliases": { + + } + } + }, + "autoload": { + "psr-4": { + "$MODULE_NAMESPACE$\\$STUDLY_NAME$\\": "" + } + } +} diff --git a/extend/think-module/src/command/stubs/controller.stub b/extend/think-module/src/command/stubs/controller.stub new file mode 100644 index 0000000..93e64c2 --- /dev/null +++ b/extend/think-module/src/command/stubs/controller.stub @@ -0,0 +1,35 @@ +fetch('{MODULE}::index'); + } + + public function create() + { + return $this->fetch('{MODULE}::create'); + } + + public function save() + {} + + public function read() + {} + + public function edit() + { + return $this->fetch('{MODULE}::edit'); + } + + public function update() + {} + + public function delete() + {} + +} \ No newline at end of file diff --git a/extend/think-module/src/command/stubs/event.stub b/extend/think-module/src/command/stubs/event.stub new file mode 100644 index 0000000..f6232f4 --- /dev/null +++ b/extend/think-module/src/command/stubs/event.stub @@ -0,0 +1,11 @@ +loadRoutesFrom(__DIR__ . DIRECTORY_SEPARATOR . 'route.php'); + + $this->loadViewFrom(); + } + + protected function loadViewFrom(): void + { + moduleViewPathManager()->set('login', __DIR__ . DIRECTORY_SEPARATOR . 'view' .DIRECTORY_SEPARATOR); + } +} diff --git a/extend/think-module/src/command/stubs/request.stub b/extend/think-module/src/command/stubs/request.stub new file mode 100644 index 0000000..9d56612 --- /dev/null +++ b/extend/think-module/src/command/stubs/request.stub @@ -0,0 +1,17 @@ +get('index', 'controller@method'); + diff --git a/extend/think-module/src/command/stubs/seeder.stub b/extend/think-module/src/command/stubs/seeder.stub new file mode 100644 index 0000000..6982f54 --- /dev/null +++ b/extend/think-module/src/command/stubs/seeder.stub @@ -0,0 +1,19 @@ +
- - - - - -