* @Date : 2020/1/13 5:52 下午 */ public static function bootHasRelations() { self::created(function ($model) { if (isset($model->parent_id) && is_numeric($model->parent_id) && $model->parent_id != 0) { $parent = User::find($model->parent_id); if ($parent && $model->id != $model->parent_id) { $model->relation()->create([ 'parent_id' => $parent->id, 'bloodline' => $parent->relation->bloodline.$parent->id.',', 'layer' => $parent->relation->layer + 1, ]); } else { $model->relation()->create([ 'parent_id' => config('user.default_parent_id'), 'bloodline' => config('user.default_parent_id').',', 'layer' => 1, ]); } } else { $model->relation()->create([ 'parent_id' => config('user.default_parent_id'), 'bloodline' => config('user.default_parent_id').',', 'layer' => 1, ]); } }); } /** * Notes: 这个方法,是为了给用户创建事件监听模型使用的 * 目的是去除attribute里面的parent_id参数,防止数据库写入错误 * * @Author: * @Date : 2020/1/13 5:58 下午 * @param int $parentID */ protected function setParentIdAttribute(int $parentID) { $this->parent_id = $parentID; } /** * Notes: 用户关联关系 * * @Author: * @Date : 2020/1/13 5:51 下午 * @return HasOne */ public function relation(): HasOne { return $this->hasOne(Relation::class)->withDefault(); } /** * Notes: 上级用户 * * @Author: * @Date : 2020/1/13 5:51 下午 * @return HasOneThrough */ public function parent(): HasOneThrough { return $this->hasOneThrough( User::class, Relation::class, 'user_id', 'id', 'id', 'parent_id' ); } /** * Notes: 所有下级用户 * * @Author: * @Date : 2020/1/13 5:51 下午 * @return mixed */ public function children(): HasManyThrough { return $this->hasManyThrough( User::class, Relation::class, 'parent_id', 'id', 'id', 'user_id' ); } /** * 调整隶属 * * @param int $parent_id * @return bool * @throws Exception */ public function updateParent(int $parent_id = 0): bool { if ($parent_id == $this->id) { throw new Exception('不能绑定自己'); } if (Relation::where('user_id', $parent_id) ->where('bloodline', 'like', "%,".$this->id.",%") ->exists()) { throw new Exception('不能绑定自己的下级用户'); } try { $relation = $this->relation; $new_blood = '0,'; $new_layer = 1; $new_parent_id = 0; $blood = $relation->bloodline; $layer = $relation->layer; $parent = User::find($parent_id); if ($parent) { $new_parent_id = $parent->id; $new_blood = $parent->relation->bloodline.$new_parent_id.','; $new_layer = $parent->relation->layer + 1; } $relation->parent_id = $new_parent_id; $relation->bloodline = $new_blood; $relation->layer = $new_layer; if ($relation->save()) { $diffLayer = $layer - $new_layer; DB::update("UPDATE `user_relations` SET `bloodline`=CONCAT(?,SUBSTRING(bloodline,LENGTH(?)+1)),`layer`=`layer`-? WHERE `bloodline` LIKE ?", [$new_blood, $blood, $diffLayer, "%,".$this->id.",%"]); } return true; } catch (Exception $e) { return false; } } /** * Notes: 获取下级数量 * * @Author: 玄尘 * @Date : 2021/9/24 11:42 */ public function getRelationCount(): array { return [ 'all' => Relation::query() ->whereIn('layer', [$this->relation->layer + 1, $this->relation->layer + 2]) ->where('bloodline', 'like', "%,".$this->id.",%") ->count(), 'one' => Relation::query() ->where('layer', $this->relation->layer + 1) ->where('bloodline', 'like', "%,".$this->id.",%") ->count(), 'two' => Relation::query() ->where('layer', $this->relation->layer + 2) ->where('bloodline', 'like', "%,".$this->id.",%") ->count(), ]; } }