Files
water_new/modules/User/Models/Traits/HasRelations.php
2023-03-08 09:16:04 +08:00

193 lines
5.5 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 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(),
];
}
}