field('id,english_content,content,ids') ->where('ids',1) ->find(); // 构建任务基础结构(每图生成 N 份任务) foreach ($batch as $k => $v) { $baseItem = [ "sourceDir" => $this->sourceDir($v, 1), "outputDir" => $this->sourceDir($v, 2), "file_name" => $this->sourceDir($v, 3), "type" => $params['type'] ?? '', "selectedOption" => $params['selectedOption'],//文生图模型 "txttotxt_selectedOption" => $params['txttotxt_selectedOption'],//文生文模型 "imgtotxt_selectedOption" => $params['imgtotxt_selectedOption'],//图生文模型 "prompt" => $template['content'], "width" => $params['width'], "height" => $params['height'], "executeKeywords" => $params['executeKeywords'],//是否执行几何图 "sys_id" => $params['sys_id']//用户 ]; // 创建$num个相同的项目并合并到$arr $arr = array_merge($arr, array_fill(0, $num, $baseItem)); } // 插入队列日志 $insertData = [ 'create_time' => date('Y-m-d H:i:s'), 'old_image_file' => $params['old_image_file'], 'status' => '等待中', 'image_count' => count($arr), 'params' => json_encode($params, JSON_UNESCAPED_UNICODE) ]; //模型任务类型处理 if (empty($params['type'])) { /* * 执行全部任务时一键链式任务队列 * 用于存放队列日志 * 链式任务:图生文 → 文生文 → 文生图 * */ $insertData['model'] = "gpt-4-vision-preview,"."gpt-4,".$params['selectedOption']; $insertData['model_name'] = '文生图'; $task_id = Db::name('queue_logs')->insertGetId($insertData); $arr = array_map(function ($item) use ($task_id) { $item['type'] = '图生文'; $item['chain_next'] = ['文生文', '文生图','图生图','高清放大']; $item['task_id'] = $task_id; return $item; }, $arr); $payload = [ 'task_id' => $task_id, 'data' => $arr ]; Queue::push('app\job\ImageArrJob', $payload, "arrimage"); } else { // 指定单个独立任务类型 switch ($params['type']) { case '图生文': $insertData['model'] = 'gpt-4-vision-preview'; $insertData['model_name'] = '图生文'; break; case '文生文': $insertData['model'] = $params['txttotxt_selectedOption']; $insertData['model_name'] = '文生文'; break; case '文生图': $insertData['model'] = $params['selectedOption']; $insertData['model_name'] = '文生图'; break; case '图生图': $insertData['model'] = "realisticVisionV51_v51VAE-inpainting.safetensors [f0d4872d24]"; $insertData['model_name'] = '图生图'; break; case '高清放大': $insertData['model'] = "高清放大"; $insertData['model_name'] = '高清放大'; break; default: return false; } //将一组队列存放queue_logs任务表中,将新增id最为任务id记录 $task_id = Db::name('queue_logs')->insertGetId($insertData); $arr = array_map(function ($item) use ($params, $task_id) { $item['type'] = $params['type']; $item['task_id'] = $task_id; return $item; }, $arr); // 投递任务到队列 $payload = [ 'task_id' => $task_id, 'data' => $arr ]; Queue::push('app\job\ImageArrJob', $payload, "arrimage"); } return true; } /** * 解析图像路径,返回不同组成部分 * * @param string $filePath 图像路径(如 uploads/operate/ai/Preview/20240610/xxx.png) * @param int $type 返回内容类型: * 1 = 基础路径(去掉日期+文件名) * sourceDir 源目录uploads/operate/ai/Preview/ * 2 = 输出路径(Preview 替换为 dall-e,并加日期代表当天数据存到当天文件夹中) * outputDir 输出目录/uploads/operate/ai/dall-e/hua/并加日期 * 3 = 文件名 * file_name 文件名0194b6fdd6203fda369d5e3b74b6b454.png * @return string|null */ public function sourceDir($filePath, $type) { $arr = []; $pathParts = explode('/', $filePath); $filename = array_pop($pathParts); // 最后是文件名 $baseParts = $pathParts; // 查找是否有 8 位数字(即日期)文件夹 $date = ''; foreach ($pathParts as $index => $part) { if (preg_match('/^\d{8}$/', $part)) { $date = $part; unset($baseParts[$index]); // 日期不算在 basePath 里 break; } } $arr = [ 'basePath' => implode('/', $baseParts), 'date' => $date, 'filename' => $filename ]; // 根据类型返回不同路径 if ($type == 1) { return $arr["basePath"]; } if ($type == 2) { return '/' . str_replace('/Preview/', '/dall-e/', $arr["basePath"]) . $arr["date"]; } if ($type == 3) { return $arr["filename"]; } } }