Pārlūkot izejas kodu

修改增加客户的关系

cqp 3 mēneši atpakaļ
vecāks
revīzija
42b09429d1

+ 1 - 1
app/Model/Customer.php

@@ -2,7 +2,7 @@
 
 namespace App\Model;
 
-class Customer extends UseScopeBaseNewModel
+class Customer extends UseScopeBaseNewVSonSearchModel
 {
     protected $table = "customer"; //指定表
     const CREATED_AT = 'crt_time';

+ 25 - 27
app/Model/UseScopeBaseNewVModel.php → app/Model/UseScopeBaseNewVSonSearchModel.php

@@ -4,9 +4,8 @@ namespace App\Model;
 
 use App\Service\RangeService;
 use Illuminate\Database\Eloquent\Model;
-use Illuminate\Support\Facades\DB;
 
-class UseScopeBaseNewVModel extends Model
+class UseScopeBaseNewVSonSearchModel extends Model
 {
     const range_function = '';
     const is_check_function = '';
@@ -22,12 +21,12 @@ class UseScopeBaseNewVModel extends Model
         $model = $query->getModel();
         $className = get_class($model);
 
-        // 可见范围方法
+        // 可见范围方法判断
         $range_function = "";
         if (defined($className . '::range_function')) $range_function = $className::range_function;
         $function_range_bool = $this->hasMethod(new RangeService(), $range_function);
 
-        // 状态过滤方法
+        // 状态过滤方法判断
         $is_check_function = "";
         if (defined($className . '::is_check_function')) $is_check_function = $className::is_check_function;
         $is_check_function_bool = $this->hasMethod(new RangeService(), $is_check_function);
@@ -41,10 +40,10 @@ class UseScopeBaseNewVModel extends Model
             $top_depart_id = $is_all_depart ? $search_depart_id : $my_top_depart_id;
         }
 
-        // $id 现在是 Query Builder 对象(子查询)
-        $id = null;
+        // 注入 EXISTS 条件闭包 (EXISTS 不需要外层 distinct)
+        $idCondition = null;
         if($function_range_bool) {
-            $id = RangeService::customerRange2($user, $search);
+            $idCondition = RangeService::attachRangeJoin($query, $user, $search);
         }
 
         $check_search = "";
@@ -53,18 +52,17 @@ class UseScopeBaseNewVModel extends Model
         }
 
         if($is_see){
-            // 直接使用子查询
-            $query->whereIn('id', $id);
+            $query->where($idCondition);
         }elseif($is_all_depart){
-            $this->allDepart($query, $is_check, $auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $id, $check_search);
+            $this->allDepart($query, $is_check, $auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $idCondition, $check_search);
         }else{
-            $this->notAllDepart($query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $id, $check_search);
+            $this->notAllDepart($query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $idCondition, $check_search);
         }
 
         if(! empty($search['get_my_top_depart_data'])) $query->where('top_depart_id', $my_top_depart_id);
     }
 
