247 lines
6.8 KiB
Markdown
247 lines
6.8 KiB
Markdown
# 模型配置总结
|
||
|
||
## 系统字段维护配置状态
|
||
|
||
### 已启用系统字段维护的模型
|
||
|
||
#### 学校相关模型
|
||
- ✅ **School** (`app/Models/Schools/School.php`)
|
||
- `$enableSystemFields = true`
|
||
- `$enableTenantScope = true`
|
||
- 原因:主要业务表,需要完整的审计功能
|
||
|
||
- ✅ **SchoolCampus** (`app/Models/Schools/SchoolCampus.php`)
|
||
- `$enableSystemFields = true`
|
||
- `$enableTenantScope = true`
|
||
- 原因:主要业务表,需要租户隔离
|
||
|
||
- ✅ **SchoolClass** (`app/Models/Schools/SchoolClass.php`)
|
||
- `$enableSystemFields = true`
|
||
- `$enableTenantScope = true`
|
||
- 原因:主要业务表,需要租户隔离
|
||
|
||
### 关闭系统字段维护的模型
|
||
|
||
#### 学生相关模型
|
||
- ❌ **Student** (`app/Models/Students/Student.php`)
|
||
- 继承 `Authenticatable`,不是 `BaseModel`
|
||
- 使用自己的时间戳字段和认证机制
|
||
|
||
- ❌ **StudentClass** (`app/Models/Students/StudentClass.php`)
|
||
- `$enableSystemFields = false` (默认)
|
||
- `$enableTenantScope = false` (默认)
|
||
- 原因:关联表,不需要系统字段维护
|
||
|
||
#### 老师相关模型
|
||
- ❌ **TeacherClass** (`app/Models/Teachers/TeacherClass.php`)
|
||
- `$enableSystemFields = false` (默认)
|
||
- `$enableTenantScope = false` (默认)
|
||
- 原因:关联表,不需要系统字段维护
|
||
|
||
#### 系统相关模型
|
||
- ❌ **SystemUserSchoolCampus** (`app/Models/System/SystemUserSchoolCampus.php`)
|
||
- `$enableSystemFields = false` (默认)
|
||
- `$enableTenantScope = false` (默认)
|
||
- 原因:关联表,不需要系统字段维护
|
||
|
||
- ❌ **SystemUserRole** (`app/Models/System/SystemUserRole.php`)
|
||
- 已有完整的系统字段注释
|
||
- 原因:系统核心表,已有自己的字段管理
|
||
|
||
- ❌ **SystemRole** (`app/Models/System/SystemRole.php`)
|
||
- 已有完整的系统字段注释
|
||
- 原因:系统核心表,已有自己的字段管理
|
||
|
||
- ❌ **SystemMenu** (`app/Models/System/SystemMenu.php`)
|
||
- 已有完整的系统字段注释
|
||
- 原因:系统核心表,已有自己的字段管理
|
||
|
||
- ❌ **SystemRoleMenu** (`app/Models/System/SystemRoleMenu.php`)
|
||
- 已有完整的系统字段注释
|
||
- 原因:关联表,不需要系统字段维护
|
||
|
||
- ❌ **User** (`app/Models/User.php`)
|
||
- 继承 `Authenticatable`,不是 `BaseModel`
|
||
- 使用自己的时间戳字段和认证机制
|
||
|
||
## 配置原则
|
||
|
||
### 启用系统字段维护 (`$enableSystemFields = true`)
|
||
|
||
**适用场景:**
|
||
1. 主要业务实体表
|
||
2. 需要审计功能的表
|
||
3. 需要软删除的表
|
||
4. 需要跟踪创建者和更新者的表
|
||
|
||
**必要条件:**
|
||
- 表中必须包含系统字段:`tenant_id`、`creator`、`create_time`、`updater`、`update_time`、`deleted`
|
||
- 继承 `BaseModel` 类
|
||
|
||
### 启用租户隔离 (`$enableTenantScope = true`)
|
||
|
||
**适用场景:**
|
||
1. 多租户系统的业务表
|
||
2. 需要按租户隔离数据的表
|
||
3. 用户相关的数据表
|
||
|
||
**必要条件:**
|
||
- 表中必须包含 `tenant_id` 字段
|
||
- 继承 `BaseModel` 类
|
||
|
||
### 关闭配置 (默认状态)
|
||
|
||
**适用场景:**
|
||
1. 关联表(如用户角色关联、学生班级关联)
|
||
2. 日志表(有自己的时间戳管理)
|
||
3. 全局共享的配置表
|
||
4. 临时表或缓存表
|
||
5. 非 `BaseModel` 的认证表
|
||
|
||
## 数据库字段要求
|
||
|
||
### 启用系统字段维护需要的字段
|
||
|
||
```sql
|
||
-- 租户ID
|
||
tenant_id INT DEFAULT 0 COMMENT '租户ID',
|
||
|
||
-- 创建信息
|
||
creator INT DEFAULT 0 COMMENT '创建者',
|
||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
|
||
-- 更新信息
|
||
updater INT DEFAULT 0 COMMENT '更新者',
|
||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
|
||
-- 软删除
|
||
deleted TINYINT DEFAULT 0 COMMENT '删除标识',
|
||
|
||
-- 推荐的索引
|
||
INDEX idx_tenant_id (tenant_id),
|
||
INDEX idx_deleted (deleted),
|
||
INDEX idx_create_time (create_time),
|
||
INDEX idx_update_time (update_time)
|
||
```
|
||
|
||
### 启用租户隔离需要的字段
|
||
|
||
```sql
|
||
-- 租户ID(必须)
|
||
tenant_id INT DEFAULT 0 COMMENT '租户ID',
|
||
|
||
-- 推荐的索引
|
||
INDEX idx_tenant_id (tenant_id)
|
||
```
|
||
|
||
## 使用建议
|
||
|
||
### 开发新模型时
|
||
|
||
1. **分析表的性质**
|
||
- 是否为主要业务表?
|
||
- 是否需要审计功能?
|
||
- 是否需要租户隔离?
|
||
|
||
2. **设置合适的配置**
|
||
```php
|
||
// 主要业务表
|
||
protected $enableSystemFields = true;
|
||
protected $enableTenantScope = true;
|
||
|
||
// 关联表
|
||
// 保持默认关闭,不需要显式设置
|
||
```
|
||
|
||
3. **确保数据库结构匹配**
|
||
- 添加必要的系统字段
|
||
- 创建合适的索引
|
||
|
||
### 升级现有项目
|
||
|
||
1. **检查现有模型**
|
||
- 确定哪些模型需要启用配置
|
||
- 检查数据库字段是否完整
|
||
|
||
2. **逐步启用**
|
||
- 先启用主要业务表
|
||
- 测试功能是否正常
|
||
- 逐步扩展到其他表
|
||
|
||
3. **数据迁移**
|
||
- 为缺少系统字段的表添加字段
|
||
- 填充历史数据的系统字段
|
||
|
||
## 性能考虑
|
||
|
||
### 查询性能
|
||
|
||
1. **为系统字段添加索引**
|
||
```sql
|
||
ALTER TABLE table_name ADD INDEX idx_tenant_id (tenant_id);
|
||
ALTER TABLE table_name ADD INDEX idx_deleted (deleted);
|
||
```
|
||
|
||
2. **合理使用全局作用域**
|
||
- 启用租户隔离会在所有查询中添加 `tenant_id` 过滤
|
||
- 启用系统字段维护会在所有查询中添加 `deleted = 0` 过滤
|
||
|
||
### 写入性能
|
||
|
||
1. **每次保存都会更新系统字段**
|
||
- 创建时设置:`creator`、`create_time`、`tenant_id`、`deleted`
|
||
- 更新时设置:`updater`、`update_time`
|
||
|
||
2. **批量操作优化**
|
||
- 使用 `DB::table()` 进行批量操作时,系统字段不会自动设置
|
||
- 需要手动设置系统字段值
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 如何临时跳过系统字段维护?
|
||
|
||
```php
|
||
// 方法1:使用 DB::table() 直接操作
|
||
DB::table('schools')->where('id', 1)->update(['name' => 'New Name']);
|
||
|
||
// 方法2:临时禁用钩子(不推荐)
|
||
School::withoutEvents(function () {
|
||
School::where('id', 1)->update(['name' => 'New Name']);
|
||
});
|
||
```
|
||
|
||
### Q2: 如何批量设置系统字段?
|
||
|
||
```php
|
||
// 使用模型的批量操作
|
||
$userId = auth()->id();
|
||
$tenantId = auth()->user()->tenant_id;
|
||
$now = now();
|
||
|
||
School::whereIn('id', $ids)->update([
|
||
'updater' => $userId,
|
||
'update_time' => $now,
|
||
'tenant_id' => $tenantId,
|
||
]);
|
||
```
|
||
|
||
### Q3: 关联表是否需要 tenant_id?
|
||
|
||
关联表通常不需要直接的 tenant_id,因为:
|
||
- 通过关联的主表来控制访问权限
|
||
- 查询时通过关联关系自动过滤
|
||
- 减少数据冗余
|
||
|
||
但在某些情况下,为了性能考虑,可能需要添加 tenant_id 字段。
|
||
|
||
## 总结
|
||
|
||
通过合理配置BaseModel的系统字段维护功能,可以实现:
|
||
|
||
1. **灵活的字段管理** - 根据表的特点选择性启用功能
|
||
2. **统一的开发体验** - 所有表遵循相同的配置规则
|
||
3. **高效的数据维护** - 自动处理常见的系统字段
|
||
4. **安全的数据隔离** - 租户隔离确保数据安全
|
||
|
||
建议在项目开始时就制定好配置策略,确保系统的一致性和可维护性。
|