|
|
@@ -11,6 +11,8 @@ use App\Module\Cleanup\Enums\CLEANUP_TYPE;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
+use Illuminate\Database\Eloquent\Model;
|
|
|
+use Illuminate\Database\Eloquent\SoftDeletes;
|
|
|
|
|
|
/**
|
|
|
* 清理执行逻辑类
|
|
|
@@ -173,27 +175,31 @@ class CleanupExecutorLogic
|
|
|
foreach ($enabledContents as $content) {
|
|
|
try {
|
|
|
// 更新当前步骤
|
|
|
+ $targetName = $content->model_class ?: $content->table_name;
|
|
|
CleanupTaskLogic::updateTaskProgress(
|
|
|
$task->id,
|
|
|
$processedTables,
|
|
|
$totalDeleted,
|
|
|
- "正在清理表: {$content->table_name}"
|
|
|
+ "正在清理: {$targetName}"
|
|
|
);
|
|
|
|
|
|
- // 执行表清理
|
|
|
- $result = static::executeTableCleanup($content, $task->id);
|
|
|
+ // 执行清理(支持Model类和表名两种模式)
|
|
|
+ $result = static::executeCleanup($content, $task->id);
|
|
|
|
|
|
if ($result['success']) {
|
|
|
$totalDeleted += $result['deleted_records'];
|
|
|
$processedTables++;
|
|
|
} else {
|
|
|
- $errors[] = "表 {$content->table_name}: " . $result['message'];
|
|
|
+ $targetName = $content->model_class ?: $content->table_name;
|
|
|
+ $errors[] = "{$targetName}: " . $result['message'];
|
|
|
}
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
- $errors[] = "表 {$content->table_name}: " . $e->getMessage();
|
|
|
- Log::error("清理表失败", [
|
|
|
+ $targetName = $content->model_class ?: $content->table_name;
|
|
|
+ $errors[] = "{$targetName}: " . $e->getMessage();
|
|
|
+ Log::error("清理失败", [
|
|
|
'task_id' => $task->id,
|
|
|
+ 'model_class' => $content->model_class,
|
|
|
'table_name' => $content->table_name,
|
|
|
'error' => $e->getMessage()
|
|
|
]);
|
|
|
@@ -376,6 +382,17 @@ class CleanupExecutorLogic
|
|
|
return $query->count();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 检查Model是否支持软删除
|
|
|
+ *
|
|
|
+ * @param Model $model Model实例
|
|
|
+ * @return bool 是否支持软删除
|
|
|
+ */
|
|
|
+ private static function modelSupportsSoftDeletes(Model $model): bool
|
|
|
+ {
|
|
|
+ return in_array(SoftDeletes::class, class_uses_recursive($model));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 解析时间条件
|
|
|
*
|
|
|
@@ -424,58 +441,31 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行表清理
|
|
|
+ * 执行清理(支持Model类和表名两种模式)
|
|
|
*
|
|
|
* @param CleanupPlanContent $content 计划内容
|
|
|
* @param int $taskId 任务ID
|
|
|
* @return array 执行结果
|
|
|
*/
|
|
|
- private static function executeTableCleanup(CleanupPlanContent $content, int $taskId): array
|
|
|
+ private static function executeCleanup(CleanupPlanContent $content, int $taskId): array
|
|
|
{
|
|
|
$startTime = microtime(true);
|
|
|
- $tableName = $content->table_name;
|
|
|
$cleanupType = CLEANUP_TYPE::from($content->cleanup_type);
|
|
|
|
|
|
try {
|
|
|
- // 检查表是否存在
|
|
|
- if (!Schema::hasTable($tableName)) {
|
|
|
- throw new \Exception("表 {$tableName} 不存在");
|
|
|
+ // 优先使用Model类,如果没有则使用表名
|
|
|
+ if (!empty($content->model_class)) {
|
|
|
+ return static::executeModelCleanup($content, $taskId, $startTime);
|
|
|
+ } else {
|
|
|
+ return static::executeTableCleanup($content, $taskId, $startTime);
|
|
|
}
|
|
|
|
|
|
- // 记录清理前的记录数
|
|
|
- $beforeCount = DB::table($tableName)->count();
|
|
|
-
|
|
|
- // 执行清理
|
|
|
- $deletedRecords = static::performCleanup($tableName, $cleanupType, $content->conditions, $content->batch_size);
|
|
|
-
|
|
|
- // 记录清理后的记录数
|
|
|
- $afterCount = DB::table($tableName)->count();
|
|
|
- $actualDeleted = $beforeCount - $afterCount;
|
|
|
-
|
|
|
- $executionTime = round(microtime(true) - $startTime, 3);
|
|
|
-
|
|
|
- // 记录清理日志
|
|
|
- static::logCleanupOperation($taskId, $tableName, $cleanupType, [
|
|
|
- 'before_count' => $beforeCount,
|
|
|
- 'after_count' => $afterCount,
|
|
|
- 'deleted_records' => $actualDeleted,
|
|
|
- 'execution_time' => $executionTime,
|
|
|
- 'conditions' => $content->conditions,
|
|
|
- 'batch_size' => $content->batch_size,
|
|
|
- ]);
|
|
|
-
|
|
|
- return [
|
|
|
- 'success' => true,
|
|
|
- 'message' => "表 {$tableName} 清理成功",
|
|
|
- 'deleted_records' => $actualDeleted,
|
|
|
- 'execution_time' => $executionTime,
|
|
|
- ];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
$executionTime = round(microtime(true) - $startTime, 3);
|
|
|
+ $targetName = $content->model_class ?: $content->table_name;
|
|
|
|
|
|
// 记录错误日志
|
|
|
- static::logCleanupOperation($taskId, $tableName, $cleanupType, [
|
|
|
+ static::logCleanupOperation($taskId, $content, $cleanupType, [
|
|
|
'error' => $e->getMessage(),
|
|
|
'execution_time' => $executionTime,
|
|
|
'conditions' => $content->conditions,
|
|
|
@@ -491,7 +481,138 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行实际的清理操作
|
|
|
+ * 执行基于Model类的清理
|
|
|
+ *
|
|
|
+ * @param CleanupPlanContent $content 计划内容
|
|
|
+ * @param int $taskId 任务ID
|
|
|
+ * @param float $startTime 开始时间
|
|
|
+ * @return array 执行结果
|
|
|
+ */
|
|
|
+ private static function executeModelCleanup(CleanupPlanContent $content, int $taskId, float $startTime): array
|
|
|
+ {
|
|
|
+ $modelClass = $content->model_class;
|
|
|
+ $cleanupType = CLEANUP_TYPE::from($content->cleanup_type);
|
|
|
+
|
|
|
+ // 检查Model类是否存在
|
|
|
+ if (!class_exists($modelClass)) {
|
|
|
+ throw new \Exception("Model类不存在: {$modelClass}");
|
|
|
+ }
|
|
|
+
|
|
|
+ $model = new $modelClass();
|
|
|
+ $tableName = $model->getTable();
|
|
|
+
|
|
|
+ // 记录清理前的记录数
|
|
|
+ $beforeCount = $modelClass::count();
|
|
|
+
|
|
|
+ // 执行清理
|
|
|
+ $deletedRecords = static::performModelCleanup($modelClass, $cleanupType, $content->conditions, $content->batch_size);
|
|
|
+
|
|
|
+ // 记录清理后的记录数
|
|
|
+ $afterCount = $modelClass::count();
|
|
|
+ $actualDeleted = $beforeCount - $afterCount;
|
|
|
+
|
|
|
+ $executionTime = round(microtime(true) - $startTime, 3);
|
|
|
+
|
|
|
+ // 记录清理日志
|
|
|
+ static::logCleanupOperation($taskId, $content, $cleanupType, [
|
|
|
+ 'before_count' => $beforeCount,
|
|
|
+ 'after_count' => $afterCount,
|
|
|
+ 'deleted_records' => $actualDeleted,
|
|
|
+ 'execution_time' => $executionTime,
|
|
|
+ 'conditions' => $content->conditions,
|
|
|
+ 'batch_size' => $content->batch_size,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => "Model {$modelClass} 清理成功",
|
|
|
+ 'deleted_records' => $actualDeleted,
|
|
|
+ 'execution_time' => $executionTime,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行基于表名的清理(向后兼容)
|
|
|
+ *
|
|
|
+ * @param CleanupPlanContent $content 计划内容
|
|
|
+ * @param int $taskId 任务ID
|
|
|
+ * @param float $startTime 开始时间
|
|
|
+ * @return array 执行结果
|
|
|
+ */
|
|
|
+ private static function executeTableCleanup(CleanupPlanContent $content, int $taskId, float $startTime): array
|
|
|
+ {
|
|
|
+ $tableName = $content->table_name;
|
|
|
+ $cleanupType = CLEANUP_TYPE::from($content->cleanup_type);
|
|
|
+
|
|
|
+ // 检查表是否存在
|
|
|
+ if (!Schema::hasTable($tableName)) {
|
|
|
+ throw new \Exception("表 {$tableName} 不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 记录清理前的记录数
|
|
|
+ $beforeCount = DB::table($tableName)->count();
|
|
|
+
|
|
|
+ // 执行清理
|
|
|
+ $deletedRecords = static::performTableCleanup($tableName, $cleanupType, $content->conditions, $content->batch_size);
|
|
|
+
|
|
|
+ // 记录清理后的记录数
|
|
|
+ $afterCount = DB::table($tableName)->count();
|
|
|
+ $actualDeleted = $beforeCount - $afterCount;
|
|
|
+
|
|
|
+ $executionTime = round(microtime(true) - $startTime, 3);
|
|
|
+
|
|
|
+ // 记录清理日志
|
|
|
+ static::logCleanupOperation($taskId, $content, $cleanupType, [
|
|
|
+ 'before_count' => $beforeCount,
|
|
|
+ 'after_count' => $afterCount,
|
|
|
+ 'deleted_records' => $actualDeleted,
|
|
|
+ 'execution_time' => $executionTime,
|
|
|
+ 'conditions' => $content->conditions,
|
|
|
+ 'batch_size' => $content->batch_size,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => "表 {$tableName} 清理成功",
|
|
|
+ 'deleted_records' => $actualDeleted,
|
|
|
+ 'execution_time' => $executionTime,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行基于Model类的清理操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @param CLEANUP_TYPE $cleanupType 清理类型
|
|
|
+ * @param array $conditions 清理条件
|
|
|
+ * @param int $batchSize 批处理大小
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelCleanup(string $modelClass, CLEANUP_TYPE $cleanupType, array $conditions, int $batchSize): int
|
|
|
+ {
|
|
|
+ switch ($cleanupType) {
|
|
|
+ case CLEANUP_TYPE::TRUNCATE:
|
|
|
+ return static::performModelTruncate($modelClass);
|
|
|
+
|
|
|
+ case CLEANUP_TYPE::DELETE_ALL:
|
|
|
+ return static::performModelDeleteAll($modelClass, $batchSize);
|
|
|
+
|
|
|
+ case CLEANUP_TYPE::DELETE_BY_TIME:
|
|
|
+ return static::performModelDeleteByTime($modelClass, $conditions, $batchSize);
|
|
|
+
|
|
|
+ case CLEANUP_TYPE::DELETE_BY_USER:
|
|
|
+ return static::performModelDeleteByUser($modelClass, $conditions, $batchSize);
|
|
|
+
|
|
|
+ case CLEANUP_TYPE::DELETE_BY_CONDITION:
|
|
|
+ return static::performModelDeleteByCondition($modelClass, $conditions, $batchSize);
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw new \Exception("不支持的清理类型: {$cleanupType->value}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行基于表名的清理操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @param CLEANUP_TYPE $cleanupType 清理类型
|
|
|
@@ -499,23 +620,23 @@ class CleanupExecutorLogic
|
|
|
* @param int $batchSize 批处理大小
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performCleanup(string $tableName, CLEANUP_TYPE $cleanupType, array $conditions, int $batchSize): int
|
|
|
+ private static function performTableCleanup(string $tableName, CLEANUP_TYPE $cleanupType, array $conditions, int $batchSize): int
|
|
|
{
|
|
|
switch ($cleanupType) {
|
|
|
case CLEANUP_TYPE::TRUNCATE:
|
|
|
- return static::performTruncate($tableName);
|
|
|
+ return static::performTableTruncate($tableName);
|
|
|
|
|
|
case CLEANUP_TYPE::DELETE_ALL:
|
|
|
- return static::performDeleteAll($tableName, $batchSize);
|
|
|
+ return static::performTableDeleteAll($tableName, $batchSize);
|
|
|
|
|
|
case CLEANUP_TYPE::DELETE_BY_TIME:
|
|
|
- return static::performDeleteByTime($tableName, $conditions, $batchSize);
|
|
|
+ return static::performTableDeleteByTime($tableName, $conditions, $batchSize);
|
|
|
|
|
|
case CLEANUP_TYPE::DELETE_BY_USER:
|
|
|
- return static::performDeleteByUser($tableName, $conditions, $batchSize);
|
|
|
+ return static::performTableDeleteByUser($tableName, $conditions, $batchSize);
|
|
|
|
|
|
case CLEANUP_TYPE::DELETE_BY_CONDITION:
|
|
|
- return static::performDeleteByCondition($tableName, $conditions, $batchSize);
|
|
|
+ return static::performTableDeleteByCondition($tableName, $conditions, $batchSize);
|
|
|
|
|
|
default:
|
|
|
throw new \Exception("不支持的清理类型: {$cleanupType->value}");
|
|
|
@@ -523,12 +644,25 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行TRUNCATE操作
|
|
|
+ * 执行Model的TRUNCATE操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelTruncate(string $modelClass): int
|
|
|
+ {
|
|
|
+ $beforeCount = $modelClass::count();
|
|
|
+ $modelClass::truncate();
|
|
|
+ return $beforeCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行表的TRUNCATE操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performTruncate(string $tableName): int
|
|
|
+ private static function performTableTruncate(string $tableName): int
|
|
|
{
|
|
|
$beforeCount = DB::table($tableName)->count();
|
|
|
DB::statement("TRUNCATE TABLE `{$tableName}`");
|
|
|
@@ -536,13 +670,32 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行DELETE ALL操作
|
|
|
+ * 执行Model的DELETE ALL操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @param int $batchSize 批处理大小
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelDeleteAll(string $modelClass, int $batchSize): int
|
|
|
+ {
|
|
|
+ $totalDeleted = 0;
|
|
|
+
|
|
|
+ do {
|
|
|
+ $deleted = $modelClass::limit($batchSize)->delete();
|
|
|
+ $totalDeleted += $deleted;
|
|
|
+ } while ($deleted > 0);
|
|
|
+
|
|
|
+ return $totalDeleted;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行表的DELETE ALL操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @param int $batchSize 批处理大小
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performDeleteAll(string $tableName, int $batchSize): int
|
|
|
+ private static function performTableDeleteAll(string $tableName, int $batchSize): int
|
|
|
{
|
|
|
$totalDeleted = 0;
|
|
|
|
|
|
@@ -555,14 +708,52 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行按时间删除操作
|
|
|
+ * 执行Model的按时间删除操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @param array $conditions 条件
|
|
|
+ * @param int $batchSize 批处理大小
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelDeleteByTime(string $modelClass, array $conditions, int $batchSize): int
|
|
|
+ {
|
|
|
+ if (empty($conditions['time_field']) || empty($conditions['before'])) {
|
|
|
+ throw new \Exception('时间删除条件不完整');
|
|
|
+ }
|
|
|
+
|
|
|
+ $timeField = $conditions['time_field'];
|
|
|
+ $beforeTime = static::parseTimeCondition($conditions['before']);
|
|
|
+ $totalDeleted = 0;
|
|
|
+
|
|
|
+ // 检查Model是否支持软删除
|
|
|
+ $model = new $modelClass();
|
|
|
+ $supportsSoftDeletes = static::modelSupportsSoftDeletes($model);
|
|
|
+ $forceDelete = $conditions['force_delete'] ?? false;
|
|
|
+
|
|
|
+ do {
|
|
|
+ $query = $modelClass::where($timeField, '<', $beforeTime)->limit($batchSize);
|
|
|
+
|
|
|
+ if ($supportsSoftDeletes && $forceDelete) {
|
|
|
+ $deleted = $query->forceDelete();
|
|
|
+ } else {
|
|
|
+ $deleted = $query->delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalDeleted += $deleted;
|
|
|
+ } while ($deleted > 0);
|
|
|
+
|
|
|
+ return $totalDeleted;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行表的按时间删除操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @param array $conditions 条件
|
|
|
* @param int $batchSize 批处理大小
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performDeleteByTime(string $tableName, array $conditions, int $batchSize): int
|
|
|
+ private static function performTableDeleteByTime(string $tableName, array $conditions, int $batchSize): int
|
|
|
{
|
|
|
if (empty($conditions['time_field']) || empty($conditions['before'])) {
|
|
|
throw new \Exception('时间删除条件不完整');
|
|
|
@@ -584,14 +775,73 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行按用户删除操作
|
|
|
+ * 执行Model的按用户删除操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @param array $conditions 条件
|
|
|
+ * @param int $batchSize 批处理大小
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelDeleteByUser(string $modelClass, array $conditions, int $batchSize): int
|
|
|
+ {
|
|
|
+ if (empty($conditions['user_field']) || empty($conditions['user_values'])) {
|
|
|
+ throw new \Exception('用户删除条件不完整');
|
|
|
+ }
|
|
|
+
|
|
|
+ $userField = $conditions['user_field'];
|
|
|
+ $userCondition = $conditions['user_condition'] ?? 'in';
|
|
|
+ $userValues = is_array($conditions['user_values']) ? $conditions['user_values'] : [$conditions['user_values']];
|
|
|
+ $totalDeleted = 0;
|
|
|
+
|
|
|
+ // 检查Model是否支持软删除
|
|
|
+ $model = new $modelClass();
|
|
|
+ $supportsSoftDeletes = static::modelSupportsSoftDeletes($model);
|
|
|
+ $forceDelete = $conditions['force_delete'] ?? false;
|
|
|
+
|
|
|
+ do {
|
|
|
+ $query = $modelClass::query();
|
|
|
+
|
|
|
+ // 应用用户条件
|
|
|
+ switch ($userCondition) {
|
|
|
+ case 'in':
|
|
|
+ $query->whereIn($userField, $userValues);
|
|
|
+ break;
|
|
|
+ case 'not_in':
|
|
|
+ $query->whereNotIn($userField, $userValues);
|
|
|
+ break;
|
|
|
+ case 'null':
|
|
|
+ $query->whereNull($userField);
|
|
|
+ break;
|
|
|
+ case 'not_null':
|
|
|
+ $query->whereNotNull($userField);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new \Exception("不支持的用户条件: {$userCondition}");
|
|
|
+ }
|
|
|
+
|
|
|
+ $query->limit($batchSize);
|
|
|
+
|
|
|
+ if ($supportsSoftDeletes && $forceDelete) {
|
|
|
+ $deleted = $query->forceDelete();
|
|
|
+ } else {
|
|
|
+ $deleted = $query->delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalDeleted += $deleted;
|
|
|
+ } while ($deleted > 0);
|
|
|
+
|
|
|
+ return $totalDeleted;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行表的按用户删除操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @param array $conditions 条件
|
|
|
* @param int $batchSize 批处理大小
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performDeleteByUser(string $tableName, array $conditions, int $batchSize): int
|
|
|
+ private static function performTableDeleteByUser(string $tableName, array $conditions, int $batchSize): int
|
|
|
{
|
|
|
if (empty($conditions['user_field']) || empty($conditions['user_ids'])) {
|
|
|
throw new \Exception('用户删除条件不完整');
|
|
|
@@ -613,14 +863,58 @@ class CleanupExecutorLogic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行按条件删除操作
|
|
|
+ * 执行Model的按条件删除操作
|
|
|
+ *
|
|
|
+ * @param string $modelClass Model类名
|
|
|
+ * @param array $conditions 条件
|
|
|
+ * @param int $batchSize 批处理大小
|
|
|
+ * @return int 删除的记录数
|
|
|
+ */
|
|
|
+ private static function performModelDeleteByCondition(string $modelClass, array $conditions, int $batchSize): int
|
|
|
+ {
|
|
|
+ if (empty($conditions['where'])) {
|
|
|
+ throw new \Exception('自定义删除条件不完整');
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalDeleted = 0;
|
|
|
+
|
|
|
+ // 检查Model是否支持软删除
|
|
|
+ $model = new $modelClass();
|
|
|
+ $supportsSoftDeletes = static::modelSupportsSoftDeletes($model);
|
|
|
+ $forceDelete = $conditions['force_delete'] ?? false;
|
|
|
+
|
|
|
+ do {
|
|
|
+ $query = $modelClass::query();
|
|
|
+
|
|
|
+ foreach ($conditions['where'] as $condition) {
|
|
|
+ if (isset($condition['field'], $condition['operator'], $condition['value'])) {
|
|
|
+ $query->where($condition['field'], $condition['operator'], $condition['value']);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $query->limit($batchSize);
|
|
|
+
|
|
|
+ if ($supportsSoftDeletes && $forceDelete) {
|
|
|
+ $deleted = $query->forceDelete();
|
|
|
+ } else {
|
|
|
+ $deleted = $query->delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ $totalDeleted += $deleted;
|
|
|
+ } while ($deleted > 0);
|
|
|
+
|
|
|
+ return $totalDeleted;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行表的按条件删除操作(向后兼容)
|
|
|
*
|
|
|
* @param string $tableName 表名
|
|
|
* @param array $conditions 条件
|
|
|
* @param int $batchSize 批处理大小
|
|
|
* @return int 删除的记录数
|
|
|
*/
|
|
|
- private static function performDeleteByCondition(string $tableName, array $conditions, int $batchSize): int
|
|
|
+ private static function performTableDeleteByCondition(string $tableName, array $conditions, int $batchSize): int
|
|
|
{
|
|
|
if (empty($conditions['where'])) {
|
|
|
throw new \Exception('自定义删除条件不完整');
|
|
|
@@ -648,13 +942,23 @@ class CleanupExecutorLogic
|
|
|
* 记录清理操作日志
|
|
|
*
|
|
|
* @param int $taskId 任务ID
|
|
|
- * @param string $tableName 表名
|
|
|
+ * @param CleanupPlanContent $content 计划内容
|
|
|
* @param CLEANUP_TYPE $cleanupType 清理类型
|
|
|
* @param array $details 详细信息
|
|
|
*/
|
|
|
- private static function logCleanupOperation(int $taskId, string $tableName, CLEANUP_TYPE $cleanupType, array $details): void
|
|
|
+ private static function logCleanupOperation(int $taskId, CleanupPlanContent $content, CLEANUP_TYPE $cleanupType, array $details): void
|
|
|
{
|
|
|
try {
|
|
|
+ $tableName = $content->table_name;
|
|
|
+ if (!empty($content->model_class)) {
|
|
|
+ // 如果有Model类,从Model获取表名
|
|
|
+ $modelClass = $content->model_class;
|
|
|
+ if (class_exists($modelClass)) {
|
|
|
+ $model = new $modelClass();
|
|
|
+ $tableName = $model->getTable();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
CleanupLog::create([
|
|
|
'task_id' => $taskId,
|
|
|
'table_name' => $tableName,
|
|
|
@@ -665,12 +969,14 @@ class CleanupExecutorLogic
|
|
|
'execution_time' => $details['execution_time'] ?? 0,
|
|
|
'conditions' => $details['conditions'] ?? [],
|
|
|
'error_message' => $details['error'] ?? null,
|
|
|
+ 'model_class' => $content->model_class,
|
|
|
'created_at' => now(),
|
|
|
]);
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('记录清理日志失败', [
|
|
|
'task_id' => $taskId,
|
|
|
- 'table_name' => $tableName,
|
|
|
+ 'model_class' => $content->model_class ?? null,
|
|
|
+ 'table_name' => $content->table_name ?? null,
|
|
|
'error' => $e->getMessage()
|
|
|
]);
|
|
|
}
|