diff --git a/catch/login/LoginLogEvent.php b/catch/login/LoginLogEvent.php index 9041810..77dea50 100644 --- a/catch/login/LoginLogEvent.php +++ b/catch/login/LoginLogEvent.php @@ -2,6 +2,7 @@ namespace catchAdmin\login; use catchAdmin\permissions\model\Users; +use catchAdmin\system\model\LoginLog; use think\facade\Db; class LoginLogEvent @@ -12,7 +13,7 @@ class LoginLogEvent $username = Users::where('email', $params['email'])->value('username'); - Db::name('login_log')->insert([ + app(LoginLog::class)->storeBy([ 'login_name' => $username ? : $params['email'], 'login_ip' => request()->ip(), 'browser' => $this->getBrowser($agent), diff --git a/catch/system/controller/Generate.php b/catch/system/controller/Generate.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/catch/system/controller/Generate.php @@ -0,0 +1 @@ + - * @copyright By CatchAdmin - * @license https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt - */ -namespace catchAdmin\wechat\controller; - -use catcher\base\CatchController; - -class Reply extends CatchController -{ - -} diff --git a/catch/wechat/module.json b/catch/wechat/module.json deleted file mode 100644 index 24d4a77..0000000 --- a/catch/wechat/module.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "", - "alias": "wechat", - "description": "", - "keywords": [], - "order": 0, - "services": [ - "" - ], - "aliases": {}, - "files": [], - "requires": [] -} diff --git a/catch/wechat/route.php b/catch/wechat/route.php deleted file mode 100644 index 2c5c01d..0000000 --- a/catch/wechat/route.php +++ /dev/null @@ -1,5 +0,0 @@ -get('index', 'controller@method'); - diff --git a/extend/catcher/generate/Generator.php b/extend/catcher/generate/Generator.php new file mode 100644 index 0000000..e8092d5 --- /dev/null +++ b/extend/catcher/generate/Generator.php @@ -0,0 +1,25 @@ +generate($params['controller']));die; + + (new Controller())->done($params['controller']); + } + + public function preview($type, $params) + { + $class = ucfirst($type); + + (new $class)->done(); + } +} diff --git a/extend/catcher/generate/factory/Controller.php b/extend/catcher/generate/factory/Controller.php new file mode 100644 index 0000000..7d5288d --- /dev/null +++ b/extend/catcher/generate/factory/Controller.php @@ -0,0 +1,140 @@ +parseFilename($params['controller']); + if (!$className) { + throw new FailedException('未填写控制器名称'); + } + + // parse model + [$model, $modelNamespace] = $this->parseFilename($params['model']); + $content = $template->header() . + $template->nameSpace($namespace) . + str_replace('{USE}', $model ? 'use ' . $params['model'] .';' : '', $template->uses()) . + $template->createClass($className); + + + $content = str_replace('{CONTENT}', ($model ? $template->construct($model) : '') . rtrim($this->content($params, $template), "\r\n"), $content); + + // 写入成功之后 + if (file_put_contents($this->getGeneratePath($params['controller']), $content)) { + (new Route())->controller($params['controller']) + ->restful($params['restful']) + ->methods($this->parseOtherMethods($params['other_function'])) + ->done(); + } + } + + /** + * content + * + * @time 2020年04月27日 + * @param $params + * @param $template + * @return string + */ + protected function content($params, $template) + { + $content = ''; + + if ($params['restful']) { + $methods = $this->restful(); + $this->methods = array_merge($this->methods, $methods); + foreach ($methods as $method) { + $content .= $template->{$method[0]}(); + } + } + + if (!empty($params['other_function'])) { + $others = $this->parseOtherMethods($params['other_function']); + $this->methods = array_merge($this->methods, $others); + foreach ($others as $other) { + $content .= $template->otherFunction($other[0], $other[1]); + } + } + + return $content; + } + /** + * parse filename + * + * @time 2020年04月27日 + * @param $filename + * @return array + */ + public function parseFilename($filename) + { + $namespace = explode('\\', $filename); + + $className = ucfirst(array_pop($namespace)); + + $namespace = implode('\\', $namespace); + + return [$className, $namespace]; + } + + + + /** + * parse $method + * class_method/http_method + * @time 2020年04月27日 + * @param $methods + * @return false|string[] + */ + public function parseOtherMethods($methods) + { + $_methods = []; + + foreach ($methods as $method) { + if (Str::contains($method, '/')) { + $_methods[] = explode('/', $method); + } else { + // 默认使用 Get 方式 + $_methods[] = [$method, 'get']; + } + } + + return $_methods; + } + + /** + * restful 路由 + * + * @time 2020年04月27日 + * @return \string[][] + */ + public function restful() + { + return [ + ['index', 'get'], + ['save', 'post'], + ['read', 'get'], + ['update', 'put'], + ['delete', 'delete'], + ]; + } + +} diff --git a/extend/catcher/generate/factory/Factory.php b/extend/catcher/generate/factory/Factory.php new file mode 100644 index 0000000..0e2b5b9 --- /dev/null +++ b/extend/catcher/generate/factory/Factory.php @@ -0,0 +1,66 @@ +parsePsr4(); + + $filePath = root_path() . $psr4[$projectRootNamespace.'\\'] . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $path); + + CatchAdmin::makeDirectory($filePath); + + return $filePath . DIRECTORY_SEPARATOR . $filename . '.php'; + } + + /** + * 获取模块地址 + * + * @time 2020年04月28日 + * @param $filePath + * @return string + */ + public function getModulePath($filePath) + { + $path = explode('\\', $filePath); + + $projectRootNamespace = array_shift($path); + + $module = array_shift($path); + + $psr4 = $this->parsePsr4(); + + return root_path() . $psr4[$projectRootNamespace.'\\'] . DIRECTORY_SEPARATOR. $module . DIRECTORY_SEPARATOR; + } +} \ No newline at end of file diff --git a/extend/catcher/generate/factory/Model.php b/extend/catcher/generate/factory/Model.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/extend/catcher/generate/factory/Model.php @@ -0,0 +1 @@ +restful) { + $route[] = sprintf("\$router->resource('%s', '\%s')", $this->controllerName, $this->controller); + } + + if (!empty($this->methods)) { + foreach ($this->methods as $method) { + $route[] = sprintf("\$router->%s('%s/%s', '\%s@%s')", $method[1], $this->controllerName, $method[0], $this->controller, $method[0] ); + } + } + + return file_put_contents($this->getModulePath($this->controller) . DIRECTORY_SEPARATOR . 'route.php', + $this->header() . implode(';'. PHP_EOL , $route) . ';'); + } + + /** + * set class + * + * @time 2020年04月28日 + * @param $class + * @return $this + */ + public function controller($class) + { + $this->controller = $class; + + $class = explode('\\', $class); + + $this->controllerName = lcfirst(array_pop($class)); + + return $this; + } + + /** + * set restful + * + * @time 2020年04月28日 + * @param $restful + * @return $this + */ + public function restful($restful) + { + $this->restful = $restful; + + return $this; + } + + /** + * set methods + * + * @time 2020年04月28日 + * @param $methods + * @return $this + */ + public function methods($methods) + { + $this->methods = $methods; + + return $this; + } +} \ No newline at end of file diff --git a/extend/catcher/generate/factory/SQL.php b/extend/catcher/generate/factory/SQL.php new file mode 100644 index 0000000..dd67e24 --- /dev/null +++ b/extend/catcher/generate/factory/SQL.php @@ -0,0 +1,151 @@ +primaryKey($extra['primary_key']); + // 字段 + $ifHaveNotFields = true; + foreach ($params['model']['data'] as $sql) { + if (!$sql['field'] || !$sql['type']) { + continue; + } + $ifHaveNotFields = false; + $createSql .= $this->parseSQL($sql); + } + // 如果没有设置数据库字段 + if ($ifHaveNotFields) { + return false; + } + // 创建时间 + if ($extra['created_at'] ?? false) { + $createSql .= $this->parseCreatedAt(); + } + // 软删除 + if ($extra['soft_delete'] ?? false) { + $createSql .= $this->parseDeletedAt(); + } + // 索引 + if ($this->index) { + $createSql .= $this->index; + } + // 创建表 SQL + return $this->createTable($table, $createSql, $extra['engine'], 'utf8mb4', $extra['comment']); + } + + + /** + * parse sql + * + * @time 2020年04月27日 + * @param $sql + * @return string + */ + protected function parseSQL($sql) + { + + // 解析索引 + if ($sql['index']) { + $this->parseIndex($sql['index'], $sql['field']); + } + + return implode(' ', [ + sprintf('`%s`', $sql['field']), + $sql['type'], + $sql['length'] ? sprintf('(%s)', $sql['length']) : '', + $sql['unsigned'] ? 'unsigned' : '', + $sql['default'] ? 'default ' . $sql['default']: '', + $sql['nullable'] ? 'not null' : '', + $sql['comment'] ? sprintf('comment \'%s\'', $sql['comment']) : '' + ]) . ','. PHP_EOL; + } + + /** + * parse primary key + * + * @time 2020年04月27日 + * @param $id + * @return string + */ + protected function primaryKey($id) + { + return sprintf('`%s`', $id) . ' int unsigned not null auto_increment primary key,'. PHP_EOL; + } + + /** + * parse created_at & updated_at + * + * @time 2020年04月27日 + * @return string + */ + protected function parseCreatedAt() + { + return sprintf('`created_at` int unsigned not null default 0 comment \'%s\',', '创建时间') . PHP_EOL . + sprintf('`updated_at` int unsigned not null default 0 comment \'%s\',', '更新时间') . PHP_EOL; + } + + /** + * parse deleted_at + * + * @time 2020年04月27日 + * @return string + */ + protected function parseDeletedAt() + { + return sprintf('`deleted_at` int unsigned not null default 0 comment \'%s\',', '软删除') . PHP_EOL; + } + + /** + * created table + * + * @time 2020年04月27日 + * @param $table + * @param $sql + * @param string $engine + * @param string $charset + * @param string $comment + * @return string + */ + protected function createTable($table, $sql, $engine='InnoDB', $charset = 'utf8mb4', $comment = '') + { + return sprintf('create table `%s`(' . PHP_EOL. + '%s)'.PHP_EOL . + 'engine=%s default charset=%s comment=\'%s\'', $table, $sql, $engine, $charset, $comment); + } + + /** + * parse index + * + * @time 2020年04月27日 + * @param $index + * @param $field + * @return void + */ + protected function parseIndex($index, $field) + { + if ($index == 'unique') { + $this->index .= "unique index unique_ . $field($field)"; + } elseif ($index == 'index') { + $this->index .= "index($field)"; + } elseif ($index == 'fulltext') { + $this->index .= "fulltext key fulltext_ .$field($field)"; + } elseif ($index == 'spatial') { + $this->index .= "spatial index spatial_.$field($field)"; + } + } +} \ No newline at end of file diff --git a/extend/catcher/generate/template/Content.php b/extend/catcher/generate/template/Content.php new file mode 100644 index 0000000..e446658 --- /dev/null +++ b/extend/catcher/generate/template/Content.php @@ -0,0 +1,42 @@ +model = \$model; + } + + +TMP; + + } + + public function createClass($class) + { + return <<controllerFunctionComment('列表', 'Request $request')} + public function index(Request \$request) + { + return CatchResponse::paginate(\$this->model->getList(\$request->param())); + } + + +TMP; + } + + /** + * create template + * + * @time 2020年04月24日 + * @return string + */ + public function create() + { + return <<controllerFunctionComment('单页')} + public function create() + { + // + } + + +TMP; + + } + + /** + * save template + * + * @time 2020年04月24日 + * @param $createRequest + * @return string + */ + public function save($createRequest = '') + { + $request = $createRequest ? 'CreateRequest' : 'Request'; + + return <<controllerFunctionComment('保存', 'Request ' . $request)} + public function save({$request} \$request) + { + return CatchResponse::success(\$this->model->storeBy(\$request->post())); + } + + +TMP; + } + + /** + * read template + * + * @time 2020年04月24日 + * @return string + */ + public function read() + { + return <<controllerFunctionComment('读取', '$id')} + public function read(\$id) + { + return CatchResponse::success(\$this->model->findBy(\$id)); + } + + +TMP; + } + + /** + * edit template + * + * @time 2020年04月24日 + * @return string + */ + public function edit() + { + return <<controllerFunctionComment('编辑', '\$id')} + public function edit(\$id) + { + // + } + + +TMP; + } + + /** + * update template + * + * @time 2020年04月24日 + * @param $updateRequest + * @return string + */ + public function update($updateRequest = '') + { + $updateRequest = ($updateRequest ? 'UpdateRequest' : 'Request') . ' $request'; + + return <<controllerFunctionComment('更新', $updateRequest)} + public function update({$updateRequest}, \$id) + { + return CatchResponse::success(\$this->model->updateBy(\$id, \$request->post())); + } + + +TMP; + } + + /** + * delete template + * + * @time 2020年04月24日 + * @return string + */ + public function delete() + { + return <<controllerFunctionComment('删除', '$id')} + public function delete(\$id) + { + return CatchResponse::success(\$this->model->deleteBy(\$id)); + } + + +TMP; + } + + /** + * 其他方法 + * + * @time 2020年04月27日 + * @param $function + * @param string $method + * @return string + */ + public function otherFunction($function, $method = 'get') + { + $params = $method === 'delete' ? '$id' : 'Request $request'; + + return <<controllerFunctionComment('', $params)} + public function {$function}({$params}) + { + // todo + } + + +TMP; + } + + /** + * 控制器方法注释 + * + * @time 2020年04月24日 + * @param $des + * @param $params + * @return string + */ + protected function controllerFunctionComment($des, $params = '') + { + $now = date('Y/m/d H:i', time()); + + $params = $params ? '@param ' . $params : ''; + + return <<catchSearch() + ->order(\$this->getPk(), 'desc') + ->paginate(); + } +TMP; + } + + /** + * 一对一关联 + * + * @time 2020年04月24日 + * @param $model + * @param string $foreignKey + * @param string $pk + * @return string + */ + public function hasOne($model, $foreignKey = '', $pk = '') + { + $func = lcfirst($model); + + return <<hasOne({$model}::class{$this->keyRelate($foreignKey, $pk)}); + } +TMP; + + } + + /** + * + * + * @time 2020年04月24日 + * @param $model + * @param string $foreignKey + * @param string $pk + * @return string + */ + public function hasMany($model, $foreignKey = '', $pk = '') + { + $func = lcfirst($model); + + return <<hasMany({$model}::class{$this->keyRelate($foreignKey, $pk)}); + } +TMP; + } + + /** + * 远程一对多 + * + * @time 2020年04月24日 + * @param $model + * @param $middleModel + * @param string $foreignKey + * @param string $pk + * @param string $middleRelateId + * @param string $middleId + * @return string + */ + public function hasManyThrough($model, $middleModel, $foreignKey = '', $pk = '', $middleRelateId = '', $middleId = '') + { + $func = lcfirst($model); + + return <<hasManyThrough({$model}::class, {$middleModel}::class{$this->keyRelate($foreignKey, $pk, $middleRelateId, $middleId)}); + } +TMP; + } + + /** + * 远程一对一 + * + * @time 2020年04月24日 + * @param $model + * @param $middleModel + * @param string $foreignKey + * @param string $pk + * @param string $middleRelateId + * @param string $middleId + * @return string + */ + public function hasOneThrough($model, $middleModel, $foreignKey = '', $pk = '', $middleRelateId = '', $middleId = '') + { + $func = lcfirst($model); + + return <<hasOneThrough({$model}::class, {$middleModel}::class{$this->keyRelate($foreignKey, $pk, $middleRelateId, $middleId)}); + } +TMP; + } + + /** + * 多对多关联 + * + * @time 2020年04月24日 + * @param $model + * @param string $table + * @param string $foreignKey + * @param string $relateKey + * @return string + */ + public function belongsToMany($model, $table = '', $foreignKey = '', $relateKey = '') + { + $func = lcfirst($model); + + $table = !$table ? : ','.$table; + + $relateKey = !$relateKey ? : ','.$relateKey; + + return <<hasOneThrough({$model}::class{$table}{$this->keyRelate($foreignKey)}{$relateKey}); + } +TMP; + } + + /** + * 模型关联key + * + * @time 2020年04月24日 + * @param string $foreignKey + * @param string $pk + * @param string $middleRelateId + * @param string $middleId + * @return string + */ + public function keyRelate($foreignKey = '', $pk = '', $middleRelateId = '', $middleId = '') + { + return !$foreignKey ? : ',' . $foreignKey . + !$middleRelateId ? : ','. $middleRelateId . + !$pk ? : ',' . $pk . + !$middleId ? : ',' . $middleId; + + } +} \ No newline at end of file diff --git a/extend/catcher/generate/template/Request.php b/extend/catcher/generate/template/Request.php new file mode 100644 index 0000000..90c2dc7 --- /dev/null +++ b/extend/catcher/generate/template/Request.php @@ -0,0 +1,42 @@ +