| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- <?php
- namespace App\Module\Cleanup\Logics;
- use App\Module\Cleanup\Models\CleanupPlan;
- use App\Module\Cleanup\Models\CleanupPlanContent;
- use App\Module\Cleanup\Models\CleanupConfig;
- use App\Module\Cleanup\Enums\DATA_CATEGORY;
- use App\Module\Cleanup\Enums\CLEANUP_TYPE;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 清理计划管理逻辑类
- *
- * 负责清理计划的创建、管理和内容生成
- */
- class CleanupPlanLogic
- {
- /**
- * 创建清理计划
- *
- * @param array $planData 计划数据
- * @return array 创建结果
- */
- public static function createPlan(array $planData): array
- {
- try {
- DB::beginTransaction();
- // 验证计划数据
- $validatedData = static::validatePlanData($planData);
-
- // 创建计划
- $plan = CleanupPlan::create($validatedData);
-
- // 如果需要自动生成内容,则生成计划内容
- if ($planData['auto_generate_contents'] ?? true) {
- $contentResult = static::generateContents($plan->id, true);
- if (!$contentResult['success']) {
- throw new \Exception('生成计划内容失败: ' . $contentResult['message']);
- }
- }
- DB::commit();
- return [
- 'success' => true,
- 'message' => '清理计划创建成功',
- 'data' => [
- 'plan_id' => $plan->id,
- 'plan_name' => $plan->plan_name,
- 'plan_type' => $plan->plan_type,
- 'contents_count' => $plan->contents()->count(),
- ]
- ];
- } catch (\Exception $e) {
- DB::rollBack();
- Log::error('创建清理计划失败', [
- 'plan_data' => $planData,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return [
- 'success' => false,
- 'message' => '创建清理计划失败: ' . $e->getMessage(),
- 'data' => null
- ];
- }
- }
- /**
- * 为计划生成内容配置
- *
- * @param int $planId 计划ID
- * @param bool $autoGenerate 是否自动生成
- * @return array 生成结果
- */
- public static function generateContents(int $planId, bool $autoGenerate = true): array
- {
- try {
- $plan = CleanupPlan::findOrFail($planId);
-
- // 根据计划类型获取目标表
- $targetTables = static::getTargetTables($plan);
-
- if (empty($targetTables)) {
- return [
- 'success' => false,
- 'message' => '未找到符合条件的目标表',
- 'data' => null
- ];
- }
- $generatedCount = 0;
- $skippedCount = 0;
- $errors = [];
- foreach ($targetTables as $tableName) {
- try {
- // 检查是否已存在内容配置
- $existingContent = CleanupPlanContent::where('plan_id', $planId)
- ->where('table_name', $tableName)
- ->first();
- if ($existingContent && !$autoGenerate) {
- $skippedCount++;
- continue;
- }
- // 获取表的配置信息
- $tableConfig = CleanupConfig::where('table_name', $tableName)->first();
-
- // 生成内容配置
- $contentData = static::generateTableContent($plan, $tableName, $tableConfig);
-
- if ($existingContent) {
- $existingContent->update($contentData);
- } else {
- $contentData['plan_id'] = $planId;
- $contentData['table_name'] = $tableName;
- CleanupPlanContent::create($contentData);
- }
-
- $generatedCount++;
- } catch (\Exception $e) {
- $errors[] = "表 {$tableName}: " . $e->getMessage();
- Log::error("生成表内容配置失败", [
- 'plan_id' => $planId,
- 'table_name' => $tableName,
- 'error' => $e->getMessage()
- ]);
- }
- }
- return [
- 'success' => true,
- 'message' => "内容生成完成,生成 {$generatedCount} 个,跳过 {$skippedCount} 个",
- 'data' => [
- 'generated_count' => $generatedCount,
- 'skipped_count' => $skippedCount,
- 'total_tables' => count($targetTables),
- 'errors' => $errors
- ]
- ];
- } catch (\Exception $e) {
- Log::error('生成计划内容失败', [
- 'plan_id' => $planId,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return [
- 'success' => false,
- 'message' => '生成计划内容失败: ' . $e->getMessage(),
- 'data' => null
- ];
- }
- }
- /**
- * 验证计划数据
- *
- * @param array $planData 计划数据
- * @return array 验证后的数据
- * @throws \Exception
- */
- private static function validatePlanData(array $planData): array
- {
- // 必填字段验证
- $required = ['plan_name', 'plan_type'];
- foreach ($required as $field) {
- if (empty($planData[$field])) {
- throw new \Exception("字段 {$field} 不能为空");
- }
- }
- // 验证计划类型
- $planType = PLAN_TYPE::tryFrom($planData['plan_type']);
- if (!$planType) {
- throw new \Exception('无效的计划类型');
- }
- // 根据计划类型验证目标选择
- if ($planType !== PLAN_TYPE::CUSTOM && empty($planData['target_selection'])) {
- throw new \Exception('目标选择不能为空');
- }
- return [
- 'plan_name' => $planData['plan_name'],
- 'plan_type' => $planData['plan_type'],
- 'target_selection' => $planData['target_selection'] ?? [],
- 'global_conditions' => $planData['global_conditions'] ?? [],
- 'backup_config' => $planData['backup_config'] ?? [],
- 'is_template' => $planData['is_template'] ?? false,
- 'is_enabled' => $planData['is_enabled'] ?? true,
- 'description' => $planData['description'] ?? '',
- 'created_by' => $planData['created_by'] ?? 0,
- ];
- }
- /**
- * 根据计划获取目标表列表
- *
- * @param CleanupPlan $plan 清理计划
- * @return array 目标表列表
- */
- private static function getTargetTables(CleanupPlan $plan): array
- {
- $tables = [];
- $selectedModels = $plan->selected_tables ?? [];
- foreach ($selectedModels as $modelClass) {
- if (class_exists($modelClass) && is_subclass_of($modelClass, \Illuminate\Database\Eloquent\Model::class)) {
- try {
- // 通过模型实例获取表名
- $model = new $modelClass();
- $tableName = $model->getTable();
- $tables[] = $tableName;
- } catch (\Exception $e) {
- // 如果模型实例化失败,记录错误但继续处理其他模型
- \Log::warning("Failed to get table name for model: {$modelClass}", ['error' => $e->getMessage()]);
- }
- }
- }
- return array_unique($tables);
- }
- /**
- * 为表生成内容配置
- *
- * @param CleanupPlan $plan 清理计划
- * @param string $tableName 表名
- * @param CleanupConfig|null $tableConfig 表配置
- * @return array 内容配置数据
- */
- private static function generateTableContent(CleanupPlan $plan, string $tableName, ?CleanupConfig $tableConfig): array
- {
- // 基础配置
- $contentData = [
- 'cleanup_type' => $tableConfig?->default_cleanup_type ?? CLEANUP_TYPE::DELETE_ALL->value,
- 'conditions' => $tableConfig?->default_conditions ?? [],
- 'priority' => $tableConfig?->priority ?? 100,
- 'batch_size' => $tableConfig?->batch_size ?? 1000,
- 'backup_enabled' => true,
- 'is_enabled' => true,
- 'notes' => $tableConfig?->description ?? "自动生成的 {$tableName} 表清理配置",
- ];
- // 合并计划的全局条件
- if (!empty($plan->global_conditions)) {
- $contentData['conditions'] = array_merge(
- $contentData['conditions'],
- $plan->global_conditions
- );
- }
- // 合并计划的备份配置
- if (!empty($plan->backup_config)) {
- $contentData['backup_config'] = $plan->backup_config;
- }
- return $contentData;
- }
- /**
- * 获取计划详情
- *
- * @param int $planId 计划ID
- * @return array 计划详情
- */
- public static function getPlanDetails(int $planId): array
- {
- try {
- $plan = CleanupPlan::with(['contents.config'])->findOrFail($planId);
- $contents = $plan->contents->map(function ($content) {
- return [
- 'id' => $content->id,
- 'table_name' => $content->table_name,
- 'cleanup_type' => $content->cleanup_type,
- 'cleanup_type_name' => CLEANUP_TYPE::from($content->cleanup_type)->getDescription(),
- 'conditions' => $content->conditions,
- 'priority' => $content->priority,
- 'batch_size' => $content->batch_size,
- 'backup_enabled' => $content->backup_enabled,
- 'is_enabled' => $content->is_enabled,
- 'notes' => $content->notes,
- 'module_name' => $content->config?->module_name,
- 'data_category' => $content->config?->data_category,
- ];
- });
- return [
- 'success' => true,
- 'data' => [
- 'plan' => [
- 'id' => $plan->id,
- 'plan_name' => $plan->plan_name,
- 'selected_tables' => $plan->selected_tables,
- 'global_conditions' => $plan->global_conditions,
- 'backup_config' => $plan->backup_config,
- 'is_template' => $plan->is_template,
- 'is_enabled' => $plan->is_enabled,
- 'description' => $plan->description,
- 'created_at' => $plan->created_at,
- 'updated_at' => $plan->updated_at,
- ],
- 'contents' => $contents,
- 'statistics' => [
- 'total_tables' => $contents->count(),
- 'enabled_tables' => $contents->where('is_enabled', true)->count(),
- 'backup_enabled_tables' => $contents->where('backup_enabled', true)->count(),
- ]
- ]
- ];
- } catch (\Exception $e) {
- Log::error('获取计划详情失败', [
- 'plan_id' => $planId,
- 'error' => $e->getMessage()
- ]);
- return [
- 'success' => false,
- 'message' => '获取计划详情失败: ' . $e->getMessage(),
- 'data' => null
- ];
- }
- }
- /**
- * 更新计划
- *
- * @param int $planId 计划ID
- * @param array $planData 计划数据
- * @return array 更新结果
- */
- public static function updatePlan(int $planId, array $planData): array
- {
- try {
- $plan = CleanupPlan::findOrFail($planId);
- // 验证数据
- $validatedData = static::validatePlanData($planData);
- // 更新计划
- $plan->update($validatedData);
- return [
- 'success' => true,
- 'message' => '计划更新成功',
- 'data' => [
- 'plan_id' => $plan->id,
- 'plan_name' => $plan->plan_name,
- ]
- ];
- } catch (\Exception $e) {
- Log::error('更新计划失败', [
- 'plan_id' => $planId,
- 'plan_data' => $planData,
- 'error' => $e->getMessage()
- ]);
- return [
- 'success' => false,
- 'message' => '更新计划失败: ' . $e->getMessage(),
- 'data' => null
- ];
- }
- }
- /**
- * 删除计划
- *
- * @param int $planId 计划ID
- * @return array 删除结果
- */
- public static function deletePlan(int $planId): array
- {
- try {
- DB::beginTransaction();
- $plan = CleanupPlan::findOrFail($planId);
- // 检查是否有关联的任务
- if ($plan->tasks()->exists()) {
- throw new \Exception('该计划存在关联的任务,无法删除');
- }
- // 删除计划内容
- $plan->contents()->delete();
- // 删除计划
- $plan->delete();
- DB::commit();
- return [
- 'success' => true,
- 'message' => '计划删除成功',
- 'data' => null
- ];
- } catch (\Exception $e) {
- DB::rollBack();
- Log::error('删除计划失败', [
- 'plan_id' => $planId,
- 'error' => $e->getMessage()
- ]);
- return [
- 'success' => false,
- 'message' => '删除计划失败: ' . $e->getMessage(),
- 'data' => null
- ];
- }
- }
- }
|