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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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;
}
}