* DateTime: 2020/7/17 16:20
*/
namespace sdModule\layui\tableDetail;
/**
* Class TableConstruct
* @package sdModule\layui\tableDetail
*/
class TableConstruct
{
const TR = "
\r\n:tds
\r\n";
const TD = ":title | :value | \r\n";
const TITLE = ":title
";
const TABLE = <<<'TAB'
:token
:title
:before_button
:after_button
:layui_js
:custom_js
TAB;
private $data;
private $title = '';
private $multiple = false;
private $current_table_index = 0;
private $event_js = '';
private $after_button = '';
private $before_button = '';
private $root;
/**
* TableConstruct constructor.
* @param $table_data
* @param $multiple
*/
private function __construct(array $table_data, bool $multiple)
{
$this->root = rtrim(strtr(dirname($_SERVER['SCRIPT_NAME']), ['\\' => '/']), '/') . '/';
$this->data = $table_data;
$this->multiple = $multiple;
}
/**
* 设置字段值[key => value]
* @param array $data 值数据,多个表格则是二维数组
* @param bool $multiple 是否是多个表格
* @return TableConstruct
*/
public static function data(array $data, bool $multiple = false)
{
return new self($data, $multiple);
}
/**
* 设置标题
* @param string|array $title
* @return $this
*/
public function title($title)
{
$this->title = $title;
return $this;
}
/**
* 获取value值
* @param $name
* @param $type
* @return string
*/
private function getValue($name, $type)
{
$td_value = $this->multiple
? ($this->data[$this->current_table_index][$name] ?? null)
: ($this->data[$name] ?? null);
if ($td_value || $td_value === 0) {
if ($type === 'text') return $td_value;
if ($type === 'image') {
$td_value = preg_match('/^http/', $td_value) ? $td_value : ($this->root . $td_value);
return "
";
}
$string = '';
foreach (explode(',', $td_value) as $value) {
$value = preg_match('/^http/', $value) ? $value : ($this->root . $value);
$string .= "
";
}
return $string;
}
return '——';
}
/**
* @param array $trs 行数据
* @return string
*/
public function render(array $trs)
{
$table_html = '';
if ($this->multiple) {
foreach ($trs as $index => $sub_trs) {
$this->current_table_index = $index;
/**
* 判断是否是多维数组,多维数组即表示为 【 标题 | 值 | 标题 | 值 】类型
* 一维数组则表示数据为竖向的多个数据
* 姓名 | 年龄
* 张三 | 18
* 李四 | 18
*/
if (count($sub_trs) == count($sub_trs, 1)) {
$table_html .= $this->formatData($sub_trs);
}else{
foreach ($sub_trs as $tr) {
$table_html .= $this->trRender($tr);
}
}
$title = is_array($this->title) && isset($this->title[$index + 1])
? strtr(self::TITLE, [':title' => $this->title[$index + 1]]) : '';
$table_html .= "{$title}";
}
} else {
if (count($trs) == count($trs, 1)) {
$table_html .= $this->formatData($trs);
}else{
foreach ($trs as $tr) {
$table_html .= $this->trRender($tr);
}
}
}
return strtr(self::TABLE, [
':title' => is_array($this->title) ? $this->title[0] : $this->title,
':trs' => $table_html,
':ROOT' => $this->root,
':layui_js' => $this->layuiJs(),
':custom_js' => $this->customJs(),
':after_button' => $this->after_button,
':before_button' => $this->before_button,
':token' => token_meta()
]);
}
/**
* @param mixed ...$td
* @return array
*/
public static function tr(...$td)
{
return $td;
}
/**
* 列表式的数据
* @param array $thead 头字段
* @return string
*/
private function formatData(array $thead)
{
$title = '' . implode(' | ', $thead) . ' | ';
$th = "{$title}
";
$data = $this->multiple ? $this->data[$this->current_table_index] : $this->data;
foreach ($data as $item) {
$th .= '';
foreach ($thead as $field => $omission){
$th .= '' . ($item[$field] ?? '——') . ' | ';
}
$th .= '
';
}
return $th;
}
/**
* @param string $title 标题
* @param string $name 对应的值的field
* @param int $td_grid 值占用列数
* @param string $type 可选:image|images|text
* @return array
*/
public static function td(string $title, string $name, $td_grid = 1, $type = 'text')
{
return compact('title', 'td_grid', 'name', 'type');
}
/**
* 之后的按钮
* @param mixed ...$buttons button按钮集合
* @return mixed|string
*/
public function afterButton(...$buttons)
{
foreach ($buttons as $button) {
$this->buttonConstruct($button, false);
}
return $this;
}
/**
* @param mixed ...$buttons button按钮集合
* @return $this
*/
public function beforeButton(...$buttons)
{
array_map([$this, 'buttonConstruct'], $buttons);
return $this;
}
/**
* button 组建
* @param array $button 组建button的数据array
* @param bool $isBefore 是否是表格之前
*/
private function buttonConstruct(array $button, $isBefore = true)
{
$event = 'e' . mt_rand(100, 999);
$this->eventJs($button['url'], $button['request_data'], $event);
$buttonHtml = "";
$isBefore ? $this->before_button .= $buttonHtml : $this->after_button .= $buttonHtml;
}
/**
* 生成button
* @param string $title 按钮文字
* @param string|\Closure $url 事件请求地址或自定义js代码的回调函数
* @param array $request_data 请求数据,$url 为Closure时,此为$url的参数
* @param string $class layui button的类名
* @return array
*/
public static function button(string $title, $url, array $request_data, $class = '')
{
return compact('title', 'url', 'request_data', 'class');
}
/**
* 按钮事件的js代码
* @param string $url 请求地址
* @param string $data 请求数据
* @param string $event 事件名
*/
private function eventJs($url, $data, $event)
{
if ($url instanceof \Closure) {
$code = call_user_func($url, ...$data);
}else{
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
$code = "sc_event('{$url}', {$data});";
}
$this->event_js .= <<tdRender($td);
}
return strtr(self::TR, [':tds' => $tr_string]);
}
/**
* 渲染td
* @param array $td
* @return string
*/
private function tdRender(array $td)
{
return strtr(self::TD, [
':title' => $td['title'],
':td_grid' => $td['td_grid'],
':value' => $this->getValue($td['name'], $td['type'])
]);
}
private function lang($key)
{
return lang($key);
}
private function layuiJs()
{
return include __DIR__ . '/js_var.php';
}
private function customJs()
{
$event_js = $this->event_js ? strtr($this->eventRequest(), ['{::event::}' => $this->event_js]) : '';
return <<
layer.ready(function() {
custom.enlarge(layer,layui.jquery,'.img-table');
});
{$event_js}
CUSTOM;
}
}