@@ -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