Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_NaiveVue/zh/guide/model.md
T
2026-10-08 17:50:29 +08:00

151 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3.3 模型层开发
:::tip 概述
模型层负责定义数据库表的映射关系。通过组合两个模型 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', // 排序值,数值越小越靠前(视业务而定)
];
}
```
:::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 # 案例模型
└── ...
```