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

Laravel员工排班与销售点管理系统数据库表关系设计咨询

Laravel公司管理系统表关系设计方案

一、用户与销售点的时段性关联设计

用户归属销售点是时段性的(不同时段可能属于不同网点),不能直接在users表添加固定的front_office_id,需创建中间表user_front_office_assignments记录这种动态归属关系:

中间表字段:

  • id:主键
  • user_id:关联users表ID(外键)
  • front_office_id:关联front_offices表ID(外键)
  • start_date:归属生效日期
  • end_date:归属失效日期(可为null表示永久生效)
  • priority:优先级(同用户同时段存在多条归属记录时,取优先级最高的)

模型关联:

  • User模型:
public function frontOfficeAssignments()
{
    return $this->hasMany(UserFrontOfficeAssignment::class);
}
  • FrontOffice模型:
public function userAssignments()
{
    return $this->hasMany(UserFrontOfficeAssignment::class);
}

通过这个表可实现:

  • 查询指定时间用户所属销售点:筛选start_date <= 指定时间且(end_date >= 指定时间 OR end_date IS NULL)的记录,按priority降序取第一条
  • 查询指定时间销售点内的用户:反向筛选上述条件,关联users表获取用户列表

二、排班表(Schedules)的多态关联设计

根据业务场景,排班分为用户个人排班(加班、病假、外出)和销售点排班(固定排班、临时关闭)两种类型,适合用多态关联统一管理,无需拆分多张排班表。

排班表字段调整:

保留核心字段,移除morning_or_afternoon(start_time和end_time已能区分时段),添加多态关联字段:

  • id:主键
  • start_time:排班开始时间(精确到时分)
  • end_time:排班结束时间(精确到时分)
  • day_of_week:星期几(整数,如1=周一、7=周日,按业务定义)
  • type_day:排班类型(如工作日/节假日/病假/加班/临时关闭,建议用数据库枚举或单独字典表维护)
  • valid_from:排班生效起始日期
  • valid_through:排班失效结束日期
  • priority:优先级(同有效期同类型排班,取优先级最高的)
  • scheduleable_id:关联模型ID(用户/销售点ID)
  • scheduleable_type:关联模型类名(如App\Models\User/App\Models\FrontOffice)

模型关联:

  • User模型:
public function schedules()
{
    return $this->morphMany(Schedule::class, 'scheduleable');
}
  • FrontOffice模型:
public function schedules()
{
    return $this->morphMany(Schedule::class, 'scheduleable');
}
  • Schedule模型:
public function scheduleable()
{
    return $this->morphTo();
}

这种设计的优势:

  • 统一管理所有排班类型,避免表冗余
  • 灵活扩展后续可能的其他排班主体(如部门)
  • 天然支持单个用户/销售点多条排班记录的场景

三、核心功能实现思路

  1. 查询员工排班:
    通过用户模型关联获取排班,再按有效期过滤:
// 获取用户指定日期范围内的有效排班
$user->schedules()
    ->where('valid_from', '<=', $endDate)
    ->where('valid_through', '>=', $startDate)
    ->orderBy('priority', 'desc')
    ->get();
  1. 查询销售点排班:
    类似员工排班,通过销售点模型关联获取:
$frontOffice->schedules()
    ->where('valid_from', '<=', $endDate)
    ->where('valid_through', '>=', $startDate)
    ->orderBy('priority', 'desc')
    ->get();
  1. 统计假期/病假数据:
    通过type_day筛选对应类型,关联用户或时间范围统计:
// 统计某用户本月病假总时长
Schedule::where('scheduleable_type', User::class)
    ->where('scheduleable_id', $userId)
    ->where('type_day', '病假')
    ->whereMonth('valid_from', date('m'))
    ->sum(DB::raw('TIMESTAMPDIFF(HOUR, start_time, end_time)'));
  1. 处理同时段高优先级排班:
    查询时按priority降序,配合groupBy(如按日期、类型)取最高优先级记录,避免冲突。

四、补充说明

  • 如果需要精细权限控制,可在中间表或排班表添加created_by字段,记录创建排班的用户
  • type_day建议用Laravel支持的数据库枚举,或单独创建schedule_types字典表关联,便于后续维护
  • 销售点固定排班可设置valid_from为远早日期、valid_through为null表示永久生效,临时调整的排班设置更高优先级即可覆盖原有规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:28