招标
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.
 
 
 
 
 

377 lines
9.9 KiB

<?php
/**
*
* TableConstruct.php
* User: ChenLong <vip_chenlong@163.com>
* DateTime: 2020/7/17 16:20
*/
namespace sdModule\layui\tableDetail;
/**
* Class TableConstruct
* @package sdModule\layui\tableDetail
*/
class TableConstruct
{
const TR = "<tr>\r\n:tds</tr>\r\n";
const TD = "<td>:title</td><td colspan=\":td_grid\">:value</td>\r\n";
const TITLE = "<blockquote class=\"layui-elem-quote\">:title</blockquote>";
const TABLE = <<<'TAB'
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href=":ROOTadmin_static/layui/css/layui.css">
:token
<style>
body{margin: 20px}
td:nth-child(2n-1){text-align: center;width: 120px}
td img{margin-right: 10px}
.layui-table th {text-align: center;}
</style>
</head>
<body>
<blockquote class="layui-elem-quote">:title</blockquote>
:before_button
<table class="layui-table">
:trs
</table>
:after_button
:layui_js
:custom_js
</body>
</html>
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 "<div class='img-table layui-inline'><img src='{$td_value}' alt='{$td_value}' /></div>";
}
$string = '';
foreach (explode(',', $td_value) as $value) {
$value = preg_match('/^http/', $value) ? $value : ($this->root . $value);
$string .= "<div class='img-table layui-inline'><img src='{$value}' alt='{$value}' /></div>";
}
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 .= "</table>{$title}<table class=\"layui-table\">";
}
} 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 = '<th>' . implode('</th><th>', $thead) . '</th>';
$th = "<tr>{$title}</tr>";
$data = $this->multiple ? $this->data[$this->current_table_index] : $this->data;
foreach ($data as $item) {
$th .= '<tr>';
foreach ($thead as $field => $omission){
$th .= '<td>' . ($item[$field] ?? '——') . '</td>';
}
$th .= '</tr>';
}
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 = "<button class=\"layui-btn {$button['class']}\" lay-active=\"{$event}\">{$button['title']}</button>";
$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 .= <<<EVENT
{$event}:function(){{$code}},
EVENT;
}
/**
* @return string
*/
private function eventRequest()
{
return <<<EVENT
layui.util.event('lay-active', {
{::event::}
});
EVENT;
}
/**
* @param string $title
* @param string $name
* @param int $td_grid
* @return array
*/
public static function tdImages(string $title, string $name, $td_grid = 1)
{
return self::td($title, $name, $td_grid, 'images');
}
/**
* @param string $title
* @param string $name
* @param int $td_grid
* @return array
*/
public static function tdImage(string $title, string $name, $td_grid = 1)
{
return self::td($title, $name, $td_grid, 'image');
}
/**
* @param array $tr
* @return string
*/
private function trRender(array $tr)
{
$tr_string = '';
foreach ($tr as $td) {
$tr_string .= $this->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 <<<CUSTOM
<script >
layer.ready(function() {
custom.enlarge(layer,layui.jquery,'.img-table');
});
{$event_js}
</script>
CUSTOM;
}
}