初始化仓库
This commit is contained in:
101
admin/components/UI/Form/Area.php
Normal file
101
admin/components/UI/Form/Area.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 地区选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Area extends Element implements Component
|
||||
{
|
||||
protected bool $multi = false;
|
||||
protected array $map = [
|
||||
'province' => 'province',
|
||||
'city' => 'city',
|
||||
'region' => 'region',
|
||||
'street' => 'street',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $map
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, array $map = [], string $has = '')
|
||||
{
|
||||
if ($map) {
|
||||
$this->map = $map;
|
||||
}
|
||||
$this->name = $name;
|
||||
$this->field = end($this->map);
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function multi(): self
|
||||
{
|
||||
$this->multi = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-cascader',
|
||||
'nParams' => [
|
||||
'cascade' => true,
|
||||
'show-path' => true,
|
||||
'filterable' => false,
|
||||
'clearable' => true,
|
||||
'leaf-only' => true,
|
||||
'multiple' => $this->multi,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
],
|
||||
'dataUrl' => route('service.area', ['level' => count($this->map)]),
|
||||
];
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function appendInput($data): array
|
||||
{
|
||||
$info = \backend\components\Model\Area::where(['code' => $data])->first();
|
||||
|
||||
$code = $info->parent_code;
|
||||
if ($info->level > 3) {
|
||||
$region = \backend\components\Model\Area::where(['code' => $code])->first();
|
||||
$code = $region['parent_code'];
|
||||
}
|
||||
if ($info->level > 2) {
|
||||
$city = \backend\components\Model\Area::where(['code' => $code])->first();
|
||||
$code = $city['parent_code'];
|
||||
}
|
||||
if ($info->level > 1) {
|
||||
$province = \backend\components\Model\Area::where(['code' => $code])->first();
|
||||
}
|
||||
$data = [];
|
||||
if ($region) {
|
||||
$data[$this->map['region']] = $region->code;
|
||||
}
|
||||
if ($city) {
|
||||
$data[$this->map['city']] = $city->code;
|
||||
}
|
||||
if ($province) {
|
||||
$data[$this->map['province']] = $province->code;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
48
admin/components/UI/Form/Card.php
Normal file
48
admin/components/UI/Form/Card.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 卡片布局
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Card extends Composite implements Component
|
||||
{
|
||||
protected \Closure $callback;
|
||||
|
||||
public function __construct($callback)
|
||||
{
|
||||
$this->callback = $callback;
|
||||
$form = new Form();
|
||||
$form->dialog($this->dialog);
|
||||
$form->vertical($this->vertical);
|
||||
$callback($form);
|
||||
$this->column[] = [
|
||||
'object' => $form,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$inner = [];
|
||||
foreach ($this->column as $vo) {
|
||||
$inner = $vo['object']->renderForm();
|
||||
}
|
||||
|
||||
if (!$this->dialog) {
|
||||
$this->class('mb-4 bg-white dark:bg-blackgray-4 rounded shadow p-7 pb-2');
|
||||
}
|
||||
|
||||
return [
|
||||
'nodeName' => 'div',
|
||||
'class' => implode(' ', $this->class),
|
||||
'child' => $inner
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
200
admin/components/UI/Form/Cascader.php
Normal file
200
admin/components/UI/Form/Cascader.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 级联选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Cascader extends Element implements Component
|
||||
{
|
||||
protected bool $tip = false;
|
||||
protected bool $multi = false;
|
||||
protected bool $leaf = true;
|
||||
private array $params = [];
|
||||
protected bool $treeData = false;
|
||||
protected string $url = '';
|
||||
protected string $route = '';
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = null, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加选项
|
||||
* @param $name
|
||||
* @param $id
|
||||
* @param $pid
|
||||
* @return $this
|
||||
*/
|
||||
public function add($name, $id, $pid): self
|
||||
{
|
||||
$this->data[] = [
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'pid' => $pid
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url($url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function route(string $route, array $params = []): self
|
||||
{
|
||||
$this->route = $route;
|
||||
$this->url = app_route($route, $params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function multi(): self
|
||||
{
|
||||
$this->multi = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* leaf choice
|
||||
* @param bool $leaf
|
||||
* @return $this
|
||||
*/
|
||||
public function leaf(bool $leaf): self
|
||||
{
|
||||
$this->leaf = $leaf;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* tree data
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function tree(bool $bool = true): self
|
||||
{
|
||||
$this->treeData = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签显示最大条数
|
||||
* @param int $num
|
||||
* @return $this
|
||||
*/
|
||||
public function maxTagCount(int $num){
|
||||
return $this->nParams('maxTagCount',$num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附加参数
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function nParams($key,$value){
|
||||
$this->params[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data, $this);
|
||||
}
|
||||
if (is_array($this->data)) {
|
||||
$data = $this->data;
|
||||
}
|
||||
|
||||
if (!$this->treeData) {
|
||||
$options = [];
|
||||
foreach ($data as $vo) {
|
||||
$options[] = [
|
||||
'id' => $vo['id'],
|
||||
'pid' => $vo['parent_id'],
|
||||
'value' => $vo['id'],
|
||||
'label' => $vo['name'],
|
||||
];
|
||||
}
|
||||
|
||||
$options = \backend\components\Tree::arr2tree($options, 'id', 'pid', 'children');
|
||||
} else {
|
||||
$options = $data;
|
||||
}
|
||||
|
||||
|
||||
$data = [
|
||||
'nodeName' => 'app-cascader',
|
||||
'nParams' => array_merge($this->params, [
|
||||
'check-strictly' => !$this->leaf,
|
||||
'multiple' => $this->multi,
|
||||
'options' => $options,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
])
|
||||
];
|
||||
|
||||
if ($this->route) {
|
||||
$data['vBind:dataUrl'] = $this->url;
|
||||
} else {
|
||||
$data['dataUrl'] = $this->url;
|
||||
}
|
||||
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function dataValue($value)
|
||||
{
|
||||
return $this->multi ? array_values(array_filter((array)$this->getValueArray($value))) : $this->getValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
96
admin/components/UI/Form/Checkbox.php
Normal file
96
admin/components/UI/Form/Checkbox.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 多选框
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Checkbox extends Element implements Component
|
||||
{
|
||||
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Select constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null|array|callable $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = null, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* add data
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function add($name, $value): self
|
||||
{
|
||||
$this->data[] = [
|
||||
'name' => $name,
|
||||
'value' => $value
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [];
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data);
|
||||
}
|
||||
if (is_array($this->data)) {
|
||||
$data = $this->data;
|
||||
}
|
||||
|
||||
$child = [];
|
||||
foreach ($data as $key => $vo) {
|
||||
$child[] = [
|
||||
'nodeName' => 'a-checkbox',
|
||||
'value' => $key,
|
||||
'child' => $vo,
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'nodeName' => 'a-checkbox-group',
|
||||
'child' => $child
|
||||
];
|
||||
|
||||
if ($this->model) {
|
||||
$data['vModel:model-value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function dataValue($value): array
|
||||
{
|
||||
return array_values(array_filter((array)$this->getValueArray($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
184
admin/components/UI/Form/Choice.php
Normal file
184
admin/components/UI/Form/Choice.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\Exceptions\ErrorException;
|
||||
|
||||
/**
|
||||
* 表格管理选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Choice extends Element implements Component
|
||||
{
|
||||
|
||||
protected array $column = [];
|
||||
protected array $ajax = [];
|
||||
protected bool $option = true;
|
||||
protected int $number = 0;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $key
|
||||
* @param callable $column
|
||||
* @param array $types
|
||||
* @return $this
|
||||
*/
|
||||
public function ajax(string $url, string $key, callable $column, array $types = []): self
|
||||
{
|
||||
$this->ajax = [
|
||||
'url' => $url,
|
||||
'key' => $key,
|
||||
'column' => $column,
|
||||
'type' => $types
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* text column
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function text(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'text'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* image column
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function image(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'image'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* show column
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function show(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'show'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hidden column
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function hidden(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'hidden'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* option status
|
||||
* @param bool $status
|
||||
* @return $this
|
||||
*/
|
||||
public function option(bool $status = true): self
|
||||
{
|
||||
$this->option = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* maximum number
|
||||
* @param int $num
|
||||
* @return $this
|
||||
*/
|
||||
public function num(int $num = 0): self
|
||||
{
|
||||
$this->number = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$url = route('service.image.placeholder', ['w' => 64, 'h' => 64, 't' => $this->attr['placeholder'] ?: '图片']);
|
||||
|
||||
$ajaxColumn = $this->ajax['column'] ?: [];
|
||||
if (is_callable($ajaxColumn)) {
|
||||
$ajaxColumn = $ajaxColumn(new ChoiceColumn());
|
||||
if (!$ajaxColumn instanceof ChoiceColumn) {
|
||||
app_error('Choice component configuration error');
|
||||
}
|
||||
$ajaxColumn = $ajaxColumn->getData();
|
||||
}
|
||||
|
||||
return [
|
||||
'nodeName' => 'app-choice',
|
||||
'vModel:value' => $this->getModelField(),
|
||||
'column' => $this->column,
|
||||
'ajaxColumn' => $ajaxColumn,
|
||||
'ajaxType' => $this->ajax['type'],
|
||||
'key' => $this->ajax['key'],
|
||||
'url' => $this->ajax['url'],
|
||||
'number' => $this->number,
|
||||
'option' => $this->option,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|null
|
||||
*/
|
||||
public function dataValue($value): ?array
|
||||
{
|
||||
$value = $this->getValue($value);
|
||||
if ($value instanceof \Illuminate\Database\Eloquent\Collection && $value->count()) {
|
||||
$values = $value->toArray();
|
||||
} else if (is_array($value)) {
|
||||
$values = $value;
|
||||
} else {
|
||||
$values = [];
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
}
|
||||
55
admin/components/UI/Form/ChoiceColumn.php
Normal file
55
admin/components/UI/Form/ChoiceColumn.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 表格关联选择器列
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class ChoiceColumn
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $column;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function text(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'text'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function image(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'image'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData(): array
|
||||
{
|
||||
return $this->column;
|
||||
}
|
||||
|
||||
}
|
||||
72
admin/components/UI/Form/Color.php
Normal file
72
admin/components/UI/Form/Color.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 颜色选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Color extends Element implements Component
|
||||
{
|
||||
protected array $color = [];
|
||||
protected bool $picker = false;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function picker(): self
|
||||
{
|
||||
$this->picker = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function color(array $data): self
|
||||
{
|
||||
$this->color = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
if ($this->picker) {
|
||||
// 暂无组件
|
||||
$data = [
|
||||
|
||||
];
|
||||
}else {
|
||||
$data = [
|
||||
'nodeName' => 'app-color',
|
||||
'colors' => $this->color,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
];
|
||||
}
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
12
admin/components/UI/Form/Component.php
Normal file
12
admin/components/UI/Form/Component.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 组件接口
|
||||
* Class Component
|
||||
* @package backend\components\UI
|
||||
*/
|
||||
interface Component
|
||||
{
|
||||
}
|
||||
62
admin/components/UI/Form/Composite.php
Normal file
62
admin/components/UI/Form/Composite.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Tools;
|
||||
|
||||
/**
|
||||
* 复合组件
|
||||
* @package backend\components\UI
|
||||
*/
|
||||
class Composite extends Element
|
||||
{
|
||||
|
||||
public array $column = [];
|
||||
public bool $component = true;
|
||||
public object $form;
|
||||
|
||||
/**
|
||||
* @param null $key
|
||||
* @param string $item
|
||||
* @return array|object
|
||||
*/
|
||||
public function getColumn($key = null, string $item = '')
|
||||
{
|
||||
return $key !== null ? ($item ? $this->column[$key][$item] : $this->column[$key]) : $this->column;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取值
|
||||
* @param string $time
|
||||
* @return array
|
||||
*/
|
||||
public function getInput(string $time = 'add'): array
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->column as $vo) {
|
||||
$vo['object']->getElement()->map(function ($item) use (&$data, $time) {
|
||||
foreach ($item->getInput($time) as $k => $v) {
|
||||
$data[$k] = $v;
|
||||
}
|
||||
});
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $info
|
||||
* @return array
|
||||
*/
|
||||
public function getData($info): array
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->column as $vo) {
|
||||
$vo['object']->getElement()->map(function ($item) use (&$data, $info) {
|
||||
foreach ($item->getData($info) as $k => $v) {
|
||||
$data[$k] = $v;
|
||||
}
|
||||
});
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
213
admin/components/UI/Form/Data.php
Normal file
213
admin/components/UI/Form/Data.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Widget\Icon;
|
||||
|
||||
/**
|
||||
* 动态数据编辑器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Data extends Element implements Component
|
||||
{
|
||||
protected array $column = [];
|
||||
protected bool $option = true;
|
||||
protected ?int $numberMax = null;
|
||||
protected ?int $numberMin = null;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本列
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $width
|
||||
* @return $this
|
||||
*/
|
||||
public function text(string $name, string $field, $width = null): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'text',
|
||||
'width' => $width,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片列
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $width
|
||||
* @return $this
|
||||
*/
|
||||
public function image(string $name, string $field, $width = null): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'image',
|
||||
'width' => $width,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示列
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $width
|
||||
* @return $this
|
||||
*/
|
||||
public function show(string $name, string $field, $width = null): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'show',
|
||||
'width' => $width,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏列
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return $this
|
||||
*/
|
||||
public function hidden(string $name, string $field): self
|
||||
{
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'key' => $field,
|
||||
'type' => 'hidden'
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作状态
|
||||
* @param bool $status
|
||||
* @return $this
|
||||
*/
|
||||
public function option(bool $status = true): self
|
||||
{
|
||||
$this->option = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大数量
|
||||
* @param int $num
|
||||
* @return $this
|
||||
*/
|
||||
public function max(int $num = 0): self
|
||||
{
|
||||
$this->numberMax = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小数量
|
||||
* @param int $num
|
||||
* @return $this
|
||||
*/
|
||||
public function min(int $num = 0): self
|
||||
{
|
||||
$this->numberMin = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$url = route('service.image.placeholder', ['w' => 64, 'h' => 64, 't' => $this->attr['placeholder'] ?: '图片']);
|
||||
|
||||
$inner = [];
|
||||
$default = [];
|
||||
foreach ($this->column as $column) {
|
||||
$default[$column['key']] = '';
|
||||
$field = "value['{$column['key']}']";
|
||||
if ($column['type'] === 'text') {
|
||||
$inner[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-grow',
|
||||
'child' => [
|
||||
'nodeName' => 'a-input',
|
||||
'placeholder' => '请输入' . $column['name'],
|
||||
'vModel:model-value' => $field
|
||||
]
|
||||
];
|
||||
}
|
||||
if ($column['type'] === 'image') {
|
||||
$inner[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-none',
|
||||
'child' => [
|
||||
'nodeName' => 'app-file',
|
||||
'image' => 'true',
|
||||
'mini' => true,
|
||||
'size' => 8,
|
||||
'vModel:value' => $field
|
||||
]
|
||||
];
|
||||
}
|
||||
if ($column['type'] === 'show') {
|
||||
$inner[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-grow',
|
||||
'child' => "{{ $field || '-'}}"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$create = json_encode($default);
|
||||
$data = [
|
||||
'nodeName' => 'app-dynamic-data',
|
||||
'vModel:value' => $this->getModelField(),
|
||||
'vBind:on-create' => "() => { return $create }",
|
||||
'child' => [
|
||||
'vSlot' => '{ index, value }',
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex flex-grow gap-4 items-center',
|
||||
'child' => $inner
|
||||
]
|
||||
];
|
||||
|
||||
if ($this->numberMax) {
|
||||
$data['max'] = $this->numberMax;
|
||||
}
|
||||
|
||||
if ($this->numberMin) {
|
||||
$data['min'] = $this->numberMin;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array|null
|
||||
*/
|
||||
public function dataValue($data): ?array
|
||||
{
|
||||
$data = $this->getValue($data);
|
||||
return $data ?: [];
|
||||
}
|
||||
|
||||
}
|
||||
87
admin/components/UI/Form/Date.php
Normal file
87
admin/components/UI/Form/Date.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 时间选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Date extends Element implements Component
|
||||
{
|
||||
|
||||
protected ?string $type = null;
|
||||
|
||||
private array $types = [
|
||||
'year',
|
||||
'month',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type): self
|
||||
{
|
||||
if (!in_array($type, $this->types)) {
|
||||
throw new \RuntimeException('There is no type "' . $type . '"');
|
||||
}
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-date-picker',
|
||||
'allowClear' => true,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
'vModel:modelValue' => $this->getModelField()
|
||||
];
|
||||
if ($this->type) {
|
||||
$data['nodeName'] = 'a-' . $this->type . '-picker';
|
||||
}
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return $data ? date('Y-m-d', strtotime($data)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataValue($data): ?string
|
||||
{
|
||||
$data = $this->getValue($data);
|
||||
return $data ?: null;
|
||||
}
|
||||
|
||||
}
|
||||
106
admin/components/UI/Form/Daterange.php
Normal file
106
admin/components/UI/Form/Daterange.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Tools;
|
||||
|
||||
/**
|
||||
* 时间范围选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Daterange extends Element implements Component
|
||||
{
|
||||
|
||||
private string $stopField;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置结束字段
|
||||
* @param $field
|
||||
* @return $this
|
||||
*/
|
||||
public function stopField($field): self
|
||||
{
|
||||
$this->stopField = $field;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-range-picker',
|
||||
'allowClear' => true,
|
||||
'vModel:modelValue' => $this->getModelField()
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function appendInput($value): array
|
||||
{
|
||||
if (!$this->stopField) {
|
||||
return [];
|
||||
}
|
||||
$data = [];
|
||||
$data[$this->stopField] = is_array($value) && $value[1] ? date('Y-m-d H:i:s', strtotime($value[1])) : null;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataInput($value): ?string
|
||||
{
|
||||
if ($this->stopField) {
|
||||
return is_array($value) && $value[0] ? date('Y-m-d H:i:s',strtotime($value[0])) : null;
|
||||
}
|
||||
return is_array($value) ? date('Y-m-d H:i:s', strtotime($value[0])) . ',' . date('Y-m-d H:i:s', strtotime($value[1])) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $info
|
||||
* @return array|null
|
||||
*/
|
||||
public function dataValue($value, $info): ?array
|
||||
{
|
||||
$value = $this->getValue($value);
|
||||
$data = [];
|
||||
if ($this->stopField) {
|
||||
$data[] = $value ?: null;
|
||||
$stopValue = Tools::parsingArrData($info, $this->stopField);
|
||||
$data[] = $stopValue ?: null;
|
||||
return $data;
|
||||
}
|
||||
if ($value) {
|
||||
$data = explode(',', $value);
|
||||
}
|
||||
return $data ? [$data[0], $data[1]] : null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
79
admin/components/UI/Form/Datetime.php
Normal file
79
admin/components/UI/Form/Datetime.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 日期时间选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Datetime extends Element implements Component
|
||||
{
|
||||
|
||||
protected string $string = 'YYYY-MM-DD HH:mm';
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式
|
||||
* @param string $format
|
||||
* @return $this
|
||||
*/
|
||||
public function string(string $format): self
|
||||
{
|
||||
$this->string = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染组件
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-date-picker',
|
||||
'vModel:value' => $this->getModelField(),
|
||||
'showTime' => true,
|
||||
'allowClear' => true,
|
||||
'format' => $this->string,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
'vModel:modelValue' => $this->getModelField()
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return $data ? date('Y-m-d H:i:s', strtotime($data)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataValue($data): ?string
|
||||
{
|
||||
$data = $this->getValue($data);
|
||||
return $data ?: null;
|
||||
}
|
||||
|
||||
}
|
||||
38
admin/components/UI/Form/Editor.php
Normal file
38
admin/components/UI/Form/Editor.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 编辑器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Editor extends Element implements Component
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-editor'
|
||||
];
|
||||
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
536
admin/components/UI/Form/Element.php
Normal file
536
admin/components/UI/Form/Element.php
Normal file
@@ -0,0 +1,536 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Tools;
|
||||
|
||||
/**
|
||||
* 单元素组件
|
||||
* Class Component
|
||||
* @package backend\components\UI
|
||||
*/
|
||||
class Element
|
||||
{
|
||||
protected string $name = '';
|
||||
protected string $field = '';
|
||||
protected string $has = '';
|
||||
protected $help = '';
|
||||
protected $helpLine = '';
|
||||
protected string $prompt = '';
|
||||
protected string $model = 'data.';
|
||||
protected array $class = [];
|
||||
protected $replace = '';
|
||||
protected array $attr = [];
|
||||
protected array $layoutAttr = [];
|
||||
protected array $style = [];
|
||||
protected array $pivot = [];
|
||||
protected array $verify = [];
|
||||
protected array $verifyMsg = [];
|
||||
protected array $format = [];
|
||||
protected bool $dialog = false;
|
||||
protected bool $vertical = false;
|
||||
protected bool $label = true;
|
||||
protected bool $component = false;
|
||||
protected bool $must = false;
|
||||
protected array $group = [];
|
||||
protected ?int $sort = null;
|
||||
protected $modelElo;
|
||||
protected $value;
|
||||
protected $default;
|
||||
|
||||
|
||||
/**
|
||||
* 设置弹窗
|
||||
* @param $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function dialog($bool): self
|
||||
{
|
||||
$this->dialog = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置方向
|
||||
* @param $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function vertical($bool): self
|
||||
{
|
||||
$this->vertical = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据模型
|
||||
*/
|
||||
public function modelElo($class)
|
||||
{
|
||||
$this->modelElo = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据前缀
|
||||
*/
|
||||
public function model($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型字段
|
||||
* @return string
|
||||
*/
|
||||
public function getModelField()
|
||||
{
|
||||
return $this->model . $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签状态
|
||||
* @return bool
|
||||
*/
|
||||
public function getLabel(): bool
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取字段名
|
||||
* @return string
|
||||
*/
|
||||
public function getField(): string
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关联模型
|
||||
* @return string
|
||||
*/
|
||||
public function getHas(): string
|
||||
{
|
||||
return $this->has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取值
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue($value = null)
|
||||
{
|
||||
return ($this->value ?? $value) ?? $this->default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组值
|
||||
* @param $value
|
||||
* @param bool $json
|
||||
* @return array|null
|
||||
*/
|
||||
public function getValueArray($value, bool $json = false): ?array
|
||||
{
|
||||
if ($value instanceof \Illuminate\Database\Eloquent\Collection) {
|
||||
if ($value->count()) {
|
||||
$values = $value->pluck($value->first()->getKeyName())->toArray();
|
||||
} else {
|
||||
$values = $json ? [] : null;
|
||||
}
|
||||
} else if (is_array($value)) {
|
||||
$values = $value;
|
||||
} else if ($value !== null) {
|
||||
$values = $json ? json_decode($value, true) : explode(',', $value);
|
||||
} else {
|
||||
$values = $json ? [] : null;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取回调数据组
|
||||
* @param $data
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function getCallbackArray($data, $value): array
|
||||
{
|
||||
if ($data instanceof \Closure) {
|
||||
return call_user_func($data, [$value]);
|
||||
}
|
||||
if (is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选项值
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function value($value): self
|
||||
{
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认值
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function default($value): self
|
||||
{
|
||||
$this->default = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置帮助信息
|
||||
* @param string|array $value
|
||||
* @param bool $line
|
||||
* @return $this
|
||||
*/
|
||||
public function help($value, bool $line = false): self
|
||||
{
|
||||
if ($line) {
|
||||
$this->helpLine = $value;
|
||||
} else {
|
||||
$this->help = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 属性数据
|
||||
* @param string $name
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
*/
|
||||
public function attr(string $name, $value): self
|
||||
{
|
||||
$this->attr[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 布局树形
|
||||
* @param string $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function layoutAttr(string $name, $value): self
|
||||
{
|
||||
$this->layoutAttr[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 属性数组
|
||||
* @param $attr
|
||||
* @return $this
|
||||
*/
|
||||
public function attrArray($attr): self
|
||||
{
|
||||
$this->attr = $attr;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* class样式
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function class(string $name): self
|
||||
{
|
||||
$this->class[] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串替换标签(数字字符串处理使用)
|
||||
* @param $replace
|
||||
* @return $this
|
||||
*/
|
||||
public function replace($replace): self
|
||||
{
|
||||
$this->replace = $replace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function placeholder($name): self
|
||||
{
|
||||
if ($name) {
|
||||
$this->attr['placeholder'] = $name;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 元素分组
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function group($name, $value): self
|
||||
{
|
||||
$this->group[] = [
|
||||
'name' => $name,
|
||||
'value' => $value
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 必填样式
|
||||
* @return $this
|
||||
*/
|
||||
public function must(): self
|
||||
{
|
||||
$this->must = true;
|
||||
$this->verify['all'][$this->field][] = 'required';
|
||||
$this->verifyMsg['all'][$this->field . '.' . 'required'] = '请输入' . $this->name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 帮助信息
|
||||
* @param $content
|
||||
* @return $this
|
||||
*/
|
||||
public function prompt($content): self
|
||||
{
|
||||
$this->prompt = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 排序
|
||||
* @param $num
|
||||
* @return $this
|
||||
*/
|
||||
public function sort($num): self
|
||||
{
|
||||
$this->sort = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组
|
||||
* @return array
|
||||
*/
|
||||
public function getGroup(): array
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取必须
|
||||
* @return bool
|
||||
*/
|
||||
public function getMust(): bool
|
||||
{
|
||||
return $this->must;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提醒
|
||||
* @return string
|
||||
*/
|
||||
public function getPrompt(): string
|
||||
{
|
||||
return $this->prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帮助行
|
||||
* @return string|array
|
||||
*/
|
||||
public function getHelpLine()
|
||||
{
|
||||
return $this->helpLine;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取层属性
|
||||
* @return array
|
||||
*/
|
||||
public function getLayoutAttr()
|
||||
{
|
||||
return $this->layoutAttr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步附加数据
|
||||
* @param $data
|
||||
* @return $this
|
||||
*/
|
||||
public function pivot($data)
|
||||
{
|
||||
$this->pivot = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段验证
|
||||
* @param $rule
|
||||
* @param array $msg
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function verify($rule, array $msg = [], string $time = 'all'): self
|
||||
{
|
||||
$this->verify[$time][$this->field] = $rule;
|
||||
foreach ($msg as $key => $vo) {
|
||||
$this->verifyMsg[$time][$this->field . '.' . $key] = $vo;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证规则
|
||||
* @param string $time
|
||||
* @return array
|
||||
*/
|
||||
public function getVerify(string $time = 'add'): array
|
||||
{
|
||||
return [
|
||||
'rule' => (array)$this->verify['all'] + (array)$this->verify[$time],
|
||||
'msg' => (array)$this->verifyMsg['all'] + (array)$this->verifyMsg[$time]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表单格式化
|
||||
* @param string|callable $rule
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function format($rule, string $time = 'all'): self
|
||||
{
|
||||
$this->format[$time][] = $rule;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表单格式化
|
||||
* @param string $time
|
||||
* @return array
|
||||
*/
|
||||
public function getFormat(string $time = 'add'): array
|
||||
{
|
||||
return (array)$this->format['all'] + (array)$this->format[$time];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取提交数据
|
||||
* @param string $time
|
||||
* @return mixed
|
||||
*/
|
||||
public function getInput(string $time = 'add'): array
|
||||
{
|
||||
$data = \Yii::$app->request->get($this->field);
|
||||
$inputs = [];
|
||||
if (method_exists($this, 'appendInput') && !$this->has) {
|
||||
$appendData = $this->appendInput($data);
|
||||
foreach ($appendData as $key => $vo) {
|
||||
$inputs[$key] = ['value' => $vo];
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($this, 'dataInput') && !$this->has) {
|
||||
$data = $this->dataInput($data);
|
||||
}
|
||||
$inputs[$this->field] = ['value' => $data, 'has' => $this->has, 'format' => $this->getFormat($time), 'verify' => $this->getVerify($time), 'pivot' => $this->pivot];
|
||||
|
||||
return $inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帮助信息
|
||||
* @return string|array
|
||||
*/
|
||||
public function getHelp()
|
||||
{
|
||||
return $this->help;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取顺序
|
||||
* @return null
|
||||
*/
|
||||
public function getSort(): ?int
|
||||
{
|
||||
return $this->sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复合组件
|
||||
* @return bool
|
||||
*/
|
||||
public function getComponent(): bool
|
||||
{
|
||||
return $this->component;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取渲染组件
|
||||
* @return array
|
||||
*/
|
||||
public function getRender(): array
|
||||
{
|
||||
if ($this->class) {
|
||||
$this->attr['class'] = implode(' ', $this->class);
|
||||
}
|
||||
return array_merge($this->render(), $this->attr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据值
|
||||
* @param $info
|
||||
* @return array
|
||||
*/
|
||||
public function getData($info): array
|
||||
{
|
||||
$field = $this->getHas() ?: $this->getField();
|
||||
$value = Tools::parsingArrData($info, $field);
|
||||
$data = [];
|
||||
if (method_exists($this, 'appendValue')) {
|
||||
$appendValue = $this->appendValue($info);
|
||||
foreach ($appendValue as $key => $vo) {
|
||||
$data[$key] = $vo;
|
||||
}
|
||||
}
|
||||
if (method_exists($this, 'dataValue')) {
|
||||
$value = $this->dataValue($value, $info);
|
||||
} else {
|
||||
$value = $this->getValue($value);
|
||||
}
|
||||
$data[$this->getField()] = $value;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
36
admin/components/UI/Form/Email.php
Normal file
36
admin/components/UI/Form/Email.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 邮箱输入
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Email extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->object = new Text($this->name, $this->field, $this->has);
|
||||
$this->object->afterIcon('email');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return $this->object->getRender();
|
||||
}
|
||||
|
||||
}
|
||||
84
admin/components/UI/Form/File.php
Normal file
84
admin/components/UI/Form/File.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class File extends Element implements Component
|
||||
{
|
||||
protected string $type = 'upload';
|
||||
protected string $url = '';
|
||||
protected string $fileUrl = '';
|
||||
|
||||
/**
|
||||
* File constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传方式
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type = 'upload'): self
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function fileUrl(string $url): self
|
||||
{
|
||||
$this->fileUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-file',
|
||||
];
|
||||
if ($this->url) {
|
||||
$data['upload'] = $this->url;
|
||||
}
|
||||
if ($this->fileUrl) {
|
||||
$data['fileUrl'] = $this->fileUrl;
|
||||
}
|
||||
if ($this->type) {
|
||||
$data['type'] = $this->type;
|
||||
}
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
85
admin/components/UI/Form/Files.php
Normal file
85
admin/components/UI/Form/Files.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 多文件上传
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Files extends Element implements Component
|
||||
{
|
||||
protected string $type = 'manage';
|
||||
protected string $url = '';
|
||||
protected string $fileUrl = '';
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传方式
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type = 'manage'): self
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function fileUrl(string $url): self
|
||||
{
|
||||
$this->fileUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-files',
|
||||
];
|
||||
if ($this->type) {
|
||||
$data['type'] = $this->type;
|
||||
}
|
||||
if ($this->url) {
|
||||
$data['upload'] = $this->url;
|
||||
}
|
||||
if ($this->fileUrl) {
|
||||
$data['fileUrl'] = $this->fileUrl;
|
||||
}
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
40
admin/components/UI/Form/Html.php
Normal file
40
admin/components/UI/Form/Html.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 自定义Html
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Html extends Element implements Component
|
||||
{
|
||||
protected \Closure $callback;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param \Closure $callback
|
||||
*/
|
||||
public function __construct(string $name, \Closure $callback)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$callback = is_callable($this->callback) ? call_user_func($this->callback) : $this->callback;
|
||||
|
||||
if (is_array($callback)) {
|
||||
return $callback;
|
||||
}
|
||||
return [
|
||||
'nodeName' => 'rich-text',
|
||||
'nodes' => $callback
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
124
admin/components/UI/Form/Image.php
Normal file
124
admin/components/UI/Form/Image.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Image
|
||||
* 图片上传
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Image extends Element implements Component
|
||||
{
|
||||
|
||||
private array $thumb = [];
|
||||
private array $water = [];
|
||||
protected string $type = 'manage';
|
||||
protected string $url = '';
|
||||
protected string $fileUrl = '';
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩图
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function thumb(int $width, int $height, string $type = 'scale'): self
|
||||
{
|
||||
$this->thumb = [
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'thumb' => $type
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 水印
|
||||
* @param string $position
|
||||
* @param int $alpha
|
||||
* @return $this
|
||||
*/
|
||||
public function water(string $position = 'center', int $alpha = 80): self
|
||||
{
|
||||
$this->water = [
|
||||
'alpha' => $alpha,
|
||||
'water' => $position
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type = 'manage'): self
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function fileUrl(string $url): self
|
||||
{
|
||||
$this->fileUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 渲染组件
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-file',
|
||||
'format' => 'image',
|
||||
'image' => true,
|
||||
'size' => 125
|
||||
];
|
||||
if ($this->url) {
|
||||
$data['upload'] = $this->url;
|
||||
}
|
||||
if ($this->fileUrl) {
|
||||
$data['fileUrl'] = $this->fileUrl;
|
||||
}
|
||||
if ($this->type) {
|
||||
$data['type'] = $this->type;
|
||||
}
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
79
admin/components/UI/Form/Images.php
Normal file
79
admin/components/UI/Form/Images.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 组图上传
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Images extends Element implements Component
|
||||
{
|
||||
protected string $type = 'manage';
|
||||
protected string $url = '';
|
||||
protected string $fileUrl = '';
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
public function type($type = 'manage')
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function fileUrl(string $url): self
|
||||
{
|
||||
$this->fileUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'app-images',
|
||||
];
|
||||
if ($this->type) {
|
||||
$data['type'] = $this->type;
|
||||
}
|
||||
if ($this->url) {
|
||||
$data['upload'] = $this->url;
|
||||
}
|
||||
if ($this->fileUrl) {
|
||||
$data['fileUrl'] = $this->fileUrl;
|
||||
}
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
35
admin/components/UI/Form/Ip.php
Normal file
35
admin/components/UI/Form/Ip.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Ip extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->object = new Text($this->name, $this->field, $this->has);
|
||||
$this->object->afterIcon('desktop');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return $this->object->getRender();
|
||||
}
|
||||
|
||||
}
|
||||
35
admin/components/UI/Form/Layout.php
Normal file
35
admin/components/UI/Form/Layout.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Row
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Layout extends Composite implements Component
|
||||
{
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* @param callable|array $callback
|
||||
*/
|
||||
public function __construct($callback)
|
||||
{
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$callback = is_callable($this->callback) ? call_user_func($this->callback) : $this->callback;
|
||||
return [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'mb-4',
|
||||
'child' => $callback
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
96
admin/components/UI/Form/Location.php
Normal file
96
admin/components/UI/Form/Location.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 地图
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Location extends Element implements Component
|
||||
{
|
||||
protected array $map = [
|
||||
'province' => 'province',
|
||||
'city' => 'city',
|
||||
'district' => 'district',
|
||||
'street' => 'street',
|
||||
'streetNumber' => 'streetNumber',
|
||||
'address' => 'address',
|
||||
'lat' => 'lat',
|
||||
'lng' => 'lng'
|
||||
];
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$child = [];
|
||||
|
||||
return [
|
||||
'nodeName' => 'app-map',
|
||||
'vModel:value' => $this->getModelField(),
|
||||
'child' => $child,
|
||||
'placeholder' => '请输入' . $this->name,
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function appendInput($data): array
|
||||
{
|
||||
$ret = [];
|
||||
if ($data->province) {
|
||||
$ret[$this->map['province']] = $data->province;
|
||||
}
|
||||
if ($data->city) {
|
||||
$ret[$this->map['city']] = $data->city;
|
||||
}
|
||||
if ($data->district) {
|
||||
$ret[$this->map['district']] = $data->district;
|
||||
}
|
||||
if ($data->street) {
|
||||
$ret[$this->map['street']] = $data->street;
|
||||
}
|
||||
if ($data->streetNumber) {
|
||||
$ret[$this->map['streetNumber']] = $data->streetNumber;
|
||||
}
|
||||
if ($data->address) {
|
||||
$ret[$this->map['address']] = $data->address;
|
||||
}
|
||||
if ($data->lat) {
|
||||
$ret[$this->map['lat']] = $data->lat;
|
||||
}
|
||||
if ($data->lng) {
|
||||
$ret[$this->map['lng']] = $data->lng;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
/**
|
||||
* @param $data
|
||||
* @return string|null
|
||||
*/
|
||||
public function dataValue($data): ?array
|
||||
{
|
||||
$data = $this->getValue($data);
|
||||
if( empty($data) ){
|
||||
return [];
|
||||
}else{
|
||||
return json_decode($data,true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
264
admin/components/UI/Form/Node.php
Normal file
264
admin/components/UI/Form/Node.php
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 表单节点
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Node
|
||||
{
|
||||
|
||||
private string $url;
|
||||
private string $method;
|
||||
private ?string $title;
|
||||
private bool $back = false;
|
||||
private bool $dialog = false;
|
||||
private bool $vertical = false;
|
||||
private array $element = [];
|
||||
private array $data = [];
|
||||
private array $side = ['left'=>[],'right'=>[]];
|
||||
private array $script = [];
|
||||
private array $scriptReturn = [];
|
||||
|
||||
/**
|
||||
* Node constructor.
|
||||
* @param string $action
|
||||
* @param string $method
|
||||
* @param string|null $title
|
||||
*/
|
||||
public function __construct(string $action, string $method, ?string $title = '')
|
||||
{
|
||||
$this->url = $action;
|
||||
$this->method = $method;
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bool
|
||||
*/
|
||||
public function back(bool $bool): void
|
||||
{
|
||||
$this->back = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure|string $content
|
||||
* @param string $return
|
||||
* @return $this
|
||||
*/
|
||||
public function script($content, string $return): self
|
||||
{
|
||||
if ($content instanceof \Closure) {
|
||||
$this->script[] = $content();
|
||||
} else {
|
||||
$this->script[] = $content;
|
||||
}
|
||||
$this->scriptReturn[] = $return;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function dialog(bool $bool): self
|
||||
{
|
||||
$this->dialog = $bool;
|
||||
$this->vertical = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function vertical(bool $bool): self
|
||||
{
|
||||
$this->vertical = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $node
|
||||
* @return $this
|
||||
*/
|
||||
public function element(array $node): self
|
||||
{
|
||||
$this->element = $node;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Closure|array $node
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function side($node, string $type = 'left'): self
|
||||
{
|
||||
$this->side[$type] = is_callable($node) ? $node() : $node;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return $this
|
||||
*/
|
||||
public function data($data): self
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染页面
|
||||
* @return array[]
|
||||
*/
|
||||
private function renderPage(): array
|
||||
{
|
||||
return [
|
||||
$this->side['left'] ? [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-none flex h-screen flex-col',
|
||||
'child' => $this->side['left']
|
||||
] : [],
|
||||
[
|
||||
'nodeName' => 'app-layout',
|
||||
'class' => 'flex-grow w-10',
|
||||
'title' => $this->title ?: '信息详情',
|
||||
'form' => true,
|
||||
'back' => $this->back,
|
||||
'vBind:formLoading' => 'loading',
|
||||
'child' => [
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'class' => 'p-4',
|
||||
'child' => [
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'child' => $this->element
|
||||
],
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex items-center justify-end gap-2 flex-row ',
|
||||
'child' => [
|
||||
$this->back ? [
|
||||
'nodeName' => 'route',
|
||||
'type' => 'back',
|
||||
'child' => [
|
||||
'type' => "outline",
|
||||
'nodeName' => 'a-button',
|
||||
'child' => '返回',
|
||||
]
|
||||
] : [],
|
||||
[
|
||||
'nodeName' => 'a-button',
|
||||
'html-type' => 'submit',
|
||||
'vBind:loading' => "loading",
|
||||
'type' => 'primary',
|
||||
'child' => $this->back ? '提交' : '保存',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
$this->side['right']? [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-none flex h-screen flex-col',
|
||||
'child' => $this->side['right']
|
||||
] : [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染弹窗
|
||||
* @return array
|
||||
*/
|
||||
private function renderDialog(): array
|
||||
{
|
||||
|
||||
return [
|
||||
'nodeName' => 'app-dialog',
|
||||
'title' => $this->title ?: '信息详情',
|
||||
'class' => 'flex-grow',
|
||||
'child' => [
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'vSlot:default' => '',
|
||||
'class' => 'flex',
|
||||
'child' => [
|
||||
$this->side['left'] ? [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-none',
|
||||
'child' => $this->side['left']
|
||||
] : [],
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-grow p-5 pb-0',
|
||||
'child' => $this->element
|
||||
],
|
||||
$this->side['right'] ? [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex-none',
|
||||
'child' => $this->side['right']
|
||||
] : []
|
||||
]
|
||||
],
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'vSlot:footer' => '',
|
||||
'class' => 'arco-modal-footer',
|
||||
'child' => [
|
||||
[
|
||||
'nodeName' => 'route',
|
||||
'type' => 'back',
|
||||
'child' => [
|
||||
'nodeName' => 'a-button',
|
||||
'child' => '取消'
|
||||
]
|
||||
],
|
||||
[
|
||||
'nodeName' => 'a-button',
|
||||
'type' => 'primary',
|
||||
'html-type' => 'submit',
|
||||
'vBind:loading' => "loading",
|
||||
'child' => '提交'
|
||||
],
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染布局
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return [
|
||||
'node' => [
|
||||
'nodeName' => 'app-form',
|
||||
'url' => $this->url,
|
||||
'method' => $this->method,
|
||||
'value' => $this->data,
|
||||
'layout' => $this->vertical ? 'vertical' : 'horizontal',
|
||||
'back' => $this->back,
|
||||
'child' => [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'flex',
|
||||
'vSlot' => '{value: data, submitStatus: loading}',
|
||||
'child' => $this->dialog ? $this->renderDialog() : $this->renderPage()
|
||||
]
|
||||
],
|
||||
'setupScript' => implode("\n", $this->script) . "\n" . ' return {' . implode(",", $this->scriptReturn) . '}'
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
101
admin/components/UI/Form/Number.php
Normal file
101
admin/components/UI/Form/Number.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 数字输入器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Number extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
/**
|
||||
* @var int|float
|
||||
*/
|
||||
protected $step = 1;
|
||||
/**
|
||||
* @var ?int|float
|
||||
*/
|
||||
protected $max = null;
|
||||
/**
|
||||
* @var int|float
|
||||
*/
|
||||
protected $min = 0;
|
||||
protected ?int $precision = null;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大值
|
||||
* @param int|float $default
|
||||
* @return $this
|
||||
*/
|
||||
public function max($default = 0): self
|
||||
{
|
||||
$this->max = $default;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小值
|
||||
* @param int|float $default
|
||||
* @return $this
|
||||
*/
|
||||
public function min($default = 0): self
|
||||
{
|
||||
$this->min = $default;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 步进数值
|
||||
* @param int|float $default
|
||||
* @param int|null $precision
|
||||
* @return $this
|
||||
*/
|
||||
public function step($default = 1, ?int $precision = null): self
|
||||
{
|
||||
$this->step = $default;
|
||||
$this->precision = $precision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-input-number',
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请输入' . $this->name,
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'step' => $this->step,
|
||||
'min' => $this->min,
|
||||
'mode' => 'button'
|
||||
];
|
||||
if ($this->max) {
|
||||
$data['max'] = $this->max;
|
||||
}
|
||||
if ($this->precision) {
|
||||
$data['precision'] = $this->precision;
|
||||
}
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
48
admin/components/UI/Form/Password.php
Normal file
48
admin/components/UI/Form/Password.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 密码输入器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Password extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-input-password',
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请输入' . $this->name,
|
||||
'allowClear' => true
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
108
admin/components/UI/Form/Radio.php
Normal file
108
admin/components/UI/Form/Radio.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 单选框
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Radio extends Element implements Component
|
||||
{
|
||||
protected array $box = [];
|
||||
protected $data = [];
|
||||
protected string $switch = '';
|
||||
|
||||
/**
|
||||
* Select constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null|array|callable $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = [], string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加选项
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function add($name, $value): self
|
||||
{
|
||||
$this->data[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换组件
|
||||
* @param $group
|
||||
* @return $this
|
||||
*/
|
||||
public function switch($group): self
|
||||
{
|
||||
$this->switch = $group;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型选择
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function box(array $data): self
|
||||
{
|
||||
$this->box = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data);
|
||||
}
|
||||
if (is_array($this->data)) {
|
||||
$data = $this->data;
|
||||
}
|
||||
$this->data = $data;
|
||||
|
||||
|
||||
$child = [];
|
||||
foreach ($data as $key => $vo) {
|
||||
$child[] = [
|
||||
'nodeName' => 'a-radio',
|
||||
'child' => $vo,
|
||||
'value' => $key,
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'nodeName' => 'a-radio-group',
|
||||
'name' => $this->field,
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'child' => $child
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function dataValue($value)
|
||||
{
|
||||
return $this->getValue($value) ?? array_key_first((array)$this->data);
|
||||
}
|
||||
|
||||
}
|
||||
54
admin/components/UI/Form/Row.php
Normal file
54
admin/components/UI/Form/Row.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Row
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Row extends Composite implements Component
|
||||
{
|
||||
|
||||
/**
|
||||
* 设置列
|
||||
* @param callable $callback
|
||||
* @param int $width
|
||||
* @return $this
|
||||
*/
|
||||
public function column(callable $callback, int $width = 0): self
|
||||
{
|
||||
$form = new Form();
|
||||
$callback($form);
|
||||
$this->column[] = [
|
||||
'width' => $width,
|
||||
'object' => $form,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$inner = [];
|
||||
foreach ($this->column as $vo) {
|
||||
$width = $vo['width'] ? "lg:row-span-{$vo['width']}" : '';
|
||||
$form = $vo['object']->renderForm();
|
||||
$inner[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => $width,
|
||||
'child' => $form
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'grid lg:grid-flow-col gap-4',
|
||||
'child' => $inner
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
198
admin/components/UI/Form/Select.php
Normal file
198
admin/components/UI/Form/Select.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Select
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Select extends Element implements Component
|
||||
{
|
||||
protected string $url = '';
|
||||
protected string $route = '';
|
||||
protected int $tagCount = 0;
|
||||
protected bool $tip = false;
|
||||
protected bool $search = false;
|
||||
protected bool $multi = false;
|
||||
protected array $optionRender = [];
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Select constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = null, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加选项
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function add($name, $value): self
|
||||
{
|
||||
$this->data[$value] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认提示
|
||||
* @param bool $tip
|
||||
* @return $this
|
||||
*/
|
||||
public function tip(bool $tip = true): self
|
||||
{
|
||||
$this->tip = $tip;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param bool $search
|
||||
* @return $this
|
||||
*/
|
||||
public function search(bool $search = true): self
|
||||
{
|
||||
$this->search = $search;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
* @param string $route
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function route(string $route, array $params = []): self
|
||||
{
|
||||
$this->route = $route;
|
||||
$this->url = app_route($route, $params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选
|
||||
* @param int $count
|
||||
* @return $this
|
||||
*/
|
||||
public function multi(int $count = 0): self
|
||||
{
|
||||
$this->multi = true;
|
||||
$this->tagCount = $count;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 选项渲染
|
||||
* @param array $data JS Node
|
||||
* @return $this
|
||||
*/
|
||||
public function optionRender(array $data): self
|
||||
{
|
||||
$this->optionRender = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [];
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data);
|
||||
}
|
||||
if (is_array($this->data)) {
|
||||
$data = $this->data;
|
||||
}
|
||||
$options = [];
|
||||
if(isset($data[0]['label'])){
|
||||
$options=$data;
|
||||
}else{
|
||||
foreach ($data as $key => $vo) {
|
||||
$options[] = [
|
||||
'label' => $vo,
|
||||
'value' => $key
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$object = [
|
||||
|
||||
'nodeName' => 'app-select',
|
||||
'nParams' => [
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
'options' => $options
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->model) {
|
||||
$object['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
$object['nParams']['allowClear'] = true;
|
||||
if ($this->multi) {
|
||||
$object['nParams']['multiple'] = true;
|
||||
}
|
||||
if ($this->url) {
|
||||
$object['nParams']['allowSearch'] = true;
|
||||
$object['nParams']['filterOption'] = false;
|
||||
if ($this->route) {
|
||||
$object['vBind:dataUrl'] = $this->url;
|
||||
} else {
|
||||
$object['dataUrl'] = $this->url;
|
||||
}
|
||||
}
|
||||
if ($this->search) {
|
||||
$object['nParams']['allowSearch'] = true;
|
||||
}
|
||||
if ($this->tagCount) {
|
||||
$object['nParams']['maxTagCount'] = $this->tagCount;
|
||||
}
|
||||
if ($this->optionRender) {
|
||||
$object['vRender:optionRender:item'] = $this->optionRender;
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function dataValue($value)
|
||||
{
|
||||
return $this->multi ? array_values(array_filter((array)$this->getValueArray($value))) : $this->getValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
99
admin/components/UI/Form/Tab.php
Normal file
99
admin/components/UI/Form/Tab.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Tab
|
||||
* 切换组件
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Tab extends Composite implements Component
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param callable $callback
|
||||
* @param int|null $order
|
||||
* @param string $title
|
||||
* @param string $desc
|
||||
* @return $this
|
||||
*/
|
||||
public function column($name, callable $callback, int $order = null, string $title = '', string $desc = ''): self
|
||||
{
|
||||
$form = new Form();
|
||||
$form->dialog($this->dialog);
|
||||
$form->vertical($this->vertical);
|
||||
$callback($form);
|
||||
$this->column[] = [
|
||||
'name' => $name,
|
||||
'title' => $title,
|
||||
'desc' => $desc,
|
||||
'order' => $order ?? (count($this->column) + 1),
|
||||
'object' => $form,
|
||||
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$nodes = [];
|
||||
|
||||
$column = collect($this->column)->sortBy('order')->toArray();
|
||||
|
||||
foreach ($column as $key => $vo) {
|
||||
|
||||
$child = [];
|
||||
if ($vo['title']) {
|
||||
$child[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'py-4 flex flex-col gap-2',
|
||||
'child' => [
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'class' => 'text-xl',
|
||||
'child' => $vo['title'],
|
||||
],
|
||||
[
|
||||
'nodeName' => 'div',
|
||||
'class' => 'text-gray-500',
|
||||
'child' => $vo['desc'],
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
$child[] = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'pt-2',
|
||||
'child' => $vo['object']->renderForm()
|
||||
];
|
||||
|
||||
$nodes[] = [
|
||||
'nodeName' => 'a-tab-pane',
|
||||
'title' => $vo['name'],
|
||||
'key' => $key,
|
||||
'class' => !$this->dialog ? ' border-t border-gray-200 dark:border-blackgray-1 px-3 pt-4 pb-0' : '',
|
||||
'child' => [
|
||||
'nodeName' => 'div',
|
||||
'class' => '',
|
||||
'child' => $child
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'nodeName' => 'a-tabs',
|
||||
'class' => !$this->dialog ? 'mb-4 bg-white dark:bg-blackgray-4 rounded shadow p-4 pb-1' : '',
|
||||
'type' => 'rounded',
|
||||
'child' => $nodes
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
78
admin/components/UI/Form/Tags.php
Normal file
78
admin/components/UI/Form/Tags.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Tags
|
||||
* 标签输入框
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Tags extends Element implements Component
|
||||
{
|
||||
protected int $limit = 0;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $num
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($num): self
|
||||
{
|
||||
$this->limit = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-input-tag',
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请输入' . $this->name,
|
||||
'allowClear' => true
|
||||
];
|
||||
if ($this->limit) {
|
||||
$data['maxTagCount'] = $this->limit;
|
||||
}
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array
|
||||
*/
|
||||
public function dataValue($value): array
|
||||
{
|
||||
return array_values(array_filter((array)$this->getValueArray($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
48
admin/components/UI/Form/Tel.php
Normal file
48
admin/components/UI/Form/Tel.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Tel
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Tel extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
protected string $mask = '19999999999';
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->object = new Text($this->name, $this->field, $this->has);
|
||||
$this->object->afterIcon('phone');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置掩码
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function mask($value): self
|
||||
{
|
||||
$this->mask = (string) $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$this->object->attrArray($this->attr);
|
||||
return $this->object->getRender();
|
||||
}
|
||||
|
||||
}
|
||||
121
admin/components/UI/Form/Text.php
Normal file
121
admin/components/UI/Form/Text.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
use admin\components\UI\Widget\Icon;
|
||||
|
||||
/**
|
||||
* 输入框
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Text extends Element implements Component
|
||||
{
|
||||
protected string $type = 'text';
|
||||
protected array $before = [];
|
||||
protected array $after = [];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本类型
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function type($name): self
|
||||
{
|
||||
$this->type = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 前置图标
|
||||
* @param $content
|
||||
* @return $this
|
||||
*/
|
||||
public function beforeIcon($content): self
|
||||
{
|
||||
$this->before = (new Icon($content))->attr('vSlot:prepend', '')->getRender();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置图标
|
||||
* @param $content
|
||||
* @return $this
|
||||
*/
|
||||
public function afterIcon($content): self
|
||||
{
|
||||
$this->after = (new Icon($content))->attr('vSlot:append', '')->getRender();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 前置文本
|
||||
* @param $content
|
||||
* @return $this
|
||||
*/
|
||||
public function beforeText($content): self
|
||||
{
|
||||
$this->before = [
|
||||
'vSlot:prepend' => '',
|
||||
'nodeName' => 'span',
|
||||
'child' => $content
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置文本
|
||||
* @param $content
|
||||
* @return $this
|
||||
*/
|
||||
public function afterText($content): self
|
||||
{
|
||||
$this->after = [
|
||||
'vSlot:append' => '',
|
||||
'nodeName' => 'span',
|
||||
'child' => $content
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$child = [];
|
||||
if ($this->before || $this->after) {
|
||||
$child = [
|
||||
$this->before,
|
||||
$this->after
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'nodeName' => 'a-input',
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'child' => $child,
|
||||
'placeholder' => '请输入' . $this->name
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
62
admin/components/UI/Form/Textarea.php
Normal file
62
admin/components/UI/Form/Textarea.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Textarea
|
||||
* 多行输入框
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Textarea extends Element implements Component
|
||||
{
|
||||
protected int $limit = 0;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $num
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($num): self
|
||||
{
|
||||
$this->limit = $num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-textarea',
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请输入' . $this->name,
|
||||
'allowClear' => true,
|
||||
'showWordLimit' => true
|
||||
];
|
||||
if ($this->limit) {
|
||||
$data['maxLength'] = $this->limit;
|
||||
}
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
53
admin/components/UI/Form/Time.php
Normal file
53
admin/components/UI/Form/Time.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Time
|
||||
* 时间选择器
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Time extends Element implements Component
|
||||
{
|
||||
protected string $string = 'HH:mm:ss';
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间格式
|
||||
* @param string $format
|
||||
* @return $this
|
||||
*/
|
||||
public function string(string $format): self
|
||||
{
|
||||
$this->string = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
return [
|
||||
'nodeName' => 'a-time-picker',
|
||||
'allowClear' => true,
|
||||
'format' => $this->string,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
'vModel:model-value' => $this->getModelField()
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
67
admin/components/UI/Form/Toggle.php
Normal file
67
admin/components/UI/Form/Toggle.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* 开关切换
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Toggle extends Element implements Component
|
||||
{
|
||||
private $checkedValue = 1;
|
||||
private $uncheckedValue = 0;
|
||||
|
||||
/**
|
||||
* Toggle constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = [
|
||||
'nodeName' => 'a-switch',
|
||||
'vModel:modelValue' => $this->getModelField(),
|
||||
'checkedValue' => $this->checkedValue,
|
||||
'uncheckedValue' => $this->uncheckedValue
|
||||
];
|
||||
|
||||
if($this->replace != ''){
|
||||
$data['vStringReplace'] = $this->replace;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开关数据
|
||||
* @param string|number|boolean $checkedValue
|
||||
* @param string|number|boolean $uncheckedValue
|
||||
* @return $this
|
||||
*/
|
||||
public function data($checkedValue,$uncheckedValue){
|
||||
$this->checkedValue = $checkedValue;
|
||||
$this->uncheckedValue = $uncheckedValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return int
|
||||
*/
|
||||
public function dataInput($data): int
|
||||
{
|
||||
return $data ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
96
admin/components/UI/Form/Tree.php
Normal file
96
admin/components/UI/Form/Tree.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class Tree
|
||||
* @package backend\components\UI\Table
|
||||
*/
|
||||
class Tree extends Element implements Component
|
||||
{
|
||||
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Tree constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param null $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = null, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$data = $this->data;
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data);
|
||||
}
|
||||
if ($data instanceof \Illuminate\Database\Eloquent\Collection) {
|
||||
$data = $data->toArray();
|
||||
}
|
||||
|
||||
$data = $this->loop($data);
|
||||
$data = [
|
||||
'nodeName' => 'div',
|
||||
'class' => 'bg-gray-100 dark:bg-blackgray-2 p-2 rounded w-full h-56 overflow-y-auto app-scrollbar',
|
||||
'child' => [
|
||||
'nodeName' => 'a-tree',
|
||||
'blockNode' => true,
|
||||
'checkable' => true,
|
||||
'showLine' => true,
|
||||
'vModel:checked-keys' => $this->getModelField(),
|
||||
'data' => $data,
|
||||
]
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|null
|
||||
*/
|
||||
public function dataValue($value): ?array
|
||||
{
|
||||
return $this->getValueArray($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
protected function loop($data): array
|
||||
{
|
||||
$newData = [];
|
||||
foreach ($data as $item) {
|
||||
$tmpData = [
|
||||
'title' => $item['name'],
|
||||
'key' => $item['id'],
|
||||
];
|
||||
if ($item['children']) {
|
||||
$tmpData['children'] = $this->loop($item['children']);
|
||||
}
|
||||
$newData[] = $tmpData;
|
||||
}
|
||||
return $newData;
|
||||
}
|
||||
|
||||
}
|
||||
183
admin/components/UI/Form/TreeSelect.php
Normal file
183
admin/components/UI/Form/TreeSelect.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* Class TreeSelect
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class TreeSelect extends Element implements Component
|
||||
{
|
||||
protected bool $tip = false;
|
||||
protected bool $multi = false;
|
||||
protected bool $treeData = false;
|
||||
protected string $strategy = 'all';
|
||||
protected string $url = '';
|
||||
protected string $route = '';
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Select constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param array|callback|null $data
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, $data = null, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->data = $data;
|
||||
$this->has = $has;
|
||||
$this->attr['placeholder'] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加选项
|
||||
* @param $name
|
||||
* @param $id
|
||||
* @param $pid
|
||||
* @return $this
|
||||
*/
|
||||
public function add($name, $id, $pid): self
|
||||
{
|
||||
$this->data[] = [
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'pid' => $pid
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置动态地址
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function url(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function route(string $route, array $params = []): self
|
||||
{
|
||||
$this->route = $route;
|
||||
$this->url = app_route($route, $params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选组件
|
||||
* @return $this
|
||||
*/
|
||||
public function multi(): self
|
||||
{
|
||||
$this->multi = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树形模式
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function tree(bool $bool = true): self
|
||||
{
|
||||
$this->treeData = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 回填方式
|
||||
* @param string $model
|
||||
* @return $this
|
||||
*/
|
||||
public function strategy(string $model): self
|
||||
{
|
||||
$this->strategy = $model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
if ($this->data instanceof \Closure) {
|
||||
$data = call_user_func($this->data, $this);
|
||||
}
|
||||
if (is_array($this->data)) {
|
||||
$data = $this->data;
|
||||
}
|
||||
|
||||
if (!$this->treeData) {
|
||||
$options = [];
|
||||
foreach ($data as $vo) {
|
||||
$options[] = [
|
||||
'id' => $vo['id'],
|
||||
'pid' => $vo['pid'],
|
||||
'value' => $vo['id'],
|
||||
'label' => $vo['name'],
|
||||
];
|
||||
}
|
||||
$options = \backend\components\Util\Tree::arr2tree($options, 'id', 'pid', 'children');
|
||||
|
||||
} else {
|
||||
$options = $data;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'nodeName' => 'app-tree-select',
|
||||
'nParams' => [
|
||||
'multiple' => $this->multi,
|
||||
'treeCheckable' => $this->multi,
|
||||
'treeCheckedStrategy' => $this->strategy,
|
||||
'data' => $options,
|
||||
'placeholder' => $this->attr['placeholder'] ?: '请选择' . $this->name,
|
||||
|
||||
]
|
||||
];
|
||||
|
||||
if ($this->route) {
|
||||
$data['vBind:dataUrl'] = $this->url;
|
||||
} else {
|
||||
$data['dataUrl'] = $this->url;
|
||||
}
|
||||
|
||||
if ($this->model) {
|
||||
$data['vModel:value'] = $this->getModelField();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function dataValue($value)
|
||||
{
|
||||
return $this->multi ? array_values(array_filter((array)$this->getValueArray($value))) : $this->getValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function dataInput($data): ?string
|
||||
{
|
||||
return is_array($data) ? implode(',', $data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
37
admin/components/UI/Form/Url.php
Normal file
37
admin/components/UI/Form/Url.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace admin\components\UI\Form;
|
||||
|
||||
/**
|
||||
* url输入
|
||||
* @package backend\components\UI\Form
|
||||
*/
|
||||
class Url extends Element implements Component
|
||||
{
|
||||
protected Text $object;
|
||||
|
||||
/**
|
||||
* Text constructor.
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @param string $has
|
||||
*/
|
||||
public function __construct(string $name, string $field, string $has = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->field = $field;
|
||||
$this->has = $has;
|
||||
$this->object = new Text($this->name, $this->field, $this->has);
|
||||
$this->object->beforeText('http(s)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$this->object->attrArray($this->attr);
|
||||
return $this->object->getRender();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user