first
This commit is contained in:
192
modules/User/Models/Traits/HasRelations.php
Normal file
192
modules/User/Models/Traits/HasRelations.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?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(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user