-    private function allDepart(&$query, $is_check, $auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $id, $check_search)
+    private function allDepart(&$query, $is_check, $auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $idCondition, $check_search)
     {
         if(empty($search_depart_id)){
             if ($is_check){
@@ -77,8 +75,8 @@ class UseScopeBaseNewVModel extends Model
                         ->when(! empty($check_search), function ($query) use ($check_search) {
                             return $query->whereRaw($check_search);
                         })
-                        ->when($id, function ($query) use ($id) { // 这里 $id 是对象
-                            return $query->orWhereIn('id', $id);
+                        ->when($idCondition, function ($query) use ($idCondition) {
+                            return $query->orWhere($idCondition);
                         });
                 }elseif ($auth_type == 2 || $auth_type == 3){
                     $query->whereIn('depart_id', $depart_range)
@@ -89,8 +87,8 @@ class UseScopeBaseNewVModel extends Model
             }else{
                 if($auth_type == 1) {
                     $query->where('crt_id', $user['id'])
-                        ->when($id, function ($query) use ($id) {
-                            return $query->orWhereIn('id', $id);
+                        ->when($idCondition, function ($query) use ($idCondition) {
+                            return $query->orWhere($idCondition);
                         });
                 }elseif ($auth_type == 2 || $auth_type == 3){
                     $query->whereIn('depart_id', $depart_range);
@@ -108,19 +106,19 @@ class UseScopeBaseNewVModel extends Model
 
             if($auth_type == 1) {
                 $query->where('crt_id', $user['id'])
-                    ->when($id, function ($query) use ($id) {
-                        return $query->orWhereIn('id', $id);
+                    ->when($idCondition, function ($query) use ($idCondition) {
+                        return $query->orWhere($idCondition);
                     });
             }elseif ($auth_type == 2 || $auth_type == 3){
                 $query->whereIn('depart_id', $depart_range)
-                    ->when($id, function ($query) use ($id) {
-                        return $query->orWhereIn('id', $id);
+                    ->when($idCondition, function ($query) use ($idCondition) {
+                        return $query->orWhere($idCondition);
                     });
             }
         }
     }
 
-    private function notAllDepart(&$query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $id, $check_search)
+    private function notAllDepart(&$query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $idCondition, $check_search)
     {
         $query->where('top_depart_id', $top_depart_id);
 
@@ -131,18 +129,18 @@ class UseScopeBaseNewVModel extends Model
         }
 
         if(! $auth_type || $auth_type == 3){
-            $query->when($id, function ($query) use ($id) {
-                return $query->orWhereIn('id', $id);
+            $query->when($idCondition, function ($query) use ($idCondition) {
+                return $query->orWhere($idCondition);
             });
         }else if($auth_type == 1) {
             $query->where('crt_id', $user['id'])
-                ->when($id, function ($query) use ($id) {
-                    return $query->orWhereIn('id', $id);
+                ->when($idCondition, function ($query) use ($idCondition) {
+                    return $query->orWhere($idCondition);
                 });
         }elseif ($auth_type == 2) {
             $query->whereIn('depart_id', $depart_range)
-                ->when($id, function ($query) use ($id) {
-                    return $query->orWhereIn('id', $id);
+                ->when($idCondition, function ($query) use ($idCondition) {
+                    return $query->orWhere($idCondition);
                 });
         }
     }

+ 69 - 0
app/Service/RangeService.php

@@ -248,6 +248,75 @@ class RangeService extends Service
         return $query->distinct();
     }
 
+    public static function attachRangeJoin2($query, $user, $search)
+    {
+        $userId = $user['id'];
+        $departIds = $user['depart_range'] ?? [];
+        $searchTopDepartId = $search['top_depart_id'] ?? 0;
+
+        // 1. 构建去重的权限子查询
+        $subQuery = DB::table('customer_access_flat as caf')
+            ->select('caf.customer_id')
+            ->where(function ($q) use ($userId, $departIds) {
+                $q->where(function ($q1) use ($userId) {
+                    $q1->where('caf.target_id', $userId)->where('caf.type', 1);
+                });
+                if (!empty($departIds)) {
+                    $q->orWhere(function ($q2) use ($departIds) {
+                        $q2->whereIn('caf.target_id', $departIds)->whereIn('caf.type', [2, 3]);
+                    });
+                }
+            });
+
+        if (!empty($searchTopDepartId) && !empty($user['is_all_depart'])) {
+            $subQuery->where('caf.top_depart_id', $searchTopDepartId);
+        }
+
+        $subQuery->distinct(); // 确保 ID 唯一,防止主表数据翻倍
+
+        // 2. 挂载 JoinSub
+        $query->leftJoinSub($subQuery, 'authorized', function ($join) {
+            $join->on('customer.id', '=', 'authorized.customer_id');
+        });
+
+        // 3. 返回条件闭包
+        return function ($q) {
+            $q->whereNotNull('authorized.customer_id');
+        };
+    }
+
+    public static function attachRangeJoin($query, $user, $search)
+    {
+        $userId = $user['id'];
+        $departIds = $user['depart_range'] ?? [];
+        $searchTopDepartId = $search['top_depart_id'] ?? 0;
+
+        // 返回一个闭包,利用 whereExists 替代 Join
+        // 这样主表的字段如 id, top_depart_id 就不需要加前缀了
+        return function ($q) use ($userId, $departIds, $searchTopDepartId, $user) {
+            $q->whereExists(function ($sub) use ($userId, $departIds, $searchTopDepartId, $user) {
+                $sub->select(DB::raw(1))
+                    ->from('customer_access_flat as caf')
+                    // 关键点:将子查询关联到主表 id
+                    ->whereRaw('caf.customer_id = customer.id')
+                    ->where(function ($inner) use ($userId, $departIds) {
+                        $inner->where(function ($q1) use ($userId) {
+                            $q1->where('caf.target_id', $userId)->where('caf.type', 1);
+                        });
+                        if (!empty($departIds)) {
+                            $inner->orWhere(function ($q2) use ($departIds) {
+                                $q2->whereIn('caf.target_id', $departIds)->whereIn('caf.type', [2, 3]);
+                            });
+                        }
+                    });
+
+                if (!empty($searchTopDepartId) && !empty($user['is_all_depart'])) {
+                    $sub->where('caf.top_depart_id', $searchTopDepartId);
+                }
+            });
+        };
+    }
+
     //获取施工单可见数据
     public static function constructionRange($user,$search){
         //单据中选择的签订负责协同人