You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2551 lines
101 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace app\common\builder\table;
use app\admin\model\Menu;
use app\common\builder\ZBuilder;
use app\user\model\Role;
use think\facade\Cache;
use think\facade\Env;
/**
* 表格构建器
* @package app\common\builder\table
* @author 蔡伟明 <314013107@qq.com>
*/
class Builder extends ZBuilder
{
/**
* @var string 当前模型名称
*/
private $_module = '';
/**
* @var string 当前控制器名称
*/
private $_controller = '';
/**
* @var string 当前操作名称
*/
private $_action = '';
/**
* @var string 数据表名
*/
private $_table_name = '';
/**
* @var string 插件名称
*/
private $_plugin_name = '';
/**
* @var string 模板路径
*/
private $_template = '';
/**
* @var array 要替换的右侧按钮内容
*/
private $_replace_right_buttons = [];
/**
* @var bool 有分页数据
*/
private $_has_pages = true;
/**
* @var array 存储字段筛选选项
*/
private $_filter_options = [];
/***
* @var array 存储字段筛选列表
*/
private $_filter_list = [];
/**
* @var array 存储字段筛选类型
*/
private $_filter_type = [];
/**
* @var array 列名
*/
private $_field_name = [];
/**
* @var array 存储搜索框数据
*/
private $_search = [];
/**
* @var array 顶部下拉菜单默认选项集合
*/
private $_select_list_default = [];
/**
* @var array 行class
*/
private $_tr_class = [];
/**
* @var int 前缀模式:0-不含表前缀1-含表前缀2-使用模型
*/
private $_prefix = 1;
/**
* @var mixed 表格原始数据
*/
private $data;
/**
* @var array 使用原始数据的字段
*/
protected $rawField = [];
/**
* @var array 模板变量
*/
private $_vars = [
'page_title' => '', // 页面标题
'page_tips' => '', // 页面提示
'tips_type' => '', // 提示类型
'tab_nav' => [], // 页面Tab导航
'hide_checkbox' => false, // 是否隐藏第一列多选
'extra_html' => '', // 额外HTML代码
'extra_js' => '', // 额外JS代码
'extra_css' => '', // 额外CSS代码
'order_columns' => [], // 需要排序的列表头
'filter_columns' => [], // 需要筛选功能的列表头
'filter_map' => [], // 字段筛选的排序条件
'_field_display' => [], // 字段筛选的默认选项
'_filter_content' => [], // 字段筛选的默认选中值
'_filter' => [], // 字段筛选的默认字段名
'top_buttons' => [], // 顶部栏按钮
'right_buttons' => [], // 表格右侧按钮
'search' => [], // 搜索参数
'search_button' => false, // 搜索按钮
'columns' => [], // 表格列集合
'pages' => '', // 分页数据
'row_list' => [], // 表格数据列表
'_page_info' => '', // 分页信息
'primary_key' => 'id', // 表格主键名称
'_table' => '', // 表名
'js_list' => [], // js文件名
'css_list' => [], // css文件名
'validate' => '', // 快速编辑的验证器名
'_js_files' => [], // js文件
'_css_files' => [], // css文件
'_select_list' => [], // 顶部下拉菜单列表
'_filter_time' => [], // 时间段筛选
'empty_tips' => '暂无数据', // 没有数据时的提示信息
'_search_area' => [], // 搜索区域
'_search_area_url' => '', // 搜索区域url
'_search_area_op' => '', // 搜索区域匹配方式
'builder_height' => 'fixed', // 表格高度
'fixed_right_column' => 0, // 固定右边列数量
'fixed_left_column' => 0, // 固定左边列数量
'column_width' => [], // 列宽度
'column_hide' => [], // 隐藏列
];
/**
* 初始化
* @author 蔡伟明 <314013107@qq.com>
*/
public function initialize()
{
$this->_module = $this->request->module();
$this->_controller = parse_name($this->request->controller());
$this->_action = $this->request->action();
$this->_table_name = strtolower($this->_module.'_'.$this->_controller);
$this->_template = Env::get('app_path'). 'common/builder/table/layout.html';
// 默认加载快速编辑所需js和css
$this->_vars['_js_files'][] = 'editable_js';
$this->_vars['_css_files'][] = 'editable_css';
}
/**
* 模板变量赋值
* @param mixed $name 要显示的模板变量
* @param string $value 变量的值
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function assign($name, $value = '')
{
if (is_array($name)) {
$this->_vars = array_merge($this->_vars, $name);
} else {
$this->_vars[$name] = $value;
}
return $this;
}
/**
* 设置页面标题
* @param string $page_title 页面标题
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setPageTitle($page_title = '')
{
if ($page_title != '') {
$this->_vars['page_title'] = $page_title;
}
return $this;
}
/**
* 隐藏第一列多选框
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function hideCheckbox($status = true)
{
$this->_vars['hide_checkbox'] = $status;
return $this;
}
/**
* 设置页面提示
* @param string $tips 提示信息
* @param string $type 提示类型success/info/warning/danger默认info
* @param string $pos 提示位置top,button
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setPageTips($tips = '', $type = 'info', $pos = 'top')
{
if ($tips != '') {
$this->_vars['page_tips_'.$pos] = $tips;
$this->_vars['tips_type'] = $type != '' ? trim($type) : 'info';
}
return $this;
}
/**
* 添加顶部下拉框
* @param string $name 表单名即name值
* @param string $title 第一个下来菜单项标题,不写则不显示
* @param array $options 表单项内容传递数组形式array([2015] => '2015年', [2016] => '2016年')
* @param string $default 默认选项,初始化时,默认选中的菜单项
* @param string $ignore 生成url时需要忽略的参数用于有父子关系的下拉菜单比如省份和地区省份URL不应该带有地区参数的
* 所以可以在定义省份下拉菜单时,传入地区的下拉列表名,
* 如需忽略多个参数,用逗号隔开
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addTopSelect($name = '', $title = '', $options = [], $default = '', $ignore = '')
{
if ($name != '') {
$this->_vars['_select_list'][$name] = [
'name' => $name,
'title' => $title,
'options' => $options,
'ignore' => $ignore,
'current' => '',
];
if ($default != '') {
$this->_select_list_default[$name] = $default;
}
$this->_vars['_js_files'][] = 'select2_js';
$this->_vars['_css_files'][] = 'select2_css';
$this->_vars['_js_init'][] = 'select2';
}
return $this;
}
/**
* 添加表头排序
* @param array|string $column 表头排序字段,多个以逗号隔开
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addOrder($column = [])
{
if (!empty($column)) {
$column = is_array($column) ? $column : explode(',', $column);
$this->_vars['order_columns'] = array_merge($this->_vars['order_columns'], $column);
}
return $this;
}
/**
* 添加表头筛选
* @param array|string $columns 表头筛选字段,多个以逗号隔开
* @param array $options 选项,供有些字段值需要另外显示的,比如字段值是数字,但显示的时候是其他文字。
* @param array $default 默认选项,['字段名' => '字段值,字段值...']
* @param string $type 筛选类型默认为CheckBox也可以是radio
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addFilter($columns = [], $options = [], $default = [], $type = 'checkbox')
{
if (!empty($columns)) {
$columns = is_array($columns) ? $columns : explode(',', $columns);
$this->_vars['filter_columns'] = array_merge($this->_vars['filter_columns'], $columns);
// 存储对应的字段选项
if (!empty($options) && is_array($options)) {
foreach ($columns as $key => $column) {
if (is_numeric($key)) {
if (strpos($column, '.')) {
$column = explode('.', $column)[1];
}
cache('filter_options_'.$column, $options);
$this->_filter_options[$column] = 'filter_options_'.$column;
} else {
cache('filter_options_'.$key, $options);
$this->_filter_options[$key] = 'filter_options_'.$key;
}
}
}
// 处理默认选项和值
if (!empty($default) && is_array($default)) {
foreach ($default as $display => $content) {
if (strpos($display, '|')) {
list($display, $filter) = explode('|', $display);
} else {
$filter = $display;
}
if (strpos($display, '.')) {
$display = explode('.', $display)[1];
}
$this->_vars['_field_display'][] = $display;
$this->_vars['_filter'][] = $filter;
$this->_vars['_filter_content'][] = is_array($content) ? implode(',', $content) : $content;
}
}
// 处理筛选类型
foreach ($columns as $column) {
$this->_filter_type[$column] = $type;
}
}
return $this;
}
/**
* 添加表头筛选列表
* @param string $field 表头筛选字段
* @param array $list 需要显示的列表
* @param string $default 默认值,一维数组或逗号隔开的字符串
* @param string $type 筛选类型默认为CheckBox也可以是radio
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addFilterList($field = '', $list = [], $default = '', $type = 'checkbox')
{
if ($field != '' && !empty($list)) {
$this->_vars['filter_columns'][] = $field;
$this->_filter_type[$field] = $type;
$this->_filter_list[$field] = md5('_filter_list_'.$this->_module.'_'.$this->_controller.'_'.$this->_action.'_'.session('user_auth.uid').'_'.$field);
Cache::set($this->_filter_list[$field], $list);
// 处理默认选项和值
if ($default != '') {
$this->_vars['_field_display'][] = $field;
$this->_vars['_filter'][] = $field;
$this->_vars['_filter_content'][] = is_array($default) ? implode(',', $default) : $default;
}
}
return $this;
}
/**
* 添加表头筛选条件
* @param string $fields 字段名,多个可以用逗号隔开
* @param array $map 查询条件
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function addFilterMap($fields = '', $map = [])
{
if ($fields != '') {
if (is_array($fields)) {
$this->_vars['filter_map'] = array_merge($this->_vars['filter_map'], $fields);
} else {
$map = $this->buildFilterMap($map);
if (strpos($fields, ',')) {
$fields = explode(',', $fields);
foreach ($fields as $field) {
if (isset($this->_vars['filter_map'][$field])) {
$this->_vars['filter_map'][$field] = array_merge($this->_vars['filter_map'][$field], $map);
} else {
$this->_vars['filter_map'][$field] = $map;
}
}
} else {
if (isset($this->_vars['filter_map'][$fields])) {
$this->_vars['filter_map'][$fields] = array_merge($this->_vars['filter_map'][$fields], $map);
} else {
$this->_vars['filter_map'][$fields] = $map;
}
}
}
}
return $this;
}
/**
* 组合筛选条件
* @param string $map 筛选条件
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
private function buildFilterMap($map = '')
{
if (is_array($map)) return $map;
$_map = [];
$_filter = $this->request->param('_filter');
$_filter = explode('|', $_filter);
$_pos = array_search($map, $_filter);
if ($_pos !== false) {
$_filter_content = $this->request->param('_filter_content');
$_filter_content = explode('|', $_filter_content);
if (strpos($map, '.')) {
$_field = explode('.', $map)[1];
} else {
$_field = $map;
}
$_map[] = isset($_filter_content[$_pos]) ? [$_field, 'in', $_filter_content[$_pos]] : [$_field, 'eq', ''];
}
return $_map;
}
/**
* 时间段过滤
* @param string $field 字段名
* @param string|array $date 默认的开始日期和结束日期
* @param string|array $tips 开始日期和结束日期的提示
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addTimeFilter($field = '', $date = '', $tips = '')
{
if ($field != '') {
$date_start = '';
$date_end = '';
$tips_start = '开始日期';
$tips_end = '结束日期';
if (!empty($date)) {
if (!is_array($date)) {
if (strpos($date, ',')) {
list($date_start, $date_end) = explode(',', $date);
} else {
$date_start = $date_end = $date;
}
} else {
list($date_start, $date_end) = $date;
}
}
if (!empty($tips)) {
if (!is_array($tips)) {
if (strpos($tips, ',')) {
list($tips_start, $tips_end) = explode(',', $tips);
} else {
$tips_start = $tips_end = $tips;
}
} else {
list($tips_start, $tips_end) = $tips;
}
}
$this->_vars['_js_files'][] = 'datepicker_js';
$this->_vars['_css_files'][] = 'datepicker_css';
$this->_vars['_js_init'][] = 'datepicker';
$this->_vars['_filter_time'] = [
'field' => $field,
'tips_start' => $tips_start,
'tips_end' => $tips_end,
'date_start' => $date_start,
'date_end' => $date_end,
];
}
return $this;
}
/**
* 添加快捷编辑的验证器
* @param string $validate 验证器名
* @param string $fields 要验证的字段,多个用逗号隔开,并且在验证器中要定义该字段名对应的场景
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addValidate($validate = '', $fields = '')
{
if ($validate != '') {
$this->_vars['validate'] = $validate;
$this->_vars['validate_fields'] = $fields;
}
return $this;
}
/**
* 替换右侧按钮
* @param array $map 条件,格式为:['字段名' => '字段值', '字段名' => '字段值'....]
* @param string $content 要替换的内容
* @param null $target 要替换的目标按钮
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function replaceRightButton($map = [], $content = '', $target = null)
{
if (!empty($map)) {
$maps = [];
$target = is_string($target) ? explode(',', $target) : $target;
if (is_callable($map)) {
$maps[] = [$map, $content, $target];
} else {
foreach ($map as $key => $value) {
if (is_array($value)) {
$op = strtolower($value[0]);
switch ($op) {
case '=': $op = 'eq'; break;
case '<>': $op = 'neq'; break;
case '>': $op = 'gt'; break;
case '<': $op = 'lt'; break;
case '>=': $op = 'egt'; break;
case '<=': $op = 'elt'; break;
case 'in':
case 'not in':
case 'between':
case 'not between':
$value[1] = is_array($value[1]) ? $value[1] : explode(',', $value[1]); break;
}
$maps[] = [$key, $op, $value[1]];
} else {
$maps[] = [$key, 'eq', $value];
}
}
}
$this->_replace_right_buttons[] = [
'maps' => $maps,
'content' => $content,
'target' => $target
];
}
return $this;
}
/**
* 自动创建新增页面
* @param array $items 表单项
* @param string $table 表名
* @param string $validate 验证器名
* @param string $auto_time 自动添加时间默认有两个create_time和update_time
* @param string $format 时间格式
* @param bool $pop 弹窗显示
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function autoAdd($items = [], $table = '', $validate = '', $auto_time = '', $format = '', $pop = false)
{
if (!empty($items)) {
// 默认属性
$btn_attribute = [
'title' => '新增',
'icon' => 'fa fa-plus-circle',
'class' => 'btn btn-primary'.($pop === true ? ' pop' : ''),
'href' => url(
$this->_module.'/'.$this->_controller.'/add'
).($pop === true ? '?_pop=1' : ''),
];
// 判断当前用户是否有权限,没有权限则不生成按钮
if (session('user_auth.role') != 1 && substr($btn_attribute['href'], 0, 4) != 'http' && $btn_attribute['href'] != 'javascript:history.back(-1);') {
if ($this->checkButtonAuth($btn_attribute) === false) {
return $this;
}
}
// 缓存名称
$cache_name = strtolower($this->_module.'/'.$this->_controller.'/add');
// 自动插入时间
if ($auto_time != '') {
$auto_time = $auto_time === true ? ['create_time', 'update_time'] : explode(',', $auto_time);
}
// 表单缓存数据
$form = [
'items' => $items,
'table' => $table == '' ? strtolower($this->_module . '_' . $this->_controller) : $table,
'validate' => $validate === true ? ucfirst($this->_controller) : $validate,
'auto_time' => $auto_time,
'format' => $format,
'go_back' => $this->request->server('REQUEST_URI')
];
// 开发模式
if (config('develop_mode')) {
Cache::set($cache_name, $form);
}
if (!Cache::get($cache_name)) {
Cache::set($cache_name, $form);
}
// 添加到按钮组
$this->_vars['top_buttons'][] = $btn_attribute;
}
return $this;
}
/**
* 获取默认url
* @param string $type 按钮类型add/enable/disable/delete
* @param array $params 参数
* @author 蔡伟明 <314013107@qq.com>
* @return string
*/
private function getDefaultUrl($type = '', $params = [])
{
$url = $this->_module.'/'.$this->_controller.'/'.$type;
$MenuModel = new Menu();
$menu = $MenuModel->where('url_value', $url)->find();
if ($menu['params'] != '') {
$url_params = explode('&', trim($menu['params'], '&'));
if (!empty($url_params)) {
foreach ($url_params as $item) {
list($key, $value) = explode('=', $item);
$params[$key] = $value;
}
}
}
if (!empty($params) && config('url_common_param')) {
$params = array_filter($params, function($v){return $v !== '';});
}
return $menu['url_type'] == 'module_home' ? home_url($url, $params) : url($url, $params);
}
/**
* 添加一个顶部按钮
* @param string $type 按钮类型add/enable/disable/back/delete/custom
* @param array $attribute 按钮属性
* @param bool $pop 是否使用弹出框形式
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addTopButton($type = '', $attribute = [], $pop = false)
{
if ($type == '') {
return $this;
}
// 表单名,用于替换
if (isset($attribute['table'])) {
if (isset($attribute['prefix'])) {
$table_token = $this->createTableToken($attribute['table'], $attribute['prefix']);
} else {
$table_token = $this->createTableToken($attribute['table'], $this->_prefix);
}
} else {
$table_token = '__table__';
}
// 自定义字段
$field = isset($attribute['field']) ? $attribute['field'] : '';
// 这个专门为插件准备的属性,是插件名称
$plugin_name = isset($attribute['plugin_name']) ? $attribute['plugin_name'] : $this->_plugin_name;
switch ($type) {
// 新增按钮
case 'add':
// 默认属性
$btn_attribute = [
'title' => '新增',
'icon' => 'fa fa-plus-circle',
'class' => 'btn btn-primary',
'href' => $this->getDefaultUrl($type, ['plugin_name' => $plugin_name])
];
break;
// 启用按钮
case 'enable':
// 默认属性
$btn_attribute = [
'title' => '启用',
'icon' => 'fa fa-check-circle-o',
'class' => 'btn btn-success ajax-post confirm',
'target-form' => 'ids',
'href' => $this->getDefaultUrl($type, ['_t' => $table_token, 'field' => $field])
];
break;
// 禁用按钮
case 'disable':
// 默认属性
$btn_attribute = [
'title' => '禁用',
'icon' => 'fa fa-ban',
'class' => 'btn btn-warning ajax-post confirm',
'target-form' => 'ids',
'href' => $this->getDefaultUrl($type, ['_t' => $table_token, 'field' => $field])
];
break;
// 返回按钮
case 'back':
// 默认属性
$btn_attribute = [
'title' => '返回',
'icon' => 'fa fa-reply',
'class' => 'btn btn-info',
'href' => 'javascript:history.back(-1);'
];
break;
// 删除按钮(不可恢复)
case 'delete':
// 默认属性
$btn_attribute = [
'title' => '删除',
'icon' => 'fa fa-times-circle-o',
'class' => 'btn btn-danger ajax-post confirm',
'target-form' => 'ids',
'href' => $this->getDefaultUrl($type, ['_t' => $table_token])
];
break;
// 自定义按钮
default:
// 默认属性
$btn_attribute = [
'title' => '定义按钮',
'class' => 'btn btn-default',
'target-form' => 'ids',
'href' => 'javascript:void(0);'
];
break;
}
// 合并自定义属性
if ($attribute && is_array($attribute)) {
$btn_attribute = array_merge($btn_attribute, $attribute);
}
// 判断当前用户是否有权限,没有权限则不生成按钮
if (session('user_auth.role') != 1 && substr($btn_attribute['href'], 0, 4) != 'http' && $btn_attribute['href'] != 'javascript:history.back(-1);') {
if ($this->checkButtonAuth($btn_attribute) === false) {
return $this;
}
}
// 是否为弹出框方式
if ($pop !== false) {
$btn_attribute['class'] .= ' pop';
$btn_attribute['href'] .= (strpos($btn_attribute['href'], '?') ? '&' : '?').'_pop=1';
if (is_array($pop) && !empty($pop)) {
$btn_attribute['data-layer'] = json_encode($pop);
}
}
$this->_vars['top_buttons'][] = $btn_attribute;
return $this;
}
/**
* 检查是否有按钮权限
* @param array $btn_attribute 按钮属性
* @author 蔡伟明 <314013107@qq.com>
* @return bool
*/
private function checkButtonAuth($btn_attribute = [])
{
if (preg_match('/\/(index.php|'.ADMIN_FILE.')\/(.*)/', $btn_attribute['href'], $match)) {
$url_value = explode('/', $match[2]);
if (strpos($url_value[2], '.')) {
$url_value[2] = substr($url_value[2], 0, strpos($url_value[2], '.'));
}
$url_value = $url_value[0].'/'.$url_value[1].'/'.$url_value[2];
$url_value = strtolower($url_value);
return Role::checkAuth($url_value, true);
}
return true;
}
/**
* 一次性添加多个顶部按钮
* @param array|string $buttons 按钮类型
* 例如:
* $builder->addTopButtons('add');
* $builder->addTopButtons('add,delete');
* $builder->addTopButtons(['add', 'delete']);
* $builder->addTopButtons(['add' => ['table' => '__USER__'], 'delete']);
*
* @author 蔡伟明 <314013107@qq.com>
* @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)) {
$this->addTopButton($value);
} else {
$this->addTopButton($key, $value);
}
}
}
return $this;
}
/**
* 自动创建编辑页面
* @param array $items 表单项
* @param string $table 表名
* @param string $validate 验证器名
* @param string $auto_time 自动添加时间默认有两个create_time和update_time
* @param string $format 时间格式
* @param bool $pop 弹窗显示
* @param array $extra 额外参数,设置按钮样式
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function autoEdit($items = [], $table = '', $validate = '', $auto_time = '', $format = '', $pop = false, $extra = [])
{
if (!empty($items)) {
// 按钮样式
$btn_style = array_merge(config('zbuilder.right_button'), $extra);
// 默认属性
$btn_attribute = [
'title' => '编辑',
'icon' => 'fa fa-pencil',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'].($pop === true ? ' pop' : ''),
'href' => url(
$this->_module.'/'.$this->_controller.'/edit',
['id' => '__id__']
),
'target' => '_self',
'_style' => $btn_style
];
// 是否弹窗显示
if ($pop === true) {
$btn_attribute['href'] .= (strpos($btn_attribute['href'], '?') ? '&' : '?').'_pop=1';
}
// 判断当前用户是否有权限,没有权限则不生成按钮
if (session('user_auth.role') != 1 && substr($btn_attribute['href'], 0, 4) != 'http') {
if ($this->checkButtonAuth($btn_attribute) === false) {
return $this;
}
}
// 缓存名称
$cache_name = strtolower($this->_module.'/'.$this->_controller.'/edit');
// 自动插入时间
if ($auto_time != '') {
$auto_time = $auto_time === true ? ['update_time'] : explode(',', $auto_time);
}
// 表单缓存数据
$form = [
'items' => $items,
'table' => $table == '' ? strtolower($this->_module . '_' . $this->_controller) : $table,
'validate' => $validate === true ? ucfirst($this->_controller) : $validate,
'auto_time' => $auto_time,
'format' => $format,
'go_back' => $this->request->server('REQUEST_URI')
];
// 开发模式
if (config('develop_mode')) {
Cache::set($cache_name, $form);
}
if (!Cache::get($cache_name)) {
Cache::set($cache_name, $form);
}
// 添加到按钮组
$this->_vars['right_buttons'][] = $btn_attribute;
}
return $this;
}
/**
* 创建表名Token
* @param string $table 表名
* @param int $prefix 前缀类型0使用Db类(不添加表前缀)1使用Db类(添加表前缀)2使用模型
* @author 蔡伟明 <314013107@qq.com>
* @return bool|string
*/
private function createTableToken($table = '', $prefix = 1)
{
$data = [
'table' => $table, // 表名或模型名
'prefix' => $prefix,
'module' => $this->_module,
'controller' => $this->_controller,
'action' => $this->_action,
];
$table_token = substr(sha1($this->_module.'-'.$this->_controller.'-'.$this->_action.'-'.$table), 0, 8);
session($table_token, $data);
return $table_token;
}
/**
* 添加一个右侧按钮
* @param string $type 按钮类型edit/enable/disable/delete/custom
* @param array $attribute 按钮属性
* @param bool $pop 是否使用弹出框形式
* @param array $extra 扩展参数,设置按钮样式
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addRightButton($type = '', $attribute = [], $pop = false, $extra = [])
{
if ($type == '') {
return $this;
}
// 表单名,用于替换
if (isset($attribute['table'])) {
if (isset($attribute['prefix'])) {
$table_token = $this->createTableToken($attribute['table'], $attribute['prefix']);
} else {
$table_token = $this->createTableToken($attribute['table'], $this->_prefix);
}
} else {
$table_token = '__table__';
}
// 这个专门为插件准备的属性,是插件名称
$plugin_name = isset($attribute['plugin_name']) ? $attribute['plugin_name'] : $this->_plugin_name;
// 自定义字段名
$field = isset($attribute['field']) ? $attribute['field'] : '';
// 按钮样式
$btn_style = array_merge(config('zbuilder.right_button'), $extra);
switch ($type) {
// 编辑按钮
case 'edit':
// 默认属性
$btn_attribute = [
'title' => '编辑',
'icon' => 'fa fa-pencil',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'],
'href' => $this->getDefaultUrl($type, ['id' => '__id__', 'plugin_name' => $plugin_name]),
'target' => '_self'
];
break;
// 启用按钮
case 'enable':
// 默认属性
$btn_attribute = [
'title' => '启用',
'icon' => 'fa fa-check',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'].' ajax-get confirm',
'href' => $this->getDefaultUrl($type, ['ids' => '__id__', '_t' => $table_token, 'field' => $field])
];
break;
// 禁用按钮
case 'disable':
// 默认属性
$btn_attribute = [
'title' => '禁用',
'icon' => 'fa fa-ban',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'].' ajax-get confirm',
'href' => $this->getDefaultUrl($type, ['ids' => '__id__', '_t' => $table_token, 'field' => $field])
];
break;
// 删除按钮(不可恢复)
case 'delete':
// 默认属性
$btn_attribute = [
'title' => '删除',
'icon' => 'fa fa-times',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'].' ajax-get confirm',
'href' => $this->getDefaultUrl($type, ['ids' => '__id__', '_t' => $table_token])
];
break;
// 自定义按钮
default:
// 默认属性
$btn_attribute = [
'title' => '自定义按钮',
'icon' => 'fa fa-smile-o',
'class' => 'btn btn-'.$btn_style['size'].' btn-'.$btn_style['style'],
'href' => 'javascript:void(0);'
];
break;
}
// 合并自定义属性
if ($attribute && is_array($attribute)) {
$btn_attribute = array_merge($btn_attribute, $attribute);
}
// 判断当前用户是否有权限,没有权限则不生成按钮
if (session('user_auth.role') != 1 && substr($btn_attribute['href'], 0, 4) != 'http') {
if ($this->checkButtonAuth($btn_attribute) === false) {
return $this;
}
}
// 是否为弹出框方式
if ($pop !== false) {
$btn_attribute['class'] .= ' pop';
$btn_attribute['href'] .= (strpos($btn_attribute['href'], '?') ? '&' : '?').'_pop=1';
if (is_array($pop) && !empty($pop)) {
$btn_attribute['data-layer'] = json_encode($pop);
}
}
// 添加按钮样式
$btn_attribute['_style'] = $btn_style;
// 添加按钮标签
$btn_attribute['_tag'] = $type;
$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' => ['table' => 'admin_user'], 'delete']);
*
* @author 蔡伟明 <314013107@qq.com>
* @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($key, $value);
}
}
}
return $this;
}
/**
* 设置表格高度
* @param string $height 高度fixed/auto/具体数值
* @author 蔡伟明 <314013107@qq.com>
* @return $this
* @since 1.3.0
*/
public function setHeight($height = 'fixed')
{
$this->_vars['builder_height'] = $height;
return $this;
}
/**
* 固定左侧列数
* @param int $num 数量
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function fixedRight($num = 0)
{
$this->_vars['fixed_right_column'] = $num;
return $this;
}
/**
* 固定右侧列数
* @param int $num 数量
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function fixedLeft($num = 0)
{
$this->_vars['fixed_left_column'] = $num;
return $this;
}
/**
* 设置搜索参数
* @param array $fields 参与搜索的字段
* @param string $placeholder 提示符
* @param string $url 提交地址
* @param null $search_button 提交按钮
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setSearch($fields = [], $placeholder = '', $url = '', $search_button = null)
{
if (!empty($fields)) {
$this->_search = [
'fields' => is_string($fields) ? explode(',', $fields) : $fields,
'placeholder' => $placeholder,
'url' => $url,
];
$this->_vars['search_button'] = $search_button !== null ? $search_button : config('zbuilder.search_button');
}
return $this;
}
/**
* 设置搜索区域
* @param array $items
* @param string $url
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setSearchArea($items = [], $url = '')
{
if (!empty($items)) {
$_op = [];
$_defaults = [];
$_s = $this->request->param('_s', '');
if ($_s != '') {
$_s = explode('|', $_s);
foreach ($_s as $v) {
list($field, $value) = explode('=', $v);
$_defaults[$field] = $value;
}
}
foreach ($items as &$item) {
$layout = 3;
if (strpos($item[0], ':')) {
list($item[0], $layout) = explode(':', $item[0]);
}
$type = $item[0];
$name = $item[1];
$label = $item[2];
$op = isset($item[3]) ? $item[3] : 'eq';
$item[4] = isset($_defaults[$name]) ? $_defaults[$name] : (isset($item[4]) ? $item[4] : ''); // 默认值
$item[5] = isset($item[5]) ? $item[5] : [];
switch ($op) {
case '=': $op = 'eq'; break;
case '<>': $op = 'neq'; break;
case '>': $op = 'gt'; break;
case '<': $op = 'lt'; break;
case '>=': $op = 'egt'; break;
case '<=': $op = 'elt'; break;
default:
$op = $op == '' ? 'eq' : $op;
}
switch ($type) {
case 'text':
break;
case 'select':
$this->_vars['_js_files'][] = 'select2_js';
$this->_vars['_css_files'][] = 'select2_css';
$this->_vars['_js_init'][] = 'select2';
break;
case 'daterange':
$this->_vars['_js_files'][] = 'moment_js';
$this->_vars['_js_files'][] = 'daterangepicker_js';
$this->_vars['_css_files'][] = 'daterangepicker_css';
$this->_vars['_js_init'][] = 'daterangepicker';
$op = $op == 'eq' ? 'between time' : $op . ' time';
$params = [];
if (!empty($item[5])) {
foreach ($item[5] as $key => $param) {
$params[] = 'data-'.strtolower($key).'="'.$param.'"';
}
}
$item[5] = implode(' ', $params);
break;
default:
}
$_op[] = $name.'='.strtolower($op);
$this->_vars['_search_area_layout'][$name] = $layout;
}
$this->_vars['_search_area_op'] = implode('|', $_op);
$this->_vars['_search_area'] = $items;
$this->_vars['_search_area_url'] = $url == '' ? $this->request->baseUrl(true) : $url;
}
return $this;
}
/**
* 引入模块js文件
* @param string $files_name js文件名多个文件用逗号隔开
* @param string $module 指定模块
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function js($files_name = '', $module = '')
{
if ($files_name != '') {
$this->loadFile('js', $files_name, $module);
}
return $this;
}
/**
* 引入模块css文件
* @param string $files_name css文件名多个文件用逗号隔开
* @param string $module 指定模块
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function css($files_name = '', $module = '')
{
if ($files_name != '') {
$this->loadFile('css', $files_name, $module);
}
return $this;
}
/**
* 引入css或js文件
* @param string $type 类型css/js
* @param string $files_name 文件名,多个用逗号隔开
* @param string $module 指定模块
* @author caiweiming <314013107@qq.com>
*/
private function loadFile($type = '', $files_name = '', $module = '')
{
if ($files_name != '') {
$module = $module == '' ? $this->_module : $module;
if (!is_array($files_name)) {
$files_name = explode(',', $files_name);
}
foreach ($files_name as $item) {
if (strpos($item, '/')) {
$this->_vars[$type.'_list'][] = PUBLIC_PATH. 'static/'. $item.'.'.$type;
} else {
$this->_vars[$type.'_list'][] = PUBLIC_PATH. 'static/'. $module .'/'.$type.'/'.$item.'.'.$type;
}
}
}
}
/**
* 设置数据库表名
* @param string $table 数据库表名不含前缀如果为true则使用模型方式
* @param int $prefix 前缀类型0使用Db类(不添加表前缀)1使用Db类(添加表前缀)2使用模型
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setTableName($table = '', $prefix = 1)
{
if ($table === true) {
$this->_prefix = 2;
$this->_table_name = strtolower($this->_module.'/'.$this->_controller);
} else {
$this->_prefix = $prefix === true ? 2 : $prefix;
if ($this->_prefix == 2) {
$this->_table_name = strpos($table, '/') ? $table : strtolower($this->_module.'/'.$table);
} else {
$this->_table_name = $table;
}
}
return $this;
}
/**
* 设置插件名称(此方法只供制作插件时用)
* @param string $plugin_name 插件名
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setPluginName($plugin_name = '')
{
if ($plugin_name != '') {
$this->_plugin_name = $plugin_name;
}
return $this;
}
/**
* 添加一列
* @param string $name 字段名称
* @param string $title 列标题
* @param string $type 单元格类型
* @param string $default 默认值
* @param string $param 额外参数
* @param string $class css类名
* @param string $extra 扩展参数
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addColumn($name = '', $title = '', $type = '', $default = '', $param = '', $class = '', $extra = '')
{
$field = $name;
$table = '';
// 判断是否有字段别名
if (strpos($name, '|')) {
list($name, $field) = explode('|', $name);
// 判断是否有表名
if (strpos($field, '.')) {
list($table, $field) = explode('.', $field);
}
}
$column = [
'name' => $name,
'title' => $title,
'type' => $type,
'default' => $default,
'param' => $param,
'class' => $class,
'extra' => $extra,
'field' => $field,
'table' => $table,
];
$args = array_slice(func_get_args(), 7);
$column = array_merge($column, $args);
$this->_vars['columns'][] = $column;
$this->_field_name[$name] = $title;
return $this;
}
/**
* 一次性添加多列
* @param array $columns 数据列
* @author caiweiming <314013107@qq.com>
* @return $this
*/
public function addColumns($columns = [])
{
if (!empty($columns)) {
foreach ($columns as $column) {
call_user_func_array([$this, 'addColumn'], $column);
}
}
return $this;
}
/**
* 设置列宽
* @param string $column 列名,即字段名
* @param int $width 宽度默认为100
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setColumnWidth($column = '', $width = 100)
{
if ($column != '') {
if (is_array($column)) {
foreach ($column as $field => $width) {
$this->_vars['column_width'][$field] = $width;
}
} else {
if (strpos($column, ',')) {
$columns = explode(',', $column);
foreach ($columns as $column) {
$this->_vars['column_width'][$column] = $width;
}
} else {
$this->_vars['column_width'][$column] = $width;
}
}
}
return $this;
}
/**
* 隐藏列
* @param string $column 列名,即字段名
* @param string $screen 屏幕xs/sm/md/lg
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function hideColumn($column = '', $screen = '')
{
if ($column != '') {
if (is_array($column)) {
foreach ($column as $field => $screen) {
$screens = is_array($screen) ? $screen : explode(',', $screen);
foreach ($screens as $key => $value) {
$screens[$key] = 'hidden-'.$value;
}
$screens = implode(' ', $screens);
$this->_vars['column_hide'][$field] = $screens;
}
} else {
$screens = is_array($screen) ? $screen : explode(',', $screen);
foreach ($screens as &$screen) {
$screen = 'hidden-'.$screen;
}
$screens = implode(' ', $screens);
if (strpos($column, ',')) {
$columns = explode(',', $column);
foreach ($columns as $column) {
$this->_vars['column_hide'][$column] = isset($this->_vars['column_hide'][$column]) ?
$this->_vars['column_hide'][$column]. ' ' . $screen :
$screens;
}
} else {
$this->_vars['column_hide'][$column] = isset($this->_vars['column_hide'][$column]) ?
$this->_vars['column_hide'][$column]. ' ' . $screen :
$screens;
}
}
}
return $this;
}
/**
* 设置表格数据列表
* @param array|object $row_list 表格数据
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setRowList($row_list = null)
{
if ($row_list !== null) {
// 原始表格数据
$this->data = $row_list;
// 转为数组后的表格数据
$this->_vars['row_list'] = $this->toArray($row_list);
if ($row_list instanceof \think\paginator) {
$this->_vars['_page_info'] = $row_list;
// 设置分页
$this->setPages($row_list->render());
}
}
if (empty($this->_vars['row_list'])) {
$params = $this->request->param();
if (isset($params['page'])) {
unset($params['page']);
$url = url($this->_module.'/'.$this->_controller.'/'.$this->_action).'?'.http_build_query($params);
$this->redirect($url);
}
}
return $this;
}
/**
* 将表格数据转换为纯数组
* @param array|object $row_list 数据
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
private function toArray($row_list)
{
if ($row_list instanceof \think\paginator) {
return $row_list->toArray()['data'];
} elseif ($row_list instanceof \think\model\Collection) {
return $row_list->toArray();
} else {
return $row_list;
}
}
/**
* 获取原始数据
* @param string $index 索引
* @param string $field 字段名
* @author 蔡伟明 <314013107@qq.com>
* @return mixed
*/
private function getData($index = '', $field = '')
{
if (is_object($this->data) && is_object(current($this->data->getIterator()))) {
try {
$result = $this->data[$index]->getData($field);
} catch (\Exception $e) {
$result = isset($this->data[$index][$field]) ? $this->data[$index][$field] : '';
}
return $result;
} else {
return isset($this->data[$index][$field]) ? $this->data[$index][$field] : '';
}
}
/**
* 设置需要使用原始数据的字段
* @param string|array $field 字段名
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function raw($field = '')
{
if (is_array($field)) {
$this->rawField = array_merge($this->rawField, $field);
} else {
$this->rawField = array_merge($this->rawField, explode(',', $field));
}
return $this;
}
/**
* 设置表格主键
* @param string $key 主键名称
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setPrimaryKey($key = '')
{
if ($key != '') {
$this->_vars['primary_key'] = $key;
}
return $this;
}
/**
* 设置Tab按钮列表
* @param array $tab_list Tab列表 ['title' => '标题', 'href' => 'http://www.dolphinphp.com']
* @param string $curr_tab 当前tab
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setTabNav($tab_list = [], $curr_tab = '')
{
if (!empty($tab_list)) {
$this->_vars['tab_nav'] = [
'tab_list' => $tab_list,
'curr_tab' => $curr_tab,
];
}
return $this;
}
/**
* 设置分页
* @param string $pages 分页数据
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setPages($pages = '')
{
if ($pages != '') {
$this->_vars['pages'] = $pages;
}
return $this;
}
/**
* 设置为无分页
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function noPages()
{
$this->_has_pages = false;
return $this;
}
/**
* 设置额外代码
* @param string $extra_html 额外代码
* @param string $tag 标记
* @author 蔡伟明 <314013107@qq.com>
* @alter 小乌 <82950492@qq.com>
* @return $this
*/
public function setExtraHtml($extra_html = '', $tag = '')
{
if ($extra_html != '') {
$tag != '' && $tag = '_'.$tag;
$this->_vars['extra_html'.$tag] = $extra_html;
}
return $this;
}
/**
* 通过文件设置额外代码
* @param string $template 模板文件名
* @param string $tag 标记
* @param array $vars 模板输出变量
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setExtraHtmlFile($template = '', $tag = '', $vars = [])
{
$template = $template == '' ? $this->_action : $template;
$file = Env::get('app_path'). $this->_module.'/view/admin/'.$this->_controller.'/'.$template.'.html';
if (file_exists($file)) {
$content = file_get_contents($file);
$content = $this->view->display($content, $vars);
} else {
$content = '模板文件不存在:'.$file;
}
$tag != '' && $tag = '_'.$tag;
$this->_vars['extra_html'.$tag] = $content;
return $this;
}
/**
* 设置额外JS代码
* @param string $extra_js 额外JS代码
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setExtraJs($extra_js = '')
{
if ($extra_js != '') {
$this->_vars['extra_js'] = $extra_js;
}
return $this;
}
/**
* 设置额外CSS代码
* @param string $extra_css 额外CSS代码
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setExtraCss($extra_css = '')
{
if ($extra_css != '') {
$this->_vars['extra_css'] = $extra_css;
}
return $this;
}
/**
* 设置页面模版
* @param string $template 模版
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function setTemplate($template = '')
{
if ($template != '') {
$this->_template = $template;
}
return $this;
}
/**
* 列class
* @param string $class class名
* @param mixed $field 字段名
* @param null $op 表达式
* @param null $condition 查询条件
* @author 蔡伟明 <314013107@qq.com>
* @return $this
*/
public function addTrClass($class = '', $field, $op = null, $condition = null)
{
if ($class != '') {
if (is_callable($field)) {
$args = array_slice(func_get_args(), 2);
$this->_tr_class[$class][] = [$field, $args];
} elseif (!is_null($op)) {
$op = strtolower($op);
if (is_null($condition)) {
$this->_tr_class[$class][] = [$field, 'eq', $op];
} else {
switch ($op) {
case '=': $op = 'eq'; break;
case '<>': $op = 'neq'; break;
case '>': $op = 'gt'; break;
case '<': $op = 'lt'; break;
case '>=': $op = 'egt'; break;
case '<=': $op = 'elt'; break;
case 'in':
case 'not in':
case 'between':
case 'not between':
$condition = is_array($condition) ? $condition : explode(',', $condition); break;
}
$this->_tr_class[$class][] = [$field, $op, $condition];
}
}
}
return $this;
}
/**
* 编译HTML属性
* @param array $attr 要编译的数据
* @author 蔡伟明 <314013107@qq.com>
* @return array|string
*/
private function compileHtmlAttr($attr = []) {
$result = [];
if ($attr) {
foreach ($attr as $key => &$value) {
if ($key == 'title') {
$value = trim(htmlspecialchars(strip_tags(trim($value))));
} else {
$value = htmlspecialchars($value);
}
array_push($result, "$key=\"$value\"");
}
}
return implode(' ', $result);
}
/**
* 编译表格数据row_list的值
* @author 蔡伟明 <314013107@qq.com>
*/
private function compileRows()
{
foreach ($this->_vars['row_list'] as $key => &$row) {
// 处理行class
if ($this->_tr_class) {
$_tr_class = $this->parseTrClass($row);
if (!empty($_tr_class)) {
$row['_tr_class'] = implode(' ', $_tr_class);
}
}
// 编译右侧按钮
if ($this->_vars['right_buttons']) {
// 默认给列添加个空的右侧按钮
if (!isset($row['right_button'])) {
$row['right_button'] = '';
}
foreach ($this->_vars['right_buttons'] as $index => $button) {
// 处理按钮替换
if (!empty($this->_replace_right_buttons)) {
foreach ($this->_replace_right_buttons as $replace_right_button) {
// 是否能匹配到条件
$_button_match = true;
foreach ($replace_right_button['maps'] as $condition) {
if (is_string($condition[0])) {
if (!isset($row[$condition[0]])) {
$_button_match = false; continue;
}
$_button_match = $this->parseCondition($row, $condition) ? $_button_match : false;
} elseif (is_callable($condition[0])) {
$_button_match = call_user_func($condition[0], $row) ? $_button_match : false;
}
}
// 替换按钮内容支持数据变量
if ($replace_right_button['content'] != '') {
if (preg_match_all('/__(.*?)__/', $replace_right_button['content'], $matches)) {
$replace_to = [];
$pattern = [];
foreach ($matches[1] as $match) {
$pattern[] = '/__'. $match .'__/i';
$replace_to[] = $row[$match];
}
$replace_right_button['content'] = preg_replace($pattern, $replace_to, $replace_right_button['content']);
}
}
if ($_button_match) {
if ($replace_right_button['target'] === null) {
$row['right_button'] = $replace_right_button['content'];
break(2);
} else {
if (in_array($button['_tag'], $replace_right_button['target'])) {
$row['right_button'] .= $replace_right_button['content'];
continue(2);
}
}
}
}
}
// 处理主键变量值
$button['href'] = preg_replace(
'/__id__/i',
$row[$this->_vars['primary_key']],
$button['href']
);
// 处理表名变量值
if (strpos($button['href'], '__table__') !== false) {
$button['href'] = preg_replace(
'/__table__/i',
$this->createTableToken($this->_table_name, $this->_prefix),
$button['href']
);
}
// 替换其他字段值
if (preg_match_all('/__(.*?)__/', $button['href'], $matches)) {
// 要替换的字段名
$replace_to = [];
$pattern = [];
foreach ($matches[1] as $match) {
$replace = in_array($match, $this->rawField) ? $this->getData($key, $match) : (isset($row[$match]) ? $row[$match] : '');
if (isset($row[$match])) {
$pattern[] = '/__'. $match .'__/i';
$replace_to[] = $replace;
}
}
$button['href'] = preg_replace(
$pattern,
$replace_to,
$button['href']
);
}
$button_style = $button['_style'];
unset($button['_style']);
// 编译按钮属性
$button['attribute'] = $this->compileHtmlAttr($button);
if ($button_style['title']) {
$row['right_button'] .= '<a '.$button['attribute'].'">';
if ($button_style['icon']) {
$row['right_button'] .= '<i class="'.$button['icon'].'"></i> ';
}
$row['right_button'] .= $button['title'].'</a>';
} else {
$row['right_button'] .= '<a '.$button['attribute'].' data-toggle="tooltip"><i class="'.$button['icon'].'"></i></a>';
}
}
$row['right_button'] = '<div class="btn-group">'. $row['right_button'] .'</div>';
}
// 编译单元格数据类型
if ($this->_vars['columns']) {
// 另外拷贝一份主键值,以免将主键设置为快速编辑的时候解析出错
$row['_primary_key_value'] = isset($row[$this->_vars['primary_key']]) ? $row[$this->_vars['primary_key']] : '';
foreach ($this->_vars['columns'] as $column) {
$_name = $column['field'];
$_table_name = $column['table'];
// 如果需要显示编号
if ($column['name'] == '__INDEX__') {
$row[$column['name']] = $key + 1;
}
if (in_array($column['name'], $this->rawField)) {
$row[$column['name']] = $this->getData($key, $column['name']);
}
// 备份原数据
if (isset($row[$column['name']])) {
$row['__'.$column['name'].'__'] = $row[$column['name']];
}
switch ($column['type']) {
case 'link': // 链接
if ($column['default'] != '') {
// 要替换的字段名
$replace_to = [];
$pattern = [];
$url = $column['default'];
$target = $column['param'] == '' ? '_self' : $column['param'];
if (preg_match_all('/__(.*?)__/', $column['default'], $matches)) {
foreach ($matches[1] as $match) {
$pattern[] = '/__'. $match .'__/i';
$replace_to[] = $row[$match];
}
$url = preg_replace($pattern, $replace_to, $url);
}
$url = $column['class'] == 'pop' ? $url.(strpos($url, '?') ? '&' : '?').'_pop=1' : $url;
if ($column['extra'] != '') {
$title = $column['extra'] === true ? $column['title'] : $column['extra'];
} else {
$title = $row[$column['name']];
}
$row[$column['name'].'__'.$column['type']] = '<a href="'. $url .'"
title="'. $title .'"
class="'. $column['class'] .'"
target="'.$target.'">'.$row[$column['name']].'</a>';
}
break;
case 'switch': // 开关
switch ($row[$column['name']]) {
case '0': // 关闭
$row[$column['name'].'__'.$column['type']] = '<label class="css-input switch switch-sm switch-primary" title="开启/关闭"><input type="checkbox" data-table="'.$this->createTableToken($this->_table_name, $this->_prefix).'" data-id="'.$row['_primary_key_value'].'" data-field="'.$column['name'].'"><span></span></label>';
break;
case '1': // 开启
$row[$column['name'].'__'.$column['type']] = '<label class="css-input switch switch-sm switch-primary" title="开启/关闭"><input type="checkbox" data-table="'.$this->createTableToken($this->_table_name, $this->_prefix).'" data-id="'.$row['_primary_key_value'].'" data-field="'.$column['name'].'" checked=""><span></span></label>';
break;
}
break;
case 'status': // 状态
$status = $row[$column['name']];
$list_status = !empty($column['param']) ? $column['param'] : ['禁用:warning', '启用:success'];
if (isset($list_status[$status])) {
switch ($status) {
case '0': $class = 'warning';break;
case '1': $class = 'success';break;
case '2': $class = 'primary';break;
case '3': $class = 'info';break;
default: $class = 'default';
}
if (strpos($list_status[$status], ':')) {
list($label, $class) = explode(':', $list_status[$status]);
} else {
$label = $list_status[$status];
}
$row[$column['name'].'__'.$column['type']] = '<span class="label label-'.$class.'">'.$label.'</span>';
}
break;
case 'yesno': // 是/否
switch ($row[$column['name']]) {
case '0': // 否
$row[$column['name'].'__'.$column['type']] = '<i class="fa fa-ban text-danger"></i>';
break;
case '1': // 是
$row[$column['name'].'__'.$column['type']] = '<i class="fa fa-check text-success"></i>';
break;
}
break;
case 'text.edit': // 可编辑的单行文本
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="text-edit"
data-placeholder="请输入'.$column['title'].'"
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="text"
data-pk="'.$row['_primary_key_value'].'"
data-name="'.$_name.'">'.$row[$column['name']].'</a>';
break;
case 'textarea.edit': // 可编辑的多行文本
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="textarea-edit"
data-placeholder="请输入'.$column['title'].'"
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="textarea"
data-pk="'.$row['_primary_key_value'].'"
data-name="'.$_name.'">'.$row[$column['name']].'</a>';
break;
case 'password': // 密码框
$column['param'] = $column['param'] != '' ? $column['param'] : $column['name'];
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="text-edit"
data-placeholder="请输入'.$column['title'].'"
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="password"
data-value=""
data-pk="'.$row['_primary_key_value'].'"
data-name="'.$_name.'">******</a>';
break;
case 'email': // 邮箱地址
case 'url': // 链接地址
case 'tel': // 电话
case 'number': // 数字
case 'range': // 范围
$column['param'] = $column['param'] != '' ? $column['param'] : $column['name'];
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="text-edit"
data-placeholder="请输入'.$column['title'].'"
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="'.$column['type'].'"
data-value="'.$row[$column['name']].'"
data-pk="'.$row['_primary_key_value'].'"
data-name="'.$_name.'">'.$row[$column['name']].'</a>';
break;
case 'icon': // 图标
if ($row[$column['name']] === '') {
$row[$column['name'].'__'.$column['type']] = '<i class="'.$column['default'].'"></i>';
} else {
$row[$column['name'].'__'.$column['type']] = '<i class="'.$row[$column['name']].'"></i>';
}
break;
case 'byte': // 字节
if ($row[$column['name']] === '') {
$row[$column['name'].'__'.$column['type']] = $column['default'];
} else {
$row[$column['name'].'__'.$column['type']] = format_bytes($row[$column['name']], $column['param']);
}
break;
case 'date': // 日期
case 'datetime': // 日期时间
case 'time': // 时间
// 默认格式
$format = 'Y-m-d H:i';
switch ($column['type']) {
case 'date': $format = 'Y-m-d';break;
case 'datetime': $format = 'Y-m-d H:i';break;
case 'time': $format = 'H:i';break;
}
// 格式
$format = $column['param'] == '' ? $format : $column['param'];
if ($row[$column['name']] == '') {
$row[$column['name'].'__'.$column['type']] = $column['default'];
} else {
$row[$column['name'].'__'.$column['type']] = format_time($row[$column['name']], $format);
}
break;
case 'date.edit': // 可编辑日期时间,默认发送的是格式化好的
case 'datetime.edit': // 可编辑日期时间,默认发送的是格式化好的
case 'time.edit': // 可编辑时间,默认发送的是格式化好的
// 默认格式
$format = 'YYYY-MM-DD HH:mm';
switch ($column['type']) {
case 'date.edit': $format = 'YYYY-MM-DD';break;
case 'datetime.edit': $format = 'YYYY-MM-DD HH:mm';break;
case 'time.edit': $format = 'HH:mm';break;
}
// 格式
$format = $column['param'] == '' ? $format : $column['param'];
// 时间戳
$timestamp = $row[$column['name']];
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="combodate-edit"
data-format="'.$format.'"
data-name="'.$_name.'"
data-template="'.$format.'"
data-callback=""
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="combodate"
data-pk="'.$row['_primary_key_value'].'">';
if ($row[$column['name']] == '') {
$row[$column['name'].'__'.$column['type']] .= $column['default'].'</a>';
} else {
$row[$column['name'].'__'.$column['type']] .= format_moment($timestamp, $format).'</a>';
}
// 加载moment.js
$this->_vars['_js_files'][] = 'moment_js';
break;
case 'avatar': // 头像
break;
case 'img_url': // 外链图片
if ($row[$column['name']] != '') {
$row[$column['name'].'__'.$column['type']] = '<div class="js-gallery"><img class="image" data-original="'.$row[$column['name']].'" src="'.$row[$column['name']].'"></div>';
}
break;
case 'picture': // 单张图片
$row[$column['name'].'__'.$column['type']] = '<div class="js-gallery"><img class="image" data-original="'.get_file_path($row[$column['name']]).'" src="'.get_thumb($row[$column['name']]).'"></div>';
break;
case 'pictures': // 多张图片
if ($row[$column['name']] === '') {
$row[$column['name'].'__'.$column['type']] = !empty($column['default']) ? $column['default'] : '暂无图片';
} else {
$list_img = is_array($row[$column['name']]) ? $row[$column['name']] : explode(',', $row[$column['name']]);
$imgs = '<div class="js-gallery">';
foreach ($list_img as $k => $img) {
if ($column['param'] != '' && $k == $column['param']) {
break;
}
$imgs .= ' <img class="image" data-original="'.get_file_path($img).'" src="'.get_thumb($img).'">';
}
$row[$column['name'].'__'.$column['type']] = $imgs.'</div>';
}
break;
case 'files':
if ($row[$column['name']] === '') {
$row[$column['name'].'__'.$column['type']] = !empty($column['default']) ? $column['default'] : '暂无文件';
} else {
$list_file = is_array($row[$column['name']]) ? $row[$column['name']] : explode(',', $row[$column['name']]);
$files = '<div>';
foreach ($list_file as $k => $file) {
if ($column['param'] != '' && $k == $column['param']) {
break;
}
$files .= ' [<a href="'.get_file_path($file).'">'.get_file_name($file).'</a>]';
}
$row[$column['name'].'__'.$column['type']] = $files.'</div>';
}
break;
case 'select': // 下拉框
if ($column['default']) {
if (isset($column['default'][$row[$column['name']]])) {
$prepend = $column['default'][$row[$column['name']]] != '' ? $column['default'][$row[$column['name']]] : '空值';
} else {
$prepend = '无对应值';
}
$class = ($prepend == '无对应值' || $prepend == '空值') ? 'select-edit text-danger' : 'select-edit';
$source = json_encode($column['default'], JSON_FORCE_OBJECT);
$row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
class="'.$class.'"
data-table="'.$this->createTableToken($_table_name == '' ? $this->_table_name : $_table_name, $this->_prefix).'"
data-type="select"
data-value="'.$row[$column['name']].'"
data-source=\''.$source.'\'
data-pk="'.$row['_primary_key_value'].'"
data-name="'.$_name.'">'.$prepend.'</a>';
}
break;
case 'select2': // tag编辑(有BUG)
// if ($column['default']) {
// $source = json_encode($column['default']);
// $row[$column['name'].'__'.$column['type']] = '<a href="javascript:void(0);"
// class="select2-edit"
// data-table="'.$this->_table_name.'"
// data-value="'.$row[$column['name']].'"
// data-type="select2"
// data-source=\''.$source.'\'
// data-pk="'.$row['_primary_key_value'].'"
// data-name="'.$column['name'].'">'.$row[$column['name']].'</a>';
// }
break;
case 'callback': // 调用回调方法
unset($column['field']);
unset($column['table']);
$params = array_slice($column, 4);
$params = array_filter($params, function($v){return $v !== '';});
if (isset($row[$column['name']]) || array_key_exists($column['name'], $row)) {
$params = array_merge([$row[$column['name']]], $params);
}
if (!empty($params)) {
foreach ($params as &$param) {
if ($param === '__data__') $param = $row;
}
}
$row[$column['name'].'__'.$column['type']] = call_user_func_array($column['default'], $params);
break;
case 'popover':
$length = empty($column['default']) ? 10 : $column['default'];
$placement = empty($column['param']) ? 'top' : $column['param'];
$row[$column['name'].'__'.$column['type']] = mb_substr($row[$column['name']], 0, $length, 'utf-8').'... <i class="fa fa-fw fa-question-circle" data-toggle="popover" data-placement="'.$placement.'" data-content="'.$row[$column['name']].'"></i>';
break;
case 'text':
default: // 默认
// 设置默认值
if (!isset($row[$column['name']]) && !empty($column['default'])) {
$row[$column['name']] = $column['default'];
}
if (is_array($column['type']) && !empty($column['type'])) {
if (isset($column['type'][$row[$column['name']]])) {
$row[$column['name']] = $column['type'][$row[$column['name']]];
}
} else {
if (!empty($column['param'])) {
if (isset($column['param'][$row[$column['name']]])) {
$row[$column['name']] = $column['param'][$row[$column['name']]];
}
} else {
if (isset($row[$column['name']]) && $row[$column['name']] == '' && $column['default'] != '') {
$row[$column['name']] = $column['default'];
}
}
}
}
}
}
}
}
/**
* 分析行class
* @param mixed $row 行数据
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
private function parseTrClass($row)
{
$_tr_class = [];
foreach ($this->_tr_class as $tr_class => $conditions) {
$match = true;
foreach ($conditions as $condition) {
if (is_callable($condition[0])) {
$params = array_merge([$row], $condition[1]);
$match = call_user_func_array($condition[0], $params) ? $match : false;
continue;
}
if (!isset($row[$condition[0]])) {
$match = false; continue;
}
$match = $this->parseCondition($row, $condition) ? $match : false;
}
if ($match) {
$_tr_class[] = $tr_class;
}
}
return $_tr_class;
}
/**
* 分析条件
* @param mixed $row 行数据
* @param array $condition 对比条件
* @author 蔡伟明 <314013107@qq.com>
* @return bool
*/
private function parseCondition($row, $condition = [])
{
$match = true;
switch ($condition[1]) {
case 'eq':
$row[$condition[0]] != $condition[2] && $match = false;
break;
case 'neq':
$row[$condition[0]] == $condition[2] && $match = false;
break;
case 'gt':
$row[$condition[0]] <= $condition[2] && $match = false;
break;
case 'lt':
$row[$condition[0]] >= $condition[2] && $match = false;
break;
case 'egt':
$row[$condition[0]] < $condition[2] && $match = false;
break;
case 'elt':
$row[$condition[0]] > $condition[2] && $match = false;
break;
case 'in':
!in_array($row[$condition[0]], $condition[2]) && $match = false;
break;
case 'not in':
in_array($row[$condition[0]], $condition[2]) && $match = false;
break;
case 'between':
($row[$condition[0]] < $condition[2][0] || $row[$condition[0]] > $condition[2][1]) && $match = false;
break;
case 'not between':
($row[$condition[0]] >= $condition[2][0] && $row[$condition[0]] <= $condition[2][1]) && $match = false;
break;
}
return $match;
}
/**
* 创建筛选Token
* @param string $table 表名
* @param string $field 字段
* @author 蔡伟明 <314013107@qq.com>
* @return bool|string
*/
private function createFilterToken($table = '', $field = '')
{
$table_token = substr(sha1($table.'-'.$field.'-'.session('user_auth.last_login_ip').'-'.session('user_auth.uid').'-'.session('user_auth.last_login_time')), 0, 8);
session($table_token, ['table' => $table, 'field' => $field]);
return $table_token;
}
/**
* 编译表格数据
* @author 蔡伟明 <314013107@qq.com>
*/
private function compileTable(){
// 设置表名
$this->_vars['_table'] = $this->_table_name;
// 处理字段筛选
if ($this->_vars['filter_columns']) {
// 要筛选的字段
$filter_columns = [];
// 要筛选的字段条件
$filter_maps = [];
// 处理字段筛选条件
if (!empty($this->_vars['filter_map'])) {
foreach ($this->_vars['filter_map'] as $fields => $map) {
if (strpos($fields, ',')) {
$fields = explode(',', $fields);
foreach ($fields as $field) {
if (isset($filter_maps[$field])) {
// 如果某字段的条件已存在,则合并条件
$filter_maps[$field] = array_merge($filter_maps[$field], $map);
} else {
$filter_maps[$field] = $map;
}
}
} else {
if (isset($filter_maps[$fields])) {
// 如果某字段的条件已存在,则合并条件
$filter_maps[$fields] = array_merge($filter_maps[$fields], $map);
} else {
$filter_maps[$fields] = $map;
}
}
}
// 将条件转换为json格式
foreach ($filter_maps as &$filter_map) {
$filter_map = json_encode($filter_map);
}
}
// 组合字段筛选
foreach ($this->_vars['filter_columns'] as $key => $value) {
if (is_numeric($key)) {
if (strpos($value, '.')) {
list($table, $field) = explode('.', $value);
$_filter_token = $this->createFilterToken($table, $field);
$filter_columns[$field] = [
'token' => $_filter_token,
'type' => $this->_filter_type[$value],
'filter' => $value,
'map' => isset($filter_maps[$field]) ? $filter_maps[$field] : '',
'options' => isset($this->_filter_options[$field]) ? $this->_filter_options[$field] : '',
'list' => isset($this->_filter_list[$field]) ? $this->_filter_list[$field] : ''
];
} else {
$_filter_token = $this->createFilterToken($this->_table_name, $value);
$filter_columns[$value] = [
'token' => $_filter_token,
'type' => $this->_filter_type[$value],
'filter' => $value,
'map' => isset($filter_maps[$value]) ? $filter_maps[$value] : '',
'options' => isset($this->_filter_options[$value]) ? $this->_filter_options[$value] : '',
'list' => isset($this->_filter_list[$value]) ? $this->_filter_list[$value] : ''
];
}
} else {
if (strpos($value, '.')) {
list($table, $field) = explode('.', $value);
$_filter_token = $this->createFilterToken($table, $field);
$filter_columns[$key] = [
'token' => $_filter_token,
'type' => $this->_filter_type[$value],
'filter' => $value,
'map' => isset($filter_maps[$key]) ? $filter_maps[$key] : '',
'options' => isset($this->_filter_options[$key]) ? $this->_filter_options[$key] : '',
'list' => isset($this->_filter_list[$key]) ? $this->_filter_list[$key] : ''
];
} else {
$_filter_token = $this->createFilterToken($value, $key);
$filter_columns[$key] = [
'token' => $_filter_token,
'type' => $this->_filter_type[$value],
'filter' => $value . '.' . $key,
'map' => isset($filter_maps[$key]) ? $filter_maps[$key] : '',
'options' => isset($this->_filter_options[$key]) ? $this->_filter_options[$key] : '',
'list' => isset($this->_filter_list[$key]) ? $this->_filter_list[$key] : ''
];
}
}
}
$this->_vars['filter_columns'] = $filter_columns;
}
// 处理字段筛选默认选项
$this->_vars['_filter_content'] = implode('|', $this->_vars['_filter_content']);
$this->_vars['_field_display'] = implode(',', $this->_vars['_field_display']);
$this->_vars['_filter'] = implode('|', $this->_vars['_filter']);
// 处理字段排序
if ($this->_vars['order_columns']) {
$order_columns = [];
foreach ($this->_vars['order_columns'] as $key => $value) {
if (is_numeric($key)) {
if (strpos($value, '.')) {
$tmp = explode('.', $value);
$order_columns[$tmp[1]] = $value;
} else {
$order_columns[$value] = $value;
}
} else {
if (strpos($value, '.')) {
$order_columns[$key] = $value;
} else {
$order_columns[$key] = $value. '.' .$key;
}
}
}
$this->_vars['order_columns'] = $order_columns;
}
// 编译顶部按钮
if ($this->_vars['top_buttons']) {
foreach ($this->_vars['top_buttons'] as &$button) {
// 处理表名变量值
if (strpos($button['href'], '__table__')) {
$button['href'] = preg_replace(
'/__table__/i',
$this->createTableToken($this->_table_name, $this->_prefix),
$button['href']
);
}
$button['attribute'] = $this->compileHtmlAttr($button);
$new_button = "<a {$button['attribute']}>";
if (isset($button['icon']) && $button['icon'] != '') {
$new_button .= '<i class="'.$button['icon'].'"></i> ';
}
$new_button .= "{$button['title']}</a>";
$button = $new_button;
}
}
// 编译顶部下拉菜单
if ($this->_vars['_select_list']) {
foreach ($this->_vars['_select_list'] as $name => &$select) {
// 当前url参数
$url_params = $this->request->param();
// 要搜索的字段
$select_field = $this->request->param('_select_field', '');
$select_field = $select_field != '' ? explode('|', $select_field) : [];
// 对应的值
$select_value = $this->request->param('_select_value', '');
$select_value = $select_value != '' ? explode('|', $select_value) : [];
// 合并默认值
if ($this->_select_list_default) {
foreach ($this->_select_list_default as $field => $value) {
if (!in_array($field, $select_field)) {
array_push($select_field, $field);
array_push($select_value, $value);
}
}
}
// 当前选中值
if (in_array($name, $select_field)) {
$select['current'] = $select_value[array_search($name, $select_field)];
}
// 剔除要忽略的参数
if ($select['ignore'] !== '') {
$ignores = explode(',', $select['ignore']);
foreach ($ignores as $ignore) {
if (array_search($ignore, $select_field) !== false) {
$pos = array_search($ignore, $select_field);
array_splice($select_field, $pos, 1);
array_splice($select_value, $pos, 1);
}
}
}
// 生成除默认选项的下拉项的跳转url
if (!empty($select_field)) {
if (!in_array($name, $select_field)) {
array_push($select_field, $name);
}
$url_params['_select_field'] = implode('|', $select_field);
foreach ($select['options'] as $key => $option) {
$select_value[array_search($name, $select_field)] = $key;
$url_params['_select_value'] = implode('|', $select_value);
$select['url'][$key] = url('').'?'.http_build_query($url_params);
}
} else {
$url_params['_select_field'] = $name;
foreach ($select['options'] as $key => $option) {
$url_params['_select_value'] = $key; // 添加下拉菜单项查询参数
$select['url'][$key] = url('').'?'.http_build_query($url_params);
}
}
// 生成默认选项的url
if (isset($this->_select_list_default[$name])) {
$url_params['_select_field'] = implode('|', $select_field);
$select_value[array_search($name, $select_field)] = '_all';
$url_params['_select_value'] = implode('|', $select_value);
} else {
if (array_search($name, $select_field) !== false) {
$pos = array_search($name, $select_field);
unset($select_value[$pos]);
unset($select_field[$pos]);
if (empty($select_field)) {
unset($url_params['_select_field']);
unset($url_params['_select_value']);
} else {
$url_params['_select_field'] = implode('|', $select_field);
$url_params['_select_value'] = implode('|', $select_value);
}
}
}
$select['default_url'] = url('').'?'.http_build_query($url_params);
}
}
// 处理搜索框
if ($this->_search) {
$_temp_fields = [];
foreach ($this->_search['fields'] as $key => $field) {
if (is_numeric($key)) {
if (strpos($field, '.')) {
$_field = explode('.', $field)[1];
} else {
$_field = $field;
}
$_temp_fields[$field] = isset($this->_field_name[$_field]) ? $this->_field_name[$_field] : '';
} else {
$_temp_fields[$key] = $field;
}
}
$this->_vars['search'] = [
'fields' => $_temp_fields,
'field_all' => implode('|', array_keys($_temp_fields)),
'placeholder' => $this->_search['placeholder'] != '' ? $this->_search['placeholder'] : '请输入'. implode('/', $_temp_fields),
'url' => $this->_search['url'] == '' ? $this->request->baseUrl(true) : $this->_search['url']
];
}
// 编译表格数据row_list的值
$this->compileRows();
// 处理页面标题
if ($this->_vars['page_title'] == '') {
$location = get_location('', false, false);
if ($location) {
$curr_location = end($location);
$this->_vars['page_title'] = $curr_location['title'];
}
}
// 处理是否有分页数据
if (!$this->_has_pages) {
$this->_vars['pages'] = '';
}
// 处理js和css合并的参数
if (!empty($this->_vars['_js_files'])) {
$this->_vars['_js_files'] = array_unique($this->_vars['_js_files']);
}
if (!empty($this->_vars['_css_files'])) {
$this->_vars['_css_files'] = array_unique($this->_vars['_css_files']);
sort($this->_vars['_css_files']);
}
if (!empty($this->_vars['_js_init'])) {
$this->_vars['_js_init'] = array_unique($this->_vars['_js_init']);
sort($this->_vars['_js_init']);
$this->_vars['_js_init'] = json_encode($this->_vars['_js_init']);
}
}
/**
* 加载模板输出
* @param string $template 模板文件名
* @param array $vars 模板输出变量
* @param array $config 模板参数
* @author 蔡伟明 <314013107@qq.com>
* @return mixed
*/
public function fetch($template = '', $vars = [], $config = [])
{
// 编译表格数据
$this->compileTable();
if ($template != '') {
$this->_template = $template;
}
if (!empty($vars)) {
$this->_vars = array_merge($this->_vars, $vars);
}
// 实例化视图并渲染
return parent::fetch($this->_template, $this->_vars, $config);
}
}