308 lines
6.7 KiB
Markdown
308 lines
6.7 KiB
Markdown
# BaseModel系统字段配置使用指南
|
||
|
||
## 概述
|
||
|
||
BaseModel提供了灵活的系统字段自动维护功能,允许开发者根据不同表的需求选择性地启用或关闭系统字段的自动维护。
|
||
|
||
## 配置选项
|
||
|
||
### 1. `$enableSystemFields`
|
||
控制是否自动维护系统字段,默认为 `false`。
|
||
|
||
**维护的字段包括:**
|
||
- `tenant_id` - 租户ID
|
||
- `creator` - 创建者
|
||
- `create_time` - 创建时间
|
||
- `updater` - 更新者
|
||
- `update_time` - 更新时间
|
||
- `deleted` - 删除标识
|
||
|
||
### 2. `$enableTenantScope`
|
||
控制是否启用租户隔离查询,默认为 `false`。
|
||
|
||
**功能:**
|
||
- 自动在查询中添加 `tenant_id` 过滤条件
|
||
- 确保用户只能访问自己租户的数据
|
||
|
||
## 使用示例
|
||
|
||
### 主要业务表(推荐启用)
|
||
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Models\Schools;
|
||
|
||
use App\Models\BaseModel;
|
||
|
||
/**
|
||
* 学校模型
|
||
*/
|
||
class School extends BaseModel
|
||
{
|
||
protected $table = 'school';
|
||
|
||
/**
|
||
* 启用系统字段自动维护
|
||
*/
|
||
protected $enableSystemFields = true;
|
||
|
||
/**
|
||
* 启用租户隔离
|
||
*/
|
||
protected $enableTenantScope = true;
|
||
|
||
protected $fillable = [
|
||
'name',
|
||
'type',
|
||
'status',
|
||
// ... 其他业务字段
|
||
];
|
||
}
|
||
```
|
||
|
||
### 关联表(推荐关闭)
|
||
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Models\Students;
|
||
|
||
use App\Models\BaseModel;
|
||
|
||
/**
|
||
* 学生班级关联模型
|
||
*/
|
||
class StudentClass extends BaseModel
|
||
{
|
||
protected $table = 'student_class';
|
||
|
||
// 默认关闭,不需要显式设置
|
||
// protected $enableSystemFields = false;
|
||
// protected $enableTenantScope = false;
|
||
|
||
protected $fillable = [
|
||
'student_id',
|
||
'class_id',
|
||
'join_time',
|
||
'leave_time',
|
||
'status',
|
||
'remark',
|
||
];
|
||
}
|
||
```
|
||
|
||
### 日志表(只启用系统字段)
|
||
|
||
```php
|
||
<?php
|
||
|
||
namespace App\Models\Logs;
|
||
|
||
use App\Models\BaseModel;
|
||
|
||
/**
|
||
* 操作日志模型
|
||
*/
|
||
class OperationLog extends BaseModel
|
||
{
|
||
protected $table = 'operation_log';
|
||
|
||
/**
|
||
* 启用系统字段自动维护
|
||
*/
|
||
protected $enableSystemFields = true;
|
||
|
||
/**
|
||
* 日志表不需要租户隔离
|
||
*/
|
||
protected $enableTenantScope = false;
|
||
|
||
protected $fillable = [
|
||
'user_id',
|
||
'action',
|
||
'description',
|
||
'ip_address',
|
||
// ... 其他日志字段
|
||
];
|
||
}
|
||
```
|
||
|
||
## 使用建议
|
||
|
||
### 启用系统字段维护的场景
|
||
|
||
1. **主要业务表**
|
||
- 学校、用户、产品等核心业务实体
|
||
- 需要跟踪创建者、更新者信息
|
||
- 需要软删除功能
|
||
|
||
2. **配置表**
|
||
- 系统配置、字典表等
|
||
- 需要审计功能的表
|
||
|
||
3. **内容表**
|
||
- 文章、新闻、公告等内容实体
|
||
- 需要发布状态管理
|
||
|
||
### 关闭系统字段维护的场景
|
||
|
||
1. **关联表**
|
||
- 用户角色关联、学生班级关联等
|
||
- 通常不需要创建者、更新者信息
|
||
- 不需要软删除(直接删除关联关系)
|
||
|
||
2. **日志表**
|
||
- 操作日志、访问日志等
|
||
- 已经有自己的时间戳字段
|
||
- 不需要软删除
|
||
|
||
3. **临时表**
|
||
- 导入导出的临时数据
|
||
- 缓存表
|
||
|
||
### 启用租户隔离的场景
|
||
|
||
1. **多租户系统的业务表**
|
||
- 需要按租户隔离数据
|
||
- 确保数据安全性
|
||
|
||
2. **用户相关的数据表**
|
||
- 用户创建的内容
|
||
- 用户的配置信息
|
||
|
||
### 关闭租户隔离的场景
|
||
|
||
1. **全局共享的表**
|
||
- 系统配置、字典表
|
||
- 所有租户共享的数据
|
||
|
||
2. **关联表**
|
||
- 通常通过关联的主表来控制访问权限
|
||
- 不需要直接的租户隔离
|
||
|
||
## 影响和注意事项
|
||
|
||
### 启用系统字段维护的影响
|
||
|
||
1. **数据库结构要求**
|
||
- 表必须包含相应的系统字段
|
||
- 字段类型必须匹配
|
||
|
||
2. **查询影响**
|
||
- 自动过滤 `deleted = 0` 的记录
|
||
- 需要使用 `withTrashed()` 查询已删除记录
|
||
|
||
3. **性能考虑**
|
||
- 每次保存都会更新系统字段
|
||
- 建议为系统字段添加索引
|
||
|
||
### 启用租户隔离的影响
|
||
|
||
1. **查询限制**
|
||
- 所有查询都会自动加上租户过滤
|
||
- 跨租户查询需要使用 `withoutGlobalScope('tenant')`
|
||
|
||
2. **数据完整性**
|
||
- 确保所有记录都有正确的租户ID
|
||
- 防止数据泄露
|
||
|
||
## 迁移指南
|
||
|
||
### 从旧版本升级
|
||
|
||
如果你的项目已经在使用BaseModel的自动维护功能,升级后需要:
|
||
|
||
1. **为需要系统字段维护的模型添加配置**
|
||
```php
|
||
protected $enableSystemFields = true;
|
||
```
|
||
|
||
2. **为需要租户隔离的模型添加配置**
|
||
```php
|
||
protected $enableTenantScope = true;
|
||
```
|
||
|
||
3. **检查关联表**
|
||
- 确保关联表不启用不需要的功能
|
||
- 移除不必要的系统字段
|
||
|
||
### 新项目开发
|
||
|
||
1. **分析表的性质**
|
||
- 确定是否需要系统字段维护
|
||
- 确定是否需要租户隔离
|
||
|
||
2. **设置合适的配置**
|
||
- 主要业务表:启用所有功能
|
||
- 关联表:保持默认关闭
|
||
- 特殊表:根据需求单独配置
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 如何查询已删除的记录?
|
||
```php
|
||
// 包含已删除的记录
|
||
$schools = School::withTrashed()->get();
|
||
|
||
// 只查询已删除的记录
|
||
$deletedSchools = School::onlyTrashed()->get();
|
||
```
|
||
|
||
### Q2: 如何跨租户查询?
|
||
```php
|
||
// 跨租户查询
|
||
$allSchools = School::withoutGlobalScope('tenant')->get();
|
||
```
|
||
|
||
### Q3: 如何为现有表添加系统字段?
|
||
```php
|
||
// 创建迁移文件
|
||
php artisan make:migration add_system_fields_to_schools_table
|
||
|
||
// 在迁移文件中添加字段
|
||
public function up()
|
||
{
|
||
Schema::table('schools', function (Blueprint $table) {
|
||
$table->integer('tenant_id')->default(0)->comment('租户ID');
|
||
$table->integer('creator')->default(0)->comment('创建者');
|
||
$table->timestamp('create_time')->useCurrent()->comment('创建时间');
|
||
$table->integer('updater')->default(0)->comment('更新者');
|
||
$table->timestamp('update_time')->useCurrent()->on('update')->comment('更新时间');
|
||
$table->tinyInteger('deleted')->default(0)->comment('删除标识');
|
||
|
||
// 添加索引
|
||
$table->index('tenant_id');
|
||
$table->index('deleted');
|
||
});
|
||
}
|
||
```
|
||
|
||
### Q4: 如何自定义系统字段的值?
|
||
```php
|
||
// 在模型中重写方法
|
||
public function setCreateFields(): void
|
||
{
|
||
if (!$this->enableSystemFields) {
|
||
return;
|
||
}
|
||
|
||
// 自定义逻辑
|
||
$this->creator = auth()->id() ?? 0;
|
||
$this->create_time = now();
|
||
$this->tenant_id = $this->getCustomTenantId();
|
||
$this->deleted = 0;
|
||
}
|
||
```
|
||
|
||
## 总结
|
||
|
||
通过合理配置BaseModel的系统字段维护功能,可以:
|
||
|
||
1. **提高开发效率** - 自动维护常用的系统字段
|
||
2. **增强数据安全** - 租户隔离确保数据安全
|
||
3. **简化代码逻辑** - 减少重复的字段维护代码
|
||
4. **提高灵活性** - 根据表的特点选择性启用功能
|
||
|
||
建议在项目开始时就规划好各个表的配置策略,确保系统的一致性和可维护性。
|