193 lines
5.5 KiB
PHP
193 lines
5.5 KiB
PHP
<?php
|
||
|
||
namespace Modules\User\Models\Traits;
|
||
|
||
use Exception;
|
||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Modules\User\Models\Relation;
|
||
use Modules\User\Models\User;
|
||
|
||
trait HasRelations
|
||
{
|
||
|
||
/**
|
||
* 这个参数,是为了给用户创建事件监听模型使用的
|
||
*
|
||
* @var int
|
||
*/
|
||
public int $parent_id = 0;
|
||
|
||
/**
|
||
* Notes: 创建的监听,转移到这里了
|
||
*
|
||
* @Author: <C.Jason>
|
||
* @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: <C.Jason>
|
||
* @Date : 2020/1/13 5:58 下午
|
||
* @param int $parentID
|
||
*/
|
||
protected function setParentIdAttribute(int $parentID)
|
||
{
|
||
$this->parent_id = $parentID;
|
||
}
|
||
|
||
/**
|
||
* Notes: 用户关联关系
|
||
*
|
||
* @Author: <C.Jason>
|
||
* @Date : 2020/1/13 5:51 下午
|
||
* @return HasOne
|
||
*/
|
||
public function relation(): HasOne
|
||
{
|
||
return $this->hasOne(Relation::class)->withDefault();
|
||
}
|
||
|
||
/**
|
||
* Notes: 上级用户
|
||
*
|
||
* @Author: <C.Jason>
|
||
* @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: <C.Jason>
|
||
* @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(),
|
||
];
|
||
}
|
||
|
||
}
|