123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- <?php
- declare(strict_types=1);
- namespace addons\shopro\library;
- use think\model\Collection;
- class Tree
- {
- protected $model = null;
- public function __construct($model)
- {
- $this->model = $model;
- }
- /**
- * 获取递归树
- *
- * @param integer|array|Collection $items 可以传入某个id 查询这个id的下级树,也可以传一个查询列表结果,将获取这个列表的所有的下级 树
- * @param \Closure $resultCb 用来处理每一次查询的结果 比如要取出树中的所有 name
- * @return Collection
- */
- public function getTree($items = 0, \Closure $resultCb = null)
- {
- if (!is_array($items) && !$items instanceof Collection) {
- $items = $this->getQuery()->where('parent_id', $items)->select();
- $resultCb && $items = $resultCb($items);
- }
- foreach ($items as $key => &$item) {
- $child = $this->getTree($item->id, $resultCb);
- if ($child) {
- $item->children = $child;
- }
- }
- return $items;
- }
- /**
- * 获取递归树(包含自身)
- *
- * @param integer $id
- * @param \Closure $resultCb 用来处理每一次查询的结果 比如要取出树中的所有 name
- * @return Collection
- */
- public function getChildren($id, \Closure $resultCb = null)
- {
- $self = $this->getQuery()->where('id', $id)->select();
- if(!$self) {
- error_stop('未找到数据');
- }
- $items = $this->getQuery()->where('parent_id', $id)->select();
- $resultCb && $items = $resultCb($items);
- foreach ($items as $key => &$item) {
- $child = $this->getTree($item->id, $resultCb);
- if ($child) {
- $item->children = $child;
- }
- }
- $self[0]->children = $items;
- return $self;
- }
- /**
- * 检测id 是不是自己的下级
- *
- * @param [type] $parent_id
- * @param [type] $id
- * @return void
- */
- public function checkParent($parent_id, $id)
- {
- if ($parent_id == $id) {
- error_stop('当前上级不能是自己');
- }
- $childIds = $this->getChildIds($id);
- if (in_array($parent_id, $childIds)) {
- error_stop('当前上级不能是自己的下级');
- }
- return true;
- }
- /**
- * 获取当前对象所属级别
- *
- * @param [type] $object
- * @return void
- */
- public function getLevel($object)
- {
- $parentIds = $this->getParentFields($object, 'id');
- return count($parentIds);
- }
- /**
- * 缓存递归获取当前对象的上级 指定字段
- *
- * @param \think\Model|int $id
- * @param boolean $self 是否包含自己
- * @return array
- */
- public function getParentFields($item, $field = 'id', $self = true)
- {
- if (!$item instanceof \think\Model) {
- $item = $this->getQuery()->find($item);
- if (!$item) {
- return [];
- }
- }
- // 判断缓存
- $cacheKey = 'object-' . $this->getTable() . '-' . $item->id . '-' . $field . '-parent-ids';
- $objectIds = cache($cacheKey);
- if (!$objectIds) {
- $objectIds = array_reverse($this->recursionGetParentFields($item, $field));
- if ($self) {
- $objectIds[] = $item[$field]; // 加上自己
- }
- // 缓存暂时注释,如果需要,可以打开,请注意后台更新角色记得清除缓存
- // cache($cacheKey, $objectIds, (600 + mt_rand(0, 300))); // 加入随机秒数,防止一起全部过期
- }
- return $objectIds;
- }
- /**
- * 递归获取所有上级 id
- */
- private function recursionGetParentFields($item, $field = 'id', $ids = [])
- {
- if ($item->parent_id) {
- $parent = $this->getQuery()->find($item->parent_id);
- if ($parent) {
- $ids[] = $parent[$field];
- return $this->recursionGetParentFields($parent, $field, $ids);
- }
- }
- return $ids;
- }
- /**
- * 缓存递归获取子对象 id
- *
- * @param int $id 要查询的 id
- * @param boolean $self 是否包含自己
- * @return array
- */
- public function getChildIds($id, $self = true)
- {
- // 判断缓存
- $cacheKey = 'object-' . $this->getTable() . '-' . $id . '-child-ids';
- $objectIds = cache($cacheKey);
- if (!$objectIds) {
- $objectIds = $this->recursionGetChildIds($id, $self);
- // 缓存暂时注释,如果需要,可以打开,请注意后台更新角色记得清除缓存
- // cache($cacheKey, $objectIds, (600 + mt_rand(0, 300))); // 加入随机秒数,防止一起全部过期
- }
- return $objectIds;
- }
- /**
- * 递归获取子分类 id
- *
- */
- private function recursionGetChildIds($id, $self)
- {
- $ids = $self ? [$id] : [];
- $childrenIds = $this->getQuery()->where(['parent_id' => $id])->column('id');
- if ($childrenIds) {
- foreach ($childrenIds as $v) {
- $grandsonIds = $this->recursionGetChildIds($v, true);
- $ids = array_merge($ids, $grandsonIds);
- }
- }
- return $ids;
- }
- /**
- * 获取当前 查询
- *
- * @return think\model|think\db\Query
- */
- private function getQuery()
- {
- if ($this->model instanceof \Closure) {
- return ($this->model)();
- }
- return $this->model;
- }
- /**
- * 获取表
- */
- private function getTable()
- {
- $query = $this->getQuery();
- if ($query instanceof \think\Model) {
- $table_name = $query->getQuery()->getTable();
- } else {
- $table_name = $query->getTable();
- }
- return $table_name;
- }
- }
|