扩展功能

This commit is contained in:
wuyanwen 2019-12-06 09:17:40 +08:00
parent 397c8bb7f7
commit 5c7765c97f
18 changed files with 1396 additions and 0 deletions

View File

@ -0,0 +1,325 @@
<?php
namespace catcher;
use think\helper\Arr;
class CatchAdmin
{
public const NAME = 'catchAdmin';
/**
*
* @time 2019年11月30日
* @return string
*/
public static function directory(): string
{
return app()->getRootPath() . self::NAME . DIRECTORY_SEPARATOR;
}
/**
*
* @time 2019年12月04日
* @param $module
* @return string
*/
public static function moduleDirectory($module): string
{
$directory = self::directory() . $module . DIRECTORY_SEPARATOR;
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年11月30日
* @return string
*/
public static function cacheDirectory(): string
{
$directory = app()->getRuntimePath() . self::NAME . DIRECTORY_SEPARATOR;
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日
* @param $module
* @return string
*/
public static function moduleMigrationsDirectory($module): string
{
return self::directory() . $module . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR. 'migrations' . DIRECTORY_SEPARATOR;
}
/**
*
* @time 2019年12月03日
* @param $module
* @return string
*/
public static function moduleSeedsDirectory($module): string
{
return self::directory() . $module . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR. 'seeds' . DIRECTORY_SEPARATOR;
}
/**
* 获取模块 view path
*
* @time 2019年12月03日
* @param $module
* @return string
*/
public static function getModuleViewPath($module): string
{
$directory = self::directory() . $module . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR;
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日
* @param $module
* @return string
*/
public static function getModuleModelDirectory($module): string
{
$directory = self::directory() . $module . DIRECTORY_SEPARATOR . 'model' . DIRECTORY_SEPARATOR;
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年11月30日
* @return array
*/
public static function getModulesDirectory(): array
{
$modules = glob(self::directory() . '*');
foreach ($modules as $key => &$module) {
if (!is_dir($module)) {
unset($modules[$key]);
}
$module .= DIRECTORY_SEPARATOR;
}
return $modules;
}
/**
*
* @time 2019年11月30日
* @return array
*/
protected static function getModuleServices(): array
{
$services = [];
foreach (self::getModulesDirectory() as $module) {
if (is_dir($module)) {
$moduleInfo = self::getModuleInfo($module);
if (isset($moduleInfo['services']) && !empty($moduleInfo['services'])) {
$services = array_merge($services, $moduleInfo['services']);
}
}
}
return $services;
}
/**
*
* @time 2019年11月30日
* @return array
*/
protected static function getModuleViews(): array
{
$views = [];
foreach (self::getModulesDirectory() as $module) {
if (is_dir($module . 'view')) {
$moduleInfo = self::getModuleInfo($module);
$moduleName = $moduleInfo['alias'] ?? Arr::last(explode('/', $module));
$views[$moduleName] = $module . 'view' . DIRECTORY_SEPARATOR;
}
}
return $views;
}
/**
* 获取模块信息
*
* @time 2019年11月30日
* @param $module
* @return mixed
*/
public static function getModuleInfo($module)
{
if (file_exists($module . DIRECTORY_SEPARATOR . 'module.json')) {
return \json_decode(file_get_contents($module . DIRECTORY_SEPARATOR . 'module.json'), true);
}
return [];
}
/**
* 获取服务
*
* @time 2019年11月30日
* @return array
*/
public static function getServices(): array
{
if (file_exists(self::getCacheServicesFile())) {
return self::getCacheServices();
}
return self::getModuleServices();
}
/**
*
* @time 2019年11月30日
* @return string
*/
public static function getRoutes(): string
{
if (file_exists(self::getCacheViewsFile())) {
return self::getCacheRoutesFile();
}
self::cacheRoutes();
return self::getCacheRoutesFile();
}
/**
*
* @time 2019年11月30日
* @return array|mixed
*/
public static function getViews()
{
if (file_exists(self::getCacheViewsFile())) {
return self::getCacheViews();
}
return self::getModuleViews();
}
/**
*
* @time 2019年11月30日
* @return false|int
*/
public static function cacheRoutes()
{
$routeFiles = [];
foreach (self::getModulesDirectory() as $module) {
if (file_exists($module . 'route.php')) {
$routeFiles[] = $module . 'route.php';
}
}
$routes = '';
foreach ($routeFiles as $route) {
$routes .= trim(str_replace('<?php', '', file_get_contents($route))) . PHP_EOL;
}
return file_put_contents(self::getCacheRoutesFile(), "<?php\r\n " . $routes);
}
/**
*
* @time 2019年11月30日
* @return false|int
*/
public static function cacheServices()
{
return file_put_contents(self::getCacheServicesFile(), "<?php\r\n return "
. var_export(self::getModuleServices(), true) . ';');
}
/**
*
* @time 2019年11月30日
* @return false|int
*/
public static function cacheViews()
{
return file_put_contents(self::getCacheViewsFile(), "<?php\r\n return "
. var_export(self::getModuleViews(), true) . ';');
}
/**
*
* @time 2019年11月30日
* @return mixed
*/
protected static function getCacheViews()
{
return include self::getCacheViewsFile();
}
/**
*
* @time 2019年11月30日
* @return mixed
*/
protected static function getCacheServices()
{
return include self::getCacheServicesFile();
}
/**
*
* @time 2019年11月30日
* @return mixed
*/
protected static function getCacheViewsFile()
{
return self::cacheDirectory() . 'views.php';
}
/**
*
* @time 2019年11月30日
* @return mixed
*/
protected static function getCacheServicesFile()
{
return self::cacheDirectory() . 'services.php';
}
/**
*
* @time 2019年11月30日
* @return string
*/
protected static function getCacheRoutesFile(): string
{
return self::cacheDirectory() . 'routes.php';
}
}

View File

@ -0,0 +1,174 @@
<?php
namespace catcher;
/**
* Class CatchForm
* @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
*
*/
class CatchForm
{
protected $name;
private $fields = [];
public function id($id)
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'id' => $id,
]);
return $this;
}
public function class($class='', $labelClass = '', $inlineClass = '')
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'class' => $class,
'labelClass' => $labelClass,
'inlineClass' => $inlineClass,
]);
return $this;
}
public function options(array $options)
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'options' => $options,
]);
return $this;
}
public function default($value)
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'default' => $value,
]);
return $this;
}
public function disabled()
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'disabled' => '',
]);
return $this;
}
public function placeholder($content)
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'placeholder' => 'placeholder='.$content,
]);
return $this;
}
public function readonly()
{
$this->fields[$this->name] = array_merge($this->fields[$this->name], [
'readonly' => 'readonly',
]);
return $this;
}
public function render()
{
$form = '';
foreach ($this->fields as $field) {
$form .= sprintf($this->baseField(),
$field['labelClass'] ?? '',
$field['label'],
$field['inlineClass'] ?? '',
$this->{$field['type'].'Field'}($field));
}
return $form;
}
public function __call($method, $arguments)
{
// TODO: Implement __call() method.
$this->name = $arguments[0] ?? '';
$label = $arguments[1] ?? '';
$this->fields[$this->name] = [
'name' => $this->name,
'type' => $method,
'label' => $label,
];
return $this;
}
protected function inline()
{
$this->fields[] = array_merge($this->fields, [
'inline' => true,
]);
return $this;
}
private function baseField()
{
return
'<div class="layui-inline">
<label class="layui-form-label %s">%s: </label>
<div class="layui-input-inline %s">
%s
</div>
</div>';
}
private function textField($field)
{
return
sprintf('<input name="%s" class="layui-input %s" value="%s" type="text" %s %s %s>',
$field['name'],
$field['class'],
$field['default'] ?? '',
$field['readonly'] ?? '',
$field['placeholder'] ?? '',
$field['disabled'] ?? ''
);
}
private function selectField($field)
{
$select = sprintf('<select name="%s">', $field['name']);
$default = $field['default'] ?? '';
foreach ($field['options'] as $key => $option) {
$select .= sprintf('<option value="%s"%s>%s</option>', $key, $default == $key ? ' selected' : '',$option);
}
return $select . '</select>';
}
private function radioField()
{}
private function textareaField()
{}
private function imageField()
{}
}

