用户管理

This commit is contained in:
wuyanwen
2019-12-07 17:31:38 +08:00
parent fa4837487b
commit 330a19e8c3
35 changed files with 1181 additions and 214 deletions

View File

@@ -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('<form id="%s" lay-filter="%s" class="layui-form model-form">', $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. '</form>';
}
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
'<div class="layui-inline">
<label class="layui-form-label %s">%s: </label>
<div class="layui-input-inline %s">
'<div class="layui-form-item">
<label class="layui-form-label%s">%s: </label>
<div class="layui-input-block%s">
%s
</div>
</div>';
}
/**
* form btn
*
* @time 2019年12月06日
* @param $filter
* @param string $position
* @return string
*/
public function formBtn($filter, $position = 'text-right')
{
$this->btn = sprintf('<div class="layui-form-item %s">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="%s" lay-submit>保存</button>
</div>', $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('<input name="%s" class="layui-input %s" value="%s" type="text" %s %s %s>',
sprintf('<input name="%s" class="layui-input %s" %s value="%s" type="text" %s %s %s%s>',
$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 . '</select>';
}
private function passwordField($field)
{
return sprintf('<input name="%s" class="layui-input" %s type="password" %s %s>',
$field['name'],
$field['id'] ?? '',
$field['verify'] ?? '',
$field['placeholder'] ?? ''
);
}
private function radioField()
{}

View File

@@ -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;
}

View File

@@ -1,7 +1,7 @@
<?php
namespace catcher\base;
use catcher\validates\Uniques;
use catcher\validates\Sometimes;
use think\Validate;
abstract class BaseValidate extends Validate
@@ -18,8 +18,12 @@ abstract class BaseValidate extends Validate
abstract protected function getRules(): array ;
private function register()
/**
*
* @time 2019年12月07日
* @return void
*/
private function register(): void
{
if (!empty($this->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(),
];
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace catcher\validates;
class Sometimes implements ValidateInterface
{
public function type(): string
{
// TODO: Implement type() method.
return 'sometimes';
}
public function verify($value): bool
{
// TODO: Implement verify() method.
if ($value) {
return true;
}
return false;
}
public function message(): string
{
// TODO: Implement message() method.
return '';
}
}

View File

@@ -5,7 +5,7 @@ interface ValidateInterface
{
public function type(): string ;
public function verify($value, $field): bool ;
public function verify($value): bool ;
public function message(): string ;
}

View File

@@ -0,0 +1,19 @@
{
"name": "jaguarjack/think-module",
"description": "thinkphp module",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "jaguarjack",
"email": "njphper@gmail.com"
}
],
"autoload": {
"psr-4": {
"jaguarjack\\think\\module\\": "src"
}
},
"minimum-stability": "dev",
"require": {}
}

View File

@@ -0,0 +1,213 @@
<?php
use Nwidart\Modules\Activators\FileActivator;
return [
/*
|--------------------------------------------------------------------------
| Module Namespace
|--------------------------------------------------------------------------
|
| Default module namespace.
|
*/
'namespace' => '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',
];

View File

@@ -0,0 +1,17 @@
<?php
namespace jaguarjack\think\module;
use jaguarjack\think\module\command\CreateModuleCommand;
use jaguarjack\think\module\command\DiscoverModuleServiceCommand;
use think\Service;
class ThinkModuleService extends Service
{
public function boot()
{
$this->commands([
CreateModuleCommand::class,
DiscoverModuleServiceCommand::class,
]);
}
}

View File

@@ -0,0 +1,131 @@
<?php
namespace jaguarjack\think\module\command;
use catcher\CatchAdmin;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class CreateModuleCommand extends Command
{
protected $module;
protected $moduleDir;
protected $namespaces;
protected function configure()
{
$this->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')));
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace jaguarjack\think\module\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class DiscoverModuleServiceCommand extends Command
{
protected function configure()
{
$this->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 =
'<?php ' . PHP_EOL . $header . 'return ' .
var_export($moduleServices, true) . ';';
file_put_contents($this->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;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace {NAMESPACE};
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class {CLASS}Command extends Command
{
protected function configure()
{
$this->setName('')
->setDescription('');
}
protected function execute(Input $input, Output $output)
{
}
}

View File

@@ -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$\\": ""
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace {NAMESPACE};
use app\BaseController;
class {CLASS} extends BaseController
{
public function index()
{
return $this->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()
{}
}

View File

@@ -0,0 +1,11 @@
<?php
declare (strict_types = 1);
namespace {NAMESPACE};
class {CLASS}
{
public function handle()
{
}
}

View File

@@ -0,0 +1,33 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class {CLASS} extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace {NAMESPACE};
use think\Model;
class {CLASS} extends Model
{
protected $fillable = $FILLABLE$;
}

View File

@@ -0,0 +1,13 @@
{
"name": "",
"alias": "{MODULE}",
"description": "",
"keywords": [],
"order": 0,
"services": [
"{SERVICE}"
],
"aliases": {},
"files": [],
"requires": []
}

View File

@@ -0,0 +1,23 @@
<?php
namespace {NAMESPACE};
use think\Service;
class {CLASS}Service extends Service
{
/**
*
* @return void
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__ . DIRECTORY_SEPARATOR . 'route.php');
$this->loadViewFrom();
}
protected function loadViewFrom(): void
{
moduleViewPathManager()->set('login', __DIR__ . DIRECTORY_SEPARATOR . 'view' .DIRECTORY_SEPARATOR);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace {NAMESPACE};
use catcher\base\BaseRequest;
class {CLASS}Request extends BaseRequest
{
/**
*
* @time 2019年11月27日
* @return string
*/
protected function getValidate()
{
// TODO: Implement getValidate() method.
}
}

View File

@@ -0,0 +1,5 @@
<?php
// you should user `$router`
// $router->get('index', 'controller@method');

View File

@@ -0,0 +1,19 @@
<?php
use think\migration\Seeder;
class {CLASS} extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace {Namespace};
use catcher\base\BaseValidate;
class {Class}Validate extends BaseValidate
{
protected $rule = [
// todo your rules
];
}