import{_ as i,o as a,c as t,a2 as n}from"./chunks/framework.BbmSSMjL.js";const y=JSON.parse('{"title":"3.3 模型层开发","description":"","frontmatter":{},"headers":[],"relativePath":"zh/guide/model.md","filePath":"zh/guide/model.md"}'),l={name:"zh/guide/model.md"};function h(k,s,e,p,d,r){return a(),t("div",null,[...s[0]||(s[0]=[n(`

3.3 模型层开发 ​

概述

模型层负责定义数据库表的映射关系。通过组合两个模型 Trait(SoftDeletesByFlag、HasAuditColumns),自动获得软删除和审计字段能力。

模型文件位置 ​

text
app/Models/Example.php

完整代码(来自项目实际代码) ​

php
<?php

namespace App\\Models;

use App\\Models\\Concerns\\HasAuditColumns;
use App\\Models\\Concerns\\SoftDeletesByFlag;
use Illuminate\\Database\\Eloquent\\Model;

/**
 * 案例演示模型
 *
 * 对应数据表 example,继承 Eloquent Model 获得通用模型能力。
 *
 * 说明:
 * - 通过 HasAuditColumns 自动维护审计字段(如 created_by、updated_by 等)。
 * - 通过 SoftDeletesByFlag 实现基于标志位的软删除(如 is_deleted 字段)。
 * - type 类型:1=类型1,2=类型2,3=类型3,4=类型4。
 * - status 状态:1=在用,2=停用。
 * - 本模型通常作为开发示例/模板使用,不承载具体业务逻辑。
 */
class Example extends Model
{
    use HasAuditColumns, SoftDeletesByFlag;

    /**
     * 数据表名
     *
     * 显式指定表名为 example,覆盖默认的类名推导规则。
     *
     * @var string
     */
    protected $table = 'example';

    /**
     * 允许批量赋值的字段列表
     *
     * 白名单中的字段可通过 create()、update()、fill() 等方式批量赋值。
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',   // 名称
        'avatar', // 头像/图片地址
        'type',   // 类型:1=类型1,2=类型2,3=类型3,4=类型4
        'status', // 状态:1=在用,2=停用
        'sort',   // 排序值,数值越小越靠前(视业务而定)
    ];
}

表名与前缀

$table = 'example' 不含前缀,实际查询时由 DB_PREFIX=laravel_ 自动拼接为 laravel_example。

组合 Trait 后获得的能力 ​

Trait能力代码示例
SoftDeletesByFlag注册 SoftDeleteFlagScope 全局范围,查询自动过滤 is_delete=1Example::query() 自动排除已删除
SoftDeletesByFlag标记删除单条$model->softDelete();(置 is_delete=1)
SoftDeletesByFlag批量标记删除Example::batchSoftDelete([1,2,3]);
HasAuditColumnscreating 事件自动填充 create_user(当前登录人)和 create_timeExample::create([...]) 时自动填充
HasAuditColumnsupdating 事件自动填充 update_user、update_time(每次强制覆盖)$model->update([...]) 时自动填充

审计字段说明

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 复杂模型 ​

模型层职责

模型层只负责表映射和关联关系,不包含业务逻辑。所有查询条件、排序、唯一性校验等都由 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                    # 案例模型
└── ...
`,22)])])}const g=i(l,[["render",h]]);export{y as __pageData,g as default};