You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 4.5多公司事故登记系统账号权限配置需求求助

解决Laravel 4.5多公司事故登记系统的权限与账号管理问题

我来帮你搞定这个多公司权限管控的需求,Laravel 4.5虽然版本不算新,但核心的ORM和路由过滤器完全能支撑这个场景,咱们一步步来实现:

1. 调整数据库表结构

首先得把关联关系理清楚,需要三张核心表:

  • companies:存储公司基础信息(比如id、名称)
  • users:存储所有用户(员工+管理员),需要关联公司并标记角色
  • incidents:事故记录表,关联所属公司和创建者

迁移代码示例

在app/database/migrations里创建对应的迁移文件:

公司表迁移

Schema::create('companies', function($table) {
    $table->increments('id');
    $table->string('name')->unique();
    $table->timestamps();
});

用户表迁移(修改原有users表)

Schema::table('users', function($table) {
    $table->integer('company_id')->unsigned()->index();
    $table->enum('role', ['employee', 'admin'])->default('employee');
    $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
});

事故记录表迁移

Schema::create('incidents', function($table) {
    $table->increments('id');
    $table->integer('company_id')->unsigned()->index();
    $table->integer('user_id')->unsigned()->index();
    // 这里加你的事故字段,比如title、description、occurred_at等
    $table->string('title');
    $table->text('description');
    $table->dateTime('occurred_at');
    $table->timestamps();
    
    $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

2. 设置模型关联

在对应的模型里定义关联关系,方便后续查询:

Company模型(app/models/Company.php)

class Company extends Eloquent {
    public function users() {
        return $this->hasMany('User');
    }
    
    public function incidents() {
        return $this->hasMany('Incident');
    }
}

User模型(app/models/User.php)

class User extends Eloquent implements UserInterface, RemindableInterface {
    // ...原有代码
    
    public function company() {
        return $this->belongsTo('Company');
    }
    
    public function incidents() {
        return $this->hasMany('Incident');
    }
}

Incident模型(app/models/Incident.php)

class Incident extends Eloquent {
    public function company() {
        return $this->belongsTo('Company');
    }
    
    public function user() {
        return $this->belongsTo('User');
    }
}

3. 用路由过滤器实现权限控制

Laravel 4.5用路由过滤器来做权限校验(Laravel 5之后才叫中间件),咱们在app/filters.php里定义几个关键过滤器:

验证用户所属公司

确保用户只能访问自己公司的资源:

Route::filter('company.auth', function() {
    $user = Auth::user();
    if (!$user) return Redirect::route('login');
    
    // 如果请求里有company_id参数,校验是否匹配用户所属公司
    if (Request::has('company_id') && Request::get('company_id') != $user->company_id) {
        return App::abort(403, '无权访问该公司资源');
    }
});

员工权限过滤器

限制员工只能操作自己创建的事故:

Route::filter('employee.auth', function() {
    $user = Auth::user();
    if ($user->role != 'employee') return App::abort(403, '仅员工可执行此操作');
    
    // 如果是编辑/删除请求,校验事故是否属于当前用户
    if (Request::segment(2) == 'incidents' && Request::segment(3)) {
        $incident = Incident::find(Request::segment(3));
        if (!$incident || $incident->user_id != $user->id) {
            return App::abort(403, '无权操作该事故记录');
        }
    }
});

管理员权限过滤器

限制管理员只能操作本公司的所有事故:

Route::filter('admin.auth', function() {
    $user = Auth::user();
    if ($user->role != 'admin') return App::abort(403, '仅管理员可执行此操作');
    
    // 如果是编辑/删除请求,校验事故是否属于当前用户的公司
    if (Request::segment(2) == 'incidents' && Request::segment(3)) {
        $incident = Incident::find(Request::segment(3));
        if (!$incident || $incident->company_id != $user->company_id) {
            return App::abort(403, '无权操作该公司的事故记录');
        }
    }
});

然后在路由里应用这些过滤器:

// 员工路由组
Route::group(['before' => 'auth|company.auth|employee.auth'], function() {
    Route::get('incidents/create', 'IncidentsController@create');
    Route::post('incidents', 'IncidentsController@store');
    Route::get('incidents', 'IncidentsController@myIncidents'); // 查看自己的事故
});

// 管理员路由组
Route::group(['before' => 'auth|company.auth|admin.auth'], function() {
    Route::get('admin/incidents', 'IncidentsController@index'); // 查看本公司所有事故
    Route::get('incidents/{id}/edit', 'IncidentsController@edit');
    Route::put('incidents/{id}', 'IncidentsController@update');
    Route::delete('incidents/{id}', 'IncidentsController@destroy');
});

4. 控制器逻辑实现

以IncidentsController为例,写核心方法:

员工创建事故

自动关联当前用户的公司和ID:

public function store() {
    $input = Input::all();
    $input['company_id'] = Auth::user()->company_id;
    $input['user_id'] = Auth::user()->id;
    
    $validator = Validator::make($input, Incident::$rules);
    if ($validator->fails()) {
        return Redirect::back()->withErrors($validator)->withInput();
    }
    
    Incident::create($input);
    return Redirect::route('incidents.my')->with('success', '事故记录已保存');
}

管理员查看本公司所有事故

public function index() {
    $incidents = Incident::where('company_id', Auth::user()->company_id)->get();
    return View::make('admin.incidents.index', compact('incidents'));
}

员工查看自己的事故

public function myIncidents() {
    $incidents = Auth::user()->incidents()->get();
    return View::make('incidents.my', compact('incidents'));
}

5. 账号管理建议

关于你提到的“主用户账号”,我建议不要用单一账号给所有员工共用(这样无法追踪是谁创建的事故),而是:

  • 为每个公司创建多个员工账号,统一关联该公司的company_id,角色设为employee
  • 每个公司单独创建1个管理员账号,角色设为admin,关联对应公司

如果你的业务确实需要员工用同一个“主账号”登录,可以在用户表加个group_account字段标记所属组,但还是建议每个员工有独立账号,这样事故记录的创建者可追溯,也更符合权限管控的最佳实践。

内容的提问来源于stack exchange,提问作者Andre Jonker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:27:16