# 3.3 模型层开发 :::tip 概述 模型层负责定义数据库表的映射关系。通过组合两个模型 Trait(`SoftDeletesByFlag`、`HasAuditColumns`),自动获得软删除和审计字段能力。 ::: ## 模型文件位置 ```text app/Models/Example.php ``` ## 完整代码(来自项目实际代码) ```php */ protected $fillable = [ 'name', // 名称 'avatar', // 头像/图片地址 'type', // 类型:1=类型1,2=类型2,3=类型3,4=类型4 'status', // 状态:1=在用,2=停用 'sort', // 排序值,数值越小越靠前(视业务而定) ]; } ``` :::tip 表名与前缀 `$table = 'example'` 不含前缀,实际查询时由 `DB_PREFIX=laravel_` 自动拼接为 `laravel_example`。 ::: ## 组合 Trait 后获得的能力 | Trait | 能力 | 代码示例 | |------|------|----------| | `SoftDeletesByFlag` | 注册 `SoftDeleteFlagScope` 全局范围,查询自动过滤 `is_delete=1` | `Example::query()` 自动排除已删除 | | `SoftDeletesByFlag` | 标记删除单条 | `$model->softDelete();`(置 `is_delete=1`) | | `SoftDeletesByFlag` | 批量标记删除 | `Example::batchSoftDelete([1,2,3]);` | | `HasAuditColumns` | `creating` 事件自动填充 `create_user`(当前登录人)和 `create_time` | `Example::create([...])` 时自动填充 | | `HasAuditColumns` | `updating` 事件自动填充 `update_user`、`update_time`(每次强制覆盖) | `$model->update([...])` 时自动填充 | :::tip 审计字段说明 `create_user` 取自 `Auth::username()`(当前登录用户);`create_*` 采用 `??` 逻辑——已显式赋值则保留原值,`update_*` 每次强制覆盖。表结构不含 Laravel 默认的 `created_at` / `updated_at`。 ::: ## 查询已删除数据 ```php // 查询单条(包括已删除)—— 移除全局软删除范围 $example = Example::withoutGlobalScope(SoftDeleteFlagScope::class)->find($id); // 查询所有(包括已删除) $all = Example::withoutGlobalScope(SoftDeleteFlagScope::class)->get(); // 恢复(软删除字段归零) $example->update(['is_delete' => 0]); ``` ## 简单模型 vs 复杂模型 :::tip 模型层职责 模型层只负责表映射和关联关系,不包含业务逻辑。所有查询条件、排序、唯一性校验等都由 Service 层配置。 ::: ### 简单模型(如 Example) 只需声明表名与批量赋值白名单,所有逻辑由 Service 层配置: ```php class Example extends Model { use HasAuditColumns, SoftDeletesByFlag; protected $table = 'example'; protected $fillable = ['name', 'avatar', 'type', 'status', 'sort']; } ``` ### 复杂模型(如 Role) 包含关联关系(以项目实际代码为例): ```php class Role extends Model { use HasAuditColumns, SoftDeletesByFlag; protected $table = 'role'; protected $fillable = [...]; /** * 角色关联的菜单(多对多,经 role_menu 中间表) */ public function menus(): BelongsToMany { return $this->belongsToMany(Menu::class, 'role_menu', 'role_id', 'menu_id') ->wherePivot('is_delete', 0); } } ``` ## 模型相关文件 ```text app/Models/ ├── Concerns/ │ ├── SoftDeletesByFlag.php # is_delete 软删除(注册全局 Scope + softDelete 方法) │ ├── SoftDeleteFlagScope.php # 全局查询范围(WHERE is_delete = 0) │ └── HasAuditColumns.php # 审计字段(creating/updating 事件填充) ├── Example.php # 案例模型 └── ... ```