[ 'name' => $template->name, 'description' => $template->description, 'category' => $template->category, 'tags' => $template->tags, 'version' => $template->version, 'applicable_departments' => $template->applicable_departments, 'applicable_positions' => $template->applicable_positions, ], 'steps' => $template->steps->map(function ($step) { return [ 'step_number' => $step->step_number, 'title' => $step->title, 'content' => $step->content, 'sort_order' => $step->sort_order, 'is_required' => $step->is_required, 'interactive_tasks' => $step->interactiveTasks->map(function ($task) { return [ 'task_type' => $task->task_type, 'task_config' => $task->task_config, 'validation_rules' => $task->validation_rules, 'timeout_seconds' => $task->timeout_seconds, 'is_required' => $task->is_required, ]; })->toArray(), ]; })->toArray(), 'exported_at' => now()->toIso8601String(), 'exported_by' => auth()->user()?->name, ]; return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } /** * 从 JSON 导入模板 * * @param string $json * @return SopTemplate * @throws ValidationException */ public function importFromJson(string $json): SopTemplate { $data = json_decode($json, true); if (json_last_error() !== JSON_ERROR_NONE) { throw ValidationException::withMessages([ 'file' => ['无效的 JSON 格式'], ]); } // 验证数据结构 $validator = Validator::make($data, [ 'template' => 'required|array', 'template.name' => 'required|string|max:255', 'template.version' => 'required|string|max:50', 'steps' => 'required|array|min:1', 'steps.*.step_number' => 'required|integer', 'steps.*.title' => 'required|string|max:255', ]); if ($validator->fails()) { throw new ValidationException($validator); } return DB::transaction(function () use ($data) { // 创建模板 $template = SopTemplate::create([ 'name' => $data['template']['name'], 'description' => $data['template']['description'] ?? null, 'category' => $data['template']['category'] ?? null, 'tags' => $data['template']['tags'] ?? [], 'version' => $data['template']['version'], 'status' => 'draft', 'applicable_departments' => $data['template']['applicable_departments'] ?? [], 'applicable_positions' => $data['template']['applicable_positions'] ?? [], 'created_by' => auth()->id(), ]); // 创建步骤 foreach ($data['steps'] as $stepData) { $step = $template->steps()->create([ 'step_number' => $stepData['step_number'], 'title' => $stepData['title'], 'content' => $stepData['content'] ?? null, 'sort_order' => $stepData['sort_order'] ?? $stepData['step_number'], 'is_required' => $stepData['is_required'] ?? true, ]); // 创建交互任务 if (!empty($stepData['interactive_tasks'])) { foreach ($stepData['interactive_tasks'] as $taskData) { $step->interactiveTasks()->create([ 'task_type' => $taskData['task_type'], 'task_config' => $taskData['task_config'] ?? [], 'validation_rules' => $taskData['validation_rules'] ?? [], 'timeout_seconds' => $taskData['timeout_seconds'] ?? null, 'is_required' => $taskData['is_required'] ?? true, ]); } } } return $template; }); } /** * 发布模板 * * @param SopTemplate $template * @param string|null $changeLog * @return void */ public function publish(SopTemplate $template, ?string $changeLog = null): void { // 创建版本快照 $this->createVersion($template, $changeLog); // 更新状态 $template->update([ 'status' => 'published', 'published_at' => now(), ]); } /** * 创建版本快照 * * @param SopTemplate $template * @param string|null $changeLog * @return SopTemplateVersion */ public function createVersion(SopTemplate $template, ?string $changeLog = null): SopTemplateVersion { return SopTemplateVersion::create([ 'sop_template_id' => $template->id, 'version' => $template->version, 'change_log' => $changeLog ?? '版本快照', 'content_snapshot' => [ 'template' => $template->toArray(), 'steps' => $template->steps->map(function ($step) { return array_merge($step->toArray(), [ 'interactive_tasks' => $step->interactiveTasks->toArray(), ]); })->toArray(), ], 'created_by' => auth()->id(), 'created_at' => now(), ]); } /** * 归档模板 * * @param SopTemplate $template * @return void */ public function archive(SopTemplate $template): void { $template->update([ 'status' => 'archived', ]); } /** * 复制模板 * * @param SopTemplate $template * @param string $newName * @return SopTemplate */ public function duplicate(SopTemplate $template, string $newName): SopTemplate { return DB::transaction(function () use ($template, $newName) { // 复制模板 $newTemplate = $template->replicate(); $newTemplate->name = $newName; $newTemplate->status = 'draft'; $newTemplate->published_at = null; $newTemplate->created_by = auth()->id(); $newTemplate->save(); // 复制步骤 foreach ($template->steps as $step) { $newStep = $step->replicate(); $newStep->sop_template_id = $newTemplate->id; $newStep->save(); // 复制交互任务 foreach ($step->interactiveTasks as $task) { $newTask = $task->replicate(); $newTask->sop_step_id = $newStep->id; $newTask->save(); } } return $newTemplate; }); } }