更新版本

This commit is contained in:
zoomtk@126.com 2023-02-23 20:14:36 +08:00
parent dd771a009e
commit d0c3c06659
167 changed files with 16265 additions and 76 deletions

View File

@ -17,9 +17,11 @@ use Builder\MineController;
use Builder\Entity\UISettingEntity; use Builder\Entity\UISettingEntity;
use Builder\Entity\UserEntity; use Builder\Entity\UserEntity;
use Builder\View;
use Builder\View\Layout\Content;
use Builder\View\Components\Widgets\Alert;
use Builder\Entity\MenuEntity; use Builder\Entity\MenuEntity;
use Builder\Entity\MenuItemEntity; use Builder\Entity\MenuItemEntity;
use Builder\View;
/** /**
* Class IndexController * Class IndexController
* @package App\Mall\Controller * @package App\Mall\Controller
@ -35,4 +37,19 @@ class IndexController extends MineController
$setting->setUser($user); $setting->setUser($user);
return View::make($setting); return View::make($setting);
} }
#[GetMapping("test")]
public function test()
{
$content = new Content();
$content->showHeader()
->title('测试')
->body(
Alert::make()
->type('error')
->title('这里是警告信息')
->description('我是提示消息哈哈哈')
);
return $content;
}
} }

View File

@ -19,6 +19,7 @@ use Builder\Entity\UISettingEntity;
use Builder\Entity\UserEntity; use Builder\Entity\UserEntity;
use Builder\MineController; use Builder\MineController;
use Builder\View; use Builder\View;
use Builder\View\Layout\Content;
/** /**
* Class IndexController * Class IndexController
* @package App\System\Controller * @package App\System\Controller
@ -35,4 +36,18 @@ class IndexController extends MineController
return View::make($setting); return View::make($setting);
} }
#[GetMapping("test")]
public function test(){
$content = new Content();
$content->showHeader()->title('测试')->body(Alert::make()->type('error')
->title('这里是警告信息')
->description('我是提示消息哈哈哈')
);
return $content;
var_dump(5555);
return 1;
}
} }

View File

@ -30,12 +30,6 @@ class LoginController extends MineController
#[Inject] #[Inject]
protected UserServiceInterface $userService; protected UserServiceInterface $userService;
public function index(){
}
/** /**
* @param SystemUserRequest $request * @param SystemUserRequest $request
* @return ResponseInterface * @return ResponseInterface
@ -68,6 +62,8 @@ class LoginController extends MineController
/** /**
* 用户信息 * 用户信息
* /**
* @param SystemUserRequest $request
* @return ResponseInterface * @return ResponseInterface
* @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface

View File

@ -8,9 +8,9 @@ use Hyperf\Utils\Filesystem\Filesystem;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\NullOutput;
use Builder\Mine;
use Builder\Abstracts\AbstractService; use Builder\Abstracts\AbstractService;
use Builder\Generator\ModuleGenerator; use Builder\Generator\ModuleGenerator;
use Builder\Mine;
class ModuleService extends AbstractService class ModuleService extends AbstractService
{ {
/** /**

View File

@ -2,7 +2,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\System\Service; namespace App\System\Service;
use App\System\Mapper\SystemUserMapper; use App\System\Mapper\SystemUserMapper;
use Hyperf\Cache\Annotation\Cacheable; use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Cache\Annotation\CacheEvict; use Hyperf\Cache\Annotation\CacheEvict;

View File

@ -170,12 +170,10 @@ class MineExecutor
{ {
return function () use ($crontab, $runnable) { return function () use ($crontab, $runnable) {
$taskMutex = $this->getTaskMutex(); $taskMutex = $this->getTaskMutex();
if ($taskMutex->exists($crontab) || ! $taskMutex->create($crontab)) { if ($taskMutex->exists($crontab) || ! $taskMutex->create($crontab)) {
$this->logger->info(sprintf('Crontab task [%s] skipped execution at %s.', $crontab->getName(), date('Y-m-d H:i:s'))); $this->logger->info(sprintf('Crontab task [%s] skipped execution at %s.', $crontab->getName(), date('Y-m-d H:i:s')));
return; return;
} }
try { try {
$runnable(); $runnable();
} finally { } finally {

View File

@ -1,10 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Entity; namespace Builder\Entity;
use Hyperf\Utils\Arr;
class EntityBean class EntityBean
{ {
public function __construct($array = []) public function __construct($array = [])
@ -25,10 +21,8 @@ class EntityBean
}, $str); }, $str);
return $str; return $str;
} }
public function toArray() public function toArray()
{ {
return (array)$this; return (array)$this;
} }
} }

View File

@ -1,8 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Entity; namespace Builder\Entity;
class MenuEntity class MenuEntity
{ {
/** /**

View File

@ -1,8 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Entity; namespace Builder\Entity;
class MenuItemEntity extends EntityBean class MenuItemEntity extends EntityBean
{ {
public $id; public $id;

View File

@ -1,17 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/**
* This file is part of Hyperf.plus
*
* @link https://www.hyperf.plus
* @document https://doc.hyperf.plus
* @contact 4213509@qq.com
* @license https://github.com/hyperf/hyperf-plus/blob/master/LICENSE
*/
namespace Builder\Entity; namespace Builder\Entity;
class UISettingEntity extends EntityBean class UISettingEntity extends EntityBean
{ {
/** /**

View File

@ -1,8 +1,6 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Entity; namespace Builder\Entity;
class UserEntity extends EntityBean class UserEntity extends EntityBean
{ {
/** /**

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Builder\Exception;
use Throwable;
class ApiException extends \Exception
{
public function __construct(string $message = null, int $code = 0, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Builder\Exception;
use Throwable;
class AppException extends \Exception
{
public function __construct(int $code = 0, string $message = null, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Builder\Exception;
use Throwable;
class BusinessException extends \Exception
{
public function __construct(int $code = 0, string $message = null, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -11,7 +11,6 @@
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Exception; namespace Builder\Exception;
class CaptchaException extends MineException class CaptchaException extends MineException
{ {

View File

@ -1,17 +1,6 @@
<?php <?php
/**
* MineAdmin is committed to providing solutions for quickly building web applications
* Please view the LICENSE file that was distributed with this source code,
* For the full copyright and license information.
* Thank you very much for using MineAdmin.
*
* @Author X.Mo<root@imoi.cn>
* @Link https://gitee.com/xmo/MineAdmin
*/
declare(strict_types=1); declare(strict_types=1);
namespace Builder\Exception; namespace Builder\Exception;
class MineException extends \RuntimeException class MineException extends \RuntimeException
{ {

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Builder\Exception;
use Throwable;
class ValidateException extends \Exception
{
public function __construct(int $code = 0, string $message = null, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -13,6 +13,10 @@ use App\System\Vo\QueueMessageVo;
use Hyperf\Contract\StdoutLoggerInterface; use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Logger\LoggerFactory; use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext; use Hyperf\Utils\ApplicationContext;
use Hyperf\HttpMessage\Server\Response;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\HttpServer\Request;
use Builder\Helper\LoginUser; use Builder\Helper\LoginUser;
use Builder\Helper\AppVerify; use Builder\Helper\AppVerify;
use Builder\Helper\Id; use Builder\Helper\Id;
@ -48,7 +52,6 @@ if (! function_exists('redis')) {
} }
if (! function_exists('console')) { if (! function_exists('console')) {
/** /**
* 获取控制台输出实例 * 获取控制台输出实例
* @return StdoutLoggerInterface * @return StdoutLoggerInterface
@ -59,7 +62,6 @@ if (! function_exists('console')) {
{ {
return container()->get(StdoutLoggerInterface::class); return container()->get(StdoutLoggerInterface::class);
} }
} }
if (! function_exists('logger')) { if (! function_exists('logger')) {
@ -235,4 +237,109 @@ if (! function_exists('add_queue')) {
->get(\App\System\Service\SystemQueueLogService::class) ->get(\App\System\Service\SystemQueueLogService::class)
->addQueue($amqpQueueVo); ->addQueue($amqpQueueVo);
} }
} }
if (!function_exists('request')) {
/**
* Get admin path.
* @param null $key
* @param null $default
* @return string
*/
function request($key = null, $default = null)
{
if ($key !== null) {
return (new Request())->all()[$key] ?? $default;
}
return new Request();
}
}
if (!function_exists('response')) {
/**
* Get admin path.
*
* @param string $path
*
* @return string
*/
function response(): ResponseInterface
{
return new Response();//return $res->withBody(new SwooleStream(json_encode($re_data,256)));
}
}
if (!function_exists('admin_api_url')) {
/**
* Get admin url.
*
* @param string $path
* @param mixed $parameters
* @param bool $secure
*
* @return string
*/
function admin_api_url($path = '', $parameters = [], $secure = null)
{
return '/' . str_replace('/list', '', $path);
}
}
//输出控制台日志
if (!function_exists('p')) {
function p($val, $title = null, $starttime = '')
{
print_r('[ ' . date("Y-m-d H:i:s") . ']:');
if ($title != null) {
print_r("[" . $title . "]:");
}
print_r($val);
print_r("\r\n");
}
}
if (!function_exists('uuid')) {
function uuid($length)
{
if (function_exists('random_bytes')) {
$uuid = bin2hex(\random_bytes($length));
} else if (function_exists('openssl_random_pseudo_bytes')) {
$uuid = bin2hex(\openssl_random_pseudo_bytes($length));
} else {
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$uuid = substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}
return $uuid;
}
}
if (!function_exists('route')) {
function route($url, $param = [])
{
if (is_validURL($url)) {
return $url;
}
$prefix = config('admin.route.prefix');
$https = config('admin.https');
$uri = request()->getUri();
$param = http_build_query($param);
if ($https) {
$uri = $uri->withScheme('https');
}
$uri = $uri->withQuery($param);
if (substr($url, 0, 1) !== '/') {
$url = '/' . $prefix . '/' . $url;
}
return $uri->withPath($url)->__toString();
}
}
if (!function_exists('is_validURL')) {
function is_validURL($url)
{
$check = 0;
if (filter_var($url, FILTER_VALIDATE_URL) !== false) {
$check = 1;
}
return $check;
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Builder\Interfaces;
interface MenuInterface
{
public function getId(): int;
public function getTitle(): string;
public function getIcon(): ?string;
public function getUri(): string;
public function getRoute(): string;
public function children(): array;
public function toArray(): array;
}

View File

@ -11,9 +11,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Builder; namespace Builder;
use Builder\Traits\ControllerTrait; use Builder\Traits\ControllerTrait;
/** /**
* API接口控制器基类 * API接口控制器基类
* Class MineApi * Class MineApi

View File

@ -26,7 +26,6 @@ class MineCollection extends Collection
{ {
$data = $this->toArray(); $data = $this->toArray();
if (empty($data)) return []; if (empty($data)) return [];
$routers = []; $routers = [];
foreach ($data as $menu) { foreach ($data as $menu) {
array_push($routers, $this->setRouter($menu)); array_push($routers, $this->setRouter($menu));
@ -69,11 +68,8 @@ class MineCollection extends Collection
public function toTree(array $data = [], int $parentId = 0, string $id = 'id', string $parentField = 'parent_id', string $children='children'): array public function toTree(array $data = [], int $parentId = 0, string $id = 'id', string $parentField = 'parent_id', string $children='children'): array
{ {
$data = $data ?: $this->toArray(); $data = $data ?: $this->toArray();
if (empty($data)) return []; if (empty($data)) return [];
$tree = []; $tree = [];
foreach ($data as $value) { foreach ($data as $value) {
if ($value[$parentField] == $parentId) { if ($value[$parentField] == $parentId) {
$child = $this->toTree($data, $value[$id], $id, $parentField, $children); $child = $this->toTree($data, $value[$id], $id, $parentField, $children);
@ -83,11 +79,9 @@ class MineCollection extends Collection
array_push($tree, $value); array_push($tree, $value);
} }
} }
unset($data); unset($data);
return $tree; return $tree;
} }
/** /**
* 导出数据 * 导出数据
* @param string $dto * @param string $dto
@ -129,5 +123,4 @@ class MineCollection extends Collection
} }
return $excel->import($model, $closure); return $excel->import($model, $closure);
} }
} }

View File

@ -11,9 +11,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Builder; namespace Builder;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerInterface;
use Builder\Traits\ControllerTrait; use Builder\Traits\ControllerTrait;
/** /**

View File

@ -8,10 +8,8 @@
* @Author X.Mo<root@imoi.cn> * @Author X.Mo<root@imoi.cn>
* @Link https://gitee.com/xmo/MineAdmin * @Link https://gitee.com/xmo/MineAdmin
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Builder; namespace Builder;
use Hyperf\DbConnection\Model\Model; use Hyperf\DbConnection\Model\Model;
use Hyperf\ModelCache\Cacheable; use Hyperf\ModelCache\Cacheable;
use Builder\Traits\ModelMacroTrait; use Builder\Traits\ModelMacroTrait;
@ -48,7 +46,6 @@ class MineModel extends Model
public function __construct(array $attributes = []) public function __construct(array $attributes = [])
{ {
parent::__construct($attributes); parent::__construct($attributes);
//注册常用方法 //注册常用方法
$this->registerBase(); $this->registerBase();
//注册用户数据权限方法 //注册用户数据权限方法

View File

@ -14,7 +14,6 @@ namespace Builder;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Request; use Hyperf\HttpServer\Request;
class MineRequest extends Request class MineRequest extends Request
{ {
/** /**
@ -39,7 +38,6 @@ class MineRequest extends Request
} else if (isset($headers['http_x_forwarded_for'])) { } else if (isset($headers['http_x_forwarded_for'])) {
$ip = $headers['http_x_forwarded_for'][0]; $ip = $headers['http_x_forwarded_for'][0];
} }
return $ip; return $ip;
} }

View File

@ -16,7 +16,7 @@ use Hyperf\HttpServer\Server;
class MineServer extends Server class MineServer extends Server
{ {
protected ?string $serverName = 'MineAdmin'; protected ?string $serverName = 'ViewUI';
protected $routes; protected $routes;

View File

@ -25,11 +25,12 @@ class MineStart extends ServerStartCallback
$service = container()->get(ModuleService::class); $service = container()->get(ModuleService::class);
$service->setModuleCache(); $service->setModuleCache();
$console = console(); $console = console();
$console->info('MineAdmin start success...'); $console->info('ViewUI start success...');
$console->info($this->welcome()); $console->info($this->welcome());
$console->info('current booting the user: ' . shell_exec('whoami')); $console->info('current booting the user: ' . shell_exec('whoami'));
} }
protected function welcome(): string protected function welcome(): string
{ {
return sprintf(' return sprintf('

View File

@ -10,7 +10,6 @@
*/ */
declare(strict_types = 1); declare(strict_types = 1);
namespace Builder\Traits; namespace Builder\Traits;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace Builder\Traits;
use Hyperf\Utils\Codec\Json;
class JsonBuilder
{
protected $hideAttrs = [];
public function jsonSerialize()
{
$data = [];
$hide = collect($this->hideAttrs)->push("hideAttrs")->toArray();
foreach ($this as $key => $val) {
if (!in_array($key, $hide) && $val !== null) {
$data[$key] = $val;
}
}
return $data;
}
public function __toString(): string
{
// TODO: Implement __toString() method.
return json_encode($this->jsonSerialize(), JSON_UNESCAPED_UNICODE);
}
}

View File

@ -10,14 +10,13 @@
*/ */
namespace Builder\Traits; namespace Builder\Traits;
use Hyperf\Contract\LengthAwarePaginatorInterface; use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Database\Model\Builder; use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model; use Hyperf\Database\Model\Model;
use Builder\Annotation\Transaction; use Builder\Annotation\Transaction;
use Builder\MineCollection; use Builder\MineCollection;
use Builder\MineModel; use Builder\MineModel;
trait MapperTrait trait MapperTrait
{ {
/** /**
@ -124,7 +123,6 @@ trait MapperTrait
if (isset($params['_mineadmin_tree'])) { if (isset($params['_mineadmin_tree'])) {
$query->orderBy($params['_mineadmin_tree_pid']); $query->orderBy($params['_mineadmin_tree_pid']);
} }
if ($params['orderBy'] ?? false) { if ($params['orderBy'] ?? false) {
if (is_array($params['orderBy'])) { if (is_array($params['orderBy'])) {
foreach ($params['orderBy'] as $key => $order) { foreach ($params['orderBy'] as $key => $order) {
@ -134,7 +132,6 @@ trait MapperTrait
$query->orderBy($params['orderBy'], $params['orderType'] ?? 'asc'); $query->orderBy($params['orderBy'], $params['orderType'] ?? 'asc');
} }
} }
return $query; return $query;
} }

View File

@ -0,0 +1,59 @@
<?php
namespace Builder\Validate\Annotations;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("METHOD")
*/
class RequestValidation extends AbstractAnnotation
{
/**
* 规则类
* @var string
*/
public $rules = [];
/**
* 验证器
* @var string
*/
public $validate = '';
/**
* 场景
* @var string
*/
public $scene = '';
/**
* 场景
* @var string
*/
public $value = '';
/**
* 是否过滤多余字段
* @var bool
*/
public $filter = false;
/**
* 安全模式严格按照规则字段,如果多字段会抛出异常
* @var bool
*/
public $security = false;
/**
* 是否批量验证
* @var bool
*/
public $batch = false;
/**
* 验证数据类型支持json|xml|form表单
* @var string
*/
public $dateType = 'json';
public function __construct($value = null)
{
parent::__construct($value);
$this->bindMainProperty('scene', $value);
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace Builder\Validate\Annotations;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("METHOD")
*/
class Validation extends AbstractAnnotation
{
/**
* 自定义规则
* @var string
*/
public $rules = [];
/**
* 验证器
* @var string
*/
public $validate = '';
/**
* 场景
* @var string
*/
public $value = '';
/**
* 场景
* @var string
*/
public $scene = '';
/**
* 是否过滤多余字段
* @var bool
*/
public $filter = false;
/**
* 安全模式严格按照规则字段,如果多字段会抛出异常
* @var bool
*/
public $security = false;
/**
* 是否批量验证
* @var bool
*/
public $batch = false;
/**
* 验证哪个参数
* @var string
*/
public $field = "data";
public function __construct($value = null)
{
parent::__construct($value);
$this->bindMainProperty('scene', $value);
}
}

View File

@ -0,0 +1,145 @@
<?php
declare(strict_types=1);
namespace Builder\Validate\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
use Hyperf\Context\Context;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Builder\Validate\Annotations\RequestValidation;
use Builder\Validate\Annotations\Validation;
use Builder\Validate\Validate;
use Builder\Validate\Exception\ValidateException;
/**
* @Aspect
*/
class ValidationAspect extends AbstractAspect
{
protected $container;
protected $request;
// 要切入的类,可以多个,亦可通过 :: 标识到具体的某个方法,通过 * 可以模糊匹配
public array $annotations = [
Validation::class,
RequestValidation::class
];
public function __construct(ContainerInterface $container, ServerRequestInterface $Request)
{
$this->container = $container;
$this->request = $this->container->get(ServerRequestInterface::class);
}
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws Exception
* @throws ValidateException
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
foreach ($proceedingJoinPoint->getAnnotationMetadata()->method as $validation) {
/**
* @var Validation $validation
*/
switch (true) {
case $validation instanceof RequestValidation:
$verData = $this->request->all();
$this->validationData($validation, $verData, $validation->validate, $proceedingJoinPoint, true);
break;
case $validation instanceof Validation:
$verData = $proceedingJoinPoint->arguments['keys'][$validation->field];
$this->validationData($validation, $verData, $validation->validate, $proceedingJoinPoint);
break;
default:
break;
}
}
return $proceedingJoinPoint->process();
}
/**
* @param $validation
* @param $verData
* @param $class
* @param $proceedingJoinPoint
* @param $isRequest
* @throws ValidateException
*/
private function validationData($validation, $verData, $class, $proceedingJoinPoint, $isRequest = false)
{
/**
* @var RequestValidation $validation
*/
/**
* @var Validate $validate
*/
if ($validation->rules != null) {
$validate = new Validate();
$rules = $validation->rules;
} else {
if (class_exists($class)) {
$validate = new $class;
} else {
throw new ValidateException('class not exists:' . $class);
}
if ($validation->scene == '') {
$validation->scene = $proceedingJoinPoint->methodName;
}
$rules = $validate->getSceneRule($validation->scene);
}
if ($validate->batch($validation->batch)->check($verData, $rules, $validation->scene) === false) {
throw new ValidateException($validate->getError());
}
if ($validation->security) {
$fields = $this->getFields($rules);
foreach ($verData as $key => $item) {
if (!in_array($key, $fields)) {
throw new ValidateException('params ' . $key . ' invalid');
}
}
};
if ($validation->filter) {
$fields = $this->getFields($rules);
$verData = array_filter($verData, function ($value, $key) use ($fields) {
return in_array($key, $fields);
}, ARRAY_FILTER_USE_BOTH);
switch ($isRequest) {
case true:
Context::override(ServerRequestInterface::class, function (ServerRequestInterface $request) use ($verData) {
return $request->withParsedBody($verData);
});
break;
default:
$proceedingJoinPoint->arguments['keys'][$validation->field] = $verData;
break;
}
}
}
protected function getFields(array $rules)
{
$fields = [];
foreach ($rules as $field => $rule) {
if (is_numeric($field)) {
$field = $rule;
}
if (strpos($field, '|')) {
// 字段|描述 用于指定属性名称
list($field,) = explode('|', $field);
}
$fields[] = $field;
}
return $fields;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Builder\Validate;
class ConfigProvider
{
public function __invoke(): array
{
return [
'annotations' => [
'scan' => [
'paths' => [
__DIR__,
]
]
]
];
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace Builder\Validate\Exception;
class ValidateException extends \Exception
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
<?php
namespace Builder\Validate;
/**
* Class ValidateRule
* @package think\validate
* @method ValidateRule confirm(mixed $field, string $msg = '') static 验证是否和某个字段的值一致
* @method ValidateRule different(mixed $field, string $msg = '') static 验证是否和某个字段的值是否不同
* @method ValidateRule egt(mixed $value, string $msg = '') static 验证是否大于等于某个值
* @method ValidateRule gt(mixed $value, string $msg = '') static 验证是否大于某个值
* @method ValidateRule elt(mixed $value, string $msg = '') static 验证是否小于等于某个值
* @method ValidateRule lt(mixed $value, string $msg = '') static 验证是否小于某个值
* @method ValidateRule eg(mixed $value, string $msg = '') static 验证是否等于某个值
* @method ValidateRule in(mixed $values, string $msg = '') static 验证是否在范围内
* @method ValidateRule notIn(mixed $values, string $msg = '') static 验证是否不在某个范围
* @method ValidateRule between(mixed $values, string $msg = '') static 验证是否在某个区间
* @method ValidateRule notBetween(mixed $values, string $msg = '') static 验证是否不在某个区间
* @method ValidateRule length(mixed $length, string $msg = '') static 验证数据长度
* @method ValidateRule max(mixed $max, string $msg = '') static 验证数据最大长度
* @method ValidateRule min(mixed $min, string $msg = '') static 验证数据最小长度
* @method ValidateRule after(mixed $date, string $msg = '') static 验证日期
* @method ValidateRule before(mixed $date, string $msg = '') static 验证日期
* @method ValidateRule expire(mixed $dates, string $msg = '') static 验证有效期
* @method ValidateRule allowIp(mixed $ip, string $msg = '') static 验证IP许可
* @method ValidateRule denyIp(mixed $ip, string $msg = '') static 验证IP禁用
* @method ValidateRule regex(mixed $rule, string $msg = '') static 使用正则验证数据
* @method ValidateRule token(mixed $token, string $msg = '') static 验证表单令牌
* @method ValidateRule is(mixed $rule = null, string $msg = '') static 验证字段值是否为有效格式
* @method ValidateRule isRequire(mixed $rule = null, string $msg = '') static 验证字段必须
* @method ValidateRule isNumber(mixed $rule = null, string $msg = '') static 验证字段值是否为数字
* @method ValidateRule isArray(mixed $rule = null, string $msg = '') static 验证字段值是否为数组
* @method ValidateRule isInteger(mixed $rule = null, string $msg = '') static 验证字段值是否为整形
* @method ValidateRule isFloat(mixed $rule = null, string $msg = '') static 验证字段值是否为浮点数
* @method ValidateRule isMobile(mixed $rule = null, string $msg = '') static 验证字段值是否为手机
* @method ValidateRule isIdCard(mixed $rule = null, string $msg = '') static 验证字段值是否为身份证号码
* @method ValidateRule isChs(mixed $rule = null, string $msg = '') static 验证字段值是否为中文
* @method ValidateRule isChsDash(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母及下划线
* @method ValidateRule isChsAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为中文和字母
* @method ValidateRule isChsAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母和数字
* @method ValidateRule isDate(mixed $rule = null, string $msg = '') static 验证字段值是否为有效格式
* @method ValidateRule isBool(mixed $rule = null, string $msg = '') static 验证字段值是否为布尔值
* @method ValidateRule isAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为字母
* @method ValidateRule isAlphaDash(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和下划线
* @method ValidateRule isAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和数字
* @method ValidateRule isAccepted(mixed $rule = null, string $msg = '') static 验证字段值是否为yes, on, 或是 1
* @method ValidateRule isEmail(mixed $rule = null, string $msg = '') static 验证字段值是否为有效邮箱格式
* @method ValidateRule isUrl(mixed $rule = null, string $msg = '') static 验证字段值是否为有效URL地址
* @method ValidateRule activeUrl(mixed $rule = null, string $msg = '') static 验证是否为合格的域名或者IP
* @method ValidateRule ip(mixed $rule = null, string $msg = '') static 验证是否有效IP
* @method ValidateRule fileExt(mixed $ext, string $msg = '') static 验证文件后缀
* @method ValidateRule fileMime(mixed $mime, string $msg = '') static 验证文件类型
* @method ValidateRule fileSize(mixed $size, string $msg = '') static 验证文件大小
* @method ValidateRule image(mixed $rule, string $msg = '') static 验证图像文件
* @method ValidateRule method(mixed $method, string $msg = '') static 验证请求类型
* @method ValidateRule dateFormat(mixed $format, string $msg = '') static 验证时间和日期是否符合指定格式
* @method ValidateRule unique(mixed $rule, string $msg = '') static 验证是否唯一
* @method ValidateRule behavior(mixed $rule, string $msg = '') static 使用行为类验证
* @method ValidateRule filter(mixed $rule, string $msg = '') static 使用filter_var方式验证
* @method ValidateRule requireIf(mixed $rule, string $msg = '') static 验证某个字段等于某个值的时候必须
* @method ValidateRule requireCallback(mixed $rule, string $msg = '') static 通过回调方法验证某个字段是否必须
* @method ValidateRule requireWith(mixed $rule, string $msg = '') static 验证某个字段有值的情况下必须
* @method ValidateRule must(mixed $rule = null, string $msg = '') static 必须验证
*/
class ValidateRule
{
// 验证字段的名称
protected $title;
// 当前验证规则
protected $rule = [];
// 验证提示信息
protected $message = [];
/**
* 添加验证因子
* @access protected
* @param string $name 验证名称
* @param mixed $rule 验证规则
* @param string $msg 提示信息
* @return $this
*/
protected function addItem($name, $rule = null, $msg = '')
{
if ($rule || 0 === $rule) {
$this->rule[$name] = $rule;
} else {
$this->rule[] = $name;
}
$this->message[] = $msg;
return $this;
}
/**
* 获取验证规则
* @access public
* @return array
*/
public function getRule()
{
return $this->rule;
}
/**
* 获取验证字段名称
* @access public
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* 获取验证提示
* @access public
* @return array
*/
public function getMsg()
{
return $this->message;
}
/**
* 设置验证字段名称
* @access public
* @return $this
*/
public function title($title)
{
$this->title = $title;
return $this;
}
public function __call($method, $args)
{
if ('is' == strtolower(substr($method, 0, 2))) {
$method = substr($method, 2);
}
array_unshift($args, lcfirst($method));
return call_user_func_array([$this, 'addItem'], $args);
}
public static function __callStatic($method, $args)
{
$rule = new static();
if ('is' == strtolower(substr($method, 0, 2))) {
$method = substr($method, 2);
}
array_unshift($args, lcfirst($method));
return call_user_func_array([$rule, 'addItem'], $args);
}
}

View File

@ -17,6 +17,48 @@ use Builder\Entity\UISettingEntity;
use Hyperf\HttpServer\Response; use Hyperf\HttpServer\Response;
class View extends MineResponse class View extends MineResponse
{ {
public static $metaTitle;
public static function response($data, $message = '', $code = 200, $headers = [])
{
$re_data = [
'code' => $code,
'message' => $message,
];
if ($data) {
$re_data['data'] = $data;
}
$response = new Response();
return $response->withBody(new SwooleStream(json_encode($re_data, 256)));
}
public static function responseMessage($message = '', $code = 200)
{
return self::response([], $message, $code);
}
public static function responseError($message = '', $code = 400)
{
return self::response([], $message, $code);
}
/**
* @param $url
* @param bool $isVueRoute
* @param string $message
* @param string $type info/success/warning/error
*/
public static function responseRedirect($url, $isVueRoute = true, $message = null, $type = 'success')
{
return self::response([
'url' => $url,
'isVueRoute' => $isVueRoute,
'type' => $type,
], $message, 301);
}
/*** /***
* @param UISettingEntity $setting * @param UISettingEntity $setting
* @param null $content * @param null $content

View File

@ -0,0 +1,125 @@
<?php
declare(strict_types=1);
namespace Builder\View\Actions;
use Builder\View\Components\Component;
use Builder\View\Grid\Concerns\HasDialog;
class BaseAction extends Component
{
use HasDialog;
const HANDLER_ROUTE = "route";
const HANDLER_LINK = "link";
const HANDLER_REQUEST = "request";
protected $componentName = "";
protected $className;
protected $style;
protected $resource;
protected $message;
protected $tooltip;
protected $requestMethod = "get";
protected $beforeEmit = [];
protected $afterEmit = [];
protected $successEmit = [];
public $hideAttrs = [];
/**
* BaseAction constructor.
*/
public function __construct()
{
$this->resource = admin_api_url(request()->path());
}
/**
* 设置request模式请求类型
* @param string $requestMethod
* @return $this
*/
public function requestMethod(string $requestMethod)
{
$this->requestMethod = $requestMethod;
return $this;
}
/**
* 确认操作提示信息
* @param mixed $message
* @return $this
*/
public function message($message)
{
$this->message = $message;
return $this;
}
/**
* 按钮气泡信息
* @param mixed $tooltip
* @return $this
*/
public function tooltip($tooltip)
{
$this->tooltip = $tooltip;
return $this;
}
/**
* 请求前出发事件
* @param string $beforeEmit
* @param mixed $data
* @return $this
*/
public function beforeEmit(string $beforeEmit, $data=null)
{
$this->beforeEmit = collect($this->beforeEmit)->push(["eventName" => $beforeEmit, "eventData" => $data]);
return $this;
}
/**
* 操作成功后触发事件
* @param string $successEmit
* @param mixed $data
* @return $this
*/
public function successEmit(string $successEmit, $data=null)
{
$this->successEmit = collect($this->successEmit)->push(["eventName" => $successEmit, "eventData" => $data]);
return $this;
}
/**
* 操作完成后触发事件,失败成功都会触发
* @param string $afterEmit
* @param mixed $data
* @return $this
*/
public function afterEmit(string $afterEmit, $data=null)
{
$this->afterEmit = collect($this->afterEmit)->push(["eventName" => $afterEmit, "eventData" => $data]);
return $this;
}
/**
* @return string
*/
public function getResource()
{
return $this->resource;
}
public function jsonSerialize()
{
$data = [];
$hide = collect($this->hideAttrs)->push("hideAttrs")->toArray();
foreach ($this as $key => $val) {
if (!in_array($key, $hide)) {
$data[$key] = $val;
}
}
return $data;
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Builder\View\Actions;
use Builder\View\Components\Attrs\Button;
class BaseRowAction extends BaseAction
{
use Button;
protected $order = 1;
protected $vif;
/**
* 设置排序越大越靠前
* @param int $order
* @return $this
*/
public function order(int $order)
{
$this->order = $order;
return $this;
}
/**
* 设置操作vif属性算法
* @param array $vif
* @return $this
*/
public function vif($vif)
{
$this->vif = $vif;
return $this;
}
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
class Area extends Line
{
protected $componentName = "AntvArea";
protected $canvasId;
protected $data;
protected $config;
public static function make()
{
return new Area();
}
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
class Column extends Line
{
protected $componentName = "AntvColumn";
protected $canvasId;
protected $data;
protected $config;
public static function make()
{
return new Column();
}
}

View File

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
use Builder\View\Components\Component;
class Funnel extends Component
{
protected $componentName = "AntvFunnel";
protected $canvasId;
protected $data;
protected $class;
protected $config;
public function __construct()
{
$this->canvasId = \Hyperf\Utils\Str::random();
}
public static function make()
{
return new Funnel();
}
/**
* 设置数据
* @param mixed $data
* @return $this
*/
public function data($data)
{
if ($data instanceof \Closure) {
$this->data = call_user_func($data);
} else {
$this->data = $data;
}
return $this;
}
/**
* 设置配置信息
* @param mixed $config
* @return $this
*/
public function config($config)
{
if ($config instanceof \Closure) {
$this->config = call_user_func($config);
} else {
$this->config = $config;
}
return $this;
}
public function class(string $class)
{
$this->class = $class;
return $this;
}
}

View File

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
use Hyperf\Utils\Str;
use Builder\View\Components\Component;
class Line extends Component
{
protected $componentName = "AntvLine";
protected $canvasId;
protected $data;
protected $config;
public function __construct()
{
$this->canvasId = Str::random();
}
public static function make()
{
return new Line();
}
/**
* 设置数据
* @param mixed $data
* @return $this
*/
public function data($data)
{
if ($data instanceof \Closure) {
$this->data = call_user_func($data);
} else {
$this->data = $data;
}
return $this;
}
/**
* 设置配置信息
* @param mixed $config
* @return $this
*/
public function config($config)
{
if ($config instanceof \Closure) {
$this->config = call_user_func($config);
} else {
$this->config = $config;
}
return $this;
}
}

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
use Builder\View\Components\Component;
class Pie extends Component
{
protected $componentName = "AntvPie";
protected $canvasId;
protected $data;
protected $config;
public function __construct()
{
$this->canvasId = \Hyperf\Utils\Str::random();
}
public static function make()
{
return new Pie();
}
/**
* 设置数据
* @param mixed $data
* @return $this
*/
public function data($data)
{
if ($data instanceof \Closure) {
$this->data = call_user_func($data);
} else {
$this->data = $data;
}
return $this;
}
/**
* 设置配置信息
* @param mixed $config
* @return $this
*/
public function config($config)
{
if ($config instanceof \Closure) {
$this->config = call_user_func($config);
} else {
$this->config = $config;
}
return $this;
}
}

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Antv;
class StepLine extends Line
{
protected $componentName = "AntvStepLine";
protected $canvasId;
protected $data;
protected $config;
public static function make()
{
return new StepLine();
}
}

View File

@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
trait Button
{
protected $content;
protected $size;
protected $type = "primary";
protected $plain = false;
protected $round = false;
protected $circle = false;
protected $disabled = false;
protected $icon;
protected $autofocus = false;
/**
* @param mixed $content
* @return $this
*/
public function content($content)
{
$this->content = $content;
return $this;
}
/**
* @param mixed $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* @param mixed $type
* @return $this
*/
public function type($type)
{
$this->type = $type;
return $this;
}
/**
* @param bool $plain
* @return $this
*/
public function plain(bool $plain = true)
{
$this->plain = $plain;
return $this;
}
/**
* @param bool $round
* @return $this
*/
public function round(bool $round = true)
{
$this->round = $round;
return $this;
}
/**
* @param bool $circle
* @return $this
*/
public function circle(bool $circle = true)
{
$this->circle = $circle;
return $this;
}
/**
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param mixed $icon
* @return $this
*/
public function icon($icon)
{
$this->icon = $icon;
return $this;
}
/**
* @param bool $autofocus
* @return $this
*/
public function autofocus(bool $autofocus = true)
{
$this->autofocus = $autofocus;
return $this;
}
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
class CascaderOption extends SelectOption
{
/**
* @var CascaderOption[]
*/
protected $children = [];
protected $leaf = true;
static function make($value, $label)
{
$op = new CascaderOption();
$op->type = "default";
$op->value = $value;
$op->label = $label;
return $op;
}
/**
* @param CascaderOption[] $children
* @return $this
*/
public function children($children)
{
$this->children = $children;
return $this;
}
/**
* @param bool $leaf
* @return $this
*/
public function leaf($leaf=true)
{
$this->leaf = $leaf;
return $this;
}
public function jsonSerialize()
{
$data = [];
foreach ($this as $key => $val) {
if (!empty($val)) $data[$key] = $val;
}
return $data;
}
}

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
class CascaderProps
{
public $expandTrigger = 'click';
public $multiple = false;
public $checkStrictly = false;
public $emitPath = true;
public $lazy = false;
public $lazyUrl;
public $value = 'value';
public $label = 'label';
public $children = 'children';
public $leaf = 'leaf';
}

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
trait Depend
{
protected $depend;
protected $paginate = 0;
protected $extUrlParams;
protected $label;
/**
* @param mixed $depend
* @return $this
*/
public function depend($depend)
{
$this->depend = $depend;
return $this;
}
/**
* @param mixed $paginate
* @return $this
*/
public function paginate($paginate)
{
$this->paginate = $paginate;
return $this;
}
/**
* @param mixed $extUrlParams
* @return $this
*/
public function extUrlParams($extUrlParams)
{
$this->extUrlParams = $extUrlParams;
return $this;
}
/**
* 远程加载时的默认显示名称因远程时一般仅有value
* @param object form 所属表单
* @param array $label ['key'=>'model','value'=>['value'=>'id','label'=>['title','label']]] // 所属关联模型 用于从data取值
* @return $this
*/
public function label(&$form, $label)
{
$this->label = $label;
$form->item($label['key'])->vif('label' . mt_rand(10000, 99999), false);
return $this;
}
}

View File

@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
use Builder\View\Layout\Content;
trait ElDialog
{
protected $title;
protected $width = "50%";
protected $fullscreen = false;
protected $top = "15vh";
protected $modal = true;
protected $lockScroll = true;
protected $customClass;
protected $closeOnClickModal = true;
protected $closeOnPressEscape = true;
protected $showClose = true;
protected $center = false;
protected $destroyOnClose = false;
protected $url = '';
/**
* 动态创建dialog的配置地址
*
* @param null $url
*/
public function setUrl($url): void
{
$this->url = $url;
}
protected $slot;
/**
* @param mixed $title
* @return $this
*/
public function title($title)
{
$this->title = $title;
return $this;
}
/**
* @param string $width
* @return $this
*/
public function width(string $width)
{
$this->width = $width;
return $this;
}
/**
* @param bool $fullscreen
* @return $this
*/
public function fullscreen(bool $fullscreen)
{
$this->fullscreen = $fullscreen;
return $this;
}
/**
* @param string $top
* @return $this
*/
public function top(string $top)
{
$this->top = $top;
return $this;
}
/**
* @param bool $modal
* @return $this
*/
public function modal(bool $modal)
{
$this->modal = $modal;
return $this;
}
/**
* @param bool $lockScroll
* @return $this
*/
public function lockScroll(bool $lockScroll)
{
$this->lockScroll = $lockScroll;
return $this;
}
/**
* @param mixed $customClass
* @return $this
*/
public function customClass($customClass)
{
$this->customClass = $customClass;
return $this;
}
/**
* @param bool $closeOnClickModal
* @return $this
*/
public function closeOnClickModal(bool $closeOnClickModal)
{
$this->closeOnClickModal = $closeOnClickModal;
return $this;
}
/**
* @param bool $closeOnPressEscape
* @return $this
*/
public function closeOnPressEscape(bool $closeOnPressEscape)
{
$this->closeOnPressEscape = $closeOnPressEscape;
return $this;
}
/**
* @param bool $showClose
* @return $this
*/
public function showClose(bool $showClose)
{
$this->showClose = $showClose;
return $this;
}
/**
* @param bool $center
* @return $this
*/
public function center(bool $center)
{
$this->center = $center;
return $this;
}
/**
* @param bool $destroyOnClose
* @return $this
*/
public function destroyOnClose(bool $destroyOnClose)
{
$this->destroyOnClose = $destroyOnClose;
return $this;
}
public function slot(\Closure $closure)
{
$this->slot = Content::make();
call_user_func($closure, $this->slot);
}
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
trait ElLink
{
protected $type = "default";
protected $underline = false;
protected $disabled = false;
protected $href;
protected $icon;
/**
* @param string $type
* @return $this
*/
public function type(string $type)
{
$this->type = $type;
return $this;
}
/**
* @param bool $underline
* @return $this
*/
public function underline(bool $underline = true)
{
$this->underline = $underline;
return $this;
}
/**
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param mixed $icon
* @return $this
*/
public function icon($icon)
{
$this->icon = $icon;
return $this;
}
}

View File

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
use Builder\Traits\JsonBuilder;
class SelectOption extends JsonBuilder
{
protected $type = "default";
protected $label;
protected $value;
protected $avatar;
protected $desc;
protected $disabled = false;
static function make($value, $label)
{
$op = new SelectOption();
$op->type = "default";
$op->value = $value;
$op->label = $label;
return $op;
}
/**
* 是否禁用该选项
* @param bool $disabled
* @return $this
*/
public function disabled($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param string $avatar
* @return $this
*/
public function avatar($avatar)
{
$this->avatar = $avatar;
return $this;
}
/**
* @param mixed $desc
* @return $this
*/
public function desc($desc)
{
$this->desc = $desc;
return $this;
}
}

View File

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
use Builder\Traits\JsonBuilder;
class Step extends JsonBuilder
{
protected $title;
protected $description;
protected $icon;
protected $status;
public static function make()
{
return new Step();
}
/**
* 标题
* @param mixed $title
* @return $this
*/
public function title($title)
{
$this->title = $title;
return $this;
}
/**
* 描述性文字
* @param string $description
* @return $this
*/
public function description($description)
{
$this->description = $description;
return $this;
}
/**
* 图标
* @param string $icon
* @return $this
*/
public function icon($icon)
{
$this->icon = $icon;
return $this;
}
/**
* 设置当前步骤的状态,不设置则根据 steps 确定状态
* @param mixed $status
* @return $this
*/
public function status($status)
{
$this->status = $status;
return $this;
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Attrs;
use Builder\Traits\JsonBuilder;
class TransferData extends JsonBuilder
{
protected $key;
protected $label;
protected $disabled = false;
static public function make($key, $label, $disabled = false)
{
return new TransferData($key, $label, $disabled);
}
/**
* TransferData constructor.
* @param $key
* @param $label
* @param bool $disabled
*/
public function __construct($key, $label, $disabled)
{
$this->key = $key;
$this->label = $label;
$this->disabled = $disabled;
}
/**
* @inheritDoc
*/
public function jsonSerialize()
{
$data = [];
foreach ($this as $key => $val) {
$data[$key] = $val;
}
return $data;
}
}

View File

@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components;
use Builder\Traits\JsonBuilder;
/**
* 组件基类
* Class Component
* @package Builder\View\Components
*/
class Component extends JsonBuilder
{
protected $componentName = "";
protected $className;
protected $style;
protected $componentValue;
protected $ref;
protected $refData;
public function __construct($value = null)
{
$this->componentValue($value);
}
/**
* class
* @param mixed $className
* @return $this
*/
public function className($className)
{
$this->className = $className;
return $this;
}
/**
* style
* @param mixed $style
* @return $this
*/
public function style($style)
{
$this->style = $style;
return $this;
}
/**
* @param $value
* @return $this
*/
public function componentValue($value)
{
$this->componentValue = $value;
return $this;
}
/**
* @return mixed
*/
public function getComponentValue()
{
return $this->componentValue;
}
/**
* @return mixed
*/
public function getRef()
{
return $this->ref;
}
/**
* 注册ref
* @param string $ref
* @return $this
*/
public function ref(string $ref)
{
$this->ref = $ref;
return $this;
}
/**
* ref动态注入
* @param string $ref 选择已注册的ref组件
* @param string|\Closure $refData 目标组件注入的js代码
* @param string $event 当前组件触发什么事件进行注入 click
* @return $this
*/
public function refData(string $ref, $refData, string $event = "click")
{
if ($refData instanceof \Closure) {
$data = call_user_func($refData);
} else {
$data = $refData;
}
$this->refData = [
'ref' => $ref,
"data" => $data
];
return $this;
}
}

View File

@ -0,0 +1,165 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class CSwitch extends Component
{
protected $componentName = "CSwitch";
protected $disabled = false;
protected $width = 40;
protected $activeIconClass;
protected $inactiveIconClass;
protected $activeText;
protected $inactiveText;
protected $activeValue = 1;
protected $inactiveValue = 0;
protected $activeColor = "#409EFF";
protected $inactiveColor = "#C0CCDA";
protected $name = "#C0CCDA";
protected $validateEvent = true;
static public function make($value = false)
{
return new CSwitch($value);
}
public function getValue($value)
{
return $value;//boolval($value == $this->activeValue);
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* switch 的宽度(像素)
* @param int $width
* @return $this
*/
public function width(int $width)
{
$this->width = $width;
return $this;
}
/**
* switch 打开时所显示图标的类名,设置此项会忽略 active-text
* @param string $activeIconClass
* @return $this
*/
public function activeIconClass($activeIconClass)
{
$this->activeIconClass = $activeIconClass;
return $this;
}
/**
* switch 关闭时所显示图标的类名,设置此项会忽略 inactive-text
* @param string $inactiveIconClass
* @return $this
*/
public function inactiveIconClass($inactiveIconClass)
{
$this->inactiveIconClass = $inactiveIconClass;
return $this;
}
/**
* switch 打开时的文字描述
* @param string $activeText
* @return $this
*/
public function activeText($activeText)
{
$this->activeText = $activeText;
return $this;
}
/**
* switch 关闭时的文字描述
* @param string $inactiveText
* @return $this
*/
public function inactiveText($inactiveText)
{
$this->inactiveText = $inactiveText;
return $this;
}
/**
* switch 打开时的值
* @param bool $activeValue
* @return $this
*/
public function activeValue($activeValue)
{
$this->activeValue = $activeValue;
return $this;
}
/**
* switch 关闭时的值
* @param bool $inactiveValue
* @return $this
*/
public function inactiveValue($inactiveValue)
{
$this->inactiveValue = $inactiveValue;
return $this;
}
/**
* switch 打开时的背景色
* @param string $activeColor
* @return $this
*/
public function activeColor($activeColor)
{
$this->activeColor = $activeColor;
return $this;
}
/**
* switch 关闭时的背景色
* @param string $inactiveColor
* @return $this
*/
public function inactiveColor($inactiveColor)
{
$this->inactiveColor = $inactiveColor;
return $this;
}
/**
* switch 对应的 name 属性
* @param string $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* 改变 switch 状态时是否触发表单的校验
* @param bool $validateEvent
* @return $this
*/
public function validateEvent($validateEvent = true)
{
$this->validateEvent = $validateEvent;
return $this;
}
}

View File

@ -0,0 +1,276 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Attrs\CascaderProps;
use Builder\View\Components\Component;
/**
* 级联选择器
* Class Cascader
* @package HPlus\UI\Components\Form
*/
class Cascader extends Component
{
protected $componentName = "Cascader";
protected $options = [];
/**
* @var CascaderProps;
*/
protected $props;
protected $size;
protected $placeholder = "请选择";
protected $disabled = false;
protected $clearable = false;
protected $showAllLevels = true;
protected $collapseTags = false;
protected $separator = " / ";
protected $filterable = false;
protected $debounce = 300;
protected $popperClass;
protected $panel = false;
static public function make($value = null)
{
$cascader = new Cascader($value);
$cascader->props = new CascaderProps();
return $cascader;
}
/**
* 显示为面板模式
* @param bool $panel
* @return $this
*/
public function panel($panel = true)
{
$this->panel = $panel;
return $this;
}
/**
* 尺寸
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 输入框占位文本
* @param string $placeholder
* @return $this
*/
public function placeholder($placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 是否支持清空选项
* @param bool $clearable
* @return $this
*/
public function clearable($clearable = true)
{
$this->clearable = $clearable;
return $this;
}
/**
* 输入框中是否显示选中值的完整路径
* @param bool $showAllLevels
* @return $this
*/
public function showAllLevels($showAllLevels = true)
{
$this->showAllLevels = $showAllLevels;
return $this;
}
/**
* 多选模式下是否折叠Tag
* @param bool $collapseTags
* @return $this
*/
public function collapseTags($collapseTags = true)
{
$this->collapseTags = $collapseTags;
return $this;
}
/**
* 选项分隔符
* @param string $separator
* @return $this
*/
public function separator($separator)
{
$this->separator = $separator;
return $this;
}
/**
* 是否可搜索选项
* @param bool $filterable
* @return $this
*/
public function filterable($filterable = true)
{
$this->filterable = $filterable;
return $this;
}
/**
* debounce
* @param int $debounce
* @return $this
*/
public function debounce($debounce)
{
$this->debounce = $debounce;
return $this;
}
/**
* 自定义浮层类名
* @param mixed $popperClass
* @return $this
*/
public function popperClass($popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* 次级菜单的展开方式
* click / hover
* @param string $expandTrigger
* @return $this
*/
public function expandTrigger($expandTrigger)
{
$this->props->expandTrigger = $expandTrigger;
return $this;
}
/**
* 是否多选
* @param bool $multiple
* @return $this
*/
public function multiple($multiple = true)
{
$this->props->multiple = $multiple;
return $this;
}
/**
* 是否严格的遵守父子节点不互相关联
* @param bool $checkStrictly
* @return $this
*/
public function checkStrictly($checkStrictly = true)
{
$this->props->checkStrictly = $checkStrictly;
return $this;
}
/**
* 在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
* @param bool $emitPath
* @return $this
*/
public function emitPath($emitPath = true)
{
$this->props->emitPath = $emitPath;
return $this;
}
/**
* 是否动态加载子节点,需与 lazyLoad 方法结合使用
* @param bool $layz
* @param string $lazyUrl
* @return $this
*/
public function lazy($layz = true, $lazyUrl = '')
{
$this->props->lazy = $layz;
$this->props->lazyUrl = $lazyUrl;
return $this;
}
/**
* 指定选项的值为选项对象的某个属性值
* @param string $value
* @return $this
*/
public function value($value)
{
$this->props->value = $value;
return $this;
}
/**
* 指定选项标签为选项对象的某个属性值
* @param string $label
* @return $this
*/
public function label($label)
{
$this->props->label = $label;
return $this;
}
/**
* 指定选项的子选项为选项对象的某个属性值
* @param string $children
* @return $this
*/
public function children($children)
{
$this->props->children = $children;
return $this;
}
/**
* 指定选项的叶子节点的标志位为选项对象的某个属性值
* @param string $leaf
* @return $this
*/
public function leaf($leaf)
{
$this->props->leaf = $leaf;
return $this;
}
/**
* 设置选项值数组
* @param array $options
* @return $this
*/
public function options($options)
{
$this->options = $options;
return $this;
}
}

View File

@ -0,0 +1,138 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class Checkbox extends Component
{
protected $componentName = "Checkbox";
protected $label;
protected $trueLabel;
protected $falseLabel;
protected $disabled = false;
protected $border = false;
protected $size;
protected $name;
protected $checked = false;
protected $indeterminate = false;
protected $title;
/**
* @param string|int|bool $label
* @param string $title
* @return Checkbox
*/
static public function make($label, $title = null)
{
$title = $title ?: $label;
return (new Checkbox($label))->label($label)->title($title);
}
/**
* 选中状态的值只有在checkbox-group或者绑定对象类型为array时有效
* @param string|int|bool $label
* @return $this
*/
public function label($label)
{
$this->label = $label;
return $this;
}
/**
* 选中时的值
* @param string|int $trueLabel
* @return $this
*/
public function trueLabel($trueLabel)
{
$this->trueLabel = $trueLabel;
return $this;
}
/**
* 没有选中时的值
* @param string|int $falseLabel
* @return $this
*/
public function falseLabel($falseLabel)
{
$this->falseLabel = $falseLabel;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 是否显示边框
* @param bool $border
* @return $this
*/
public function border(bool $border = true)
{
$this->border = $border;
return $this;
}
/**
* Checkbox 的尺寸,仅在 border 为真时有效
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 原生 name 属性
* @param string $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* 当前是否勾选
* @param bool $checked
* @return $this
*/
public function checked(bool $checked = true)
{
$this->checked = $checked;
return $this;
}
/**
* 设置 indeterminate 状态,只负责样式控制
* @param bool $indeterminate
* @return $this
*/
public function indeterminate(bool $indeterminate = true)
{
$this->indeterminate = $indeterminate;
return $this;
}
public function title(string $title)
{
$this->title = $title;
return $this;
}
}

View File

@ -0,0 +1,113 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class CheckboxGroup extends Component
{
protected $componentName = "CheckboxGroup";
/**
* @var string
*/
protected $size;
protected $disabled = false;
/**
* @var int
*/
public $min = 0;
/**
* @var int
*/
protected $max;
protected $textColor = "#ffffff";
protected $fill = "#409EFF";
/**
* @var Checkbox[]
*/
protected $options = [];
static public function make($value = [], $options = [])
{
return (new CheckboxGroup($value))->options($options);
}
/**
* 多选框组尺寸,仅对按钮形式的 Checkbox 或带有边框的 Checkbox 有效
* @param string $size
* @return $this
*/
public function size(string $size)
{
$this->size = $size;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* 可被勾选的 checkbox 的最小数量
* @param int $min
* @return $this
*/
public function min(int $min)
{
$this->min = $min;
return $this;
}
/**
* 可被勾选的 checkbox 的最大数量
* @param int $max
* @return $this
*/
public function max(int $max)
{
$this->max = $max;
return $this;
}
/**
* 按钮形式的 Checkbox 激活时的文本颜色
* @param string $textColor
* @return $this
*/
public function textColor(string $textColor)
{
$this->textColor = $textColor;
return $this;
}
/**
* 按钮形式的 Checkbox 激活时的填充色和边框色
* @param string $fill
* @return $this
*/
public function fill(string $fill)
{
$this->fill = $fill;
return $this;
}
/**
* @param Checkbox[] $options
* @return $this
*/
public function options(array $options)
{
$this->options = $options;
if (!$this->max) {
$this->max = count($options);
}
return $this;
}
}

View File

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class ColorPicker extends Component
{
protected $componentName = "ColorPicker";
protected $disabled = false;
/**
* @var string
*/
protected $size;
protected $showAlpha = false;
/**
* @var string
*/
protected $colorFormat;
/**
* @var string
*/
protected $popperClass;
protected $predefine = [];
static public function make($value = null)
{
return new ColorPicker($value);
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 尺寸 medium / small / mini
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 是否支持透明度选择
* @param bool $showAlpha
* @return $this
*/
public function showAlpha($showAlpha = true)
{
$this->showAlpha = $showAlpha;
return $this;
}
/**
* 写入 v-model 的颜色的格式
* hsl / hsv / hex / rgb
* @param string $colorFormat
* @return $this
*/
public function colorFormat($colorFormat)
{
$this->colorFormat = $colorFormat;
return $this;
}
/**
* ColorPicker 下拉框的类名
* @param string $popperClass
* @return $this
*/
public function popperClass($popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* 预定义颜色
* @param array $predefine
* @return $this
*/
public function predefine($predefine)
{
$this->predefine = $predefine;
return $this;
}
}

View File

@ -0,0 +1,274 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
use Carbon\Traits\Date;
/**
* Class DatePicker
* @package HPlus\UI\Components
*/
class DatePicker extends Component
{
protected $componentName = "DatePicker";
protected $readonly = false;
protected $disabled = false;
protected $editable = true;
protected $clearable = true;
protected $size;
protected $placeholder;
protected $startPlaceholder;
protected $endPlaceholder;
protected $type = "date";
protected $format = "yyyy-MM-dd";
protected $align = "left";
protected $popperClass;
protected $pickerOptions;
protected $rangeSeparator = "-";
protected $defaultValue;
protected $defaultTime;
protected $valueFormat = "yyyy-MM-dd";
protected $unlinkPanels = false;
protected $prefixIcon = "el-icon-date";
protected $clearIcon = "el-icon-circle-close";
protected $validateEvent = true;
static public function make($value = null, $type = "date")
{
return (new DatePicker($value))->type($type);
}
/**
* 完全只读
* @param bool $readonly
* @return $this
*/
public function readonly($readonly = true)
{
$this->readonly = $readonly;
return $this;
}
/**
* 禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* 文本框可输入
* @param bool $editable
* @return $this
*/
public function editable($editable = true)
{
$this->editable = $editable;
return $this;
}
/**
* 是否显示清除按钮
* @param bool $clearable
* @return $this
*/
public function clearable($clearable)
{
$this->clearable = $clearable;
return $this;
}
/**
* 输入框尺寸
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 非范围选择时的占位内容
* @param string $placeholder
* @return $this
*/
public function placeholder($placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 范围选择时开始日期的占位内容
* @param string $startPlaceholder
* @return $this
*/
public function startPlaceholder($startPlaceholder)
{
$this->startPlaceholder = $startPlaceholder;
return $this;
}
/**
* 范围选择时结束日期的占位内容
* @param string $endPlaceholder
* @return $this
*/
public function endPlaceholder($endPlaceholder)
{
$this->endPlaceholder = $endPlaceholder;
return $this;
}
/**
* 显示类型
* year/month/date/dates/week/datetime/datetimerange/daterange/monthrange
* @param string $type
* @return $this
*/
public function type($type)
{
$this->type = $type;
return $this;
}
/**
* 显示在输入框中的格式
* @param string $format
* @return $this
*/
public function format($format)
{
$this->format = $format;
return $this;
}
/**
* 对齐方式
* @param string $align
* @return $this
*/
public function align($align)
{
$this->align = $align;
return $this;
}
/**
* DatePicker 下拉框的类名
* @param string $popperClass
* @return $this
*/
public function popperClass($popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* 当前时间日期选择器特有的选项参考下表
* @param array $pickerOptions
* @return $this
*/
public function pickerOptions($pickerOptions)
{
$this->pickerOptions = $pickerOptions;
return $this;
}
/**
* 选择范围时的分隔符
* @param string $rangeSeparator
* @return $this
*/
public function rangeSeparator($rangeSeparator)
{
$this->rangeSeparator = $rangeSeparator;
return $this;
}
/**
* 可选,选择器打开时默认显示的时间
* @param Date $defaultValue
* @return $this
*/
public function defaultValue($defaultValue)
{
$this->defaultValue = $defaultValue;
return $this;
}
/**
* 范围选择时选中日期所使用的当日内具体时刻
* @param string[] $defaultTime
* @return $this
*/
public function defaultTime($defaultTime)
{
$this->defaultTime = $defaultTime;
return $this;
}
/**
* 可选,绑定值的格式。不指定则绑定值为 Date 对象
* @param mixed $valueFormat
* @return $this
*/
public function valueFormat($valueFormat)
{
$this->valueFormat = $valueFormat;
return $this;
}
/**
* 在范围选择器里取消两个日期面板之间的联动
* @param bool $unlinkPanels
* @return $this
*/
public function unlinkPanels($unlinkPanels = true)
{
$this->unlinkPanels = $unlinkPanels;
return $this;
}
/**
* 自定义头部图标的类名
* @param string $prefixIcon
* @return $this
*/
public function prefixIcon($prefixIcon)
{
$this->prefixIcon = $prefixIcon;
return $this;
}
/**
* 自定义清空图标的类名
* @param string $clearIcon
* @return $this
*/
public function clearIcon($clearIcon)
{
$this->clearIcon = $clearIcon;
return $this;
}
/**
* 输入时是否触发表单的校验
* @param bool $validateEvent
* @return $this
*/
public function validateEvent($validateEvent = true)
{
$this->validateEvent = $validateEvent;
return $this;
}
}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
class DateTimePicker extends DatePicker
{
protected $componentName = "DateTimePicker";
protected $format = "yyyy-MM-dd HH:mm:ss";
protected $valueFormat = "yyyy-MM-dd HH:mm:ss";
static public function make($value = null, $type = "datetime")
{
return (new DateTimePicker($value))->type($type);
}
}

View File

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class IconChoose extends Component
{
protected $componentName = "IconChoose";
protected $clearable = true;
protected $userInput = true;
protected $autoClose = true;
protected $disabled = false;
protected $placement = "right";
protected $placeholder = "请点击右侧选择图标";
public static function make($value = null)
{
return new IconChoose($value);
}
/**
* @param string $placement
* @return $this
*/
public function placement(string $placement)
{
$this->placement = $placement;
return $this;
}
/**
* 是否可清空
* @param bool $clearable
* @return $this
*/
public function clearable(bool $clearable = true)
{
$this->clearable = $clearable;
return $this;
}
/**
* 是否用户可输入
* @param bool $userInput
* @return $this
*/
public function userInput(bool $userInput = true)
{
$this->userInput = $userInput;
return $this;
}
/**
* 选择后关闭
* @param bool $autoClose
* @return $this
*/
public function autoClose(bool $autoClose = true)
{
$this->autoClose = $autoClose;
return $this;
}
/**
* 占位符
* @param string $placeholder
* @return $this
*/
public function placeholder(string $placeholder = '')
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
}

View File

@ -0,0 +1,354 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class Input extends Component
{
protected $componentName = "Input";
protected $type = "text";
protected $maxlength;
protected $minlength;
protected $showWordLimit = false;
protected $placeholder;
protected $clearable = false;
protected $showPassword = false;
protected $disabled = false;
protected $size;
protected $prefixIcon;
protected $suffixIcon;
protected $rows = 2;
protected $autosize = false;
protected $autocomplete = "off";
protected $readonly = false;
protected $max;
protected $min;
protected $step;
protected $resize;
protected $autofocus = false;
protected $form;
protected $label;
protected $tabindex;
protected $validateEvent = true;
protected $prepend;
protected $append;
static public function make($value = "")
{
return new Input($value);
}
/**
* @param int $rows
* @return $this
*/
public function textarea($rows = 2)
{
$this->type = "textarea";
$this->rows = $rows;
return $this;
}
/**
* @return $this
*/
public function password()
{
$this->type = "password";
return $this;
}
/**
* 类型
* texttextarea 和其他 原生 input type
* @param string $type
* @return $this
*/
public function type($type)
{
$this->type = $type;
return $this;
}
/**
* 原生属性,最大输入长度
* @param string $maxlength
* @return $this
*/
public function maxlength($maxlength)
{
$this->maxlength = $maxlength;
return $this;
}
/**
* 原生属性,最小输入长度
* @param string $minlength
* @return $this
*/
public function minlength($minlength)
{
$this->minlength = $minlength;
return $this;
}
/**
* 是否显示输入字数统计,只在 type = "text" type = "textarea" 时有效
* 必须设置maxlength才会生效
* @param bool $showWordLimit
* @return $this
*/
public function showWordLimit(bool $showWordLimit = true)
{
$this->showWordLimit = $showWordLimit;
return $this;
}
/**
* 输入框占位文本
* @param string $placeholder
* @return $this
*/
public function placeholder($placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 是否可清空
* @param bool $clearable
* @return $this
*/
public function clearable(bool $clearable = true)
{
$this->clearable = $clearable;
return $this;
}
/**
* 是否显示切换密码图标
* @param bool $showPassword
* @return $this
*/
public function showPassword(bool $showPassword = true)
{
$this->showPassword = $showPassword;
return $this;
}
/**
* 禁用
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 输入框尺寸,只在 type!="textarea" 时有效
* medium / small / mini
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 输入框头部图标
* @param string $prefixIcon
* @return $this
*/
public function prefixIcon($prefixIcon)
{
$this->prefixIcon = $prefixIcon;
return $this;
}
/**
* 输入框尾部图标
* @param string $suffixIcon
* @return $this
*/
public function suffixIcon($suffixIcon)
{
$this->suffixIcon = $suffixIcon;
return $this;
}
/**
* 输入框行数,只对 type="textarea" 有效
* @param int $rows
* @return $this
*/
public function rows(int $rows)
{
$this->rows = $rows;
return $this;
}
/**
* 自适应内容高度,只对 type="textarea" 有效,可传入对象,如,{ minRows: 2, maxRows: 6 }
* @param bool $autosize
* @return $this
*/
public function autosize(bool $autosize)
{
$this->autosize = $autosize;
return $this;
}
/**
* 原生属性,自动补全
* @param string $autocomplete
* @return $this
*/
public function autocomplete(string $autocomplete)
{
$this->autocomplete = $autocomplete;
return $this;
}
/**
* 原生属性,是否只读
* @param bool $readonly
* @return $this
*/
public function readonly(bool $readonly = true)
{
$this->readonly = $readonly;
return $this;
}
/**
* 原生属性,设置最大值
* @param string $max
* @return $this
*/
public function max($max)
{
$this->max = $max;
return $this;
}
/**
* 原生属性,设置最小值
* @param string $min
* @return $this
*/
public function min($min)
{
$this->min = $min;
return $this;
}
/**
* 原生属性,设置输入字段的合法数字间隔
* @param string $step
* @return $this
*/
public function step($step)
{
$this->step = $step;
return $this;
}
/**
* 控制是否能被用户缩放
* @param string $resize
* @return $this
*/
public function resize($resize)
{
$this->resize = $resize;
return $this;
}
/**
* 原生属性,自动获取焦点
* @param bool $autofocus
* @return $this
*/
public function autofocus(bool $autofocus = true)
{
$this->autofocus = $autofocus;
return $this;
}
/**
* 原生属性
* @param string $form
* @return $this
*/
public function form($form)
{
$this->form = $form;
return $this;
}
/**
* 输入框关联的label文字
* @param string $label
* @return $this
*/
public function label($label)
{
$this->label = $label;
return $this;
}
/**
* 输入框的tabindex
* @param string $tabindex
* @return $this
*/
public function tabindex($tabindex)
{
$this->tabindex = $tabindex;
return $this;
}
/**
* 输入时是否触发表单的校验
* @param bool $validateEvent
* @return $this
*/
public function validateEvent(bool $validateEvent = true)
{
$this->validateEvent = $validateEvent;
return $this;
}
/**
* 输入框前置内容
* @param mixed $prepend
* @return $this
*/
public function prepend($prepend)
{
$this->prepend = $prepend;
return $this;
}
/**
* 输入框后置内容
* @param mixed $append
* @return $this
*/
public function append($append)
{
$this->append = $append;
return $this;
}
}

View File

@ -0,0 +1,190 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
/**
* Class InputNumber
* @package HPlus\UI\Components
*/
class InputNumber extends Component
{
protected $componentName = 'InputNumber';
/**
* @var int
*/
protected $min = -999999999;
/**
* @var int
*/
protected $max = 999999999;
/**
* @var int|float
*/
protected $step = 1;
protected $stepStrictly = false;
/**
* @var int
*/
public $precision;
/**
* @var string
*/
protected $size;
protected $disabled = false;
protected $controls = true;
protected $controlsPosition = 'right';
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $label;
/**
* @var string
*/
protected $placeholder;
static public function make($value = 0)
{
return new InputNumber($value);
}
/**
* 设置计数器允许的最小值
* @param int|float $min
* @return $this
*/
public function min($min)
{
$this->min = $min;
return $this;
}
/**
* 设置计数器允许的最大值
* @param int|float $max
* @return $this
*/
public function max($max)
{
$this->max = $max;
return $this;
}
/**
* 计数器步长
* @param int|float $step
* @return $this
*/
public function step($step)
{
$this->step = $step;
return $this;
}
/**
* 是否只能输入 step 的倍数
* @param bool $stepStrictly
* @return $this
*/
public function stepStrictly(bool $stepStrictly = true)
{
$this->stepStrictly = $stepStrictly;
return $this;
}
/**
* 数值精度
* @param int $precision
* @return $this
*/
public function precision(int $precision)
{
$this->precision = $precision;
return $this;
}
/**
* 计数器尺寸
* large, small
* @param string $size
* @return $this
*/
public function size(string $size)
{
$this->size = $size;
return $this;
}
/**
* 是否禁用计数器
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 是否使用控制按钮
* @param bool $controls
* @return $this
*/
public function controls(bool $controls = true)
{
$this->controls = $controls;
return $this;
}
/**
* 控制按钮位置
* @param string $controlsPosition
* @return $this
*/
public function controlsPosition(string $controlsPosition)
{
$this->controlsPosition = $controlsPosition;
return $this;
}
/**
* 原生属性
* @param string $name
* @return $this
*/
public function name(string $name)
{
$this->name = $name;
return $this;
}
/**
* 输入框关联的label文字
* @param string $label
* @return $this
*/
public function label(string $label)
{
$this->label = $label;
return $this;
}
/**
* 输入框默认 placeholder
* @param string $placeholder
* @return $this
*/
public function placeholder(string $placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
}

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class ItemSelect extends Component
{
protected $componentName = "ItemSelect";
public static function make()
{
return new ItemSelect();
}
}

View File

@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class Radio extends Component
{
protected $componentName = "Radio";
/**
* @var string
*/
protected $label;
protected $disabled = false;
protected $border = false;
/**
* @var string
*/
protected $size;
/**
* 原生 name 属性
* @var string
*/
protected $name;
protected $title;
static public function make($value, $title)
{
return (new Radio($value))->label($value)->title($title);
}
/**
* Radio value
* @param $label
* @return $this
*/
public function label($label)
{
$this->label = $label;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* 是否显示边框
* @param bool $border
* @return $this
*/
public function border(bool $border = true)
{
$this->border = $border;
return $this;
}
/**
* Radio 的尺寸,仅在 border 为真时有效
* @param string $size
* @return $this
*/
public function size(string $size)
{
$this->size = $size;
return $this;
}
/**
* 原生 name 属性
* @param string $name
* @return $this
*/
public function name(string $name)
{
$this->name = $name;
return $this;
}
public function title(string $title)
{
$this->title = $title;
return $this;
}
}

View File

@ -0,0 +1,94 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class RadioGroup extends Component
{
protected $componentName = "RadioGroup";
protected $size;
protected $disabled = false;
protected $textColor = "#ffffff";
protected $fill = "#409EFF";
/**
* @var Radio[]
*/
public $options = [];
/**
* @param mixed $value
* @param Radio[] $options
* @return RadioGroup
*/
public static function make($value = null, $options = [])
{
return (new RadioGroup($value))->options($options);
}
/**
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* @param bool $disabled
* @return RadioGroup
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param string $textColor
* @return RadioGroup
*/
public function textColor(string $textColor)
{
$this->textColor = $textColor;
return $this;
}
/**
* @param string $fill
* @return RadioGroup
*/
public function fill(string $fill)
{
$this->fill = $fill;
return $this;
}
/**
* @param Radio[]|\Closure $options
* @return RadioGroup
*/
public function options($options)
{
if ($options instanceof \Closure) {
$this->options = call_user_func($options);
} else {
$this->options = $options;
}
return $this;
}
public function border()
{
collect($this->options)->each(function (Radio $radio) {
$radio->setBorder();
});
return $this;
}
}

View File

@ -0,0 +1,196 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class Rate extends Component
{
protected $componentName = "Rate";
protected $max = 5;
protected $disabled = false;
protected $allowHalf = false;
protected $lowThreshold = 2;
protected $highThreshold = 2;
protected $colors = ['#F7BA2A', '#F7BA2A', '#F7BA2A'];
protected $voidColor = '#C6D1DE';
protected $disabledVoidColor = '#EFF2F7';
protected $iconClasses = ['el-icon-star-on', 'el-icon-star-on', 'el-icon-star-on'];
protected $voidIconClass = "el-icon-star-off";
protected $disabledVoidIconClass = "el-icon-star-on";
protected $showText = false;
protected $showScore = false;
protected $textColor = "#1F2D3D";
protected $texts = ['极差', '失望', '一般', '满意', '惊喜'];
static public function make($value = 0)
{
return new Rate($value);
}
/**
* 最大分值
* @param int $max
* @return $this
*/
public function max($max)
{
$this->max = $max;
return $this;
}
/**
* 是否为只读
* @param bool $disabled
* @return $this
*/
public function disabled($disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* 是否允许半选
* @param bool $allowHalf
* @return $this
*/
public function allowHalf($allowHalf)
{
$this->allowHalf = $allowHalf;
return $this;
}
/**
* 低分和中等分数的界限值,值本身被划分在低分中
* @param int $lowThreshold
* @return $this
*/
public function lowThreshold($lowThreshold)
{
$this->lowThreshold = $lowThreshold;
return $this;
}
/**
* 高分和中等分数的界限值,值本身被划分在高分中
* @param int $highThreshold
* @return $this
*/
public function highThreshold($highThreshold)
{
$this->highThreshold = $highThreshold;
return $this;
}
/**
* icon 的颜色。若传入数组,共有 3 个元素,为 3 个分段所对应的颜色;若传入对象,可自定义分段,键名为分段的界限值,键值为对应的颜色
* @param array $colors
* @return $this
*/
public function colors($colors)
{
$this->colors = $colors;
return $this;
}
/**
* 未选中 icon 的颜色
* @param string $voidColor
* @return $this
*/
public function voidColor($voidColor)
{
$this->voidColor = $voidColor;
return $this;
}
/**
* 只读时未选中 icon 的颜色
* @param string $disabledVoidColor
* @return $this
*/
public function disabledVoidColor($disabledVoidColor)
{
$this->disabledVoidColor = $disabledVoidColor;
return $this;
}
/**
* icon 的类名。若传入数组,共有 3 个元素,为 3 个分段所对应的类名;若传入对象,可自定义分段,键名为分段的界限值,键值为对应的类名
* @param array $iconClasses
* @return $this
*/
public function iconClasses($iconClasses)
{
$this->iconClasses = $iconClasses;
return $this;
}
/**
* 未选中 icon 的类名
* @param string $voidIconClass
* @return $this
*/
public function voidIconClass($voidIconClass)
{
$this->voidIconClass = $voidIconClass;
return $this;
}
/**
* 只读时未选中 icon 的类名
* @param string $disabledVoidIconClass
* @return $this
*/
public function disabledVoidIconClass($disabledVoidIconClass)
{
$this->disabledVoidIconClass = $disabledVoidIconClass;
return $this;
}
/**
* 是否显示辅助文字,若为真,则会从 texts 数组中选取当前分数对应的文字内容
* @param bool $showText
* @return $this
*/
public function showText($showText=true)
{
$this->showText = $showText;
return $this;
}
/**
* 是否显示当前分数show-score show-text 不能同时为真
* @param bool $showScore
* @return $this
*/
public function showScore($showScore=true)
{
$this->showScore = $showScore;
return $this;
}
/**
* 辅助文字的颜色
* @param string $textColor
* @return $this
*/
public function textColor($textColor)
{
$this->textColor = $textColor;
return $this;
}
/**
* 辅助文字数组
* @param array $texts
* @return $this
*/
public function texts($texts)
{
$this->texts = $texts;
return $this;
}
}

View File

@ -0,0 +1,304 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Attrs\Depend;
use Builder\View\Components\Attrs\SelectOption;
use Builder\View\Components\Component;
class Select extends Component
{
use Depend;
public $componentName = 'Select';
protected $multiple = false;
protected $disabled = false;
protected $size;
protected $clearable = false;
protected $collapseTags = false;
protected $multipleLimit = 0;
protected $name;
protected $autocomplete;
protected $placeholder = "请选择";
protected $filterable = false;
protected $allowCreate = false;
protected $allowCreateUrl;
protected $remote = false;
protected $remoteUrl;
protected $loadingText = "加载中";
protected $noMatchText = "无匹配数据";
protected $noDataText = "无数据";
protected $popperClass;
protected $reserveKeyword = false;
protected $defaultFirstOption = false;
protected $popperAppendToBody = true;
protected $automaticDropdown = false;
/**
* @var SelectOption[]
*/
protected $options = [];
public static function make($value = null)
{
return new Select($value);
}
/**
* 宽度撑满
* @param bool $block
* @return $this
*/
public function block($block = true)
{
if ($block) {
$style = collect($this->style)->put('display','block');
$this->style($style);
}
return $this;
}
/**
* 是否多选
* @param bool $multiple
* @return $this
*/
public function multiple($multiple = true)
{
$this->multiple = $multiple;
if (!$this->componentValue) {
$this->componentValue([]);
}
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 输入框尺寸
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 是否可以清空选项
* @param bool $clearable
* @return $this
*/
public function clearable($clearable = true)
{
$this->clearable = $clearable;
return $this;
}
/**
* 多选时是否将选中值按文字的形式展示
* @param bool $collapseTags
* @return $this
*/
public function collapseTags($collapseTags = true)
{
$this->collapseTags = $collapseTags;
return $this;
}
/**
* 多选时用户最多可以选择的项目数,为 0 则不限制
* @param int $multipleLimit
* @return $this
*/
public function multipleLimit($multipleLimit)
{
$this->multipleLimit = $multipleLimit;
return $this;
}
/**
* select input name 属性
* @param string $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* select input autocomplete 属性
* @param string $autocomplete
* @return $this
*/
public function autocomplete($autocomplete)
{
$this->autocomplete = $autocomplete;
return $this;
}
/**
* 占位符
* @param string $placeholder
* @return $this
*/
public function placeholder($placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 是否可搜索
* @param bool $filterable
* @return $this
*/
public function filterable($filterable = true)
{
$this->filterable = $filterable;
return $this;
}
/**
* 是否允许用户创建新条目
* @param string $allowCreateUrl 创建新条目Url
* @return $this
*/
public function allowCreate($allowCreateUrl = null)
{
$this->allowCreate = true;
$this->filterable = true;
$this->allowCreateUrl = $allowCreateUrl;
return $this;
}
/**
* 是否为远程搜索
* @param string $remoteUrl 远程搜索URL
* @return $this
*/
public function remote($remoteUrl)
{
$this->remote = true;
$this->remoteUrl = $remoteUrl;
return $this;
}
/**
* 远程加载时显示的文字
* @param string $loadingText
* @return $this
*/
public function loadingText($loadingText)
{
$this->loadingText = $loadingText;
return $this;
}
/**
* 搜索条件无匹配时显示的文字
* @param string $noMatchText
* @return $this
*/
public function noMatchText($noMatchText)
{
$this->noMatchText = $noMatchText;
return $this;
}
/**
* 选项为空时显示的文字
* @param string $noDataText
* @return $this
*/
public function noDataText($noDataText)
{
$this->noDataText = $noDataText;
return $this;
}
/**
* Select 下拉框的类名
* @param string $popperClass
* @return $this
*/
public function popperClass($popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* 多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词
* @param bool $reserveKeyword
* @return $this
*/
public function reserveKeyword($reserveKeyword = true)
{
$this->reserveKeyword = $reserveKeyword;
return $this;
}
/**
* 在输入框按下回车,选择第一个匹配项。需配合 filterable remote 使用
* @param bool $defaultFirstOption
* @return $this
*/
public function defaultFirstOption($defaultFirstOption = true)
{
$this->defaultFirstOption = $defaultFirstOption;
return $this;
}
/**
* 是否将弹出框插入至 body 元素。在弹出框的定位出现问题时,可将该属性设置为 false
* @param bool $popperAppendToBody
* @return $this
*/
public function popperAppendToBody($popperAppendToBody = true)
{
$this->popperAppendToBody = $popperAppendToBody;
return $this;
}
/**
* 对于不可搜索的 Select是否在输入框获得焦点后自动弹出选项菜单
* @param bool $automaticDropdown
* @return $this
*/
public function automaticDropdown($automaticDropdown = true)
{
$this->automaticDropdown = $automaticDropdown;
return $this;
}
/**
* @param $options
* @return $this
*/
public function options($options)
{
if ($options instanceof \Closure) {
$this->options = call_user_func($options);
} else {
$this->options = $options;
}
return $this;
}
}

View File

@ -0,0 +1,186 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class Slider extends Component
{
protected $componentName = "Slider";
protected $min = 0;
protected $max = 100;
protected $disabled = false;
protected $step = 1;
protected $showInput = false;
protected $showInputControls = true;
protected $inputSize = "small";
protected $showStops = false;
protected $showTooltip = true;
protected $range = false;
protected $vertical = false;
protected $height;
protected $label;
protected $tooltipClass;
static public function make($value = null)
{
return new Slider($value);
}
/**
*最小值
* @param int $min
* @return $this
*/
public function min($min)
{
$this->min = $min;
return $this;
}
/**
* 最大值
* @param int $max
* @return $this
*/
public function max($max)
{
$this->max = $max;
return $this;
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* 步长
* @param int $step
* @return $this
*/
public function step($step)
{
$this->step = $step;
return $this;
}
/**
* 是否显示输入框,仅在非范围选择时有效
* @param bool $showInput
* @return $this
*/
public function showInput($showInput = true)
{
$this->showInput = $showInput;
return $this;
}
/**
* 在显示输入框的情况下,是否显示输入框的控制按钮
* @param bool $showInputControls
* @return $this
*/
public function showInputControls($showInputControls = true)
{
$this->showInputControls = $showInputControls;
return $this;
}
/**
* 输入框的尺寸
* large / medium / small / mini
* @param string $inputSize
* @return $this
*/
public function inputSize($inputSize)
{
$this->inputSize = $inputSize;
return $this;
}
/**
* 是否显示间断点
* @param bool $showStops
* @return $this
*/
public function showStops($showStops = true)
{
$this->showStops = $showStops;
return $this;
}
/**
* 是否显示 tooltip
* @param bool $showTooltip
* @return $this
*/
public function showTooltip($showTooltip = true)
{
$this->showTooltip = $showTooltip;
return $this;
}
/**
* 是否为范围选择
* @param bool $range
* @return $this
*/
public function range($range = true)
{
$this->range = $range;
return $this;
}
/**
* 是否竖向模式
* @param bool $vertical
* @param string $height
* @return $this
*/
public function vertical($vertical = true, $height = "100px")
{
$this->vertical = $vertical;
$this->height = $height;
return $this;
}
/**
* Slider 高度,竖向模式时必填
* @param mixed $height
* @return $this
*/
public function height($height)
{
$this->height = $height;
return $this;
}
/**
* 屏幕阅读器标签
* @param string $label
* @return $this
*/
public function label($label)
{
$this->label = $label;
return $this;
}
/**
* tooltip 的自定义类名
* @param string $tooltipClass
* @return $this
*/
public function tooltipClass($tooltipClass)
{
$this->tooltipClass = $tooltipClass;
return $this;
}
}

View File

@ -0,0 +1,282 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class TimePicker extends Component
{
protected $componentName = "TimePicker";
protected $readonly = false;
protected $disabled = false;
protected $editable = true;
protected $clearable = true;
protected $size;
protected $placeholder;
protected $startPlaceholder;
protected $endPlaceholder;
protected $isRange = false;
protected $arrowControl = false;
protected $align = "left";
protected $popperClass;
protected $pickerOptions;
protected $rangeSeparator = '-';
protected $valueFormat = "HH:mm:ss";
protected $defaultValue;
protected $name;
protected $prefixIcon;
protected $clearIcon;
protected $selectableRange;
protected $format = "HH:mm:ss";
protected $type = "select";
static public function make($value = '', $type = "select")
{
return (new TimePicker($value))->type($type);
}
/**
* 完全只读
* @param bool $readonly
* @return $this
*/
public function readonly($readonly = true)
{
$this->readonly = $readonly;
return $this;
}
/**
* 禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* 文本框可输入
* @param bool $editable
* @return $this
*/
public function editable($editable = true)
{
$this->editable = $editable;
return $this;
}
/**
* 是否显示清除按钮
* @param bool $clearable
* @return $this
*/
public function clearable($clearable = true)
{
$this->clearable = $clearable;
return $this;
}
/**
* 输入框尺寸
* @param string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 非范围选择时的占位内容
* @param string $placeholder
* @return $this
*/
public function placeholder($placeholder)
{
$this->placeholder = $placeholder;
return $this;
}
/**
* 范围选择时开始日期的占位内容
* @param string $startPlaceholder
* @return $this
*/
public function startPlaceholder($startPlaceholder)
{
$this->startPlaceholder = $startPlaceholder;
return $this;
}
/**
* 范围选择时开始日期的占位内容
* @param string $endPlaceholder
* @return $this
*/
public function endPlaceholder($endPlaceholder)
{
$this->endPlaceholder = $endPlaceholder;
return $this;
}
/**
* 是否为时间范围选择,仅对<el-time-picker>有效
* @param bool $isRange
* @return $this
*/
public function isRange($isRange = true)
{
$this->isRange = $isRange;
$this->type = "picker";
return $this;
}
/**
* 是否使用箭头进行时间选择,仅对<el-time-picker>有效
* @param bool $arrowControl
* @return $this
*/
public function arrowControl($arrowControl = true)
{
$this->arrowControl = $arrowControl;
return $this;
}
/**
* 对齐方式
* @param string $align
* @return $this
*/
public function align($align)
{
$this->align = $align;
return $this;
}
/**
* TimePicker 下拉框的类名
* @param mixed $popperClass
* @return $this
*/
public function popperClass($popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* 当前时间日期选择器特有的选项参考下表
* @param array $pickerOptions
* @return $this
*/
public function pickerOptions($pickerOptions)
{
$this->pickerOptions = $pickerOptions;
return $this;
}
/**
* 选择范围时的分隔符
* @param string $rangeSeparator
* @return $this
*/
public function rangeSeparator($rangeSeparator)
{
$this->rangeSeparator = $rangeSeparator;
return $this;
}
/**
* 可选仅TimePicker时可用绑定值的格式。不指定则绑定值为 Date 对象
* @param string $valueFormat
* @return $this
*/
public function valueFormat($valueFormat)
{
$this->valueFormat = $valueFormat;
return $this;
}
/**
* 可选,选择器打开时默认显示的时间
* @param string $defaultValue
* @return $this
*/
public function defaultValue($defaultValue)
{
$this->defaultValue = $defaultValue;
return $this;
}
/**
* 原生属性
* @param string $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* 自定义头部图标的类名
* @param mixed $prefixIcon
* @return $this
*/
public function prefixIcon($prefixIcon)
{
$this->prefixIcon = $prefixIcon;
return $this;
}
/**
* 自定义清空图标的类名
* @param mixed $clearIcon
* @return $this
*/
public function clearIcon($clearIcon)
{
$this->clearIcon = $clearIcon;
return $this;
}
/**
* 可选时间段,例如'18:30:00 - 20:30:00'或者传入数组['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']
* @param mixed $selectableRange
* @return $this
*/
public function selectableRange($selectableRange)
{
$this->selectableRange = $selectableRange;
return $this;
}
/**
* 时间格式化(TimePicker)
* @param string $format
* @return $this
*/
public function format($format)
{
$this->format = $format;
return $this;
}
/**
* 组件类型 select / picker
* @param string $type
* @return $this
*/
public function type($type)
{
$this->type = $type;
return $this;
}
}

View File

@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Attrs\TransferData;
use Builder\View\Components\Component;
class Transfer extends Component
{
protected $componentName = "Transfer";
protected $data = [];
protected $filterable = false;
protected $filterPlaceholder = "请输入搜索内容";
protected $targetOrder = "original";
protected $titles = ['列表', '列表'];
protected $buttonTexts=[];
protected $leftDefaultChecked = [];
protected $rightDefaultChecked = [];
static public function make($value = [])
{
return new Transfer($value);
}
/**
* Transfer 的数据源
* array[{ key, label, disabled }]
* @param TransferData[]|\Closure $data
* @return $this
*/
public function data($data)
{
if ($data instanceof \Closure) {
$this->data = call_user_func($data);
} else {
$this->data = $data;
}
return $this;
}
/**
* 是否可搜索
* @param bool $filterable
* @return $this
*/
public function filterable($filterable = true)
{
$this->filterable = $filterable;
return $this;
}
/**
* 搜索框占位符
* @param string $filterPlaceholder
* @return $this
*/
public function filterPlaceholder($filterPlaceholder)
{
$this->filterPlaceholder = $filterPlaceholder;
return $this;
}
/**
* 右侧列表元素的排序策略:若为 original则保持与数据源相同的顺序若为 push则新加入的元素排在最后若为 unshift则新加入的元素排在最前
* original / push / unshift
* @param string $targetOrder
* @return $this
*/
public function targetOrder($targetOrder)
{
$this->targetOrder = $targetOrder;
return $this;
}
/**自定义列表标题
* @param string[] $titles
* @return $this
*/
public function titles($titles)
{
$this->titles = $titles;
return $this;
}
/**
* 自定义按钮文案
* @param string[] $buttonTexts
* @return $this
*/
public function buttonTexts($buttonTexts)
{
$this->buttonTexts = $buttonTexts;
return $this;
}
/**
* 初始状态下左侧列表的已勾选项的 key 数组
* @param array $leftDefaultChecked
* @return $this
*/
public function leftDefaultChecked($leftDefaultChecked)
{
$this->leftDefaultChecked = $leftDefaultChecked;
return $this;
}
/**
* 初始状态下右侧列表的已勾选项的 key 数组
* @param array $rightDefaultChecked
* @return $this
*/
public function rightDefaultChecked($rightDefaultChecked)
{
$this->rightDefaultChecked = $rightDefaultChecked;
return $this;
}
}

View File

@ -0,0 +1,222 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Hyperf\Filesystem\Version;
use Hyperf\Utils\Arr;
use Builder\View\Components\Component;
use Builder\View\Form;
use Builder\View\Form\FormItem;
use Builder\Exception\BusinessException;
class Upload extends Component
{
protected $componentName = "Upload";
protected $type = "image";
protected $action = "";
protected $host = "";
protected $multiple = false;
protected $data = [];
protected $showFileList = false;
protected $drag = false;
protected $accept;
protected $listType = 'text';
protected $disabled = false;
protected $limit = 1;
protected $width = 100;
protected $height = 100;
protected $keyName;
protected $valueName;
protected $remove_flag_name = Form::REMOVE_FLAG_NAME;
public function __construct($value = null)
{
$this->action = route('/upload/image');
$this->host = config('admin.upload.host', route('/'));
$this->componentValue($value);
}
static public function make($value = null)
{
return new Upload($value);
}
public function destroy(FormItem $formItem)
{
$files = [];
if (is_array($formItem->original)) {
$files = $formItem->original;
} else {
$files[] = $formItem->original;
}
$storage = Storage()->getDriver();
collect($files)->each(function ($file) use ($storage) {
if (!empty($this->valueName)) {
$file = $file[$this->valueName];
}
if (!empty($file)){
$path = parse_url($file)['path'] ?? '';
$action = Version::isV2() ? 'fileExists' : 'has';
$storage->{$action}($path) && $storage->delete($path);
}
});
}
/**
* @param string $action
* @return $this
*/
public function action($action)
{
$this->action = $action;
return $this;
}
/**
* @param string $host
* @return $this;
*/
public function host(string $host)
{
$this->host = $host;
return $this;
}
/**
* @param bool $multiple
* @param null|string $keyName
* @param null|string $valueName
* @return $this
*/
public function multiple(bool $multiple = true, $keyName = null, $valueName = null)
{
$this->multiple = $multiple;
$this->keyName = $keyName;
$this->valueName = $valueName;
return $this;
}
/**
* @param array $data
* @return $this
*/
public function data($data)
{
foreach ($data as $key => $value) {
$this->data = Arr::set($this->data, $key, $value);
}
return $this;
}
/**
* 文件保存目录
* @param $path
* @return $this
*/
public function path($path)
{
$this->data = Arr::set($this->data, "path", $path);
return $this;
}
/**
* 自动生成文件名
* @return $this
*/
public function uniqueName()
{
$this->data = Arr::set($this->data, "uniqueName", true);
return $this;
}
/**
* @param bool $drag
* @return $this
*/
public function drag(bool $drag = true)
{
$this->drag = $drag;
return $this;
}
/**
* @param string $accept
* @return $this
*/
public function accept($accept)
{
$this->accept = $accept;
return $this;
}
/**
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param int $limit
* @return $this
*/
public function limit(int $limit)
{
$this->limit = $limit;
return $this;
}
/**
* @return $this;
*/
public function image()
{
$this->type = "image";
return $this;
}
public function avatar()
{
$this->type = "avatar";
return $this;
}
public function file()
{
$this->type = "file";
$this->action = route('/upload/file');
return $this;
}
/**
* @param int $width
* @return $this
*/
public function width(int $width)
{
$this->width = $width;
return $this;
}
/**
* @param int $height
* @return $this
*/
public function height(int $height)
{
$this->height = $height;
return $this;
}
}

View File

@ -0,0 +1,156 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Form;
use Builder\View\Components\Component;
class WangEditor extends Component
{
protected $componentName = 'WangEditor';
protected $menus = [
'head',
'bold',
'fontSize',
'fontName',
'italic',
'underline',
'strikeThrough',
'indent',
'lineHeight',
'foreColor',
'backColor',
'link',
'list',
'todo',
'justify',
'quote',
'emoticon',
'image',
'video',
'table',
'code',
'splitLine',
'undo',
'redo'
];
protected $zIndex = 0;
protected $uploadImgShowBase64 = false;
protected $uploadImgServer;
protected $uploadFileName;
protected $uploadImgHeaders;
protected $component;
protected $showFullScreen = true;
/**
* 开启html、word样式过滤
* @var bool
*/
protected $pasteFilterStyle = true;
static public function make($value = null)
{
return new Wangeditor($value);
}
/**
* 自定义菜单
* @param array $menus
* @return $this
*/
public function menus(array $menus)
{
$this->menus = $menus;
return $this;
}
/**
* 关闭样式过滤
* @param bool $showFullScreen
* @return $this
*/
public function pasteFilterStyle(bool $pasteFilterStyle = false)
{
$this->pasteFilterStyle = $pasteFilterStyle;
return $this;
}
/**
* 开启全屏按钮
* @param bool $showFullScreen
* @return $this
*/
public function showFullScreen(bool $showFullScreen = true)
{
$this->showFullScreen = $showFullScreen;
return $this;
}
/**
* 编辑区域的 z-index
* @param int $zIndex
* @return $this
*/
public function zIndex(int $zIndex)
{
$this->zIndex = $zIndex;
return $this;
}
/**
* 使用 base64 保存图片
* @param bool $uploadImgShowBase64
* @return $this
*/
public function uploadImgShowBase64(bool $uploadImgShowBase64 = true)
{
$this->uploadImgShowBase64 = $uploadImgShowBase64;
return $this;
}
/**
* 配置服务器端地址
* @param string $uploadImgServer
* @return $this
*/
public function uploadImgServer(string $uploadImgServer)
{
$this->uploadImgServer = $uploadImgServer;
return $this;
}
/**
* 自定义 fileName
* @param mixed $uploadFileName
* @return WangEditor
*/
public function uploadFileName(string $uploadFileName)
{
$this->uploadFileName = $uploadFileName;
return $this;
}
/**
* 自定义 header
* @param mixed $uploadImgHeaders
* @return WangEditor
*/
public function uploadImgHeaders(array $uploadImgHeaders)
{
$this->uploadImgHeaders = $uploadImgHeaders;
return $this;
}
/**
* @param mixed $component
* @return WangEditor
*/
public function component($component)
{
$this->component = $component;
return $this;
}
}

View File

@ -0,0 +1,149 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
/**
* Class Avatar
* @package HPlus\UI\Components
*/
class Avatar extends GridComponent
{
protected $componentName = "Avatar";
protected $host = "";
/**
* @var string
*/
protected $icon;
/**
* @var string|int
*/
protected $size = "small";
/**
* @var string
*/
protected $shape = "circle";
/**
* @var string
*/
protected $src;
/**
* @var string
*/
protected $srcSet;
/**
* @var string
*/
protected $alt;
/**
* @var string
*/
protected $fit = "cover";
protected $defaultSrc;
public function __construct($value = null)
{
$this->host = config('admin.upload.host');// Storage::disk(config('admin.upload.disk'));
$this->componentValue($value);
$this->defaultSrc = config('admin.default_avatar');
}
static public function make($value = null)
{
return new Avatar($value);
}
/**
* 设置头像的图标类型,参考 Icon 组件
* @param string $icon
* @return $this
*/
public function icon(string $icon)
{
$this->icon = $icon;
return $this;
}
/**
* 设置头像的大小 number / large / medium / small
* @param int|string $size
* @return $this
*/
public function size($size)
{
$this->size = $size;
return $this;
}
/**
* 设置头像的形状 circle / square
* @param string $shape
* @return $this
*/
public function shape(string $shape)
{
$this->shape = $shape;
return $this;
}
/**
* 图片头像的资源地址
* @param string $src
* @return $this
*/
public function src(string $src)
{
$this->src = $src;
return $this;
}
/**
* 以逗号分隔的一个或多个字符串列表表明一系列用户代理使用的可能的图像
* @param string $srcSet
* @return $this
*/
public function srcSet(string $srcSet)
{
$this->srcSet = $srcSet;
return $this;
}
/**
* 描述图像的替换文本
* @param string $alt
* @return $this
*/
public function alt(string $alt)
{
$this->alt = $alt;
return $this;
}
/**
* 当展示类型为图片的时候,设置图片如何适应容器框
* fill / contain / cover / none / scale-down
* @param string $fit
* @return $this
*/
public function fit(string $fit)
{
$this->fit = $fit;
return $this;
}
/**
* 设置默认头像
* @param string $defaultSrc
* @return $this
*/
public function defaultSrc($defaultSrc)
{
$this->defaultSrc = $defaultSrc;
return $this;
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\Component;
class Boole extends Component
{
protected $componentName = "Boole";
public static function make($value = null)
{
return new Boole($value);
}
}

View File

@ -0,0 +1,164 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\Component;
class GSwitch extends Component
{
protected $componentName = "GSwitch";
protected $disabled = false;
protected $width = 40;
protected $activeIconClass;
protected $inactiveIconClass;
protected $activeText;
protected $inactiveText;
protected $activeValue = true;
protected $inactiveValue = false;
protected $activeColor = "#409EFF";
protected $inactiveColor = "#C0CCDA";
protected $name = "#C0CCDA";
protected $validateEvent = true;
static public function make($value = false)
{
return new GSwitch($value);
}
public function getValue($value)
{
return boolval($value);
}
/**
* 是否禁用
* @param bool $disabled
* @return $this
*/
public function disabled($disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* switch 的宽度(像素)
* @param int $width
* @return $this
*/
public function width(int $width)
{
$this->width = $width;
return $this;
}
/**
* switch 打开时所显示图标的类名,设置此项会忽略 active-text
* @param string $activeIconClass
* @return $this
*/
public function activeIconClass($activeIconClass)
{
$this->activeIconClass = $activeIconClass;
return $this;
}
/**
* switch 关闭时所显示图标的类名,设置此项会忽略 inactive-text
* @param string $inactiveIconClass
* @return $this
*/
public function inactiveIconClass($inactiveIconClass)
{
$this->inactiveIconClass = $inactiveIconClass;
return $this;
}
/**
* switch 打开时的文字描述
* @param string $activeText
* @return $this
*/
public function activeText($activeText)
{
$this->activeText = $activeText;
return $this;
}
/**
* switch 关闭时的文字描述
* @param string $inactiveText
* @return $this
*/
public function inactiveText($inactiveText)
{
$this->inactiveText = $inactiveText;
return $this;
}
/**
* switch 打开时的值
* @param bool $activeValue
* @return $this
*/
public function activeValue($activeValue)
{
$this->activeValue = $activeValue;
return $this;
}
/**
* switch 关闭时的值
* @param bool $inactiveValue
* @return $this
*/
public function inactiveValue($inactiveValue)
{
$this->inactiveValue = $inactiveValue;
return $this;
}
/**
* switch 打开时的背景色
* @param string $activeColor
* @return $this
*/
public function activeColor($activeColor)
{
$this->activeColor = $activeColor;
return $this;
}
/**
* switch 关闭时的背景色
* @param string $inactiveColor
* @return $this
*/
public function inactiveColor($inactiveColor)
{
$this->inactiveColor = $inactiveColor;
return $this;
}
/**
* switch 对应的 name 属性
* @param string $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* 改变 switch 状态时是否触发表单的校验
* @param bool $validateEvent
* @return $this
*/
public function validateEvent($validateEvent = true)
{
$this->validateEvent = $validateEvent;
return $this;
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
class Icon extends GridComponent
{
protected $componentName = "Icon";
static public function make($value = null)
{
return new Icon($value);
}
}

View File

@ -0,0 +1,121 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
class Image extends GridComponent
{
protected $componentName = "IImage";
protected $src;
protected $host = "";
protected $fit = "cover";
protected $lazy = false;
protected $scrollContainer;
protected $preview = false;
protected $zIndex = 2000;
public function __construct($value = null)
{
$this->host = config('admin.upload.host');
$this->componentValue($value);
}
static public function make($value = null)
{
return new Image($value);
}
/**
* 图片源,同原生
* @param mixed $src
* @return $this
*/
public function src($src)
{
$this->src = $src;
return $this;
}
/**
* 确定图片如何适应容器框,同原生 object-fit
* @param string $fit
* @return $this
*/
public function fit($fit)
{
$this->fit = $fit;
return $this;
}
/**
* 是否开启懒加载
* @param bool $lazy
* @return $this
*/
public function lazy($lazy = true)
{
$this->lazy = $lazy;
return $this;
}
/**
* 开启懒加载后,监听 scroll 事件的容器
* @param mixed $scrollContainer
* @return $this
*/
public function scrollContainer($scrollContainer)
{
$this->scrollContainer = $scrollContainer;
return $this;
}
/**
* 开启图片预览功能
* @param bool $preview
* @return $this
*/
public function preview($preview = true)
{
$this->preview = $preview;
return $this;
}
/**
* 设置图片预览的 z-index
* @param int $zIndex
* @return $this
*/
public function zIndex($zIndex)
{
$this->zIndex = $zIndex;
return $this;
}
/**
* 设置图片大小
* @param $width
* @param $height
* @return $this
*/
public function size($width = null, $height = null)
{
if ($width) $this->style(collect($this->style)->push(['width' => is_int($width) ? $width . 'px' : $width]));
if ($height) $this->style(collect($this->style)->push(['height' => is_int($height) ? $height . 'px' : $height]));
return $this;
}
/**
* @param string $host
* @return $this
*/
public function host(string $host)
{
$this->host = $host;
return $this;
}
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
class Link extends GridComponent
{
protected $componentName = "Link";
protected $type;
protected $underline;
protected $disabled = false;
protected $href;
protected $icon;
static public function make($value = null)
{
return new Link($value);
}
/**
* 类型 success/info/warning/danger
* @param string|array $type
* @param bool $random
* @return $this
*/
public function type($type = null, $random = true)
{
$type = empty($type) ? ['primary', 'success', 'info', 'warning', 'danger'] : $type;
$this->type = [
'data' => $type,
'random' => $random
];
return $this;
}
/**
* @param bool $underline
* @return $this
*/
public function underline($underline = true)
{
$this->underline = $underline;
return $this;
}
/**
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled = true)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param string $href
* @return $this
*/
public function href($href)
{
$this->href = $href;
return $this;
}
/**
* @param string $icon
* @return $this
*/
public function icon($icon)
{
$this->icon = $icon;
return $this;
}
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
class Route extends GridComponent
{
protected $componentName = "GridRoute";
protected $uri;
protected $type;
protected $icon;
public function __construct($uri)
{
$this->uri = $uri;
}
public static function make($url = "")
{
return new Route($url);
}
/**
* 类型
* primary / success / warning / danger / info
* @param mixed $type
* @return $this
*/
public function type($type)
{
$this->type = $type;
return $this;
}
/**
* 图标类名
* @param mixed $icon
* @return $this
*/
public function icon($icon)
{
$this->icon = $icon;
return $this;
}
}

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Grid;
use Builder\View\Components\GridComponent;
class Tag extends GridComponent
{
protected $componentName = "Tag";
protected $type;
protected $closable = false;
protected $disableTransitions = false;
protected $hit = false;
protected $color;
protected $size = "mini";
protected $effect = "light";
/**
* @param $value
* @return Tag
*/
static public function make($value = null)
{
return new Tag($value);
}
/**
* 类型 success/info/warning/danger
* @param string|array $type
* @param bool $random
* @return $this
*/
public function type($type = null, $random = true)
{
$type = empty($type) ? ['success', 'info', 'warning', 'danger'] : $type;
$this->type = [
'data' => $type,
'random' => $random
];
return $this;
}
/**
* 是否可关闭
* @param bool $closable
* @return $this
*/
public function closable(bool $closable = true)
{
$this->closable = $closable;
return $this;
}
/**
* 是否禁用渐变动画
* @param bool $disableTransitions
* @return $this
*/
public function disableTransitions(bool $disableTransitions = true)
{
$this->disableTransitions = $disableTransitions;
return $this;
}
/**
* 是否有边框描边
* @param bool $hit
* @return $this
*/
public function hit(bool $hit = true)
{
$this->hit = $hit;
return $this;
}
/**
* 背景色
* @param string|array $color
* @param bool $random
* @return $this
*/
public function color($color, $random = true)
{
$this->color = [
'data' => $color,
'random' => $random
];;
return $this;
}
/**
* 尺寸 medium / small / mini
* @param string $size
* @return $this
*/
public function size(string $size)
{
$this->size = $size;
return $this;
}
/**
* 主题 dark / light / plain
* @param string $effect
* @return $this
*/
public function effect(string $effect)
{
$this->effect = $effect;
return $this;
}
}

View File

@ -0,0 +1,7 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components;
class GridComponent extends Component
{
}

View File

@ -0,0 +1,117 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Alert extends Component
{
protected $componentName = "Alert";
protected $title = "";
protected $type = "info";
protected $description = "";
protected $closable = true;
protected $center = false;
protected $closeText = "";
protected $showIcon = false;
protected $effect = "light";
public static function make($title = null, $description = null)
{
$alert = new Alert();
$alert->title = $title;
$alert->description = $description;
return $alert;
}
/**
* 标题
* @param string $title
* @return $this
*/
public function title(string $title)
{
$this->title = $title;
return $this;
}
/**
* 主题
* success/warning/info/error
* @param string $type
* @return $this
*/
public function type(string $type)
{
$this->type = $type;
return $this;
}
/**
* 辅助性文字。也可通过默认 slot 传入
* @param string $description
* @return $this
*/
public function description(string $description)
{
$this->description = $description;
return $this;
}
/**
* 是否可关闭
* @param bool $closable
* @return $this
*/
public function closable(bool $closable=true)
{
$this->closable = $closable;
return $this;
}
/**
* 文字是否居中
* @param bool $center
* @return $this
*/
public function center(bool $center=true)
{
$this->center = $center;
return $this;
}
/**
* 关闭按钮自定义文本
* @param string $closeText
* @return $this
*/
public function closeText(string $closeText)
{
$this->closeText = $closeText;
return $this;
}
/**
* 是否显示图标
* @param bool $showIcon
* @return $this
*/
public function showIcon(bool $showIcon=true)
{
$this->showIcon = $showIcon;
return $this;
}
/**
* 选择提供的主题
* light/dark
* @param string $effect
* @return $this
*/
public function effect(string $effect)
{
$this->effect = $effect;
return $this;
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Badge extends Component
{
protected $componentName = "Badge";
protected $value;
protected $max;
protected $isDot = false;
protected $hidden = false;
protected $type;
protected $child;
/**
* Badge constructor.
* @param $value
*/
public function __construct($value)
{
parent::__construct($value);
$this->value = $value;
}
public static function make($value)
{
return new Badge($value);
}
/**
* @param string|int $value
* @return $this
*/
public function value($value)
{
$this->value = $value;
return $this;
}
/**
* @param int $max
* @return $this
*/
public function max(int $max)
{
$this->max = $max;
return $this;
}
/**
* @param bool $isDot
* @return $this
*/
public function isDot(bool $isDot)
{
$this->isDot = $isDot;
return $this;
}
/**
* @param bool $hidden
* @return $this
*/
public function hidden(bool $hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* @param string $type
* @return $this
*/
public function type(string $type)
{
$this->type = $type;
return $this;
}
/**
* @param mixed $child
* @return $this
*/
public function child($child)
{
$this->child = $child;
return $this;
}
}

View File

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Actions\BaseAction;
use Builder\Exception\BusinessException;
use App\Components\SubForm;
class Button extends BaseAction
{
use \Builder\View\Components\Attrs\Button;
protected $componentName = "Button";
const HANDLER_ROUTE = "route";
const HANDLER_LINK = "link";
const HANDLER_REQUEST = "request";
protected $uri;
protected $subFormEmit;
protected $subForm = [];
protected $handler;
public function __construct($content)
{
parent::__construct();
$this->content = $content;
}
/**
* @param string $content 按钮内容
* @return $this
*/
public static function make($content = null)
{
return new Button($content);
}
/**
* @param mixed $uri
* @return $this
*/
public function uri($uri)
{
$this->uri = $uri;
return $this;
}
/**
* @param string $handler 响应类型 request|route|link
* @return $this
*/
public function handler($handler)
{
if (!in_array($handler, [self::HANDLER_LINK, self::HANDLER_REQUEST, self::HANDLER_ROUTE])) {
throw new BusinessException(400, "ActionButton 事件类型错误");
}
$this->handler = $handler;
return $this;
}
public function route($uri)
{
$this->uri = $uri;
$this->handler = self::HANDLER_ROUTE;
return $this;
}
public function addSubItem(SubForm $formItems)
{
$this->subFormEmit = $formItems->getSubFormEmit();
$this->subForm = $formItems->getFormItems();
return $this;
}
}

View File

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Card extends Component
{
protected $componentName = "Card";
protected $header;
protected $bodyStyle;
protected $shadow = "never";
protected $content;
public static function make()
{
return new Card();
}
/**
* 设置 header
* @param string|\Closure $header
* @return $this
*/
public function header($header)
{
$this->header = instance_content($header);
return $this;
}
/**
* 设置 body 的样式
* @param string|array $bodyStyle
* @return $this
*/
public function bodyStyle($bodyStyle)
{
$this->bodyStyle = $bodyStyle;
return $this;
}
/**
* 设置阴影显示时机
* always / hover / never
* @param string $shadow
* @return $this
*/
public function shadow(string $shadow)
{
$this->shadow = $shadow;
return $this;
}
/**
* 设置内容组件
* @param $content
* @return $this
*/
public function content($content)
{
$this->content = instance_content($content);
return $this;
}
}

View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Hyperf\Database\Model\Model as Eloquent;
use Builder\View\Components\Component;
use Builder\View\Grid\BatchActions;
use Builder\View\Grid\Column;
use Builder\View\Grid\Concerns\HasDefaultSort;
use Builder\View\Grid\Concerns\HasFilter;
use Builder\View\Grid\Concerns\HasGridAttributes;
use Builder\View\Grid\Concerns\HasPageAttributes;
use Builder\View\Grid\Concerns\HasQuickSearch;
use Builder\View\Grid\Filter;
use Builder\View\Grid\Model;
use Builder\View\Grid\Table\Attributes;
use Builder\View\Grid\Toolbars;
class Category extends Component
{
use HasGridAttributes, HasPageAttributes, HasDefaultSort, HasQuickSearch, HasFilter;
protected $componentName = "Tree";
protected $header;
protected $bodyStyle;
protected $content;
/**
* @var Model
*/
protected $model;
/**
* 组件字段
* @var Column[]
*/
protected $columns = [];
protected $rows;
/**
* 组件字段属性
* @var array
*/
protected $columnAttributes = [];
/**
* @var string
*/
protected $keyName = 'id';
/**
* @var bool
*/
protected $tree = false;
/**
* 表格数据来源
* @var string
*/
protected $dataUrl;
protected $customData;
protected $isGetData = false;
private $actions;
private $batchActions;
private $toolbars;
private $top;
private $bottom;
public function __construct(Eloquent $model = null)
{
$this->attributes = new Attributes();
$this->dataUrl = admin_api_url(request()->path()).'/list';
$this->model = new Model($model, $this);
if ($model) {
$this->keyName = $model->getKeyName();
$this->defaultSort($model->getKeyName(), "asc");
}
$this->isGetData = request('get_data') == "true";
$this->toolbars = new Toolbars($this);
$this->batchActions = new BatchActions();
$this->filter = new Filter($this->model);
}
public static function make()
{
return new Category();
}
}

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Attrs\ElDialog;
use Builder\View\Components\Component;
class Dialog extends Component
{
use ElDialog;
protected $componentName = "Dialog";
public static function make()
{
return new Dialog();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Attrs\Button;
use Builder\View\Components\Component;
class DialogButton extends Component
{
use Button;
protected $componentName = 'DialogButton';
public static function make()
{
return new DialogButton();
}
}

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Divider extends Component
{
protected $componentName = "Divider";
protected $direction = "horizontal";
protected $contentPosition = "left";
protected $content;
/**
* Divider constructor.
* @param $content
*/
public function __construct($content)
{
$this->content = $content;
}
public static function make($content)
{
return new Divider($content);
}
/**
* @param string $direction
* @return $this
*/
public function direction(string $direction)
{
$this->direction = $direction;
return $this;
}
/**
* @param string $contentPosition
* @return $this
*/
public function contentPosition(string $contentPosition)
{
$this->contentPosition = $contentPosition;
return $this;
}
}

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Html extends Component
{
protected $componentName = "Html";
protected $html = "";
public function __construct(string $html)
{
$this->html = $html;
}
public static function make($html = "")
{
return new Html($html);
}
/**
* @param string $html
* @return $this
*/
public function html(string $html)
{
$this->html = $html;
return $this;
}
}

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Markdown extends Component
{
protected $componentName = "Markdown";
protected $content;
public function __construct($content)
{
$this->content = $content;
}
public static function make($content=""){
return new Markdown($content);
}
public function content($content)
{
$this->content = $content;
return $this;
}
}

View File

@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Attrs\Step;
use Builder\View\Components\Component;
class Steps extends Component
{
protected $componentName = "Steps";
protected $space;
protected $direction = "horizontal";
protected $active = 0;
protected $processStatus = "process";
protected $finishStatus = "finish";
protected $alignCenter = false;
protected $simple = false;
/**
* @var Step[]
*/
protected $stepList;
/**
* Steps constructor.
*/
public function __construct()
{
$this->stepList = collect();
}
public static function make()
{
return new Steps();
}
/**
* 每个 step 的间距,不填写将自适应间距。支持百分比。
* @param int|string $space
* @return $this
*/
public function space($space)
{
$this->space = $space;
return $this;
}
/**
* 显示方向
* vertical / horizontal
* @param string $direction
* @return $this
*/
public function direction(string $direction)
{
$this->direction = $direction;
return $this;
}
/**
* 设置当前激活步骤
* @param int $active
* @return $this
*/
public function active(int $active)
{
$this->active = $active;
return $this;
}
/**
* 设置当前步骤的状态
* wait / process / finish / error / success
* @param string $processStatus
* @return $this
*/
public function processStatus(string $processStatus)
{
$this->processStatus = $processStatus;
return $this;
}
/**
* 设置结束步骤的状态
* wait / process / finish / error / success
* @param string $finishStatus
* @return $this
*/
public function finishStatus(string $finishStatus)
{
$this->finishStatus = $finishStatus;
return $this;
}
/**
* 进行居中对齐
* @param bool $alignCenter
* @return $this
*/
public function alignCenter(bool $alignCenter = true)
{
$this->alignCenter = $alignCenter;
return $this;
}
/**
* 是否应用简洁风格
* @param bool $simple
* @return $this
*/
public function simple(bool $simple = true)
{
$this->simple = $simple;
return $this;
}
/**
* @param Step[]|\Closure $stepList
* @return $this
*/
public function stepList($stepList)
{
if ($stepList instanceof \Closure) {
call_user_func($stepList, $this->stepList);
} else {
$this->stepList = $stepList;
}
return $this;
}
}

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Text extends Component
{
protected $componentName = "IText";
protected $text = "";
/**
* LvaText constructor.
* @param string $text
*/
public function __construct(string $text)
{
$this->text = $text;
}
static public function make($text = "")
{
return new Text($text);
}
}

View File

@ -0,0 +1,185 @@
<?php
declare(strict_types=1);
namespace Builder\View\Components\Widgets;
use Builder\View\Components\Component;
class Tooltip extends Component
{
protected $componentName = "Tooltip";
protected $effect = "dark";
protected $content = "";
protected $placement = "bottom";
protected $disabled = false;
protected $offset = 0;
protected $transition = "el-fade-in-linear";
protected $visibleArrow = true;
protected $openDelay = 0;
protected $manual = false;
protected $popperClass = "";
protected $enterable = true;
protected $hideAfter = 0;
protected $tabindex = 0;
protected $slot;
/**
* Tooltip constructor.
* @param string $content
*/
public function __construct(string $content)
{
$this->content = $content;
}
public static function make($content)
{
return new Tooltip($content);
}
/**
* @param string $effect
* @return $this
*/
public function effect(string $effect)
{
$this->effect = $effect;
return $this;
}
/**
* @param bool $disabled
* @return $this
*/
public function disabled(bool $disabled)
{
$this->disabled = $disabled;
return $this;
}
/**
* @param string $content
* @return $this
*/
public function content(string $content)
{
$this->content = $content;
return $this;
}
/**
* @param string $placement
* @return $this
*/
public function placement(string $placement)
{
$this->placement = $placement;
return $this;
}
/**
* @param int $offset
* @return $this
*/
public function offset(int $offset)
{
$this->offset = $offset;
return $this;
}
/**
* @param string $transition
* @return $this
*/
public function transition(string $transition)
{
$this->transition = $transition;
return $this;
}
/**
* @param bool $visibleArrow
* @return $this
*/
public function visibleArrow(bool $visibleArrow)
{
$this->visibleArrow = $visibleArrow;
return $this;
}
/**
* @param int $openDelay
* @return $this
*/
public function openDelay(int $openDelay)
{
$this->openDelay = $openDelay;
return $this;
}
/**
* @param bool $manual
* @return $this
*/
public function manual(bool $manual)
{
$this->manual = $manual;
return $this;
}
/**
* @param string $popperClass
* @return $this
*/
public function popperClass(string $popperClass)
{
$this->popperClass = $popperClass;
return $this;
}
/**
* @param bool $enterable
* @return $this
*/
public function enterable(bool $enterable)
{
$this->enterable = $enterable;
return $this;
}
/**
* @param int $hideAfter
* @return $this
*/
public function hideAfter(int $hideAfter)
{
$this->hideAfter = $hideAfter;
return $this;
}
/**
* @param int $tabindex
* @return $this
*/
public function tabindex(int $tabindex)
{
$this->tabindex = $tabindex;
return $this;
}
/**
* @param mixed $slot
* @return $this
*/
public function slot($slot)
{
if ($slot instanceof \Closure) {
$this->slot = call_user_func($slot);
} else {
$this->slot = $slot;
}
return $this;
}
}

944
builder/View/Form.php Normal file
View File

@ -0,0 +1,944 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.plus
* @link https://www.hyperf.plus
* @document https://doc.hyperf.plus
* @contact 4213509@qq.com
* @license https://github.com/lphkxd/hyperf-plus/blob/master/LICENSE
*/
namespace Builder\View;
use Hyperf\Database\Schema\Schema;
use Hyperf\DbConnection\Db;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Database\Model\Relations;
use Hyperf\Database\Model\Relations\Relation;
use Hyperf\HttpMessage\Server\Response;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Str;
use Builder\View\Form\FormTab;
use Builder\View\Layout\Row;
use Builder\View\Components\Component;
use Builder\View\Components\Form\Upload;
use Builder\View\Form\FormActions;
use Builder\View\Form\FormAttrs;
use Builder\View\Form\FormItem;
use Builder\View\Form\HasHooks;
use Builder\View\Form\HasRef;
use Builder\View\Form\TraitFormAttrs;
use Builder\View\Layout\Content;
use Builder\Validate\Validate;
use Builder\Exception\ValidateException;
use Builder\View as UI;
class Form extends Component
{
use TraitFormAttrs, HasHooks, HasRef;
protected $componentName = "Form";
const REMOVE_FLAG_NAME = '_remove_';
/**
* @var Model|Builder
*/
protected $model;
protected $id = 0;
protected $formItemsAttr = [];
protected $formItemsValue = [];
protected $formValue = [];
protected $formRules = [];
protected $formItemRows = [];
protected $formItems = [];
protected $formItemLayout = [];
protected $ignoreEmptyProps = [];
protected $tabPosition = "top";
const MODE_EDIT = 'edit';
const MODE_CREATE = 'create';
protected $mode = 'create';
protected $action;
protected $dataUrl;
protected $ignored = [];
protected $updates = [];
protected $isEdit = false;
/**
* Data for save to model's relations from input.
*
* @var array
*/
protected $relations = [];
/**
* Input data.
*
* @var array
*/
protected $inputs = [];
protected $isGetData = false;
/**
* 编辑数据
* @var array
*/
public $editData = [];
protected $addRule = [];
protected $addRuleMessage = [];
/**
* @var \Validator
*/
protected $validator;
private $top;
private $bottom;
protected $actions;
public function __construct($model = null)
{
$this->attrs = new FormAttrs();
$this->model = $model;
$this->dataUrl = admin_api_url(request()->path());
$this->isGetData = request()->header('getData')=="true";
$this->actions = new FormActions($this);
}
public static function make($model = null)
{
$form = new static($model);
$form->action(admin_api_url(request()->path().'?'.\http_build_query(request()->query())));
return $form;
}
/**
* 快捷生成字段
* @param $prop
* @param string $label
* @param string $field
* @return FormItem
*/
public function item($prop, $label = '', $field = '')
{
$item = $this->addItem($prop, $label, $field);
$this->row(function (Row $row) use ($item) {
$row->item($item);
});
return $item;
}
/**
* 多列布局字段
*
* @param $prop
* @param string $label
* @param string $field
*
* @return FormItem
*/
public function rowItem($prop, $label = '', $field = '')
{
return $this->addItem($prop, $label, $field);
}
/**
* 表单自定义布局
*
* @param \Closure $closure
*
* @return $this
*/
public function row(\Closure $closure)
{
$row = new Row();
call_user_func($closure, $row, $this);
$this->tab("default", function (FormTab $formTab) use ($row) {
$formTab->row($row);
});
return $this;
}
/**
* 自定义tab布局
* @param $tabName
* @param \Closure $closure
* @return $this
*/
public function tab($tabName, \Closure $closure)
{
$tab = collect($this->formItemLayout)->filter(function (FormTab $formTab) use ($tabName) {
return $formTab->getName() == $tabName;
})->first();
if (empty($tab)) {
$tab = new FormTab($tabName, $this);
call_user_func($closure, $tab, $this);
$this->formItemLayout[] = $tab;
} else {
call_user_func($closure, $tab, $this);
}
return $this;
}
/**
* tab位置
*
* @param $tabPosition
*
* @return $this
*/
public function tabPosition($tabPosition)
{
$this->tabPosition = $tabPosition;
return $this;
}
/**
* @param $prop
* @param $label
* @param $field
*
* @return FormItem
*/
protected function addItem($prop, $label, $field)
{
$item = new FormItem($prop, $label, $field);
$item->setForm($this);
$this->formItems[] = $item;
return $item;
}
/**
* @param array $items
*/
protected function items($items = [])
{
$this->ignoreEmptyProps = collect($items)->filter(function (FormItem $item) {
return $item->isIgnoreEmpty();
})->map(function (FormItem $item) {
return $item->getProp();
})->flatten()->all();
// 根据所处模式抛弃组件
$this->formItemsAttr = collect($items)->filter(function (FormItem $item) {
return $this->isMode($item->gethiddenMode());
})->map(function (FormItem $item) {
return $item->getProp();
});
/**@var FormItem $item */
foreach ($items as $item) {
Arr::set($this->formItemsValue, $item->getProp(), $item->getDefaultValue());
Arr::set($this->formRules, $item->getProp(), $item->getRules());
}
}
/**
* 自定义表单动作
*
* @param $closure
*
* @return $this
*/
public function actions(\Closure $closure)
{
call_user_func($closure, $this->actions);
return $this;
}
/**
* 表单头部组件
*
* @param $closure
*
* @return $this
*/
public function top($closure)
{
$this->top = new Content();
call_user_func($closure, $this->top);
return $this;
}
/**
* 表单底部组件
*
* @param $closure
*
* @return $this
*/
public function bottom($closure)
{
$this->bottom = new Content();
call_user_func($closure, $this->bottom);
return $this;
}
/**
* @return string
*/
public function getAction(): string
{
if ($this->action) {
return $this->action;
}
if ($this->isMode(static::MODE_EDIT)) {
return $this->resource() . '/' . $this->id;
}
if ($this->isMode(static::MODE_CREATE)) {
return $this->resource(-1);
}
return admin_api_url(request()->path());
}
/**
* 设置表单编辑模式获取编辑数据地址
*
* @param string $dataUrl
*
* @return $this
*/
public function dataUrl(string $dataUrl)
{
$this->dataUrl = $dataUrl;
return $this;
}
/**
* 设置表单提交地址
*
* @param string $action
*
* @return $this
*/
public function action($action)
{
$this->action = $action;
return $this;
}
protected function setMode($mode = 'create')
{
$this->mode = $mode;
}
public function isMode($mode): bool
{
return $this->mode === $mode;
}
public function setResourceId($id)
{
$this->id = $id;
}
public function getResourceId()
{
return $this->id;
}
public function resource($slice = -1): string
{
$segments = explode('/', trim(admin_api_url(request()->path()), '/'));
if ($slice !== 0) {
$segments = array_slice($segments, 0, $slice);
}
return '/' . implode('/', $segments);
}
/**
* @return string
*/
public function getMode(): string
{
return $this->mode;
}
/**
* 获取模型
* @return Model
*/
public function model()
{
return $this->model;
}
/**
* 设置清除模型缓存
*
* @param bool $cachePut
*
* @return self
*/
public function cachePut(bool $cachePut = true)
{
if (property_exists($this->model, 'useCacheBuilder')) {
$this->model->useCacheBuilder = $cachePut;
}
return $this;
}
/**
* 获取表单是否是编辑模式
* @return bool
*/
public function isEdit()
{
return $this->isEdit;
}
/**
* 获取表单是否是编辑模式
*
* @param bool $isEdit
*
* @return void
*/
public function setEdit($isEdit = false)
{
$this->isEdit = $isEdit;
}
/**
* 添加表单验证规则
*
* @param $rules
* @param $message
*
* @return $this
*/
public function addValidatorRule($rules, $message = [])
{
$this->addRule = $rules;
$this->addRuleMessage = $message;
return $this;
}
/**
* @param $data
*
* @return string
*/
protected function validatorData($data)
{
$rules = [];
$ruleMessages = [];
$field = [];
/* @var FormItem $formItem */
foreach ($this->formItems as $formItem) {
if (empty($formItem->getServeRole())) {
continue;
}
$field[$formItem->getField()] = $formItem->getLabel();
$rules[$formItem->getField()] = $formItem->getServeRole();
$messages = $formItem->getServeRulesMessage();
if (is_array($messages)) {
foreach ($messages as $key => $message) {
$ruleMessages[$formItem->getField() . '.' . $key] = $message;
}
}
}
$rules = array_merge($rules, $this->addRule);
$ruleMessages = array_merge($ruleMessages, $this->addRuleMessage);
$validator = new Validate($rules, $ruleMessages, $field);
if ($validator->check($data) !== true) {
throw new ValidateException(422, (string)$validator->getError());
}
}
public function input($key, $value = null)
{
if (is_null($value)) {
return Arr::get($this->inputs, $key);
}
return Arr::set($this->inputs, $key, $value);
}
protected function prepare($data = [])
{
//处理要过滤的字段
$this->inputs = array_merge($this->removeIgnoredFields($data), $this->inputs);
//处理表单提交时事件
if (($response = $this->callSaving()) instanceof Response) {
return $response;
}
//处理关联字段
$this->relations = $this->getRelationInputs($this->inputs);
$this->updates = Arr::except($this->inputs, array_keys($this->relations));
}
protected function removeIgnoredFields($input): array
{
Arr::forget($input, $this->ignored);
return $input;
}
protected function getRelationInputs($inputs = []): array
{
$relations = [];
foreach ($inputs as $column => $value) {
$column = Str::camel($column);
if (!method_exists($this->model, $column)) {
continue;
}
$relation = call_user_func([$this->model, $column]);
if ($relation instanceof Relation) {
$relations[$column] = $value;
}
}
return $relations;
}
protected function prepareInsert($inserts)
{
$prepared = [];
$columns = Schema::getColumnListing($this->model()->getTable());
foreach ($inserts as $key => $value) {
if (in_array($key, $columns)) {
Arr::set($prepared, $key, $value);
}
}
return $prepared;
}
public function getRelations(): array
{
$relations = [];
$columns = collect($this->formItems)->map(function (FormItem $item) {
return $item->getProp();
})->toArray();
foreach (Arr::flatten($columns) as $column) {
if (Str::contains($column, '.')) {
[$relation] = explode('.', $column);
if (method_exists($this->model, $relation) &&
$this->model->$relation() instanceof Relation
) {
$relations[] = $relation;
}
} else if (method_exists($this->model, $column)) {
$relations[] = $column;
}
}
return array_unique($relations);
}
public function store()
{
if (($result = $this->callSubmitted()) instanceof Response) {
return $result;
}
$data = request()->all();
if ($validationMessages = $this->validatorData($data)) {
return UI::responseError($validationMessages);
}
if (($response = $this->prepare($data)) instanceof Response) {
return $response;
}
DB::transaction(function () use ($data) {
$inserts = $this->prepareInsert($this->updates);
foreach ($inserts as $key => $value) {
$this->model->setAttribute($key, $value);
}
$this->model->save();
$this->updateRelation($this->relations);
if (($result = $this->callDbTransaction()) instanceof Response) {
throw new \Exception(400, $result->getBody()->getContents());
}
});
if (($result = $this->callSaved()) instanceof Response) {
return $result;
}
return UI::responseMessage('保存成功');
}
/**
* 编辑
*
* @param $id
*
* @return array|string
*/
public function edit($id = 0)
{
$this->isEdit = true;
$this->setMode(self::MODE_EDIT);
$this->setResourceId($id);
return $this;
}
protected function deleteFiles(Model $model, $forceDelete = false)
{
$data = $model->toArray();
collect($this->formItems)->filter(function (FormItem $formItem) {
return $formItem->getComponent() instanceof Upload;
})->each(function (FormItem $formItem) use ($data) {
$formItem->setOriginal($data);
/**@var Upload $component */
$component = $formItem->getComponent();
$component->destroy($formItem);
});
}
/**
* 模型删除
* @param $id
* @return mixed
*/
public function destroy($id)
{
try {
if (($ret = $this->callDeleting($id)) instanceof Response) {
return $ret;
}
collect(explode(',', $id))->each(function ($id) {
$builder = $this->model()->newQuery();
$relations = $this->getRelations();
$this->model = $model = $builder->with($relations)->findOrFail($id);
//删除文件
$this->deleteFiles($model);
//删除关联模型数据
$this->deleteRelation($relations);
$model->delete();
});
if (($ret = $this->callDeleted()) instanceof Response) {
return $ret;
}
return UI::responseMessage('删除成功');
} catch (\Exception $exception) {
return UI::responseError($exception->getMessage() ?: '删除成功');
}
}
/**
* @param $id
* @param null $data
*
* @return \Illuminate\Http\JsonResponse
* @throws \Throwable
*/
public function update($id, $data = null)
{
$this->isEdit = true;
if (($result = $this->callSubmitted()) instanceof Response) {
return $result;
}
$data = ($data) ?: request()->all();
$this->setResourceId($id);
$builder = $this->model();
$this->model = $builder->findOrFail($id);
$this->validatorData($data);
if (($response = $this->prepare($data)) instanceof Response) {
return $response;
}
DB::transaction(function () use ($data) {
$updates = $this->prepareUpdate($this->updates);
foreach ($updates as $key => $value) {
$this->model->setAttribute($key, $value);
}
$this->model->save();
$this->updateRelation($this->relations);
if (($result = $this->callDbTransaction()) instanceof Response) {
throw new \Exception(400, $result->getBody()->getContents());
}
});
if (($result = $this->callSaved()) instanceof Response) {
return $result;
}
return UI::responseMessage('修改成功');
}
protected function prepareUpdate(array $updates, $oneToOneRelation = false)
{
$prepared = [];
$columns = Schema::getColumnListing($this->model()->getTable());
foreach ($updates as $key => $value) {
if (in_array($key, $columns)) {
Arr::set($prepared, $key, $value);
}
}
return $prepared;
}
private function deleteRelation($relations)
{
foreach ($relations as $name) {
if (!method_exists($this->model, $name)) {
continue;
}
$relation = $this->model->$name();
switch (true) {
case $relation instanceof Relations\HasOne:
$relation->delete();
break;
}
}
}
private function updateRelation($relationsData)
{
foreach ($relationsData as $name => $values) {
if (!method_exists($this->model, $name)) {
continue;
}
$relation = $this->model->$name();
$oneToOneRelation = $relation instanceof Relations\HasOne
|| $relation instanceof Relations\MorphOne
|| $relation instanceof Relations\BelongsTo;
//$prepared = $this->prepareUpdate([$name => $values], $oneToOneRelation);
$prepared = [$name => $values];
if (empty($prepared)) {
continue;
}
switch (true) {
case $relation instanceof Relations\BelongsToMany:
case $relation instanceof Relations\MorphToMany:
if (isset($prepared[$name])) {
$relation->sync($prepared[$name]);
}
break;
case $relation instanceof Relations\HasOne:
$related = $this->model->$name;
// if related is empty
if (is_null($related)) {
$related = $relation->getRelated();
$qualifiedParentKeyName = $relation->getQualifiedParentKeyName();
$localKey = Arr::last(explode('.', $qualifiedParentKeyName));
$related->{$relation->getForeignKeyName()} = $this->model->{$localKey};
}
foreach ($prepared[$name] as $column => $value) {
$related->setAttribute($column, $value);
}
$related->save();
break;
case $relation instanceof Relations\BelongsTo:
case $relation instanceof Relations\MorphTo:
$parent = $this->model->$name;
// if related is empty
if (is_null($parent)) {
$parent = $relation->getRelated();
}
foreach ($prepared[$name] as $column => $value) {
$parent->setAttribute($column, $value);
}
$parent->save();
// When in creating, associate two models
if (!$this->model->{$relation->getForeignKeyName()}) {
$this->model->{$relation->getForeignKeyName()} = $parent->getKey();
$this->model->save();
}
break;
case $relation instanceof Relations\MorphOne:
$related = $this->model->$name;
if ($related === null) {
$related = $relation->make();
}
foreach ($prepared[$name] as $column => $value) {
$related->setAttribute($column, $value);
}
$related->save();
break;
case $relation instanceof Relations\HasMany:
case $relation instanceof Relations\MorphMany:
foreach ($prepared[$name] as $related) {
/** @var Relations\Relation $relation */
$relation = $this->model()->$name();
$keyName = $relation->getRelated()->getKeyName();
$instance = $relation->findOrNew(Arr::get($related, $keyName));
//处理已删除的关联
try {
if ($related[static::REMOVE_FLAG_NAME] == 1) {
$instance->delete();
continue;
}
Arr::forget($related, static::REMOVE_FLAG_NAME);
} catch (\Exception $exception) {
}
//过滤不存在的字段
foreach ($related as $key => $value) {
if (Schema::hasColumn($instance->getTable(), $key)) {
$instance->setAttribute($key, $value);
}
}
$instance->save();
}
break;
}
}
}
/**
* 获取编辑数据
*
* @param $id
*
* @return array
*/
public function editData($id)
{
$this->isEdit = true;
if (($result = $this->callEditing($id)) instanceof Response) {
return $result;
}
$this->setMode(self::MODE_EDIT);
$this->setResourceId($id);
$this->editData = $this->model = $this->model->with($this->getRelations())->findOrFail($this->getResourceId());
$data = [];
/**@var FormItem $formItem */
foreach ($this->formItems as $formItem) {
$field = $formItem->getField();
$prop = $formItem->getProp();
$component = $formItem->getComponent();
// 利用model的hidden属性
if (in_array($prop, $this->model->getHidden())) {
Arr::set($data, $prop, $formItem->getData(null, $this->model, $component));
} else {
Arr::set($data, $prop, $formItem->getData(Arr::get($this->editData, $prop), $this->model, $component));
}
}
foreach ($this->formItems as $formItem) {
$prop = $formItem->getProp();
if ($formItem->getCopyProp()) {
Arr::set($data, $prop, Arr::get($data, $formItem->getCopyProp()));
}
}
$this->editData = $data;
if (($result = $this->callEdiQuery($data)) instanceof Response) {
return $result;
}
return [
'code' => 200,
'data' => $this->editData,
];
}
/**
* 设置是否加载数据
*
* @param bool $isGetData
*
* @return $this
*/
public function isGetData(bool $isGetData)
{
$this->isGetData = $isGetData;
return $this;
}
/**
* @inheritDoc
*/
public function jsonSerialize()
{
if ($this->isGetData) {
return $this->editData($this->getResourceId());
}
$this->items($this->formItems);
return array_filter([
'componentName' => $this->componentName,
'action' => $this->getAction(),
'dataUrl' => $this->dataUrl,
'mode' => $this->getMode(),
'attrs' => $this->attrs,
'ignoreEmptyProps' => $this->ignoreEmptyProps,
'formItemLayout' => $this->formItemLayout,
'tabPosition' => $this->tabPosition,
'defaultValues' => (object)array_merge($this->formItemsValue, $this->formValue),
'formRules' => (object)$this->formRules,
'ref' => $this->ref,
'refData' => $this->refData,
'formRefData' => $this->FormRefDataBuild(),
'top' => $this->top,
'bottom' => $this->bottom,
'actions' => $this->actions->builderActions()
]);
}
/**
* 填充表单默认值
*
* @param $name
* @param string $value
*
* @return $this
*/
public function setFormValue($name, $value = '')
{
if (is_array($name)) {
$this->formValue = $name;
return $this;
}
if ($value === null) {
unset($this->formValue[$name]);
return $this;
}
$this->formValue[$name] = $value;
return $this;
}
public function __get($name)
{
return $this->input($name);
}
public function __set($name, $value)
{
return Arr::set($this->inputs, $name, $value);
}
}

View File

@ -0,0 +1,134 @@
<?php
declare(strict_types=1);
namespace Builder\View\Form;
use Builder\View\Components\Widgets\Button;
use Builder\View\Form;
class FormActions
{
protected $form;
protected $actions = [];
protected $addLeftActions = [];
protected $addRightActions = [];
protected $cancelButton;
protected $submitButton;
protected $hideCancelButton;
protected $hideSubmitButton;
protected $fixed = false;
public function __construct(Form $form)
{
$this->form = $form;
$this->cancelButton = new Button("取消");
$this->cancelButton->type("default");
$this->submitButton = new Button("提交");
}
/**
* 添加自定义Action
* @param $action
* @return $this
*/
public function addLeft($action)
{
if ($action instanceof \Closure) {
$this->addLeftActions = collect($this->addLeftActions)->push(call_user_func($action))->all();
} else {
$this->addLeftActions = collect($this->addLeftActions)->push($action)->all();
}
return $this;
}
/**
* 添加自定义Action
* @param $action
* @return $this
*/
public function addRight($action)
{
if ($action instanceof \Closure) {
$this->addRightActions = collect($this->addRightActions)->push(call_user_func($action))->all();
} else {
$this->addRightActions = collect($this->addRightActions)->push($action)->all();
}
return $this;
}
/**
* 获取取消按钮对象,注意此按钮只支持基本按钮属性
* @return Button
*/
public function cancelButton()
{
return $this->cancelButton;
}
/**
* 获取提交按钮对象,注意此按钮只支持基本按钮属性
* @return Button
*/
public function submitButton()
{
return $this->submitButton;
}
/**
* 隐藏取消按钮
* @return $this
*/
public function hideCancelButton()
{
$this->hideCancelButton = true;
return $this;
}
/**
* 隐藏提交按钮
* @return $this
*/
public function hideSubmitButton()
{
$this->hideSubmitButton = true;
return $this;
}
/**
* 固定操作栏
* @return $this
*/
public function fixed()
{
$this->fixed = true;
return $this;
}
/**
* @return Form
*/
public function getForm()
{
return $this->form;
}
public function builderActions()
{
$addLeftActions = collect($this->addLeftActions);
$addRightActions = collect($this->addRightActions);
$cancelButton = null;
if (!$this->hideCancelButton) {
$cancelButton = $this->cancelButton;
}
$submitButton = null;
if (!$this->hideSubmitButton) {
$submitButton = $this->submitButton;
}
return [
'addLeftActions' => $addLeftActions,
'addRightActions' => $addRightActions,
'cancelButton' => $cancelButton,
'submitButton' => $submitButton,
'fixed' => $this->fixed,
];
}
}

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Builder\View\Form;
class FormAttrs
{
public $className;
public $style;
public $rules;
public $inline = false;
public $labelPosition = 'right';
public $labelWidth = "80px";
public $labelSuffix = "";
public $hideRequiredAsterisk = false;
public $showMessage = true;
public $inlineMessage = false;
public $statusIcon = false;
public $validateOnRuleChange = true;
public $size;
public $disabled = false;
public $hideTab = true;
public $isDialog = false;
public $createButtonName = "立即添加";
public $updateButtonName = "立即修改";
public $backButtonName = "返回";
public $buttonWidth;
}

Some files were not shown because too many files have changed in this diff Show More