likeadmin php 版 ,想加一个机构表institution,然后给每个管理员绑定一个机构 Id(institution_id),每个机构管理登录只能看到该机构下的信息,基层代码或者中间件代码还有公共代码怎么改造啊,请写的详细一点,每段代码带上文件名和代码注释
likeadmin php 版 ,想加一个机构表institution,然后给每个管理员绑定一个机构 Id(institution_id),每个机构管理登录只能看到该机构下的信息,基层代码或者中间件代码还有公共代码怎么改造啊,请写的详细一点,每段代码带上文件名和代码注释
likeadmin php 版 ,想加一个机构表institution,然后给每个管理员绑定一个机构 Id(institution_id),每个机构管理登录只能看到该机构下的信息,基层代码或者中间件代码还有公共代码怎么改造啊,请写的详细一点,每段代码带上文件名和代码注释

用户545179374
01月09日
|
浏览 76
解决方案:为 LikeAdmin PHP 添加机构隔离功能
1. 数据库改造
文件名: database/migrations/2024_01_01_000000_add_institution_to_admins.php
复制代码
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddInstitutionToAdmins extends Migration
{
/**
* 为管理员表添加机构字段
*/
public function up()
{
// 1. 创建机构表
Schema::create('institution', function (Blueprint $table) {
$table->id();
$table->string('name', 100)->comment('机构名称');
$table->string('code', 50)->unique()->comment('机构编码');
$table->tinyInteger('status')->default(1)->comment('状态 1启用 0禁用');
$table->timestamps();
$table->softDeletes();
});
// 2. 为管理员表添加机构ID字段
Schema::table('admin', function (Blueprint $table) {
$table->unsignedBigInteger('institution_id')->nullable()->after('id')->comment('机构ID');
$table->foreign('institution_id')->references('id')->on('institution')->onDelete('set null');
});
// 3. 为需要隔离的数据表添加机构ID字段(以user表为例)
Schema::table('user', function (Blueprint $table) {
$table->unsignedBigInteger('institution_id')->nullable()->after('id')->comment('机构ID');
$table->index('institution_id'); // 添加索引提高查询效率
});
}
}
2. 模型层改造
文件名: app/models/Admin.php
复制代码
<?php
namespace app\models;
use think\Model;
class Admin extends Model
{
/**
* 关联机构
*/
public function institution()
{
return $this->belongsTo(Institution::class, 'institution_id');
}
/**
* 获取当前管理员的机构ID
*/
public function getInstitutionId()
{
return $this->institution_id ?? 0;
}
}
文件名: app/models/Institution.php
复制代码
<?php
namespace app\models;
use think\Model;
class Institution extends Model
{
protected $name = 'institution';
/**
* 关联管理员
*/
public function admins()
{
return $this->hasMany(Admin::class, 'institution_id');
}
}
3. 中间件实现机构隔离
文件名: app/middleware/InstitutionAuth.php
复制代码
<?php
namespace app\middleware;
use think\facade\Db;
use think\facade\Request;
class InstitutionAuth
{
/**
* 机构权限验证中间件
*/
public function handle($request, \Closure $next)
{
// 获取当前登录管理员
$adminId = session('admin_id');
if (!$adminId) {
return json(['code' => 401, 'msg' => '未登录']);
}
// 查询管理员所属机构
$admin = Db::name('admin')->where('id', $adminId)->find();
$institutionId = $admin['institution_id'] ?? 0;
// 超级管理员(institution_id为0或null)拥有全部权限
if (empty($institutionId)) {
$request->institutionId = null; // 不限制机构
return $next($request);
}
// 将机构ID注入到请求对象中
$request->institutionId = $institutionId;
// 验证机构状态是否正常
$institution = Db::name('institution')
->where('id', $institutionId)
->where('status', 1)
->find();
if (!$institution) {
return json(['code' => 403, 'msg' => '机构已被禁用或不存在']);
}
return $next($request);
}
}
4. 服务层添加机构查询作用域
文件名: app/common/InstitutionScope.php
复制代码
<?php
namespace app\common;
use think\facade\Request;
class InstitutionScope
{
/**
* 自动添加机构查询条件
* @param \think\db\Query $query
* @param string $field 机构ID字段名,默认为institution_id
*/
public static function apply($query, $field = 'institution_id')
{
$institutionId = Request::instance()->institutionId ?? null;
// 如果请求中没有机构ID(超级管理员),不添加限制
if ($institutionId === null) {
return;
}
// 普通管理员:只查询本机构数据
$query->where($field, $institutionId);
}
}
5. 控制器基类改造
文件名: app/controller/AdminBase.php
复制代码
<?php
namespace app\controller;
use app\common\InstitutionScope;
use think\facade\Request;
class AdminBase extends BaseController
{
/**
* 初始化方法
*/
protected function initialize()
{
parent::initialize();
// 获取当前机构ID
$this->institutionId = Request::instance()->institutionId;
}
/**
* 获取带机构限制的查询构造器
* @param string $model 模型名
* @param string $field 机构字段名
*/
protected function buildInstitutionQuery($model, $field = 'institution_id')
{
$query = Db::name($model);
InstitutionScope::apply($query, $field);
return $query;
}
/**
* 验证数据是否属于当前机构
* @param string $table 表名
* @param int $id 数据ID
*/
protected function checkInstitutionPermission($table, $id)
{
if ($this->institutionId === null) {
return true; // 超级管理员跳过验证
}
$data = Db::name($table)
->where('id', $id)
->where('institution_id', $this->institutionId)
->find();
return !empty($data);
}
}
6. 路由配置
文件名: route/admin.php
复制代码
<?php
use think\facade\Route;
// 需要机构隔离的路由组
Route::group('admin', function () {
// 用户管理
Route::get('user/list', 'admin.User/index');
Route::post('user/add', 'admin.User/add');
Route::put('user/edit/:id', 'admin.User/edit');
Route::delete('user/del/:id', 'admin.User/del');
// ... 其他需要隔离的路由
})->middleware([
app\middleware\CheckAdminLogin::class,
app\middleware\InstitutionAuth::class // 添加机构验证中间件
]);
7. 业务控制器示例
文件名: app/controller/admin/User.php
复制代码
<?php
namespace app\controller\admin;
class User extends AdminBase
{
/**
* 用户列表(自动机构隔离)
*/
public function index()
{
$page = input('page', 1);
$limit = input('limit', 20);
// 使用基类方法构建查询
$query = $this->buildInstitutionQuery('user');
// 添加其他查询条件
if ($keyword = input('keyword')) {
$query->whereLike('username|mobile', "%{$keyword}%");
}
$list = $query->paginate($limit, false, ['page' => $page]);
return json([
'code' => 1,
'data' => $list->items(),
'count' => $list->total()
]);
}
/**
* 编辑用户(机构权限验证)
*/
public function edit($id)
{
// 验证数据权限
if (!$this->checkInstitutionPermission('user', $id)) {
return json(['code' => 0, 'msg' => '无权操作该数据']);
}
// ... 编辑逻辑
}
}
8. 视图层改造(如果需要)
文件名: app/view/admin/layout.html
复制代码
<!-- 在侧边栏或顶部显示当前机构 -->
<div class="institution-info">
<span>当前机构:{{$admin.institution.name|default='超级管理员'}}</span>
</div>
实施步骤:
- 执行数据库迁移:
php think migrate:run - 在管理员管理页面添加机构分配功能
- 为现有管理员分配机构ID(超级管理员设为NULL)
- 逐步为需要隔离的数据表添加
institution_id字段 - 在对应的控制器中应用机构查询作用域
如需继续排查,请点击下方【🔍追问按钮】提交补充信息
我要提问
复制内容
分享给好友
AI编程问答网 免责声明:
以上内容除特别注明外均来源于网友提问,AI编程问答网回答,权益归原著者所有;
