初始化本地仓库

This commit is contained in:
2026-08-31 11:33:59 +08:00
commit 663f74b633
2390 changed files with 402918 additions and 0 deletions
@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成控制器命令
* 使用方法:
* - 生成控制器:php webman make:controller TestController
* - 生成带完整路径的控制器:php webman make:controller adminapi/controller/system/TestController
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:controller',
description: 'Generate a new controller class',
aliases: ['madong-make:controller'],
hidden: false
)]
class ControllerCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'Controller name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Controller Generator');
$name = $input->getArgument('name');
$io->info("Generating controller: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/controller目录
$file = app_path() . DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\controller';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
$this->createController($className, $namespace, $file);
$io->success("Controller {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建控制器文件
*/
protected function createController(string $className, string $namespace, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/controller.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass'],
[$namespace, $className],
$template
);
file_put_contents($file, $content);
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成Dao命令
* 使用方法:
* - 生成Dao:php webman make:dao TestDao
* - 生成带完整路径的Dao:php webman make:dao system/TestDao
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:dao',
description: 'Generate a new DAO class',
aliases: ['madong-make:dao'],
hidden: false
)]
class DaoCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'DAO name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('DAO Generator');
$name = $input->getArgument('name');
$io->info("Generating DAO: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/dao目录
$file = app_path() . DIRECTORY_SEPARATOR . 'dao' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\dao';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . 'dao' . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\dao\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
// 提取模型名称
$modelName = str_replace('Dao', '', $className);
if ($modelName === $className) {
$modelName .= 'Model';
}
$this->createDao($className, $namespace, $modelName, $file);
$io->success("DAO {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建Dao文件
*/
protected function createDao(string $className, string $namespace, string $modelName, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/dao.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass', 'DummyModel'],
[$namespace, $className, $modelName],
$template
);
file_put_contents($file, $content);
}
}
@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成中间件命令
* 使用方法:
* - 生成中间件:php webman make:middleware TestMiddleware
* - 生成带完整路径的中间件:php webman make:middleware admin/TestMiddleware
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:middleware',
description: 'Generate a new middleware class',
aliases: ['madong-make:middleware'],
hidden: false
)]
class MiddlewareCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'Middleware name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Middleware Generator');
$name = $input->getArgument('name');
$io->info("Generating middleware: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/middleware目录
$file = app_path() . DIRECTORY_SEPARATOR . 'middleware' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\middleware';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
$this->createMiddleware($className, $namespace, $file);
$io->success("Middleware {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建中间件文件
*/
protected function createMiddleware(string $className, string $namespace, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/middleware.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass'],
[$namespace, $className],
$template
);
file_put_contents($file, $content);
}
}
+115
View File
@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成模型层命令
* 使用方法:
* - 生成模型:php webman make:model TestModel
* - 生成带完整路径的模型:php webman make:model system/TestModel
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:model',
description: 'Generate a new model class',
aliases: ['madong-make:model'],
hidden: false
)]
class ModelCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'Model name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Model Generator');
$name = $input->getArgument('name');
$io->info("Generating model: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/model目录
$file = app_path() . DIRECTORY_SEPARATOR . 'model' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\model';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . 'model' . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\model\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
// 生成表名
$tableName = 'sys_' . strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $className));
$this->createModel($className, $namespace, $tableName, $file);
$io->success("Model {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建模型文件
*/
protected function createModel(string $className, string $namespace, string $tableName, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/model.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass', 'DummyTable'],
[$namespace, $className, $tableName],
$template
);
file_put_contents($file, $content);
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成服务层命令
* 使用方法:
* - 生成服务:php webman make:service TestService
* - 生成带完整路径的服务:php webman make:service admin/system/TestService
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:service',
description: 'Generate a new service class',
aliases: ['madong-make:service'],
hidden: false
)]
class ServiceCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'Service name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Service Generator');
$name = $input->getArgument('name');
$io->info("Generating service: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/service目录
$file = app_path() . DIRECTORY_SEPARATOR . 'service' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\service';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . 'service' . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\service\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
// 提取Dao名称
$daoName = str_replace('Service', 'Dao', $className);
if ($daoName === $className) {
$daoName .= 'Dao';
}
$this->createService($className, $namespace, $daoName, $file);
$io->success("Service {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建服务文件
*/
protected function createService(string $className, string $namespace, string $daoName, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/service.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass', 'DummyDao'],
[$namespace, $className, $daoName],
$template
);
file_put_contents($file, $content);
}
}
@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\command\make;
use app\command\BaseCommand;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* 生成验证层命令
* 使用方法:
* - 生成验证器:php webman make:validate TestValidate
* - 生成带完整路径的验证器:php webman make:validate adminapi/validate/system/TestValidate
*
* @author Mr.April
* @since 1.0.0
*/
#[AsCommand(
name: 'madong-make:validate',
description: 'Generate a new validate class',
aliases: ['madong-make:validate'],
hidden: false
)]
class ValidateCommand extends BaseCommand
{
/**
* 配置命令
*/
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED, 'Validate name');
}
/**
* 执行命令
*/
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Validate Generator');
$name = $input->getArgument('name');
$io->info("Generating validate: {$name}");
// 处理路径和命名空间
$name = str_replace('\\', '/', $name);
$parts = explode('/', $name);
$className = ucfirst(array_pop($parts));
// 构建文件路径和命名空间
if (empty($parts)) {
// 如果没有提供路径,默认创建到app/validate目录
$file = app_path() . DIRECTORY_SEPARATOR . 'validate' . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\validate';
} else {
// 使用用户提供的完整路径
$relativePath = implode(DIRECTORY_SEPARATOR, $parts);
$file = app_path() . DIRECTORY_SEPARATOR . $relativePath . DIRECTORY_SEPARATOR . "{$className}.php";
$namespace = 'app\\' . str_replace('/', '\\', $relativePath);
}
if (is_file($file)) {
if (!$this->confirm($io, "$file already exists. Do you want to override it?")) {
$io->warning('Operation cancelled.');
return Command::SUCCESS;
}
}
$this->createValidate($className, $namespace, $file);
$io->success("Validate {$className} generated successfully!");
return Command::SUCCESS;
}
/**
* 创建验证器文件
*/
protected function createValidate(string $className, string $namespace, string $file): void
{
$path = pathinfo($file, PATHINFO_DIRNAME);
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
// 读取模板文件
$template = file_get_contents(__DIR__ . '/stubs/validate.stub');
// 替换占位符
$content = str_replace(
['DummyNamespace', 'DummyClass'],
[$namespace, $className],
$template
);
file_put_contents($file, $content);
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use core\base\BaseController;
use support\Request;
use app\adminapi\controller\Crud;
/**
* DummyClass控制器
*
* @author Mr.April
* @since 1.0
*/
final class DummyClass extends Crud
{
/**
* 构造函数
*/
public function __construct()
{
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use app\model\DummyModel;
use core\base\BaseDao;
/**
* DummyClass数据访问对象
*
* @author Mr.April
* @since 1.0
*/
class DummyClass extends BaseDao
{
/**
* 设置模型类
*/
protected function setModel(): string
{
return DummyModel::class;
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
/**
* DummyClass中间件
*
* @author Mr.April
* @since 1.0
*/
class DummyClass implements MiddlewareInterface
{
/**
* 处理请求
*/
public function process(Request \$request, callable \$handler): Response
{
// 前置中间件逻辑
\$response = \$handler(\$request);
// 后置中间件逻辑
return \$response;
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use core\base\BaseModel;
/**
* DummyClass模型
*
* @author Mr.April
* @since 1.0
*/
class DummyClass extends BaseModel
{
/**
* 数据表名称
*/
protected \$table = 'DummyTable';
/**
* 数据表主键
*/
protected \$primaryKey = 'id';
/**
* 可批量赋值的字段
*/
protected \$fillable = [
'id',
'created_at',
'updated_at',
];
/**
* 追加字段
*/
protected \$appends = [
'created_date',
'updated_date',
];
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use app\dao\DummyDao;
use core\base\BaseService;
/**
* DummyClass服务类
*
* @author Mr.April
* @since 1.0
*/
class DummyClass extends BaseService
{
/**
* 构造方法
*/
public function __construct(DummyDao \$dao)
{
\$this->dao = \$dao;
}
}
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace DummyNamespace;
use core\base\BaseValidate;
/**
* DummyClass验证器
*
* @author Mr.April
* @since 1.0
*/
class DummyClass extends BaseValidate
{
/**
* 定义验证规则
*/
protected array \$rule = [
// 示例规则
// 'name' => 'require|max:50',
// 'code' => 'require|alphaDash',
// 'enabled' => 'require',
];
/**
* 定义错误信息
*/
protected array \$message = [
// 示例错误信息
// 'name.require' => '名称必须填写',
// 'name.max' => '名称最多50个字符',
// 'code.require' => '标识必须填写',
// 'code.alphaDash' => '标识只能由英文字母组成',
];
/**
* 定义场景
*/
protected array \$scene = [
'store' => [
// 创建时验证的字段
],
'update' => [
// 更新时验证的字段
],
];
}