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
相关产品推荐
相关产品推荐

