DataScopeBaseModel.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. namespace App\Model;
  3. use Illuminate\Database\Eloquent\Model;
  4. class DataScopeBaseModel extends Model
  5. {
  6. //人员id字段 创建人
  7. const employee_column = '';
  8. //有权限的人的表
  9. const table_column = '';
  10. //有权限的人的表关联id
  11. const table_id_column = '';
  12. public function __construct(array $attributes = [])
  13. {
  14. parent::__construct($attributes);
  15. }
  16. //根据公司过滤
  17. public function scopeTopClear($query, $user, $search)
  18. {
  19. $top_depart_id = "top_depart_id";
  20. // 获取当前查询的表名或别名(这样无论你起什么别名 i 还是 item_details 都能自适应)
  21. $table = $query->getQuery()->from;
  22. // 如果 $table 里包含 " as ",说明有别名,截取别名部分
  23. if (strpos($table, ' as ') !== false) {
  24. $segments = explode(' as ', $table);
  25. $table = trim(end($segments));
  26. $top_depart_id = $table . '.top_depart_id';
  27. }
  28. $query->where($top_depart_id, $user['top_depart_id']);
  29. return $query;
  30. $query->where('top_depart_id', $user['top_depart_id']);
  31. return $query;
  32. }
  33. //数据权限中 人员 部门 所有 (在公司的基础上)
  34. public function scopeClear1($query, $user, $search)
  35. {
  36. //权限范围内的部门
  37. $depart_range = $user['depart_id'] ?? [];
  38. //个人 部门 所有
  39. $auth_type = $this->getQx($search,$user);
  40. // 获取模型的实例
  41. $model = $query->getModel();
  42. // 获取模型类名
  43. $className = get_class($model);
  44. // 人员字段
  45. $column = defined($className . '::employee_column') ? constant($className . '::employee_column') : '';
  46. $this->makeModel($query, $auth_type, $user, $depart_range,$column);
  47. }
  48. private function makeModel1(&$query, $auth_type, $user, $depart_range, $column){
  49. $query->where('top_depart_id', $user['top_depart_id']);
  50. if(empty($column)) return;
  51. if($auth_type == Employee::AUTH_ONE){
  52. //我创建的
  53. $query->where($column,$user['id']);
  54. }elseif ($auth_type == Employee::AUTH_TWO){
  55. if (empty($depart_range)) {
  56. $query->whereRaw('1 = 0');
  57. } else {
  58. $query->whereExists(function ($q) use ($column, $depart_range) {
  59. $q->from('employee_depart_permission')
  60. ->whereColumn('employee_depart_permission.employee_id', $column)
  61. ->whereIn('employee_depart_permission.depart_id', $depart_range);
  62. });
  63. }
  64. }elseif ($auth_type == Employee::AUTH_THREE){
  65. //所有
  66. }
  67. }
  68. public function scopeClear($query, $user, $search)
  69. {
  70. // 权限范围内的部门
  71. $depart_range = $user['depart_id'] ?? [];
  72. // 个人 部门 所有
  73. $auth_type = $this->getQx($search, $user);
  74. // 获取模型的实例
  75. $model = $query->getModel();
  76. // 获取模型类名
  77. $className = get_class($model);
  78. // 🆕 核心修复 1:动态获取当前主表的表名,用来给字段加前缀防止别名冲突
  79. $tableName = $model->getTable();
  80. // 人员字段
  81. $column = defined($className . '::employee_column') ? constant($className . '::employee_column') : '';
  82. // 🆕 核心修复 2:如果定义了人员字段,且没有带表前缀,自动加上主表前缀
  83. if (!empty($column) && strpos($column, '.') === false) {
  84. $column = $tableName . '.' . $column;
  85. }
  86. $this->makeModel($query, $auth_type, $user, $depart_range, $column, $tableName);
  87. }
  88. private function makeModel(&$query, $auth_type, $user, $depart_range, $column, $tableName) {
  89. // 🆕 核心修复 3:给 top_depart_id 加上主表名前缀,防止关联表也有该字段导致冲突
  90. $query->where($tableName . '.top_depart_id', $user['top_depart_id']);
  91. if (empty($column)) return;
  92. if ($auth_type == Employee::AUTH_ONE) {
  93. // 我创建的 (此时 $column 已经是 "table_name.field" 格式)
  94. $query->where($column, $user['id']);
  95. } elseif ($auth_type == Employee::AUTH_TWO) {
  96. if (empty($depart_range)) {
  97. $query->whereRaw('1 = 0');
  98. } else {
  99. $query->whereExists(function ($q) use ($column, $depart_range) {
  100. $q->from('employee_depart_permission')
  101. ->whereColumn('employee_depart_permission.employee_id', $column) // 这里的 $column 带有表前缀,whereColumn 完美识别
  102. ->whereIn('employee_depart_permission.depart_id', $depart_range);
  103. });
  104. }
  105. } elseif ($auth_type == Employee::AUTH_THREE) {
  106. // 所有
  107. }
  108. }
  109. //根据公司过滤 加人员
  110. public function scopeTopAndEmployeeClear($query, $user, $search)
  111. {
  112. $top_depart_id = "top_depart_id";
  113. $table = $query->getQuery()->from;
  114. $alias = $table; // 默认为原表名
  115. // 如果 $table 里包含 " as ",说明有别名,截取别名部分
  116. if (strpos($table, ' as ') !== false) {
  117. $segments = explode(' as ', $table);
  118. $table = trim(end($segments));
  119. $top_depart_id = $table . '.top_depart_id';
  120. }
  121. $query->where($top_depart_id, $user['top_depart_id']);
  122. // 获取模型的实例
  123. $model = $query->getModel();
  124. // 获取模型类名
  125. $className = get_class($model);
  126. $relationTable = defined($className . '::table_column') ? constant($className . '::table_column') : '';
  127. $relationTableId = defined($className . '::table_id_column') ? constant($className . '::table_id_column') : '';
  128. if($user['is_admin'] != Employee::IS_ADMIN_TWO){
  129. if (! empty($relationTable) && ! empty($relationTableId)) {
  130. $query->whereExists(function ($subQuery) use ($relationTable, $user, $alias, $relationTableId) {
  131. $subQuery->from($relationTable)
  132. ->whereColumn($relationTable . ".{$relationTableId}", $alias . '.id') // 关联主表的 ID
  133. ->where($relationTable . '.data_id', $user['id']) // 过滤当前操作人
  134. ->where($relationTable . '.del_time', 0) // 排除已删除的关联记录
  135. ->where($relationTable . '.top_depart_id', $user['top_depart_id']);
  136. });
  137. }
  138. }
  139. return $query;
  140. }
  141. public function getQx($data, $user){
  142. if(empty($data['menu_id'])) return Employee::AUTH_ONE; // 我的
  143. if($user['is_admin'] == Employee::IS_ADMIN_TWO) return Employee::AUTH_THREE; // 全部
  144. if(! empty($user['menu_permissions'][$data['menu_id']])) {
  145. //指定菜单 显示对应权限
  146. return $user['menu_permissions'][$data['menu_id']];
  147. }else{
  148. return Employee::AUTH_ONE; // 我的
  149. }
  150. }
  151. function hasMethod($class, $methodName)
  152. {
  153. $reflection = new \ReflectionClass($class);
  154. return $reflection->hasMethod($methodName);
  155. }
  156. }