gdoo/app/Gdoo/Index/Models/BaseModel.php

195 lines
5.2 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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('|&ndash;', $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;
}
}