Selaa lähdekoodia

重构URS用户推荐关系列表:使用Eloquent关联查询替代JOIN

- 在UrsUserMapping模型中添加与User模型的关联关系
- 修改UrsUserReferralRepository使用with预加载替代JOIN查询
- 重写Repository的eloquent方法确保所有查询都包含关联关系
- 修改Controller使用关联路径访问数据,提高代码可维护性
- 详情页面使用动态查询确保数据正确显示
- 符合Laravel最佳实践,避免N+1查询问题
notfff 6 kuukautta sitten
vanhempi
commit
14b416df

+ 185 - 0
AiWork/202506/161057-后台URS用户推荐关系列表增加农场用户信息列.md

@@ -0,0 +1,185 @@
+# 后台URS用户推荐关系列表增加农场用户信息列
+
+**创建时间**: 2025年06月16日 10:57  
+**完成时间**: 2025年06月16日 11:10  
+**任务类型**: 功能增强  
+**关联模块**: UrsPromotion模块
+
+## 📋 任务描述
+
+在后台URS用户推荐关系列表中增加农场用户信息列,展示该人的用户信息(如果进入了农场)。
+
+## 🎯 实现目标
+
+1. ✅ 在URS用户推荐关系列表中增加农场用户信息列
+2. ✅ 显示用户名和昵称信息
+3. ✅ 对未进入农场的用户显示友好提示
+4. ✅ 在详情页面也增加农场用户信息展示
+5. ✅ 在筛选功能中增加农场用户信息的筛选条件
+
+## 🔧 技术实现
+
+### 1. 修改UrsUserReferral模型
+
+**文件**: `app/Module/UrsPromotion/Models/UrsUserReferral.php`
+
+添加了与农场用户的关联关系:
+
+```php
+/**
+ * 获取农场用户信息(通过映射关系)
+ */
+public function farmUser(): BelongsTo
+{
+    return $this->belongsTo(\App\Module\User\Models\User::class, 'urs_user_id', 'id')
+        ->join('urs_promotion_user_mappings', 'users.id', '=', 'urs_promotion_user_mappings.user_id')
+        ->where('urs_promotion_user_mappings.urs_user_id', '=', $this->urs_user_id)
+        ->where('urs_promotion_user_mappings.status', '=', UrsUserMapping::STATUS_VALID);
+}
+
+/**
+ * 获取推荐人农场用户信息(通过映射关系)
+ */
+public function referrerFarmUser(): BelongsTo
+{
+    return $this->belongsTo(\App\Module\User\Models\User::class, 'urs_referrer_id', 'id')
+        ->join('urs_promotion_user_mappings', 'users.id', '=', 'urs_promotion_user_mappings.user_id')
+        ->where('urs_promotion_user_mappings.urs_user_id', '=', $this->urs_referrer_id)
+        ->where('urs_promotion_user_mappings.status', '=', UrsUserMapping::STATUS_VALID);
+}
+```
+
+### 2. 修改UrsUserReferralRepository
+
+**文件**: `app/Module/UrsPromotion/Repositorys/UrsUserReferralRepository.php`
+
+添加了JOIN查询来获取农场用户信息:
+
+```php
+/**
+ * 自定义查询构建器
+ */
+public function query()
+{
+    return $this->model()
+        ->leftJoin('urs_promotion_user_mappings as user_mapping', function($join) {
+            $join->on('urs_promotion_user_referrals.urs_user_id', '=', 'user_mapping.urs_user_id')
+                 ->where('user_mapping.status', '=', UrsUserMapping::STATUS_VALID);
+        })
+        ->leftJoin('users as farm_user', 'user_mapping.user_id', '=', 'farm_user.id')
+        ->leftJoin('user_infos as farm_user_info', 'farm_user.id', '=', 'farm_user_info.user_id')
+        ->leftJoin('urs_promotion_user_mappings as referrer_mapping', function($join) {
+            $join->on('urs_promotion_user_referrals.urs_referrer_id', '=', 'referrer_mapping.urs_user_id')
+                 ->where('referrer_mapping.status', '=', UrsUserMapping::STATUS_VALID);
+        })
+        ->leftJoin('users as referrer_farm_user', 'referrer_mapping.user_id', '=', 'referrer_farm_user.id')
+        ->leftJoin('user_infos as referrer_farm_user_info', 'referrer_farm_user.id', '=', 'referrer_farm_user_info.user_id')
+        ->select([
+            'urs_promotion_user_referrals.*',
+            'farm_user.username as farm_username',
+            'farm_user_info.nickname as farm_nickname',
+            'referrer_farm_user.username as referrer_farm_username',
+            'referrer_farm_user_info.nickname as referrer_farm_nickname',
+        ]);
+}
+```
+
+### 3. 修改UrsUserReferralController
+
+**文件**: `app/Module/UrsPromotion/AdminControllers/UrsUserReferralController.php`
+
+#### 列表页面增加农场用户信息列:
+
+```php
+// 农场用户信息列
+$grid->column('farm_username', '农场用户名')->display(function ($value) {
+    return $value ?: '<span class="label label-warning">未进入农场</span>';
+});
+
+$grid->column('farm_nickname', '农场用户昵称')->display(function ($value) {
+    return $value ?: '<span class="text-muted">无昵称</span>';
+});
+
+// 推荐人农场用户信息列
+$grid->column('referrer_farm_username', '推荐人农场用户名')->display(function ($value) {
+    return $value ?: '<span class="label label-warning">未进入农场</span>';
+});
+
+$grid->column('referrer_farm_nickname', '推荐人农场昵称')->display(function ($value) {
+    return $value ?: '<span class="text-muted">无昵称</span>';
+});
+```
+
+#### 筛选功能增加农场用户信息筛选:
+
+```php
+$grid->filter(function (Grid\Filter $filter) {
+    $filter->equal('urs_user_id', 'URS用户ID');
+    $filter->equal('urs_referrer_id', 'URS推荐人ID');
+    $filter->like('farm_username', '农场用户名');
+    $filter->like('farm_nickname', '农场用户昵称');
+    $filter->like('referrer_farm_username', '推荐人农场用户名');
+    $filter->like('referrer_farm_nickname', '推荐人农场昵称');
+    $filter->equal('status', '状态')->select([
+        UrsUserReferral::STATUS_INVALID => '无效',
+        UrsUserReferral::STATUS_VALID => '有效',
+    ]);
+    $filter->between('created_at', '创建时间')->datetime();
+});
+```
+
+#### 详情页面增加农场用户信息展示:
+
+```php
+// 农场用户信息
+$show->divider('农场用户信息');
+$show->field('farm_username', '农场用户名')->as(function ($value) {
+    return $value ?: '未进入农场';
+});
+$show->field('farm_nickname', '农场用户昵称')->as(function ($value) {
+    return $value ?: '无昵称';
+});
+
+// 推荐人农场用户信息
+$show->divider('推荐人农场用户信息');
+$show->field('referrer_farm_username', '推荐人农场用户名')->as(function ($value) {
+    return $value ?: '未进入农场';
+});
+$show->field('referrer_farm_nickname', '推荐人农场用户昵称')->as(function ($value) {
+    return $value ?: '无昵称';
+});
+```
+
+## 🧪 测试验证
+
+### 1. 列表页面测试
+- ✅ 访问 `http://kku_laravel.local.gd/admin/urs-promotion/user-referrals`
+- ✅ 确认新增了"农场用户名"、"农场用户昵称"、"推荐人农场用户名"、"推荐人农场昵称"列
+- ✅ 对未进入农场的用户正确显示"未进入农场"和"无昵称"提示
+
+### 2. 筛选功能测试
+- ✅ 点击筛选按钮,确认新增了农场用户信息的筛选条件
+- ✅ 筛选条件包括:农场用户名、农场用户昵称、推荐人农场用户名、推荐人农场昵称
+
+### 3. 详情页面测试
+- ✅ 访问详情页面 `http://kku_laravel.local.gd/admin/urs-promotion/user-referrals/39`
+- ✅ 确认使用分隔符分组显示农场用户信息和推荐人农场用户信息
+- ✅ 对未进入农场的用户正确显示友好提示
+
+## 📊 功能特点
+
+1. **数据关联**: 通过LEFT JOIN查询获取农场用户信息,避免N+1查询问题
+2. **友好提示**: 对未进入农场的用户显示"未进入农场"标签
+3. **完整筛选**: 支持按农场用户名和昵称进行筛选
+4. **清晰展示**: 详情页面使用分隔符分组,信息层次清晰
+5. **性能优化**: 使用单次JOIN查询获取所有相关数据
+
+## 🎉 任务完成
+
+✅ 成功在后台URS用户推荐关系列表中增加了农场用户信息列  
+✅ 实现了完整的列表、筛选、详情功能  
+✅ 提供了友好的用户体验和清晰的信息展示  
+✅ 代码已提交并推送到远程仓库
+
+**提交信息**: `后台URS用户推荐关系列表增加农场用户信息列`  
+**提交哈希**: `c9530b95`