View File

@ -0,0 +1,39 @@
<?php
namespace catcher;
class CatchResponse
{
/**
* 成功的响应
*
* @time 2019年12月02日
* @param array $data
* @param $msg
* @param int $code
* @return \think\response\Json
*/
public static function success($data = [], $msg = '', $code = 10000): \think\response\Json
{
return json([
'code' => $code,
'msg' => $msg,
'data' => $data,
]);
}
/**
* 错误的响应
*
* @time 2019年12月02日
* @param string $msg
* @param int $code
* @return \think\response\Json
*/
public static function fail($msg = '', $code = 10001): \think\response\Json
{
return json([
'code' => $code,
'msg' => $msg,
]);
}
}

7
extend/catcher/Form.php Normal file
View File

@ -0,0 +1,7 @@
<?php
namespace catcher;
class Form
{
}

View File

@ -0,0 +1,63 @@
<?php
namespace catcher\base;
use catcher\CatchAdmin;
use think\facade\View;
abstract class BaseController
{
/**
*
* @time 2019年11月28日
* @param array $data
* @param string $template
* @return string
* @throws \Exception
*/
protected function fetch(array $data = [], $template = ''): string
{
$stack = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
$end = end($stack);
View::config([
'view_path' => CatchAdmin::getViews()[$this->getModule($end['class'])]
]);
return View::fetch($template ? : $this->getTemp($end['class'], $end['function']), $data);
}
/**
*
* @time 2019年12月03日
* @param $class
* @param $func
* @return string
*/
protected function getTemp($class, $func)
{
$viewPath = CatchAdmin::getModuleViewPath($this->getModule($class));
$class = explode('\\', $class);
$className = strtolower(end($class));
if (is_dir($viewPath . $className)) {
return sprintf('%s/%s', $className, $func);
}
return $func;
}
/**
*
* @time 2019年12月03日
* @param $class
* @return mixed
*/
protected function getModule($class)
{
return explode('\\', $class)[1];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace catcher\base;
use catcher\traits\db\BaseOptionsTrait;
use catcher\traits\db\TransTrait;
use think\model\concern\SoftDelete;
abstract class BaseModel extends \think\Model
{
use SoftDelete;
use TransTrait;
use BaseOptionsTrait;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
protected $deleteTime = 'delete_at';
}

View File

@ -0,0 +1,42 @@
<?php
namespace catcher\base;
use app\Request;
use catcher\exceptions\ValidateFailedException;
use think\Validate;
abstract class BaseRequest extends Request
{
/**
* Request constructor.
* @throws \Exception
*/
public function __construct()
{
parent::__construct();
$this->validate();
}
/**
* 初始化验证
*
* @time 2019年11月27日
* @throws \Exception
* @return mixed
*/
protected function validate()
{
$validate = new Validate();
if (!$validate->check(request()->param(), $this->rules())) {
throw new ValidateFailedException($validate->getError());
}
return true;
}
abstract protected function rules(): array;
abstract protected function message(): array;
}

View File

@ -0,0 +1,37 @@
<?php
namespace catcher\base;
use catcher\validates\Uniques;
use think\Validate;
abstract class BaseValidate extends Validate
{
public function __construct()
{
parent::__construct();
$this->register();
$this->rule = $this->getRules();
}
abstract protected function getRules(): array ;
private function register()
{
if (!empty($this->newValidates())) {
foreach ($this->newValidates() as $validate) {
$this->extend($validate->type(), [$validate, 'verify'], $validate->message());
}
}
}
private function newValidates()
{
return [
];
}
}

View File

@ -0,0 +1,329 @@
<?php
namespace catcher\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Console;
use think\facade\Db;
class InstallCommand extends Command
{
protected $dataInstall = true;
protected function configure()
{
$this->setName('install:project')
// ->addArgument('module', Argument::REQUIRED, 'module name')
->setDescription('install project');
}
/**
*
* @time 2019年11月29日
* @param Input $input
* @param Output $output
* @return int|void|null
*/
protected function execute(Input $input, Output $output)
{
$this->detectionEnvironment();
$this->firstStep();
$this->secondStep();
$this->thirdStep();
$this->finished();
$this->project();
}
/**
* 环境检测
*
* @time 2019年11月29日
* @return void
*/
protected function detectionEnvironment(): void
{
$this->output->info('environment begin to check...');
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
$this->output->error('php version should >= 7.1.0');
exit();
}
$this->output->info('php version ' . PHP_VERSION);
if (!extension_loaded('mbstring')) {
$this->output->error('mbstring extension not install');exit();
}
$this->output->info('mbstring extension is installed');
if (!extension_loaded('json')) {
$this->output->error('json extension not install');
exit();
}
$this->output->info('json extension is installed');
if (!extension_loaded('openssl')) {
$this->output->error('openssl extension not install');
exit();
}
$this->output->info('openssl extension is installed');
if (!extension_loaded('pdo')) {
$this->output->error('pdo extension not install');
exit();
}
$this->output->info('pdo extension is installed');
if (!extension_loaded('xml')) {
$this->output->error('xml extension not install');
exit();
}
$this->output->info('xml extension is installed');
$this->output->info('🎉 environment checking finished');
}
/**
* 安装第一步
*
* @time 2019年11月29日
* @return bool
*/
protected function firstStep(): bool
{
if (file_exists($this->app->getRootPath() . '.env')) {
return false;
}
$answer = strtolower($this->output->ask($this->input, '🤔️ Did You Need to Set Database information? (Y/N): '));
if ($answer === 'y' || $answer === 'yes') {
$charset = $this->output->ask($this->input, '👉 please input database charset, default (utf8mb4):') ? : 'utf8mb4';
$database = '';
while (!$database) {
$database = $this->output->ask($this->input, '👉 please input database name: ');
if ($database) {
break;
}
}
$host = $this->output->ask($this->input, '👉 please input database host, default (127.0.0.1):') ? : '127.0.0.1';
$port = $this->output->ask($this->input, '👉 please input database host port, default (3306):') ? : '3306';
$prefix = $this->output->ask($this->input, '👉 please input table prefix, default (null):') ? : '';
$username = $this->output->ask($this->input, '👉 please input database username default (root): ') ? : 'root';
$password = '';
while (!$password) {
$password = $this->output->ask($this->input, '👉 please input database password: ');
if ($password) {
break;
}
}
$this->generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix);
}
}
/**
* 安装第二部
*
* @time 2019年11月29日
* @return void
*/
protected function secondStep(): void
{
$modulePaths = glob(root_path('module') . '*');
$this->checkRootDatabase();
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));
}
}
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));
}
}
}
}
}
}
/**
* 安装第四步
*
* @time 2019年11月29日
* @return void
*/
protected function thirdStep(): void
{
Console::call('catch:cache');
}
/**
* finally
*
* @time 2019年11月30日
* @return void
*/
protected function finished(): void
{
// todo something
if ($this->dataInstall) {
rmdir($this->app->getRootPath() . 'database');
}
}
/**
* generate env file
*
* @time 2019年11月29日
* @param $host
* @param $database
* @param $username
* @param $password
* @param $port
* @param $charset
* @param $prefix
* @return void
*/
protected function generateEnvFile($host, $database, $username, $password, $port, $charset, $prefix): void
{
$env = \parse_ini_file(root_path() . '.example.env', true);
$env['DATABASE']['HOSTNAME'] = $host;
$env['DATABASE']['DATABASE'] = $database;
$env['DATABASE']['USERNAME'] = $username;
$env['DATABASE']['PASSWORD'] = $password;
$env['DATABASE']['HOSTPORT'] = $port;
$env['DATABASE']['CHARSET'] = $charset;
if ($prefix) {
$env['DATABASE']['PREFIX'] = $prefix;
}
$dotEnv = '';
foreach ($env as $key => $e) {
if (is_string($e)) {
$dotEnv .= sprintf('%s = %s', $key, $e === '1' ? 'true' : ($e === '' ? 'false' : $e)) . PHP_EOL;
$dotEnv .= PHP_EOL;
} else {
$dotEnv .= sprintf('[%s]', $key) . PHP_EOL;
foreach ($e as $k => $v) {
$dotEnv .= sprintf('%s = %s', $k, $v === '1' ? 'true' : ($v === '' ? 'false' : $v)) . PHP_EOL;
}
$dotEnv .= PHP_EOL;
}
}
file_put_contents(root_path() . '.env', $dotEnv);
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');
}
}
/**
*
* @time 2019年11月29日
* @return string
*/
protected function getEnvFile(): string
{
return file_exists(root_path() . '.env') ? root_path() . '.env' : '';
}
/**
* 检测根目录
*
* @time 2019年11月28日
* @return bool
*/
protected function checkRootDatabase(): bool
{
$databasePath = root_path('database');
if (!is_dir($databasePath)) {
if (!mkdir($databasePath, 0777, true) && !is_dir($databasePath)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $databasePath));
}
}
$migrationPath = $databasePath . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR;
$seedPath = $databasePath . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR;
if (!is_dir($migrationPath)) {
if (!mkdir($migrationPath, 0777, true) && !is_dir($migrationPath)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $migrationPath));
}
}
if (!is_dir($seedPath)) {
if (!mkdir($seedPath, 0777, true) && !is_dir($seedPath)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $seedPath));
}
}
return true;
}
protected function project()
{
$year = date('Y');
$this->output->info('🎉 project is installed, welcome!');
$this->output->info(sprintf('
/-------------------- welcome to use -------------------------\
| __ __ ___ __ _ |
| _________ _/ /______/ /_ / | ____/ /___ ___ (_)___ |
| / ___/ __ `/ __/ ___/ __ \ / /| |/ __ / __ `__ \/ / __ \ |
| / /__/ /_/ / /_/ /__/ / / / / ___ / /_/ / / / / / / / / / / |
| \___/\__,_/\__/\___/_/ /_/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ |
| |
\ __ __ __ __ _ __ _ __ enjoy it ! _ __ __ __ __ __ __ ___ _ @ 2017 %s
', $year));
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace catcher\command;
use catcher\CatchAdmin;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option as InputOption;
use think\console\Output;
use think\migration\command\migrate\Run;
class MigrateRunCommand extends Run
{
protected $module;
public function configure()
{
$this->setName('catch-migrate:run')
->setDescription('Migrate the database')
->addArgument('module', Argument::REQUIRED, 'migrate the module database')
->addOption('--target', '-t', InputOption::VALUE_REQUIRED, 'The version number to migrate to')
->addOption('--date', '-d', InputOption::VALUE_REQUIRED, 'The date to migrate to')
->setHelp(<<<EOT
The <info>migrate:run</info> command runs all available migrations, optionally up to a specific version
<info>php think catch-migrate:run module</info>
<info>php think catch-migrate:run -t 20110103081132</info>
<info>php think catch-migrate:run -d 20110103</info>
<info>php think catch-migrate:run -v</info>
EOT
);
}
protected function execute(Input $input, Output $output)
{
$this->module = strtolower($input->getArgument('module'));
$version = $input->getOption('target');
$date = $input->getOption('date');
// run the migrations
$start = microtime(true);
if (null !== $date) {
$this->migrateToDateTime(new \DateTime($date));
} else {
$this->migrate($version);
}
$end = microtime(true);
$output->writeln('');
$output->writeln('<comment>All Done. Took ' . sprintf('%.4fs', $end - $start) . '</comment>');
}
/**
* 获取 migration path
*
* @time 2019年12月03日
* @param $module
* @return string
*/
protected function getPath()
{
return CatchAdmin::moduleMigrationsDirectory($this->module);
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace catcher\command;
use catcher\CatchAdmin;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option as InputOption;
use think\console\Output;
use think\facade\Db;
use think\helper\Str;
class ModelGeneratorCommand extends Command
{
protected function configure()
{
$this->setName('create:model')
->addArgument('model', Argument::REQUIRED, 'model name')
->addArgument('module', Argument::REQUIRED, 'module name')
->setDescription('create model');
}
protected function execute(Input $input, Output $output)
{
$model = ucfirst($input->getArgument('model'));
$module = strtolower($input->getArgument('module'));
$table = Str::snake($model);
$modelFile= CatchAdmin::getModuleModelDirectory($module) . $model . '.php';
file_put_contents($modelFile, $this->replaceContent([
$module, $model, $table, $this->generateFields($this->getTableFields($table))
]));
if (file_exists($modelFile)) {
$output->info(sprintf('%s Create Successfully!', $modelFile));
} else {
$output->error(sprintf('%s Create Failed!', $modelFile));
}
}
private function getTableFields($table): array
{
$fields = Db::query('show full columns from ' .
config('database.connections.mysql.prefix') . $table);
$new = [];
foreach ($fields as $field) {
$new[$field['Field']] = $field['Comment'];
}
return $new;
}
private function generateFields($fields)
{
$f = '';
foreach ($fields as $field => $comment) {
$f .= sprintf("'%s', // %s" . "\r\n\t\t\t", $field, $comment);
}
return $f;
}
private function replaceContent(array $replace)
{
return str_replace([
'{Module}', '{Class}', '{Name}', '{Field}'
], $replace, $this->content());
}
private function content()
{
return <<<EOT
<?php
namespace catchAdmin\{Module}\model;
use cather\Model;
class {Class} extends Model
{
protected \$name = '{Name}';
protected \$field = [
{Field}
];
}
EOT;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types = 1);
namespace catcher\command;
use catcher\CatchAdmin;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class ModuleCacheCommand extends Command
{
protected function configure()
{
// 指令配置
$this->setName('catch:cache')
->setDescription('cache routes, views, services of module');
}
protected function execute(Input $input, Output $output)
{
CatchAdmin::cacheRoutes();
CatchAdmin::cacheServices();
CatchAdmin::cacheViews();
// 指令输出
$output->info('succeed!');
}
}

View File

@ -0,0 +1,25 @@
<?php
declare (strict_types = 1);
namespace catcher\event;
use catcher\CatchAdmin;
use think\Route;
class LoadModuleRoutes
{
/**
* 处理
*
* @time 2019年11月29日
* @return void
*/
public function handle(): void
{
$router = app(Route::class);
$router->group(function () use ($router) {
include CatchAdmin::getRoutes();
});
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace cather\exceptions;
class LoginFailedException extends \Exception
{
protected $code = 10002;
}

View File

@ -0,0 +1,7 @@
<?php
namespace catcher\exceptions;
class ValidateFailedException extends \Exception
{
protected $code = 10001;
}

View File

@ -0,0 +1,73 @@
<?php
namespace catcher\traits\db;
trait BaseOptionsTrait
{
/**
*
* @time 2019年12月03日
* @param array $data
* @return bool
*/
public function storeBy(array $data)
{
foreach ($data as $field => $value) {
if (in_array($field, $this->field)) {
$this->{$field} = $value;
}
}
if ($this->save()) {
return $this->id;
}
return false;
}
/**
*
* @time 2019年12月03日
* @param $id
* @param $data
* @return bool
*/
public function updateBy($id, $data)
{
$model = $this->findBy($id);
foreach ($data as $field => $value) {
if (in_array($field, $this->field)) {
$model->{$field} = $value;
}
}
if ($model->save()) {
$model->id;
}
return false;
}
/**
*
* @time 2019年12月03日
* @param $id
* @param array $field
* @return mixed
*/
public function findBy($id, array $field = ['*'])
{
return static::where($this->getPk(), $id)->select($field)->find();
}
/**
*
* @time 2019年12月03日
* @param $id
* @return mixed
*/
public function deleteBy($id)
{
return static::destory($id);
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace catcher\traits\db;
use think\facade\Db;
trait TransTrait
{
/**
*
* @time 2019年12月03日
* @return void
*/
public function startTrans()
{
Db::startTrans();
}
/**
*
* @time 2019年12月03日
* @return void
*/
public function commit()
{
Db::commit();
}
/**
*
* @time 2019年12月03日
* @return void
*/
public function rollback()
{
Db::rollback();
}
/**
*
* @time 2019年12月03日
* @param \Closure $function
* @return void
*/
public function transaction(\Closure $function)
{
Db::transaction($function());
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace catcher\validates;
interface ValidateInterface
{
public function type(): string ;
public function verify($value, $field): bool ;
public function message(): string ;
}