mr_web_api/app/common/arw/adjfut/src/Model/Pivot.php
2023-06-28 18:45:02 +08:00

259 lines
6.5 KiB
PHP

<?php
namespace app\common\app\common\arw\adjfut\src\Model;
use think\model\Collection;
use app\common\arw\adjfut\src\Exception\ErrorMsg;
/**
* 中间表关联
*
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
class Pivot
{
/**
* 中间表
*
* @var string
*/
private $pivotClass = '';
/**
* 主表
*
* @var string
*/
private $masterClass = '';
/**
* 子表
*
* @var string
*/
private $subClass = '';
/**
* 中间表主键
*
* @var string
*/
private $pivotPk = '';
/**
* 主表主键
*
* @var string
*/
private $masterPk = '';
/**
* 子表主键
*
* @var string
*/
private $subPk = '';
/**
* 是否软删除
*
* @var boolean
*/
private $softDelete = false;
/**
* 初始化
*
* @param string $pivotClass 中间表
* @param string $masterClass 主表
* @param string $subClass 子表
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
public function __construct(
string $pivotClass,
string $masterClass,
string $subClass,
bool $softDelete = false
) {
$this->pivotClass = $pivotClass;
$this->masterClass = $masterClass;
$this->subClass = $subClass;
$this->softDelete = $softDelete;
$this->pivotPk = (new $pivotClass)->getPk();
$this->masterPk = (new $masterClass)->getPk();
$this->subPk = (new $subClass)->getPk();
}
/**
* 绑定
*
* @param array|Collection $masters
* @param array|Collection $subs
* @param array $extra 中间表额外数据
* @return void
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
public function bind($masters, $subs, array $extra = []): void
{
$this->_bind($masters, $subs, $extra, false);
}
/**
* 解绑
*
* @param array|Collection $masters
* @param array|Collection $subs
* @return void
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
public function unbind(array $masters, array $subs): void
{
$masters = self::formatModel($masters, $this->masterClass);
$subs = self::formatModel($subs, $this->subClass);
$pivotClass = $this->pivotClass;
$pivotPk = $this->pivotPk;
$masterPk = $this->masterPk;
$subPk = $this->subPk;
foreach ($masters as $master) {
// 查询已绑定的数据
$subPks = $pivotClass::where([
$masterPk => $master->$masterPk
])->column($subPk);
foreach ($subs as $sub) {
if (in_array($sub->$subPk, $subPks)) {
$pivotClass::where([
$subPk => $sub->$subPk,
$masterPk => $master->$masterPk
])->field([
$pivotPk
])->select()->delete();
}
}
}
}
/**
* 重新绑定
*
* @param array|Collection $masters
* @param array|Collection $subs
* @param array $extra 中间表额外数据
* @return void
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
public function rebind($masters, $subs, array $extra = []): void
{
$this->_bind($masters, $subs, $extra, true);
}
/**
* 格式化模型
*
* @param array|Collection $models
* @param string $class
* @return Collection
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
private static function formatModel($models, string $class): Collection
{
if ($models instanceof Collection) {
return $models;
} else if (is_array($models)) {
$Collection = new Collection();
foreach ($models as $model) {
if ($model instanceof $class) {
} else if (is_string($model) || is_numeric($model)) {
$model = $class::find($model);
}
$Collection->push($model);
}
return $Collection;
} else {
throw new ErrorMsg("类型异常", 1);
}
}
/**
* 绑定数据
*
* @param array|Collection $masters
* @param array|Collection $subs
* @param array $extra
* @param boolean $rebind
* @return void
* @date 2022-12-29
* @example
* @author arw
* @since 1.0.0
*/
private function _bind($masters, $subs, array $extra = [], bool $rebind = false)
{
$masters = self::formatModel($masters, $this->masterClass);
$subs = self::formatModel($subs, $this->subClass);
$pivotClass = $this->pivotClass;
$softDelete = $this->softDelete;
$pivotPk = $this->pivotPk;
$masterPk = $this->masterPk;
$subPk = $this->subPk;
foreach ($masters as $master) {
if ($rebind) {
$pivots = $pivotClass::where([
[$masterPk, '=', $master->$masterPk],
[$subPk, 'not in', $subs->column($subPk)],
])->select();
if (!$pivots->isEmpty()) {
// 重新绑定
$this->unbind([$master], $pivots->column($subPk));
}
}
foreach ($subs as $sub) {
$pivot = null;
if ($softDelete) {
$pivot = $pivotClass::withTrashed()->where([
$subPk => $sub->$subPk,
$masterPk => $master->$masterPk
])->find();
} else {
$pivot = $pivotClass::where([
$subPk => $sub->$subPk,
$masterPk => $master->$masterPk
])->find();
}
if (is_null($pivot) || $pivot->isEmpty()) {
$pivotClass::create($extra + [
$subPk => $sub->$subPk,
$masterPk => $master->$masterPk
]);
} else {
if ($softDelete) {
$pivot->restore();
}
if ($extra) {
$pivotClass::update($extra, [
$pivotPk => $pivot->$pivotPk
]);
}
}
}
}
}
}