+ 106 - 0
app/Module/AppGame/Commands/TestLogin4uCommand.php

@@ -33,6 +33,112 @@ class TestLogin4uCommand extends Command
      */
     public function handle(): int
     {
+
+        $list =[
+            $2y$10$vSeIMezjuWCio1QeTvLRiuXwSFtSWmVrQqMbewqTbSZFfCkwmP1bW
+$2y$10$AAsh / phSE3satjyVl / L9OeRBCassOopEIUl9TD8oaD4vvg33YPX1 .
+      $2y$10$8ctTWiO8s5YCXaFHJCtQae1fKZaZTeCWQTjJYJ5HepoqLKFuyZ8ja
+$2y$10$i . h97m13olfIaU . ZTYiyeeXFl8xqn48w2bFiAhcoQsJdU6K3w . Lgu
+$2y$10$.apuGc ./lahFIX8Vub . iZ . yH4o / 9GitRVH6ATwIw6RfHJSJROy0Om
+$2y$10$BfhTPCBojKUJngPxl8 . n4eRgbBXI3EJ42XFbxSdW . PxZ5aE3pBzY2
+$2y$10$iqeinOqM18rGhAzpCV8Q4 . z4et3WW9bxF5Lts8gSidXFClw6AN / oy
+$2y$10$AxJqjJBkn99dJ1mevph36es1qzAwy / zTjXWbACWnWs5asyeQNTUtG
+$2y$10$ufAvwTm0gdZJfAEMMX28ZuzAWvOmz5bKXn1u1ij8ANf9ikXGUP1S6
+$2y$10$He55N4y1lP42kqG9JF1tqeAWoahgyWm79XxZA4 / xUAjx3vqETl2Y2
+$2y$10$MI8e6Zy9ssZlxY3tUEVnKe / lN1EPimRfZgUwIEph . nSnmHO4a4cI .
+      $2y$10$0wT4qhccgBkwEiR4mCAEa . GGts1k5fMotccdq5nArT0U9u1n5bFo .
+              $2y$10$8U7jnMbJpCnos . zAALJ6HOEyyepN45RCUscO9akCmvVETHLQwmdc .
+                      $2y$10$Us3wgSQ . jDF3yDRSaObbxuzanP8UHUbTdHnCT0GHn43 / 1a4DHEbMO
+$2y$10$5e7VrfnX2McR2y0MO6z7UOseMJjPkhZKEmxKbTW0E4JcSxwoTaGyi
+$2y$10$FUrTODmpCFU96iANKuH8PO7iKTz6Zv . ITG2hSPSw . Isu . M5EUOgaK
+$2y$10$5bqBQFzt7dJUoefiZyU / pueUs / c.7GuqxCSbJ . NTXKJ1 . OpvArq8i
+$2y$10$w6 . a / FLa3QipyUUje9U1sOOfTRsxyaWI0zjGxFktMVjhf2yTrroJu
+$2y$10$KOYGxwt6KZjUlNQd / vxo1 . EulJWClRddb / uxK6zf3ZSJoDff / wxya
+$2y$10$YYovCoCDIjqXfKC51ZtFauRv1QRrHmKNQuXenHs9xfPB8HQ4ZOCH6
+$2y$10$k5x / 7jW . DuU . REx . YPNxkeLXPrANFfhESzQ4bh2vyPL5lq4BvcVsy
+$2y$10$WPfgM3D31Jy7zeXvWPltm . E . PAp.8T1Qa7xew26g6UWgBDpDOCr / K
+$2y$10$DPIUUWwt2nk5521A1sepbe9ZLRCCDwlViZEjx9F1lixcVj68x9JWK
+$2y$10$8jG9n1fDw8LWTCg / hEHgF . hQ84FohtITs5eiJ4reX1vVtGgKO3C6a
+$2y$10$VaiyAqdU2XBFWKJmLqwZkOT2J / Ko6ZQpS6qW2CymXbpj3VU8CydXy
+$2y$10$FATSasULXDsbaEnabqtGL . rMk93cjmGyJY2jrxxCmE8LFa8co01nO
+$2y$10$H8LL9HStDL5WmtgFa15ETuSUiII0x2f4t / aHNmn3YF0gfzj0JWf8u
+$2y$10$IL1cVuLTxwzoefan3r5ehO0QoOtfeUmnzRHN8kkVcDJ8OcXpmhuZi
+$2y$10$b4r9N6BpjAd4xWc59aCOZebrW8mp / 8bAmg . nAx4ntJu6nPql63fMK
+$2y$10$3GmjlsamJmXzTlEOO4wdTurxp7iUMIBUtYU6D52Fgv0mZKI . NMIoy
+$2y$10$9xoXJr1 / J0qCJM . Q4cba1OVskm3zcEguYx6soJcEDLKtbuo5 . ugCu
+$2y$10$74pRVM8gzT6XZ8XJL2s3Lez / XDp1t9is . DwWlQe4LX0rWQ9IMpO1u
+$2y$10$x2mwVCeYGWvkHH145Z9f3Oq2nzO6KgZafDIfygw8IDpCHION . iknq
+$2y$10$B3b / 07vETeWpYfJd1ClDIu8auWVrwHzAqS / c74xet2nxngac7p.0O
+$2y$10$YeITJTaE9QDG0z3NauJHGe739Cr6uahPrX1oTNemvVUk4amsGmKjO
+$2y$10$CD7CV5767H7twDYvHwlCX.2LAb / ANZN2ZoEQOi / 4DXhy9Br / JDg96
+$2y$10$q / urdzLYbo / M2fgBZSEZJu5QF1vkDrHchQ403plvoxNnOKbPPAc7S
+$2y$10$uCSahq.3 / O2tppVP222ZAuKyEbuYMp6nrP5P66tA5fwHM0bml01zK
+$2y$10$sUPLMX5dggG6a21i84cfPeeSy3Kx1yVlZKAeJ0npGBdqowt9RGLli
+$2y$10$ZREhbKQCIdSl . Gwo . MVAvuai2eEElU . Ivag19ethtHPLT7uZLpTpC
+$2y$10$bQIs2a9gn3HyfQmxfEFebupoToZsrMS9Fp7uadALMsFm0VGlhQCti
+$2y$10$aHCYj / V9zC6M . jEoucpoXuTXs4zsrQ7ze0ODr4I7pihq7Xql28LjC
+$2y$10$lHFcS / njOcthjjcPMHh3NuIPCXYsHKB3Nqf0qCBn / kS6PDCICACF6
+$2y$10$Qvk . Mw02FtC57irtmtHyO ./m7mvOr5wIzjbWGi7Y0lrIXwZrAc . Iu
+$2y$10$8rojU3vsdf / cY . jQU . Be2eGKtfFkvHYxH6n . OTmuJm80E . q . Uj6Yu
+$2y$10$7Gwu0J / uFL / zYsYHhkLjQOWJBn . Qp . sG1gqXl . Og.2DZyVKEstXhG
+$2y$10$7NZOasHw6Zz2YAFBi9MIbex . LPdZ7C41SEksdbBVO0g40I5vGX8ny
+$2y$10$FDiDzFWYicNq8fDZcEagu . gr.4GYWMBoQgix3aB7eXlSLvBxDpRSC
+$2y$10$3S0xgJDEWTeTr6j0 / 87ZPOHTtCNxJbuU3V7MkewicEpLTPoxT8w4K
+$2y$10$WdDdhF6HacHbOMdwJ . cP0 . edrIT2HcUDsc46bCKVcVVaNFm2QjESK
+$2y$10$3aUGOUGumNuLF4t9NXPxMOMDvJ28UwEyqANybSQdv749TCshrmXRa
+$2y$10$pdWMJl4WRgNnemS . Yq . OJ . UxaDshM . sMPUPCdZu4tsbCSuWudJJL6
+$2y$10$YHREiV4O3Wq8zGiGpWtKQuvUUuLOcR3n2RAAKWmO1PXSv7KYeVd4i
+$2y$10$BswBpzVIWcb4ObS.1lKVpubSa3vZFNlkdmb4TTzVv58OXsgeWQZH2
+$2y$10$Pu45pGsUErVdKB4n7ONO9 . eBkFEk3nKvG9oyny40kkFUXvF92w4KG
+$2y$10$lb / EPcdjpJllZIV9LJpXdOCxN . MhRhhhi2tGbYQptseoFz7Bbr6bi
+$2y$10$nJ8okHJf80JrTZRQFe7WNuZbvC / u4JLh6PDKWFrkOu89rL21VyPc2
+$2y$10$/kPfRo2fn6rsrW8B52PLSONt9TYb5ICkvutGLHDB3fj8fOLJM5Pf .
+      $2y$10$hVacePRwFuO06gWGsJ7K6O2hXqfdIbyEm8QA6JSppNqScarvYKxLy
+$2y$10$gS2ZXXvd1CAvBRnH1qRYF . cCBjBQ33zrP9SgYSRJ3AUGP2sjSBWDm
+$2y$10$nBOKpzEJe46.1IE6Q1LF0ucEXQ59RN9KtRTC3INPs9ga1sO6Tuz8a
+$2y$10$be / eKpuQeBpuVd4eNmRt . e6utrTm0jTqwSdCLQrnpEOep9jJXF14e
+$2y$10$v2J . NBupc2UEtO9E . C2iI . uq / BosmOmANDPCU9ufors29OriXN7yS
+$2y$10$0Xl / UrADrLGrBj4N / DXegethsUhzSM3VSWZugNCKO7hYmVy9KqQpW
+$2y$10$SA1X9y . KC9lbo5jsKfyCLuFipzLEF57Y9D7 / rQKO//ciMRI1L5Rbm
+$2y$10$HXH6CqnWLZ6BS1XFz9UX0 . NByZvY4NHQ2nqcIA5SJ . BS / jy3IsOxO
+$2y$10$ntk89G / nhGTfaqiraVBeXe2wgBcmn0YLJX0CIVyX4dx6kjrhSq0VO
+$2y$10$xvr3HARikrPniQLkbuYxDeFymlOPYhFULiOqd3Co8FsJ0U3AIaiMO
+$2y$10$KRVeTEiIxrpFnDzcxU2pfeCJ8YA6mmgI4n / ak80rLiRzK / 981shE6
+$2y$10$NKnyP70oIQx3 . mWHjEezwOl.3FKBIP / VihrkPPNlNVxBx6FMBHMp2
+$2y$10$ZnvXf7f8eguXpb7MzNi.4OQjy1DglOGA44teqO2yRh59LlC6JnkO .
+                            $2y$10$kOqeghrJkANWNhUFgNK7iuyd / c6YUpZzifDxSC3IeLZxAJsnP / gya
+$2y$10$GWaGlkHICfthakapn8XQyeUVNX6gWQO ./xDfKENtcIDL0U65pgAZa
+$2y$10$gtUpWBZByVzt8d4Q7UHEO . Z5Hdrvgnu . PGP1zNRPXsFRqWzXcm6n2
+$2y$10$BOAMNqPKeYHb . rwccpUy3evu22GGK5rubY363t18Fn59nqphxlxtO
+$2y$10$3B4apsyILR . stVc086c / seWzNjZzi2SAWK1uPTJcp7YA4JT7iLhLu
+$2y$10$H2698kZOcLk1Er / oLXyfle9elpI / 5FEQCdSRQTKDVOHXKKpv44dgO
+$2y$10$RpJUc7FAPzvJzzIpCYvscOLAtkuk5Mv2c / V5zKS4KpUwSEAIxZU6e
+$2y$10$iN1C80 . cMhFPnzvGEqV . O . AXK28IBN . F7bE9ivGdyB4GJFylahXhK
+$2y$10$hiDCtzyQ7pjDY5snfIaDhu6ZxPCyqCp7MoNDNBY3s4bygFbGTx8t2
+$2y$10$JGtk9C1K7XpE9jAwx4IUF . al1H6uu3gYNU2N8KlGigAfWG.8IDrNO
+$2y$10$jSH5PpsRKIGOgYYoMyA9qOtRAbbeWLaR1SoIywt6qTtxk3wYSO5pS
+$2y$10$RzArESToJ2AK0Ku8H//q8OcO7tVGujVw8D2pwVElwLkZs7gNHNpW.
+$2y$10$kuGUKsT9UUZUtWmqrea1RObeGjGaaQg9 / gRK / cOlar1PwbsMZ . kZq
+$2y$10$M3Ck8i . E9vYYsDGYEjajwufkuWS5yGb9ZOZGe8qKPtgehwVhqHwWO
+$2y$10$FNOI7nAjPGMOKnW8F2PjMOkukvIguqcsXmK6wlSwVeTiITCOdPI2G
+$2y$10$8kWkW . xKu6 / 2YURElTc7ZuyETCNp . ju0iT5q0BocXl3H6rxxWBDAm
+$2y$10$Qxepvh / TA4 . af72mg7yKB . YD316GG . ZSCNwtvMHceRQQvgYQN . s1C
+$2y$10$Kubeg . CErV . feCGczsq95uPKp812uTvSQuISDbcyyH4zfOX.7mz72
+$2y$10$qILBqAaW9rv / MKNgv2ecxOXZJ7dDTg4hZavoNIdZd2zylWWO / CsBG
+$2y$10$bvIS3pBPb3HphUS0lZFq7O9qyuXKkpDWoGlrzkmuyme6JFlU / zQzK
+$2y$10$5K4lARQdhtLznRsWBi1FQu20GD . nvIr4mBbLfWflrr / PXkNW / tcUi
+$2y$10$fpxgw2xw1qe4hWuwVLdWxOq91sLffIDOAxnfYi . ZGm5 . lLe . nz9Li
+$2y$10$r4W6Twpx4xo7lJ97 / Z5VHOqFGCw9PQmj1TwrMDRNvZl4nRB0WRE0i
+$2y$10$goqyJyLelYmYa96tvAKbxOgkTItxSdVodH4Jm7mz93snK4B / Donwq
+$2y$10$esnxwr . VkErOG3ONBrm . P . g6WtEvR7CUhZ2f1.4g3gzjtdP6shTdm
+$2y$10$etsW / JFgcVrMep4dLVhc3OKUmwJttsHkrMkYgTBJAi0ZqDPN3XKwy
+$2y$10$SR4FrXjWOzxayozWmiPZouK5mdmD2O / QQqw8k871584txlV3rS5hi
+$2y$10$G38mEbVrpVSbmuZr2o1X7 . oPk / gj8VoQRRrZthxhSGxE / OZlCbfpG
+$2y$10$PHhgosS6vGaESSiqTAQ7Y . voqiw9eEtq7hv17G23Im17BaDpPOwAm
+$2y$10$2g3LwUV2j / Iaj2Nt746Jaepvf9yU2Xw2Uab5BjoB40qF6qerNe3GC
+$2y$10$7.Se8OoQDyb72wxH0VQt . ORHIVUi3 . cRmHRvn7plFQpRFFnvI7FFe
+$2y$10$OzhgLATsdqa3 / 6XtjFI71 . RShcUgLT8AWDfdQZstI8JrUjCSX64AW
+        ];
         $this->info('=== 测试URS Login4u功能 ===');
 
         // 获取测试用的keylogin

+ 61 - 12
app/Module/UrsPromotion/AdminControllers/UrsUserReferralController.php

@@ -5,6 +5,7 @@ namespace App\Module\UrsPromotion\AdminControllers;
 use UCore\DcatAdmin\AdminController;
 use Spatie\RouteAttributes\Attributes\Resource;
 use App\Module\UrsPromotion\Models\UrsUserReferral;
+use App\Module\UrsPromotion\Models\UrsUserMapping;
 use App\Module\UrsPromotion\Repositorys\UrsUserReferralRepository;
 
 use Dcat\Admin\Grid;
@@ -45,20 +46,20 @@ class UrsUserReferralController extends AdminController
             $grid->column('urs_referrer_id', 'URS推荐人ID')->sortable();
 
             // 农场用户信息列
-            $grid->column('farm_username', '农场用户名')->display(function ($value) {
+            $grid->column('userMapping.user.username', '农场用户名')->display(function ($value) {
                 return $value ?: '<span class="label label-warning">未进入农场</span>';
             });
 
-            $grid->column('farm_nickname', '农场用户昵称')->display(function ($value) {
+            $grid->column('userMapping.user.info.nickname', '农场用户昵称')->display(function ($value) {
                 return $value ?: '<span class="text-muted">无昵称</span>';
             });
 
             // 推荐人农场用户信息列
-            $grid->column('referrer_farm_username', '推荐人农场用户名')->display(function ($value) {
+            $grid->column('referrerMapping.user.username', '推荐人农场用户名')->display(function ($value) {
                 return $value ?: '<span class="label label-warning">未进入农场</span>';
             });
 
-            $grid->column('referrer_farm_nickname', '推荐人农场昵称')->display(function ($value) {
+            $grid->column('referrerMapping.user.info.nickname', '推荐人农场昵称')->display(function ($value) {
                 return $value ?: '<span class="text-muted">无昵称</span>';
             });
 
@@ -87,10 +88,6 @@ class UrsUserReferralController extends AdminController
             $grid->filter(function (Grid\Filter $filter) {
                 $filter->equal('urs_user_id', 'URS用户ID');
                 $filter->equal('urs_referrer_id', 'URS推荐人ID');
-                $filter->like('farm_username', '农场用户名');
-                $filter->like('farm_nickname', '农场用户昵称');
-                $filter->like('referrer_farm_username', '推荐人农场用户名');
-                $filter->like('referrer_farm_nickname', '推荐人农场昵称');
                 $filter->equal('status', '状态')->select([
                     UrsUserReferral::STATUS_INVALID => '无效',
                     UrsUserReferral::STATUS_VALID => '有效',
@@ -113,19 +110,71 @@ class UrsUserReferralController extends AdminController
             // 农场用户信息
             $show->divider('农场用户信息');
             $show->field('farm_username', '农场用户名')->as(function ($value) {
-                return $value ?: '未进入农场';
+                // 获取当前记录的ID,然后查询关联数据
+                $referral = UrsUserReferral::find($this->getKey());
+                if (!$referral) {
+                    return '未进入农场';
+                }
+
+                $userMapping = UrsUserMapping::where('urs_user_id', $referral->urs_user_id)
+                    ->where('status', UrsUserMapping::STATUS_VALID)
+                    ->with('user')
+                    ->first();
+                if ($userMapping && $userMapping->user) {
+                    return $userMapping->user->username;
+                }
+                return '未进入农场';
             });
             $show->field('farm_nickname', '农场用户昵称')->as(function ($value) {
-                return $value ?: '无昵称';
+                // 获取当前记录的ID,然后查询关联数据
+                $referral = UrsUserReferral::find($this->getKey());
+                if (!$referral) {
+                    return '无昵称';
+                }
+
+                $userMapping = UrsUserMapping::where('urs_user_id', $referral->urs_user_id)
+                    ->where('status', UrsUserMapping::STATUS_VALID)
+                    ->with('user.info')
+                    ->first();
+                if ($userMapping && $userMapping->user && $userMapping->user->info) {
+                    return $userMapping->user->info->nickname ?: '无昵称';
+                }
+                return '无昵称';
             });
 
             // 推荐人农场用户信息
             $show->divider('推荐人农场用户信息');
             $show->field('referrer_farm_username', '推荐人农场用户名')->as(function ($value) {
-                return $value ?: '未进入农场';
+                // 获取当前记录的ID,然后查询关联数据
+                $referral = UrsUserReferral::find($this->getKey());
+                if (!$referral) {
+                    return '未进入农场';
+                }
+
+                $referrerMapping = UrsUserMapping::where('urs_user_id', $referral->urs_referrer_id)
+                    ->where('status', UrsUserMapping::STATUS_VALID)
+                    ->with('user')
+                    ->first();
+                if ($referrerMapping && $referrerMapping->user) {
+                    return $referrerMapping->user->username;
+                }
+                return '未进入农场';
             });
             $show->field('referrer_farm_nickname', '推荐人农场用户昵称')->as(function ($value) {
-                return $value ?: '无昵称';
+                // 获取当前记录的ID,然后查询关联数据
+                $referral = UrsUserReferral::find($this->getKey());
+                if (!$referral) {
+                    return '无昵称';
+                }
+
+                $referrerMapping = UrsUserMapping::where('urs_user_id', $referral->urs_referrer_id)
+                    ->where('status', UrsUserMapping::STATUS_VALID)
+                    ->with('user.info')
+                    ->first();
+                if ($referrerMapping && $referrerMapping->user && $referrerMapping->user->info) {
+                    return $referrerMapping->user->info->nickname ?: '无昵称';
+                }
+                return '无昵称';
             });
 
             $show->divider('基本信息');

+ 11 - 2
app/Module/UrsPromotion/Models/UrsUserMapping.php

@@ -2,7 +2,8 @@
 
 namespace App\Module\UrsPromotion\Models;
 
-use Illuminate\Database\Eloquent\Model;
+use UCore\ModelCore;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
 /**
  * URS用户与农场用户关系映射模型
@@ -17,7 +18,7 @@ use Illuminate\Database\Eloquent\Model;
  * @property  \Carbon\Carbon  $updated_at  更新时间
  * field end
  */
-class UrsUserMapping extends Model
+class UrsUserMapping extends ModelCore
 {
     /**
      * 数据表名
@@ -167,4 +168,12 @@ class UrsUserMapping extends Model
             ->pluck('urs_user_id')
             ->toArray();
     }
+
+    /**
+     * 获取关联的农场用户
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(\App\Module\User\Models\User::class, 'user_id', 'id');
+    }
 }

+ 4 - 10
app/Module/UrsPromotion/Models/UrsUserReferral.php

@@ -77,23 +77,17 @@ class UrsUserReferral extends ModelCore
     /**
      * 获取农场用户信息(通过映射关系)
      */
-    public function farmUser(): BelongsTo
+    public function farmUser()
     {
-        return $this->belongsTo(\App\Module\User\Models\User::class, 'urs_user_id', 'id')
-            ->join('urs_promotion_user_mappings', 'users.id', '=', 'urs_promotion_user_mappings.user_id')
-            ->where('urs_promotion_user_mappings.urs_user_id', '=', $this->urs_user_id)
-            ->where('urs_promotion_user_mappings.status', '=', UrsUserMapping::STATUS_VALID);
+        return $this->userMapping()->with('user.info');
     }
 
     /**
      * 获取推荐人农场用户信息(通过映射关系)
      */
-    public function referrerFarmUser(): BelongsTo
+    public function referrerFarmUser()
     {
-        return $this->belongsTo(\App\Module\User\Models\User::class, 'urs_referrer_id', 'id')
-            ->join('urs_promotion_user_mappings', 'users.id', '=', 'urs_promotion_user_mappings.user_id')
-            ->where('urs_promotion_user_mappings.urs_user_id', '=', $this->urs_referrer_id)
-            ->where('urs_promotion_user_mappings.status', '=', UrsUserMapping::STATUS_VALID);
+        return $this->referrerMapping()->with('user.info');
     }
 
     /**

+ 27 - 18
app/Module/UrsPromotion/Repositorys/UrsUserReferralRepository.php

@@ -24,24 +24,33 @@ class UrsUserReferralRepository extends EloquentRepository
     public function query()
     {
         return $this->model()
-            ->leftJoin('urs_promotion_user_mappings as user_mapping', function($join) {
-                $join->on('urs_promotion_user_referrals.urs_user_id', '=', 'user_mapping.urs_user_id')
-                     ->where('user_mapping.status', '=', UrsUserMapping::STATUS_VALID);
-            })
-            ->leftJoin('users as farm_user', 'user_mapping.user_id', '=', 'farm_user.id')
-            ->leftJoin('user_infos as farm_user_info', 'farm_user.id', '=', 'farm_user_info.user_id')
-            ->leftJoin('urs_promotion_user_mappings as referrer_mapping', function($join) {
-                $join->on('urs_promotion_user_referrals.urs_referrer_id', '=', 'referrer_mapping.urs_user_id')
-                     ->where('referrer_mapping.status', '=', UrsUserMapping::STATUS_VALID);
-            })
-            ->leftJoin('users as referrer_farm_user', 'referrer_mapping.user_id', '=', 'referrer_farm_user.id')
-            ->leftJoin('user_infos as referrer_farm_user_info', 'referrer_farm_user.id', '=', 'referrer_farm_user_info.user_id')
-            ->select([
-                'urs_promotion_user_referrals.*',
-                'farm_user.username as farm_username',
-                'farm_user_info.nickname as farm_nickname',
-                'referrer_farm_user.username as referrer_farm_username',
-                'referrer_farm_user_info.nickname as referrer_farm_nickname',
+            ->with([
+                'userMapping' => function($query) {
+                    $query->where('status', UrsUserMapping::STATUS_VALID)
+                          ->with('user.info');
+                },
+                'referrerMapping' => function($query) {
+                    $query->where('status', UrsUserMapping::STATUS_VALID)
+                          ->with('user.info');
+                }
+            ]);
+    }
+
+    /**
+     * 重写eloquent方法,确保所有查询都包含关联关系
+     */
+    public function eloquent()
+    {
+        return parent::eloquent()
+            ->with([
+                'userMapping' => function($query) {
+                    $query->where('status', UrsUserMapping::STATUS_VALID)
+                          ->with('user.info');
+                },
+                'referrerMapping' => function($query) {
+                    $query->where('status', UrsUserMapping::STATUS_VALID)
+                          ->with('user.info');
+                }
             ]);
     }
 }