cqp il y a 3 semaines
Parent
commit
51c896d49f
3 fichiers modifiés avec 210 ajouts et 2 suppressions
  1. 1 1
      app/Model/Customer.php
  2. 124 0
      app/Model/UseScopeBaseNewModel.php
  3. 85 1
      app/Service/RangeService.php

+ 1 - 1
app/Model/Customer.php

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

+ 124 - 0
app/Model/UseScopeBaseNewModel.php

@@ -0,0 +1,124 @@
+<?php
+
+namespace App\Model;
+
+use App\Service\RangeService;
+use Illuminate\Database\Eloquent\Model;
+
+class UseScopeBaseNewModel extends Model
+{
+    const range_function = '';
+    const is_check_function = '';
+
+    public function scopeClear($query, $user, $search)
+    {
+        $is_all_depart = $user['is_all_depart'] ?? 0;
+        $depart_range = $user['depart_range'] ?? [];
+        $is_see = ! empty($search['is_see']);
+        $is_check = ! empty($search['is_check']);
+        $auth_type = $this->getQx($search, $user);
+
+        $model = $query->getModel();
+        $className = get_class($model);
+
+        // 1. 获取可见范围子查询 (不再是数组)
+        $range_function = "";
+        if (defined($className . '::range_function')) $range_function = $className::range_function;
+        $idSubQuery = null;
+        if ($range_function && $this->hasMethod(new RangeService(), $range_function)) {
+            $idSubQuery = RangeService::$range_function($user, $search);
+        }
+
+        // 2. 确定顶级部门 ID
+        $search_depart_id = $search['top_depart_id'] ?? 0;
+        $my_top_depart_id = $user['depart_top'][0]['depart_id'] ?? 0;
+        $top_depart_id = ($is_all_depart && !empty($search_depart_id)) ? $search_depart_id : $my_top_depart_id;
+
+        // 3. 审核状态过滤 (whereRaw)
+        $check_search = "";
+        $is_check_function = defined($className . '::is_check_function') ? $className::is_check_function : "";
+        if ($is_check && $is_check_function && $this->hasMethod(new RangeService(), $is_check_function)) {
+            $check_search = RangeService::$is_check_function($user, $search);
+        }
+
+        // 4. 执行路由过滤
+        if ($is_see) {
+            $query->whereIn('id', $idSubQuery);
+        } elseif ($is_all_depart) {
+            $this->allDepart($query, $is_check, $auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $idSubQuery, $check_search);
+        } else {
+            $this->notAllDepart($query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $idSubQuery, $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, $idSubQuery, $check_search)
+    {
+        $query->where(function ($q) use ($auth_type, $user, $depart_range, $search_depart_id, $top_depart_id, $idSubQuery) {
+            $q->where(function ($inner) use ($auth_type, $user, $depart_range, $search_depart_id, $top_depart_id) {
+                // 如果指定了 top_depart_id,则必须满足该条件
+                if (!empty($search_depart_id)) {
+                    $inner->where('top_depart_id', $top_depart_id);
+                }
+
+                // 基础权限过滤
+                if ($auth_type == 1) {
+                    $inner->where('crt_id', $user['id']);
+                } elseif ($auth_type == 2 || $auth_type == 3) {
+                    $inner->whereIn('depart_id', $depart_range);
+                }
+            });
+
+            // 加上可见范围 (OR 关系)
+            if ($idSubQuery) {
+                $q->orWhereIn('id', $idSubQuery);
+            }
+        });
+
+        if ($is_check && !empty($check_search)) {
+            $query->whereRaw($check_search);
+        }
+    }
+
+    private function notAllDepart(&$query, $is_check, $auth_type, $user, $depart_range, $top_depart_id, $idSubQuery, $check_search)
+    {
+        $query->where(function ($q) use ($auth_type, $user, $depart_range, $top_depart_id, $idSubQuery) {
+            $q->where(function ($inner) use ($auth_type, $user, $depart_range, $top_depart_id) {
+                // 非全权限模式下,top_depart_id 是强制的
+                $inner->where('top_depart_id', $top_depart_id);
+
+                if ($auth_type == 1) {
+                    $inner->where('crt_id', $user['id']);
+                } elseif ($auth_type == 2) {
+                    $inner->whereIn('depart_id', $depart_range);
+                }
+                // auth_type 为 0 或 3 时,仅保留 top_depart_id 过滤
+            });
+
+            if ($idSubQuery) {
+                $q->orWhereIn('id', $idSubQuery);
+            }
+        });
+
+        if ($is_check && !empty($check_search)) {
+            $query->whereRaw($check_search);
+        }
+    }
+
+    public function getQx($data, $user)
+    {
+        if (empty($data['menu_id'])) return 0;
+        // 假设 Employee 常量在此可用,若不可用请自行调整
+        if ($user['id'] == 1) return 0; // 这里的1代表超级管理员ID
+        return $user['role_authority'][$data['menu_id']] ?? 0;
+    }
+
+    function hasMethod($class, $methodName)
+    {
+        if (empty($methodName)) return false;
+        return method_exists($class, $methodName);
+    }
+}

+ 85 - 1
app/Service/RangeService.php

@@ -154,8 +154,92 @@ class RangeService extends Service
         return array_unique(array_column($data_id,'data_id'));
     }
 
+    // 修改为返回 Query 对象
+    public static function getRangeDataQuery($user, $data_type) {
+        $user_id = $user['id'];
+        $depart_ids = $user['depart_range'] ?? [];
+
+        return SeeRange::where('del_time', 0)
+            ->where('data_type', $data_type)
+            ->where(function ($query) use ($user_id, $depart_ids) {
+                $query->where(function($q) use ($user_id) {
+                    $q->where('param_id', $user_id)->where('type', SeeRange::data_two);
+                })->orWhere(function($q) use ($depart_ids) {
+                    $q->whereIn('param_id', $depart_ids)
+                        ->whereIn('type', [SeeRange::data_one, SeeRange::data_three]);
+                });
+            })
+            ->select('data_id');
+    }
+
+    //新的返回query
+    public static function customerRange($user, $search) {
+        // 1. 负责/协同人的子查询 (基础查询)
+        $infoQuery = CustomerInfo::where('del_time', 0)
+            ->where('data_id', $user['id'])
+            ->whereIn('type', CustomerInfo::$see_man)
+            ->select('customer_id as id');
+
+        // 2. 可见范围的子查询
+        $rangeQuery = self::getRangeDataQuery($user, SeeRange::type_one)
+            ->select('data_id as id');
+
+        // 3. 使用 union 合并两者 (数据库层面去重)
+        $combinedQuery = $infoQuery->union($rangeQuery);
+
+        // 如果有顶级部门限制
+        if (!empty($search['top_depart_id']) && !empty($user['is_all_depart'])) {
+            // 将 union 后的结果作为一个临时子表进行过滤
+            // 注意:这里用了一个技巧,将 combinedQuery 包装进一个 whereIn 子查询
+            return Customer::whereIn('id', function($q) use ($combinedQuery) {
+                $q->from(DB::raw("({$combinedQuery->toSql()}) as temp_range"))
+                    ->mergeBindings($combinedQuery->getQuery())
+                    ->select('id');
+            })
+                ->where('top_depart_id', $search['top_depart_id'])
+                ->where('del_time', 0)
+                ->select('id');
+        }
+
+        return $combinedQuery;
+    }
+
+    //新的返回数量
+    public static function customerRange1($user, $search) {
+        // 1. 负责/协同人的子查询
+        $infoQuery = CustomerInfo::where('del_time', 0)
+            ->where('data_id', $user['id'])
+            ->whereIn('type', CustomerInfo::$see_man)
+            ->select('customer_id as id');
+
+        // 2. 可见范围的子查询
+        $rangeQuery = self::getRangeDataQuery($user, SeeRange::type_one)
+            ->select('data_id as id');
+
+        // 3. 合并两个子查询逻辑 (UNION 自动去重)
+        $combinedQuery = $infoQuery->union($rangeQuery);
+
+        // 如果有顶级部门限制,直接在子查询外面再套一层过滤
+        // 注意:这里返回的是一个 Eloquent 查询构造器,而不是数组!
+        $finalQuery = DB::table(DB::raw("({$combinedQuery->toSql()}) as sub"))
+            ->mergeBindings($combinedQuery->getQuery());
+
+        if (!empty($search['top_depart_id']) && !empty($user['is_all_depart'])) {
+            // 直接关联 customer 表校验 top_depart_id,避免循环 chunk 查询
+            return Customer::whereIn('id', function($q) use ($finalQuery) {
+                $q->from(DB::raw("({$finalQuery->toSql()}) as temp"))
+                    ->mergeBindings($finalQuery);
+            })->where('top_depart_id', $search['top_depart_id'])
+                ->where('del_time', 0)
+                ->pluck('id') // 如果后续逻辑必须用数组,这里才 pluck。如果能用子查询,建议保持为 Query。
+                ->toArray();
+        }
+
+        return $finalQuery->pluck('id')->toArray();
+    }
+
     //获取客户可见数据
-    public static function customerRange($user,$search){
+    public static function customerRange2($user,$search){
         // 销售人员/负责人 3协同人  可以看见
         $customer_id = CustomerInfo::where('del_time',0)
            ->where('data_id',$user['id'])