@@ -50,56 +50,70 @@ protected function initData()
50
50
if ($ this ->isEmpty ()) {
51
51
return ;
52
52
}
53
-
54
53
$ data = $ this ->model ()->getData ();
55
54
$ properties = $ this ->getEntityPropertiesMap ();
56
55
foreach ($ properties as $ key => $ field ) {
57
56
if (is_int ($ key )) {
58
- $ this ->$ field = $ this ->fetchViewAttr ($ field );
57
+ $ this ->$ field = $ this ->fetchViewAttr ($ field, $ data );
59
58
} 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 );
74
60
} else {
75
- $ this ->$ key = $ this ->fetchViewAttr ($ field );
61
+ $ this ->$ key = $ this ->fetchViewAttr ($ field, $ data );
76
62
}
77
63
}
78
64
}
79
65
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
+
80
92
/**
81
93
* 获取视图属性值(支持视图获取器).
82
94
*
83
95
* @param string $field 视图属性
84
96
*
85
97
* @return mixed
86
98
*/
87
- private function fetchViewAttr (string $ field )
99
+ private function fetchViewAttr (string $ field, array $ data )
88
100
{
89
101
$ method = 'get ' . Str::camel ($ field ) . 'Attr ' ;
90
102
$ model = $ this ->model ();
91
103
if (method_exists ($ this , $ method )) {
104
+ // 视图获取器
92
105
$ value = $ this ->$ method ($ model );
93
106
} elseif ($ model ->hasData ($ field )) {
107
+ // 获取主模型数据(支持获取器)
94
108
$ value = $ model ->$ field ;
95
109
} else {
110
+ // 获取关联模型数据
111
+ $ mapping = $ this ->getOption ('viewMapping ' , []);
96
112
$ relations = $ this ->getOption ('autoMapping ' , []);
97
113
$ value = null ;
98
114
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 ;
103
117
if (!isset ($ mapping [$ field ])) {
104
118
$ mapping [$ field ] = $ relation . '-> ' . $ field ;
105
119
$ this ->setOption ('viewMapping ' , $ mapping );
@@ -151,6 +165,35 @@ private function getEntityPropertiesMap(): array
151
165
return $ properties ;
152
166
}
153
167
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
+
154
197
/**
155
198
* 转换为数组. 视图模型不支持 hidden visible append
156
199
*
@@ -560,18 +603,20 @@ public function __unserialize(array $data)
560
603
public static function __callStatic ($ method , $ args )
561
604
{
562
605
$ entity = new static ();
606
+ $ model = $ entity ->model ();
563
607
if (in_array ($ method , ['destroy ' , 'saveAll ' ])) {
564
- // 调用model的静态方法
565
- $ db = $ entity ->model ();
608
+ $ db = $ model ;
566
609
} 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 );
570
614
}
571
615
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 ' ])) {
573
618
// 自动关联查询
574
- $ db ->with ($ entity -> getOption ( ' autoMapping ' ) );
619
+ $ db ->with ($ auto );
575
620
}
576
621
577
622
return call_user_func_array ([$ db , $ method ], $ args );
0 commit comments