骏飞影业微信小程序API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

715 lines
22 KiB

<?php
/**
* +----------------------------------------------------------------------
* | 表格快速构造器
* +----------------------------------------------------------------------
* .::::.
* .::::::::. | AUTHOR: siyu
* ::::::::::: | EMAIL: 407593529@qq.com
* ..:::::::::::' | QQ: 407593529
* '::::::::::::' | DATETIME: 2019/08/05
* .::::::::::
* '::::::::::::::..
* ..::::::::::::.
* ``::::::::::::::::
* ::::``:::::::::' .:::.
* ::::' ':::::' .::::::::.
* .::::' :::: .:::::::'::::.
* .:::' ::::: .:::::::::' ':::::.
* .::' :::::.:::::::::' ':::::.
* .::' ::::::::::::::' ``::::.
* ...::: ::::::::::::' ``::.
* ```` ':. ':::::::::' ::::..
* '.:::::' ':'````..
* +----------------------------------------------------------------------
*/
namespace app\common\builder;
use think\facade\Request;
use think\facade\View;
class TableBuilder
{
/**
* @var array 列名
*/
private $_field_name = [];
/**
* @var string 模板路径(默认使用系统内置路径,无需设置)
*/
private $_template = '';
/**
* @var array 模板变量
*/
private $_vars = [
'page_title' => '', // 页面标题
'page_tips' => '', // 页面提示
'page_tips_top' => '', // 页面提示[top]
'page_tips_search' => '', // 页面提示[search]
'page_tips_bottom' => '', // 页面提示[bottom]
'page_size' => '', // 每页显示的行数
'tips_type' => '', // 页面提示类型
'extra_js' => '', // 额外JS代码
'extra_css' => '', // 额外CSS代码
'extra_html' => '', // 额外HTML代码
'columns' => [], // 表格列集合
'right_buttons' => [], // 表格右侧按钮
'top_buttons' => [], // 顶部栏按钮组[toolbar]
'unique_id' => 'id', // 表格主键名称(默认为id,如表主键不为id必须设置主键)
'data_url' => '', // 表格数据源
'add_url' => '', // 默认的新增地址
'edit_url' => '', // 默认的修改地址
'del_url' => '', // 默认的删除地址
'export_url' => '', // 默认的导出地址
'sort_url' => '', // 默认的排序地址
'search' => [], // 搜索参数
'pagination' => 'true', // 是否进行分页
'parent_id_field' => '', // 列表树模式需传递父id
'empty_tips' => '没有找到匹配的记录', // 空数据提示信息
'hide_checkbox' => false, // 是否隐藏第一列多选[待完善]
'layer_open' => true, // 添加/编辑等页启用layer弹层加载
'fixed_left' => 0, // 左侧固定列数
'fixed_right' => 1, // 右侧固定列数
];
/**
* @var 单例模式句柄
*/
private static $instance;
/**
* 获取句柄
* @return FormBuilder
*/
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 私有化构造函数
*/
private function __construct()
{
// 初始化
$this->initialize();
}
/**
* 初始化
*/
protected function initialize()
{
// 每页显示的行数
$this->_vars['page_size'] = \think\facade\Config::get('app.page_size', '10');
// layer弹层
$this->_vars['layer_open'] = \think\facade\Config::get('builder.layer_open', false);
// 设置默认模版
$this->_template = 'table_builder/layout';
// 设置默认URL
$this->_vars['data_url'] = Request::baseUrl() . '?getList=1';
$this->_vars['add_url'] = url('add');
$this->_vars['edit_url'] = url('edit', ['id' => '__id__']);
$this->_vars['del_url'] = url('del');
$this->_vars['export_url'] = url('export');
$this->_vars['sort_url'] = url('sort');
}
/**
* 私有化clone函数
*/
private function __clone()
{
// TODO: Implement __clone() method.
}
/**
* 渲染模版
* @param string $template 模板文件名
* @return string
* @throws \Exception
*/
public function fetch(string $template = '')
{
// 单独设置模板
if ($template != '') {
$this->_template = $template;
}
View::assign($this->_vars);
return View::fetch($this->_template);
}
/**
* 设置表格主键
* @param string $key 主键名称
* @return $this
*/
public function setUniqueId($key = '')
{
if ($key != '') {
$this->_vars['unique_id'] = $key;
}
return $this;
}
/**
* 设置页面标题
* @param string $title 页面标题
* @return $this
*/
public function setPageTitle($title = '')
{
if ($title != '') {
$this->_vars['page_title'] = trim($title);
}
return $this;
}
/**
* 设置表单页提示信息
* @param string $tips 提示信息
* @param string $type 提示类型:danger,info,warning,success
* @param string $pos 提示位置:top,search,bottom
* @return $this
*/
public function setPageTips($tips = '', $type = 'info', $pos = 'top')
{
if ($tips != '') {
$this->_vars['page_tips_' . $pos] = $tips;
$this->_vars['tips_type'] = trim($type);
}
return $this;
}
/**
* 设置额外JS代码
* @param string $extra_js 额外JS代码
* @return $this
*/
public function setExtraJs($extra_js = '')
{
if ($extra_js != '') {
$this->_vars['extra_js'] = $extra_js;
}
return $this;
}
/**
* 设置额外CSS代码
* @param string $extra_css 额外CSS代码
* @return $this
*/
public function setExtraCss($extra_css = '')
{
if ($extra_css != '') {
$this->_vars['extra_css'] = $extra_css;
}
return $this;
}
/**
* 设置额外HTML代码
* @param string $extra_html 额外HTML代码
* @param string $pos 位置 [top和bottom]
* @return $this
*/
public function setExtraHtml($extra_html = '', $pos = '')
{
if ($extra_html != '') {
$pos != '' && $pos = '_' . $pos;
$this->_vars['extra_html' . $pos] = $extra_html;
}
return $this;
}
/**
* 添加一列
* @param string $name 字段名称
* @param string $title 字段别名
* @param string $type 单元格类型
* @param string $default 默认值
* @param string $param 额外参数
* @param string $class css类名
* @param string $sortable 是否排序
* @param int $with 列宽
* @return $this
*/
public function addColumn($name = '', $title = '', $type = '', $default = '', $param = '', $class = '', $sortable = 'false', $width = 0)
{
$column = [
'name' => $name, // 字段名称
'title' => $title, // 字段别名
'type' => $type, // 单元格类型
'default' => $default, // 默认值
'param' => $param, // 额外参数
'class' => $class, // css类名
'sortable' => $sortable, // 是否排序
'width' => $width, // 列宽
];
$this->_vars['columns'][] = $column;
$this->_field_name[$name] = $title;
return $this;
}
/**
* 一次性添加多列
* @param array $columns 数据列
* @return $this
*/
public function addColumns($columns = [])
{
if (!empty($columns)) {
foreach ($columns as $column) {
call_user_func_array([$this, 'addColumn'], $column);
}
}
return $this;
}
/**
* 设置是否显示分页
* @param string $value 是否显示分页 true|false
* @return $this
*/
public function setPagination($value = '')
{
if ($value != '') {
$this->_vars['pagination'] = $value;
}
return $this;
}
/**
* 设置列表树父ID
* @param string $value 字段
* @return $this
*/
public function setParentIdField($value = '')
{
if ($value != '') {
$this->_vars['parent_id_field'] = $value;
}
return $this;
}
/**
* 设置空数据提示信息
* @param string $value 字段
* @return $this
*/
public function setEmptyTips($value = '')
{
if ($value != '') {
$this->_vars['empty_tips'] = $value;
}
return $this;
}
/**
* 设置每页显示的行数
* @param string $value 数量
* @return $this
*/
public function setPageSize($value = '')
{
if ($value != '') {
$this->_vars['page_size'] = $value;
}
return $this;
}
/**
* 隐藏第一列多选框(默认显示,多选列多用于批量删除等操作)
* @return $this
*/
public function hideCheckbox()
{
$this->_vars['hide_checkbox'] = true;
return $this;
}
/**
* 添加一个右侧按钮
* @param string $type 按钮类型:edit/delete/default
* @param array $attribute 按钮属性
* @param array $extra 扩展参数(待用)
* @return $this
*/
public function addRightButton($type = '', $attribute = [])
{
switch ($type) {
// 预览按钮
case 'preview':
// 默认属性
$btn_attribute = [
'type' => 'preview',
'title' => '预览',
'icon' => 'fa fa-eye',
'class' => 'btn btn-success btn-xs',
'href' => url('index/preview', ['module' => Request::controller(), 'id' => '__id__']),
'target' => '_blank'
];
break;
// 编辑按钮
case 'edit':
// 默认属性
$btn_attribute = [
'type' => 'edit',
'title' => '编辑',
'icon' => 'fa fa-edit',
'class' => 'btn btn-primary btn-xs',
];
break;
// 删除按钮(不可恢复)
case 'delete':
// 默认属性
$btn_attribute = [
'type' => 'delete',
'title' => '删除',
'icon' => 'far fa-trash-alt',
'class' => 'btn btn-danger btn-xs confirm',
];
break;
// 自定义按钮
default:
// 默认属性
$btn_attribute = [
'title' => '自定义按钮',
'icon' => 'fa fa-smile-o',
'class' => 'btn btn-flat btn-default btn-xs',
'href' => 'javascript:void(0);'
];
break;
}
// 合并自定义属性
if ($attribute && is_array($attribute)) {
$btn_attribute = array_merge($btn_attribute, $attribute);
}
$this->_vars['right_buttons'][] = $btn_attribute;
return $this;
}
/**
* 添加多个右侧按钮
* @param array|string $buttons 按钮类型
* 例如:
* $builder->addRightButtons('edit');
* $builder->addRightButtons('edit,delete');
* $builder->addRightButtons(['edit', 'delete']);
* $builder->addRightButtons(['edit' => ['title' => '查看'], 'delete']);
* @return $this
*/
public function addRightButtons($buttons = [])
{
if (!empty($buttons)) {
$buttons = is_array($buttons) ? $buttons : explode(',', $buttons);
foreach ($buttons as $key => $value) {
if (is_numeric($key)) {
$this->addRightButton($value);
} else {
$this->addRightButton(trim($key), $value);
}
}
}
return $this;
}
/**
* 设置表格URL
* @param string $url url地址
* @return $this
*/
public function setDataUrl($url = '')
{
if ($url != '') {
$this->_vars['data_url'] = $url;
}
return $this;
}
/**
* 设置表格默认的新增地址
* @param string $url url地址
* @return $this
*/
public function setAddUrl($url = '')
{
if ($url != '') {
$this->_vars['add_url'] = $url;
}
return $this;
}
/**
* 设置表格默认的修改地址
* @param string $url url地址
* @return $this
*/
public function setEditUrl($url = '')
{
if ($url != '') {
$this->_vars['edit_url'] = $url;
}
return $this;
}
/**
* 设置表格默认的删除地址
* @param string $url url地址
* @return $this
*/
public function setDelUrl($url = '')
{
if ($url != '') {
$this->_vars['del_url'] = $url;
}
return $this;
}
/**
* 设置表格默认的导出地址
* @param string $url url地址
* @return $this
*/
public function setExportUrl($url = '')
{
if ($url != '') {
$this->_vars['export_url'] = $url;
}
return $this;
}
/**
* 设置表格默认的更改排序地址
* @param string $url url地址
* @return $this
*/
public function setSortUrl($url = '')
{
if ($url != '') {
$this->_vars['sort_url'] = $url;
}
return $this;
}
/**
* 设置搜索参数
* @param array $items
* @return $this
* 第一个参数:类型
* 第二个参数:字段名称
* 第三个参数:字段别名
* 第四个参数:匹配方式(默认为'=',也可以是'<>,>,>=,<,<=,LIKE'等等)
* 第五个参数:默认值
* 第六个参数:额外参数(不同类型,用途不同)
*/
public function setSearch($items = [])
{
if (!empty($items)) {
foreach ($items as &$item) {
$item['type'] = $item[0] ?? ''; // 字段类型
$item['name'] = $item[1] ?? ''; // 字段名称
$item['title'] = $item[2] ?? ''; // 字段别名
$item['option'] = $item[3] ?? '='; // 匹配方式
$item['default'] = $item[4] ?? ''; // 默认值
$item['param'] = $item[5] ?? []; // 额外参数
$item['data_source'] = $item[6] ?? 0; // 数据源 [0 字段本身, 1 系统字典, 2 模型数据]
$item['relation_model'] = $item[7] ?? ''; // 模型关联
$item['relation_field'] = $item[8] ?? ''; // 关联字段
$item['field_id'] = $item[9] ?? 0; // 字段编号
}
$this->_vars['search'] = $items;
}
return $this;
}
/**
* 添加一个顶部按钮
* @param string $type 按钮类型:add/edit/del/export/build/default
* @param array $attribute 按钮属性
* @return $this
*/
public function addTopButton($type = '', $attribute = [])
{
switch ($type) {
// 新增按钮
case 'add':
// 默认属性
$btn_attribute = [
'title' => '新增',
'icon' => 'fa fa-plus',
'class' => 'btn btn-success',
'href' => '',
'onclick' => '$.operate.add()',
];
break;
// 修改按钮
case 'edit':
// 默认属性
$btn_attribute = [
'title' => '修改',
'icon' => 'fa fa-edit',
'class' => 'btn btn-primary single disabled',
'href' => '',
'onclick' => '$.operate.edit()',
];
break;
// 删除按钮
case 'del':
// 默认属性
$btn_attribute = [
'title' => '删除',
'icon' => 'fa fa-times',
'class' => 'btn btn-danger multiple disabled',
'href' => '',
'onclick' => '$.operate.removeAll()'
];
break;
// 导出按钮
case 'export':
// 默认属性
$btn_attribute = [
'title' => '导出',
'icon' => 'fa fa-download',
'class' => 'btn btn-warning',
'href' => '',
'onclick' => '$.table.export()'
];
break;
// 生成按钮
case 'build':
// 默认属性
$btn_attribute = [
'title' => '代码生成',
'icon' => 'fa fa-code',
'class' => 'btn btn-info single disabled',
'href' => '',
'onclick' => '$.operate.build(\'\', \'' . url('module/build') . '\')',
'group' => [
'class' => 'btn-info single disabled', // 下拉分组组样式
'menus' => [ // 下拉分组数据(内容同按钮一样)
[
'title' => '生成验证器',
'icon' => '',
'class' => 'btn btn-info',
'href' => '',
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'validate']) . '\')',
],
[
'title' => '生成模型',
'icon' => '',
'class' => 'btn btn-info',
'href' => '',
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'model']) . '\')',
],
[
'title' => '生成控制器',
'icon' => '',
'class' => 'btn btn-info',
'href' => '',
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'controller']) . '\')',
],
],
]
];
break;
// 自定义按钮
default:
// 默认属性
$btn_attribute = [
'title' => '自定义',
'icon' => 'fa fa-lightbulb',
'class' => 'btn btn-default',
'href' => '',
'onclick' => ''
];
break;
}
// 合并自定义属性
if ($attribute && is_array($attribute)) {
$btn_attribute = array_merge($btn_attribute, $attribute);
}
$this->_vars['top_buttons'][] = $btn_attribute;
return $this;
}
/**
* 一次性添加多个顶部按钮
* @param array|string $buttons 按钮组
* 例如:
* addTopButtons('add')
* addTopButtons('add, edit, del')
* addTopButtons(['add', 'del'])
* addTopButtons(['add' => ['title' => '增加'], 'del'])
* @return $this
*/
public function addTopButtons($buttons = [])
{
if (!empty($buttons)) {
$buttons = is_array($buttons) ? $buttons : explode(',', $buttons);
foreach ($buttons as $key => $value) {
if (is_numeric($key)) {
// key为数字则直接添加一个按钮
$this->addTopButton($value);
} else {
// key不为数字则需设置属性,去除前后空格
$this->addTopButton(trim($key), $value);
}
}
}
return $this;
}
/**
* 设置是否在添加/编辑等页启用layer弹层加载
* @param string $value 是否启用layer true|false
* @return $this
*/
public function setLayerOpen($value = true)
{
$this->_vars['layer_open'] = $value;
return $this;
}
/**
* 设置左侧固定列数
* @param string $value 列数
* @return $this
*/
public function setFixedLeft($value = 1)
{
$this->_vars['fixed_left'] = $value;
return $this;
}
/**
* 设置右侧固定列数
* @param string $value 列数
* @return $this
*/
public function setFixedRight($value = 1)
{
$this->_vars['fixed_right'] = $value;
return $this;
}
}