195 lines
5.2 KiB
PHP
195 lines
5.2 KiB
PHP
<?php namespace Gdoo\Index\Models;
|
||
|
||
use DB;
|
||
|
||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||
use App\Illuminate\Database\Query\Builder as QueryBuilder;
|
||
|
||
class BaseModel extends Eloquent
|
||
{
|
||
public $timestamps = false;
|
||
|
||
/**
|
||
* 设置不允许批量赋值的字段
|
||
*/
|
||
protected $guarded = ['id'];
|
||
|
||
/**
|
||
* 获取连接的新查询生成器实例
|
||
*
|
||
* @return \App\Database\Query\Builder
|
||
*/
|
||
protected function newBaseQueryBuilder()
|
||
{
|
||
$connection = $this->getConnection();
|
||
return new QueryBuilder(
|
||
$connection,
|
||
$connection->getQueryGrammar(),
|
||
$connection->getPostProcessor()
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 重写日期格式
|
||
*/
|
||
public function getDateFormat()
|
||
{
|
||
return 'U';
|
||
}
|
||
|
||
public function getDates()
|
||
{
|
||
return [];
|
||
}
|
||
|
||
public function scopeWithAt($query, $relation, array $columns)
|
||
{
|
||
return $query->with([$relation => function ($query) use ($columns) {
|
||
$query->select(array_merge(['id'], $columns));
|
||
}]);
|
||
}
|
||
|
||
/**
|
||
* 查询 Dialog 字段显示的值,其他模型可复写此方法
|
||
*/
|
||
public function scopeDialog($query, $value)
|
||
{
|
||
return $query->whereIn('id', $value)->get();
|
||
}
|
||
|
||
/**
|
||
* 取得所有层级
|
||
*
|
||
* @var string $columns 选择字段
|
||
*/
|
||
public function scopeTree($query, $select = ['node.*'])
|
||
{
|
||
$rows = $this->from(DB::raw($this->from.' as node, '.$this->from.' as parent'))
|
||
->select($select)
|
||
->selectRaw('(COUNT(parent.id)-1) level')
|
||
->whereRaw('node.lft BETWEEN parent.lft AND parent.rgt')
|
||
->groupBy('node.id')
|
||
->orderBy('node.lft', 'asc');
|
||
|
||
$result = array();
|
||
|
||
if (is_array($rows)) {
|
||
foreach ($rows as $row) {
|
||
$row['layer'] = str_repeat('|–', $row['level']);
|
||
$result[$row['id']] = $row;
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 取得指定层级集
|
||
*
|
||
* @var int $id 条件编号
|
||
* $type int 0.包含自己的所有子类, 1.包含自己所有父类
|
||
*/
|
||
public function scopeTreeById($query, $id, $type = 0)
|
||
{
|
||
$table = $this->table;
|
||
$rows = $this->from(DB::raw($table.' as node, '.$table.' as parent'))
|
||
->whereRaw($type == 0 ? 'node.lft BETWEEN parent.lft AND parent.rgt' : 'parent.rgt BETWEEN node.lft AND node.rgt')
|
||
->where('parent.id', $id)
|
||
->groupBy('node.id')
|
||
->orderBy('node.lft', 'asc')
|
||
->select(['node.*'])
|
||
->get();
|
||
|
||
return $rows;
|
||
}
|
||
|
||
public function scopeToTree($query, $text = 'name', $selected = 0, $state = 'closed')
|
||
{
|
||
if ($selected > 0) {
|
||
$selected = $query->treeSinglePath($selected);
|
||
}
|
||
$nodes = $query->get()->toArray();
|
||
|
||
// 格式化的树
|
||
$tree = [];
|
||
|
||
//临时扁平数据
|
||
$map = [];
|
||
|
||
foreach ($nodes as $node) {
|
||
$node['text'] = $node[$text];
|
||
$node['state'] = ($state == 'closed' && empty($selected[$node['id']])) ? 'closed' : 'open';
|
||
$map[$node['id']] = $node;
|
||
}
|
||
unset($selected);
|
||
|
||
foreach ($nodes as $node) {
|
||
if (isset($map[$node['parent_id']])) {
|
||
$map[$node['parent_id']]['children'][] = &$map[$node['id']];
|
||
} else {
|
||
$tree[] = &$map[$node['id']];
|
||
}
|
||
}
|
||
unset($map, $nodes);
|
||
return $tree;
|
||
}
|
||
|
||
/**
|
||
* 将所有子节点的ID压入根节点
|
||
*/
|
||
public function scopeToChild($query, array $select = array('*'))
|
||
{
|
||
$items = $query->get($select)->keyBy('id')->toArray();
|
||
$id = 0;
|
||
foreach ($items as &$item) {
|
||
$path = explode(',', $item['path']);
|
||
$item['parent'] = $path;
|
||
}
|
||
return $items;
|
||
}
|
||
|
||
/**
|
||
* 返回当前节点的完整路径
|
||
*/
|
||
public function scopeTreeSinglePath($query, $id)
|
||
{
|
||
$table = $this->table;
|
||
$rows = $this->from(DB::raw($table.' as node, '.$table.' as parent'))
|
||
->whereRaw('node.lft BETWEEN parent.lft AND parent.rgt')
|
||
->where('node.id', $id)
|
||
->orderBy('node.lft', 'asc')
|
||
->select(['parent.*'])
|
||
->get()->keyBy('id');
|
||
return $rows;
|
||
}
|
||
|
||
/**
|
||
* 重建树形结构的左右值
|
||
*
|
||
* @var $parent_id 构建的开始id
|
||
*/
|
||
public function scopeTreeRebuild($query, $parent_id = 0, $left = 0, $layer = 0)
|
||
{
|
||
// 左值 +1 是右值
|
||
$right = $left + 1;
|
||
|
||
// 获得这个节点的所有子节点
|
||
$rows = $this->where('parent_id', $parent_id)
|
||
->orderBy('sort', 'asc')
|
||
->get(['id', 'parent_id', 'lft', 'rgt']);
|
||
|
||
if ($rows->count()) {
|
||
foreach ($rows as $row) {
|
||
// 这个节点的子$right是当前的右值,这是由treeRebuild函数递增
|
||
$right = $this->TreeRebuild($row->id, $right, $layer + 1);
|
||
}
|
||
}
|
||
|
||
// 更新左右值
|
||
$this->where('id', $parent_id)->orderBy('sort', 'asc')
|
||
->update(['lft'=>$left, 'rgt'=>$right, 'layer' => $layer]);
|
||
|
||
// 返回此节点的右值+1
|
||
return $right + 1;
|
||
}
|
||
}
|