Skip to content

Commit 558d5f3

Browse files
committed
改进autoMapping的字段条件自动处理
1 parent 463565d commit 558d5f3

File tree

1 file changed

+74
-29
lines changed

1 file changed

+74
-29
lines changed

src/model/View.php

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,56 +50,70 @@ protected function initData()
5050
if ($this->isEmpty()) {
5151
return ;
5252
}
53-
5453
$data = $this->model()->getData();
5554
$properties = $this->getEntityPropertiesMap();
5655
foreach ($properties as $key => $field) {
5756
if (is_int($key)) {
58-
$this->$field = $this->fetchViewAttr($field);
57+
$this->$field = $this->fetchViewAttr($field, $data);
5958
} elseif (strpos($field, '->')) {
60-
$items = explode('->', $field);
61-
$relation = array_shift($items);
62-
if (isset($data[$relation])) {
63-
// 存在关联数据
64-
$value = $this->model()->$relation;
65-
foreach ($items as $item) {
66-
if (is_array($value)) {
67-
$value = $value[$item] ?? null;
68-
} elseif (is_object($value)) {
69-
$value = $value->$item ?? null;
70-
}
71-
}
72-
$this->$key = $value;
73-
}
59+
$this->$key = $this->getRelationMapAttr($field, $data);
7460
} else {
75-
$this->$key = $this->fetchViewAttr($field);
61+
$this->$key = $this->fetchViewAttr($field, $data);
7662
}
7763
}
7864
}
7965

66+
/**
67+
* 获取关联映射的属性值.
68+
*
69+
* @param string $field 视图属性
70+
*
71+
* @return mixed
72+
*/
73+
private function getRelationMapAttr(string $field, array $data)
74+
{
75+
$items = explode('->', $field);
76+
$value = null;
77+
$relation = array_shift($items);
78+
if (isset($data[$relation])) {
79+
// 存在关联数据
80+
$value = $this->model()->$relation;
81+
foreach ($items as $item) {
82+
if (is_array($value)) {
83+
$value = $value[$item] ?? null;
84+
} elseif (is_object($value)) {
85+
$value = $value->$item ?? null;
86+
}
87+
}
88+
}
89+
return $value;
90+
}
91+
8092
/**
8193
* 获取视图属性值(支持视图获取器).
8294
*
8395
* @param string $field 视图属性
8496
*
8597
* @return mixed
8698
*/
87-
private function fetchViewAttr(string $field)
99+
private function fetchViewAttr(string $field, array $data)
88100
{
89101
$method = 'get' . Str::camel($field) . 'Attr';
90102
$model = $this->model();
91103
if (method_exists($this, $method)) {
104+
// 视图获取器
92105
$value = $this->$method($model);
93106
} elseif ($model->hasData($field)) {
107+
// 获取主模型数据(支持获取器)
94108
$value = $model->$field;
95109
} else {
110+
// 获取关联模型数据
111+
$mapping = $this->getOption('viewMapping', []);
96112
$relations = $this->getOption('autoMapping', []);
97113
$value = null;
98114
foreach ($relations as $relation) {
99-
if ($model->$relation?->hasData($field)) {
100-
$value = $model->$relation->$field;
101-
$mapping = $this->getOption('viewMapping', []);
102-
115+
if (isset($data[$relation]) && $model->$relation->hasData($field)) {
116+
$value = $model->$relation->$field;
103117
if (!isset($mapping[$field])) {
104118
$mapping[$field] = $relation . '->' . $field;
105119
$this->setOption('viewMapping', $mapping);
@@ -151,6 +165,35 @@ private function getEntityPropertiesMap(): array
151165
return $properties;
152166
}
153167

168+
/**
169+
* 获取视图模型的完整映射属性(包括解析autoMapping的自动映射)
170+
*
171+
* @return array
172+
*/
173+
protected function getViewMapWithRelation(): array
174+
{
175+
$relations = $this->getOption('autoMapping', []);
176+
$mapping = $this->getOption('viewMapping', []);
177+
array_unshift($relations, $this->model());
178+
$fields = $this->getEntityProperties();
179+
foreach ($fields as $field) {
180+
if (!isset($mapping[$field]) && $relations) {
181+
foreach ($relations as $relation) {
182+
if (is_object($relation)) {
183+
if ($relation->getFieldType($field)) {
184+
break;
185+
}
186+
} elseif ($this->model()->$relation()->getFieldType($field)) {
187+
$mapping[$field] = $relation . '->' . $field;
188+
break;
189+
}
190+
}
191+
}
192+
}
193+
$this->setOption('viewMapping', $mapping);
194+
return $mapping;
195+
}
196+
154197
/**
155198
* 转换为数组. 视图模型不支持 hidden visible append
156199
*
@@ -560,18 +603,20 @@ public function __unserialize(array $data)
560603
public static function __callStatic($method, $args)
561604
{
562605
$entity = new static();
606+
$model = $entity->model();
563607
if (in_array($method, ['destroy', 'saveAll'])) {
564-
// 调用model的静态方法
565-
$db = $entity->model();
608+
$db = $model;
566609
} else {
567-
// 处理字段映射
568-
$map = $entity->getOption('viewMapping', []);
569-
$db = $entity->model()->db()->fieldMap($map);
610+
// 处理映射字段的查询
611+
$map = $entity->getViewMapWithRelation();
612+
$alias = Str::snake(class_basename($model));
613+
$db = $model->db()->alias($alias)->via($alias)->fieldMap($map);
570614
}
571615

572-
if (!in_array(strtolower($method), ['with','withjoin']) && !empty($entity->getOption('autoMapping'))) {
616+
$auto = $entity->getOption('autoMapping');
617+
if (!empty($auto) && !in_array(strtolower($method), ['with','withjoin'])) {
573618
// 自动关联查询
574-
$db->with($entity->getOption('autoMapping'));
619+
$db->with($auto);
575620
}
576621

577622
return call_user_func_array([$db, $method], $args);

0 commit comments

Comments
 (0)