# 12.4 数据删除规范 ## 软删除约定 :::tip 核心原则 所有业务数据统一使用软删除机制,通过 `is_delete` 字段标记记录状态,不物理删除数据。 ::: | is_delete 值 | 含义 | |--------------|------| | `0` | 正常记录(默认值) | | `1` | 已删除记录 | 所有查询方法自动过滤 `is_delete = 0`,业务层无需关心已删除数据。 ## 单条删除 ### URL 格式 ```text DELETE /api/{module}/delete/{id} ``` ### Controller 示例 ```php #[Log('案例演示-删除记录', Log::TYPE_DELETE, '删除案例演示ID:{id}')] #[Permission('sys:example:delete', '删除案例演示')] public function delete(int $id): Json { return parent::_remove($this->logic, $id); } ``` ### 内部流程 ```text Controller::delete($id) │ ▼ BaseController::_remove($logic, $id) │ ▼ BaseLogic::delete($id) │ ├─ beforeDelete($id) 钩子(抛异常可拦截) │ ├─ $model->find($id) │ └─ 不存在 → return false │ ├─ $model->save(['is_delete' => 1]) │ └─ afterDelete($id) 钩子 ``` ## 批量删除 ### 请求格式 ```text DELETE /api/{module}/batchDelete Content-Type: application/json { "ids": [1, 2, 3] } ``` ### Controller 示例 ```php #[Log('案例演示-批量删除', Log::TYPE_DELETE)] #[Permission('sys:example:delete', '删除案例演示')] public function batchDelete(): Json { $ids = $this->getJsonBody()['ids'] ?? []; return parent::_batchRemove($this->logic, $ids); } ``` ### 内部流程 ```text Controller::batchDelete() │ ▼ BaseController::_batchRemove($logic, $ids) │ ├─ ids 为空 → 返回失败 "请选择要删除的数据" │ ▼ BaseLogic::batchDelete($ids) │ ├─ beforeBatchDelete($ids) 钩子(整体校验) │ ├─ 逐条 beforeDelete($id) 校验 │ ├─ Model::batchSoftDelete($ids) │ └─ UPDATE SET is_delete = 1 WHERE id IN (...) │ └─ afterBatchDelete($ids) 钩子 ``` ## 删除前校验(beforeDelete 钩子) 在 Logic 中重写 `beforeDelete` 方法,抛异常可拦截删除: ```php class UserLogic extends BaseTenantLogic { protected function beforeDelete(int $id): void { // 检查是否有子级 $children = Dept::where('parent_id', $id)->where('is_delete', 0)->count(); if ($children > 0) { throw new \Exception('存在子部门,不可删除'); } // 检查是否被引用 $userCount = User::where('dept_id', $id)->where('is_delete', 0)->count(); if ($userCount > 0) { throw new \Exception('该部门下有用户,不可删除'); } } } ``` ## 何时可物理删除 | 场景 | 方式 | 说明 | |------|------|------| | 日志数据清理 | 定时任务 | CleanLogTask 清理 N 天前的日志 | | 临时数据 | 定时任务 | 清理过期的临时文件 | | 其它 | 审批 | 需经过管理员审批 | ## 前端删除规范 ### 单条删除 ```vue 确认删除该记录? ``` ### 批量删除 ```vue 批量删除 ({{ selectedIds.length }}) ```