You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.8 KiB

6 months ago
<?php
namespace App\Models;
use App\Exceptions\ErrorException;
use Illuminate\Support\Facades\Cache;
class BaseForm extends SoftDeletesModel
{
public $tableName = null;
public $customForm = null;
protected $casts = [];
protected $appends = [];
public function __construct()
{
parent::__construct();
// 初始化动态模型
$this->init();
}
/**
* 初始化模型
*/
public function init()
{
// 检测表名是否存在
$tableName = request('table_name');
if (empty($tableName)) {
throw new ErrorException('表名不存在');
}
$customFormModel = new CustomForm();
// 判断是否存在实体表
if (!$customFormModel->hasRealTable($tableName)) {
throw new ErrorException("不存在{$tableName}实体表");
}
$this->tableName = $tableName;
// 检测表是否在自定义表单中
$this->customForm = $customFormModel->hasTable($tableName);
// 设置表
$this->setTable($tableName);
// 设置关联关系
$this->relation();
// 设置json转数组字段
$this->casts = $this->jsonToArray();
}
/**
* 创建人关联
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function admin()
{
return $this->hasOne(Admin::class, 'id', 'admin_id');
}
/**
* 关联创建部门
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function department()
{
return $this->hasOne(Department::class, 'id', 'department_id');
}
/**
* 获取所有关联关系字段
* $raw=true返回原始设置false输出关联关系名字
*/
public function allRelationFields($raw = false, $showParameter = true)
{
$customFormRelation = CustomFormRelation::where('custom_form_id', $this->customForm->id)
->where(function ($query) use ($showParameter) {
$query->whereNotNull('link_table_name')->whereNotNull('link_relation');
if ($showParameter) {
$query->orWhere(function ($query) {
$query->whereNotNull('parameter_id');
});
}
})->whereNotNull('local_key')->whereNotNull('foreign_key')->whereNotNull('link_with_name')->get();
// 输出原始数据
if ($raw) return $customFormRelation;
$customFormRelation = $customFormRelation->pluck('link_with_name')->toArray();
$baseRelation = ['admin', 'department'];
return array_merge($baseRelation, $customFormRelation);
}
/**
* json字段转数组
*/
public function jsonToArray()
{
$casts = [];
$rowTableFieldsByType = (new CustomFormField)->getRowTableFieldsByType($this->tableName);
foreach ($rowTableFieldsByType as $key => $item) {
if ($item == 'json') $casts = array_merge($casts, [$key => 'json']);
}
return $casts;
}
/**
* 构建关联关系
*/
public function relation()
{
if (empty($this->customForm)) return true;
$customFormRelations = Cache::remember('custom_form_relations' . $this->customForm->id, CustomForm::$cache_ttl, function () {
return CustomFormRelation::where('custom_form_id', $this->customForm->id)->get();
});
foreach ($customFormRelations as $item) {
if (!isset($item->foreign_key) || !isset($item->local_key) || !isset($item->link_with_name) || !isset($item->link_table_name)) {
continue;
}
if (isset($item->parameter_id)) {
// 数据字典关联
self::resolveRelationUsing($item->link_with_name, function ($fromModel) use ($item) {
return $fromModel->hasOne(ParameterDetail::class, $item->foreign_key, $item->local_key);
});
}
// 关联其他表数据
if (isset($item->link_table_name) && isset($item->link_relation)) {
// 判断是否存在实体表
if (!$this->customForm->hasRealTable($item->link_table_name)) {
throw new ErrorException("不存在{$item->link_table_name}实体表");
}
self::resolveRelationUsing($item->link_with_name, function ($fromModel) use ($item) {
$relatedModel = (new RelatedModel())->setTable($item->link_table_name)->newQuery();
if ($item->link_table_name == 'uploads') {
$relatedModel = (new Upload())->newQuery();
}
return $fromModel->{$item->link_relation}($relatedModel, $this, $item->foreign_key, $item->local_key);
});
}
}
return true;
}
}