浏览代码

first commit

liuhairui 3 月之前
父节点
当前提交
96a3e92b38

+ 140 - 78
application/api/controller/Facility.php

@@ -245,7 +245,7 @@ class Facility extends Api
         // 实时查询数据库状态信息(单次批量查询)
         $dbRecords = Db::name('text_to_image')
             ->whereIn('old_image_url', $paths)
-            ->field('id as img_id, old_image_url, new_image_url, custom_image_url, chinese_description, english_description, img_name, status, status_name')
+            ->field('id as img_id, old_image_url, new_image_url, custom_image_url,imgtoimg_url,taskId,chinese_description, english_description, img_name, status, status_name')
             ->select();
 
         // 实时查询队列状态(单次批量查询)
@@ -289,8 +289,31 @@ class Facility extends Api
 
         // 筛选状态字段
         $filtered = array_filter($mergedData, function ($data) use ($status, $status_name) {
+            // 状态码筛选
             if ($status !== '' && (int)$status !== $data['dbStatus']) return false;
-            if ($status_name !== '' && $status_name !== $data['dbStatusName']) return false;
+
+            // 状态名称筛选
+            if ($status_name !== '') {
+                if ($status_name === '未图生文') {
+                    // 当状态名为"未图生文"时,匹配空值或null
+                    if (!empty($data['dbStatusName'])) return false;
+                } elseif ($status_name === '未文生文') {
+
+                    if ($data['dbStatusName'] !== '图生文') return false;
+
+                } elseif ($status_name === '未文生图') {
+
+                    if ($data['dbStatusName'] !== '图生文') return false;
+
+                } elseif ($status_name === '未图生图') {
+
+                    if ($data['dbStatusName'] !== '文生图') return false;
+
+                } else {
+                    // 其他状态名需要精确匹配
+                    if ($status_name !== $data['dbStatusName']) return false;
+                }
+            }
             return true;
         });
 
@@ -304,7 +327,9 @@ class Facility extends Api
         if ($pagedPaths) {
             $sameCountMap = Db::name('text_to_image')
                 ->whereIn('old_image_url', $pagedPaths)
+//                ->where('new_image_url', '<>', '')
                 ->where('new_image_url', '<>', '')
+                ->where('taskId', '<>', '')
                 ->group('old_image_url')
                 ->column('count(*) as cnt', 'old_image_url');
         }
@@ -318,6 +343,7 @@ class Facility extends Api
 
             $result[] = [
                 'id' => ($page - 1) * $limit + $i + 1,
+                'ids' => $item['img_id'] ?? '',
                 'path' => $path,
                 // 实时数据
                 'status' => $data['dbStatus'],
@@ -325,8 +351,10 @@ class Facility extends Api
                 'same_count' => $sameCountMap[$path] ?? 0,
                 'is_processed' => $data['isProcessed'] ? 1 : 0,
                 'queue_status' => $data['queueStatus'],
+                'taskId' => $item['taskId'] ?? '',
                 'new_image_url' => $item['new_image_url'] ?? '',
                 'custom_image_url' => $item['custom_image_url'] ?? '',
+                'imgtoimg_url' => $item['imgtoimg_url'] ?? '',
                 'chinese_description' => $item['chinese_description'] ?? '',
                 'english_description' => $item['english_description'] ?? '',
                 'img_name' => $item['img_name'] ?? '',
@@ -348,7 +376,7 @@ class Facility extends Api
     }
 
     /**
-     * 通过服务器中目录获取对应数据
+     * 通过服务器中获取对应目录
      */
     public function getlsit()
     {
@@ -412,7 +440,89 @@ class Facility extends Api
         return json(['code' => 1, 'msg' => '没有文件上传', 'data' => null]);
     }
 
-    // 获取所有模版列表,并返回当前使用模版 ID
+
+    /**
+     * 打包图片(支持对象结构中的 path 字段)
+     */
+    public function packImagess()
+    {
+        try {
+            $params = $this->request->post();
+            $paths = $params['paths'] ?? [];
+
+            if (empty($paths) || !is_array($paths)) {
+                return json(['code' => 1, 'msg' => '路径参数不能为空或格式不正确']);
+            }
+
+            // 提取所有合法的路径(支持字符串或对象中带 path 字段)
+            $validPaths = [];
+
+            foreach ($paths as $item) {
+                if (is_string($item)) {
+                    $validPaths[] = $item;
+                } elseif (is_array($item) && isset($item['path']) && is_string($item['path'])) {
+                    $validPaths[] = $item['path'];
+                }
+            }
+
+            if (empty($validPaths)) {
+                return json(['code' => 1, 'msg' => '没有有效的图片路径']);
+            }
+
+            // 设置基本路径和 zip 目录
+            $basePath = ROOT_PATH . 'public/';
+            $zipDir = $basePath . 'uploads/operate/ai/zip/';
+
+            if (!is_dir($zipDir)) {
+                mkdir($zipDir, 0755, true);
+            }
+
+            // 生成压缩文件路径
+            $fileName = 'images_' . date('Ymd_His') . '.zip';
+            $zipPath = $zipDir . $fileName;
+
+            $zip = new \ZipArchive();
+            if ($zip->open($zipPath, \ZipArchive::CREATE) !== TRUE) {
+                return json(['code' => 1, 'msg' => '无法创建压缩包']);
+            }
+
+            $addCount = 0;
+            foreach ($validPaths as $relativePath) {
+                $relativePath = ltrim($relativePath, '/');  // 去除前导斜杠
+                $fullPath = $basePath . $relativePath;
+
+                if (file_exists($fullPath)) {
+                    // 使用 basename 作为压缩包内的文件名(不保留路径结构)
+                    $zip->addFile($fullPath, basename($fullPath));
+                    $addCount++;
+                }
+            }
+
+            $zip->close();
+
+            if ($addCount === 0) {
+                @unlink($zipPath);
+                return json(['code' => 1, 'msg' => '未找到有效图片文件,未生成压缩包']);
+            }
+
+            $downloadUrl = request()->domain() . '/uploads/operate/ai/zip/' . $fileName;
+
+            return json([
+                'code' => 0,
+                'msg' => '打包成功',
+                'download_url' => $downloadUrl
+            ]);
+        } catch (\Exception $e) {
+            return json([
+                'code' => 1,
+                'msg' => '异常错误:' . $e->getMessage()
+            ]);
+        }
+    }
+
+    /**
+     * 获取所有模版列表,并返回当前使用模版 ID
+     */
     public function TemplateList()
     {
         $list = Db::name("template")->order('ids desc')->select();
@@ -491,6 +601,9 @@ class Facility extends Api
         return json(['code' => 0, 'msg' => '保存成功']);
     }
 
+    /**
+     * 设置默认使用模版
+     */
     public function setActiveTemplate()
     {
         $id = Request::instance()->param('id');
@@ -504,84 +617,33 @@ class Facility extends Api
         return json(['code' => 0, 'msg' => '模版已设为当前使用']);
     }
 
-
     /**
-     * 打包图片(支持对象结构中的 path 字段)
+     * 文生图查询模型列表
      */
-    public function packImagess()
-    {
-        try {
-            $params = $this->request->post();
-            $paths = $params['paths'] ?? [];
-
-            if (empty($paths) || !is_array($paths)) {
-                return json(['code' => 1, 'msg' => '路径参数不能为空或格式不正确']);
-            }
-
-            // 提取所有合法的路径(支持字符串或对象中带 path 字段)
-            $validPaths = [];
-
-            foreach ($paths as $item) {
-                if (is_string($item)) {
-                    $validPaths[] = $item;
-                } elseif (is_array($item) && isset($item['path']) && is_string($item['path'])) {
-                    $validPaths[] = $item['path'];
-                }
-            }
-
-            if (empty($validPaths)) {
-                return json(['code' => 1, 'msg' => '没有有效的图片路径']);
-            }
-
-            // 设置基本路径和 zip 目录
-            $basePath = ROOT_PATH . 'public/';
-            $zipDir = $basePath . 'uploads/operate/ai/zip/';
-
-            if (!is_dir($zipDir)) {
-                mkdir($zipDir, 0755, true);
-            }
-
-            // 生成压缩文件路径
-            $fileName = 'images_' . date('Ymd_His') . '.zip';
-            $zipPath = $zipDir . $fileName;
-
-            $zip = new \ZipArchive();
-            if ($zip->open($zipPath, \ZipArchive::CREATE) !== TRUE) {
-                return json(['code' => 1, 'msg' => '无法创建压缩包']);
-            }
-
-            $addCount = 0;
-            foreach ($validPaths as $relativePath) {
-                $relativePath = ltrim($relativePath, '/');  // 去除前导斜杠
-                $fullPath = $basePath . $relativePath;
-
-                if (file_exists($fullPath)) {
-                    // 使用 basename 作为压缩包内的文件名(不保留路径结构)
-                    $zip->addFile($fullPath, basename($fullPath));
-                    $addCount++;
-                }
-            }
-
-            $zip->close();
-
-            if ($addCount === 0) {
-                @unlink($zipPath);
-                return json(['code' => 1, 'msg' => '未找到有效图片文件,未生成压缩包']);
-            }
-
-            $downloadUrl = request()->domain() . '/uploads/operate/ai/zip/' . $fileName;
+    public function txttoimg_moxing(){
+        $list = Db::name("moxing")->order('id asc')->select();
+        return json([
+            'code' => 0,
+            'msg' => '模版列表',
+            'data' => [
+                'list' => $list,
+                'usedId' => Db::name("moxing")->where('txttoimg_val', 1)->value('id')
+            ]
+        ]);
+    }
 
-            return json([
-                'code' => 0,
-                'msg' => '打包成功',
-                'download_url' => $downloadUrl
-            ]);
-        } catch (\Exception $e) {
-            return json([
-                'code' => 1,
-                'msg' => '异常错误:' . $e->getMessage()
-            ]);
+    /**
+     * 文生图设置默认使用模型
+     * txttoimg_val = 1 默认使用
+     */
+    public function txttoimg_update(){
+        $id = Request::instance()->param('id');
+        if (!$id) {
+            return json(['code' => 1, 'msg' => '参数错误']);
         }
+        Db::name("moxing")->where('txttoimg_val', 1)->update(['txttoimg_val' => 0]); // 清除当前使用
+        Db::name("moxing")->where('id', $id)->update(['txttoimg_val' => 1]); // 设置新的使用模型
+        return json(['code' => 0, 'msg' => '模版已设为当前使用']);
     }
 
 }

+ 31 - 1
application/api/controller/OrderSuperLoss.php

@@ -68,13 +68,21 @@ class OrderSuperLoss extends Api
         // 搜索关键词
         $search = isset($params['search']) ? trim($params['search']) : '';
 
+        $folder = isset($params['folder']) ? trim($params['folder']) : '';
+
         $where = [];
+        $wheres = [];
         if (isset($search)) {
             $where['id|img_name|chinese_description|english_description'] = ['like', '%'. $search . '%'];
         }
+        if (isset($folder)) {
+            $wheres['old_image_url'] = ['like', '%'. $folder . '%'];
+        }
 
         $count = Db::name('text_to_image')
             ->where('new_image_url', '<>', '')
+            ->where($where)
+            ->where($wheres)
             ->where('img_name', '<>', '')
             ->select();
 
@@ -82,13 +90,35 @@ class OrderSuperLoss extends Api
             ->where('new_image_url', '<>', '')
             ->where('img_name', '<>', '')
             ->where($where)
+            ->where($wheres)
             ->order('update_time desc')
             ->page($page, $limit)
             ->select();
 
+        $folder = Db::name('text_to_image')
+            ->field('old_image_url')
+            ->where('new_image_url', '<>', '')
+            ->where('img_name', '<>', '')
+            ->order('update_time desc')
+            ->select();
+
+        // 处理路径并去重
+        $processedFolders = [];
+        foreach ($folder as $item) {
+            $url = $item['old_image_url'];
+            $lastSlashPos = strrpos($url, '/');
+            if ($lastSlashPos !== false) {
+                $folderPath = substr($url, 0, $lastSlashPos);
+                if (!in_array($folderPath, $processedFolders)) {
+                    $processedFolders[] = $folderPath;
+                }
+            }
+        }
+
         $this->success('获取成功', [
             'total' => count($count),
-            'list'  => $list
+            'list'  => $list,
+            'folder' => $processedFolders
         ]);
     }
 

+ 789 - 92
application/api/controller/WorkOrder.php

@@ -6,6 +6,7 @@ use app\job\ImageJob;
 use app\service\ImageService;
 use think\App;
 use think\Db;
+use think\Exception;
 use think\Log;
 use think\Queue;
 use think\queue\job\Redis;
@@ -28,7 +29,794 @@ class WorkOrder extends Api
 
 
 
-    //单独方法本地测试
+    public function textToImage()
+    {
+
+        $outputDirRaw = 'uploads/operate/ai/Preview/undefined_BRdP4/3';
+        $img_name = '42131321';
+        $rootPath = str_replace('\\', '/', ROOT_PATH);
+        $outputDir = rtrim($rootPath . 'public/' . $outputDirRaw, '/') . '/';
+        $dateDir = date('Y-m-d') . '/';
+        $fullBaseDir = $outputDir . $dateDir;
+        // 确保目录存在
+        if (!is_dir($fullBaseDir . '2048x2048/')) {
+            mkdir($fullBaseDir . '2048x2048/', 0755, true);
+        }
+
+//        // API配置
+//        $config = [
+//            'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine',
+//            'fetch_url' => 'https://chatapi.onechats.ai/mj/task/',
+//            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+//            'default_prompt' => '恐怖的树状怪物,拥有尖牙利爪和血红眼睛,在蓝色背景下显得阴森可怕,风格为黑暗奇幻。'
+//        ];
+//
+//        // 1. 准备请求数据
+//        $prompt =  $config['default_prompt'];
+//        $postData = [
+//            'botType' => 'MID_JOURNEY',
+//            'prompt' => $prompt,
+//            'base64Array' => [],
+//            'accountFilter' => [
+//                'channelId' => "",
+//                'instanceId' => "",
+//                'modes' => [],
+//                'remark' => "",
+//                'remix' => true,
+//                'remixAutoConsidered' => true
+//            ],
+//            'notifyHook' => "",
+//            'state' => ""
+//        ];
+//        // 2. 提交生成请求
+//        $generateResponse = $this->sendApiRequest($config['api_url'], $postData, $config['api_key']);
+//        echo "<pre>";
+//        print_r($generateResponse);
+//        echo "<pre>";
+//        $generateData = json_decode($generateResponse, true);
+//        echo "<pre>";
+//        print_r($generateData);
+//        echo "<pre>";
+//        if (empty($generateData['result'])) {
+//            throw new Exception('生成失败: '.($generateData['message'] ?? '未知错误'));
+//        }
+//
+//        die;
+
+//        $taskId = "1755229064353588";
+        $taskId = "1755234114253556";
+//        $taskId = "1755224966357751";
+
+        // 3. 等待图片生成完成
+        sleep(3);
+
+        $imageUrl = $this->getImageSeed($taskId);
+        echo "<pre>";
+        print_r($imageUrl);
+        echo "<pre>";die;
+        $img_name = mb_substr(preg_replace('/[^\x{4e00}-\x{9fa5}A-Za-z0-9_\- ]/u', '', $img_name), 0, 30);
+        $filename = $img_name . '.png';
+        $path512 = $fullBaseDir . '2048x2048/' . $filename;
+
+        // 下载并保存图片
+//        file_get_contents($imageUrl['data']['imageUrl']);
+        // 下载并保存图片到本地文件夹中
+        $imageData = file_get_contents($imageUrl['data']['imageUrl']);
+        $result = file_put_contents($path512, $imageData);
+        if ($result === false) {
+            die('保存图片失败,请检查目录权限');
+        }
+
+        // 数据库更新
+        Db::name('text_to_image')->where('id', '10694')->update([
+            'new_image_url' => str_replace($rootPath . 'public/', '', $path512),
+            'img_name' => $img_name,
+            'model' => 'MID_JOURNEY',
+            'status' => trim($img_name) === '' ? 0 : 1,
+            'status_name' => "文生图",
+            'size' => "2048",
+            'quality' => 'standard',
+            'style' => 'vivid',
+            'error_msg' => '',
+            'update_time' => date('Y-m-d H:i:s')
+        ]);
+
+        return "成功";
+    }
+
+
+
+
+    public function getImageSeed($taskId)
+    {
+        // 配置参数
+        $apiUrl = 'https://chatapi.onechats.ai/mj/task/' . $taskId . '/fetch';
+        $apiKey = 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK';
+
+        try {
+            // 初始化cURL
+            $ch = curl_init();
+
+            // 设置cURL选项
+            curl_setopt_array($ch, [
+                CURLOPT_URL => $apiUrl,
+                CURLOPT_RETURNTRANSFER => true,
+                CURLOPT_CUSTOMREQUEST => 'GET',  // 明确指定GET方法
+                CURLOPT_HTTPHEADER => [
+                    'Authorization: Bearer ' . $apiKey,
+                    'Accept: application/json',
+                    'Content-Type: application/json'
+                ],
+                CURLOPT_SSL_VERIFYPEER => false,
+                CURLOPT_SSL_VERIFYHOST => false,
+                CURLOPT_TIMEOUT => 60,
+                CURLOPT_FAILONERROR => true     // 添加失败时返回错误
+            ]);
+
+            // 执行请求
+            $response = curl_exec($ch);
+            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+            // 错误处理
+            if (curl_errno($ch)) {
+                throw new Exception('cURL请求失败: ' . curl_error($ch));
+            }
+
+            // 关闭连接
+            curl_close($ch);
+
+            // 验证HTTP状态码
+            if ($httpCode < 200 || $httpCode >= 300) {
+                throw new Exception('API返回错误状态码: ' . $httpCode);
+            }
+
+            // 解析JSON响应
+            $responseData = json_decode($response, true);
+            if (json_last_error() !== JSON_ERROR_NONE) {
+                throw new Exception('JSON解析失败: ' . json_last_error_msg());
+            }
+
+            // 返回结构化数据
+            return [
+                'success' => true,
+                'http_code' => $httpCode,
+                'data' => $responseData
+            ];
+
+        } catch (Exception $e) {
+            // 确保关闭cURL连接
+            if (isset($ch) && is_resource($ch)) {
+                curl_close($ch);
+            }
+
+            return [
+                'success' => false,
+                'error' => $e->getMessage(),
+                'http_code' => $httpCode ?? 0
+            ];
+        }
+    }
+
+//    public function textToImage()
+//    {
+//        $outputDirRaw = 'uploads/operate/ai/Preview/undefined_BRdP4/3';
+//        $img_name = '16';
+//        $rootPath = str_replace('\\', '/', ROOT_PATH);
+//        $outputDir = rtrim($rootPath . 'public/' . $outputDirRaw, '/') . '/';
+//        $dateDir = date('Y-m-d') . '/';
+//        $fullBaseDir = $outputDir . $dateDir;
+//
+//        // 确保目录存在
+//        if (!is_dir($fullBaseDir . '2048x2048/')) {
+//            mkdir($fullBaseDir . '2048x2048/', 0755, true);
+//        }
+//
+//        $taskId = '1755154312186851';
+//        //API配置
+//        $config = [
+//            'fetch_url' => 'https://chatapi.onechats.ai/mj/task/',
+//            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK'
+//        ];
+//
+//        // 1. 获取主任务信息
+//        $fetchUrl = $config['fetch_url'].$taskId.'/fetch';
+//        $fetchResponse = $this->sendApiRequest($fetchUrl, [], $config['api_key'], 'GET');
+//        echo "<pre>";
+//        print_r($fetchResponse);
+//        echo "<pre>";
+//        $fetchData = json_decode($fetchResponse, true);
+//        echo "<pre>";
+//        print_r($fetchData);
+//        echo "<pre>";
+//        if (empty($fetchData['buttons'])) {
+//            throw new Exception('无法获取变体按钮信息');
+//        }
+//
+//        echo "<pre>";
+//        print_r(777777777);
+//        echo "<pre>";
+//
+//        //选择要获取的变体(这里选择第一个变体U1)
+//        //customId MJ::JOB::upsample::1::47df46a8-b0bb-4b31-a578-09f69c73a2ed
+//        $customId = $fetchData['buttons'][0]['customId'];
+//
+//        $upscaleUrl = "https://chatapi.onechats.ai/mj/submit/action";
+//        $postData = [
+//            'customId' => $customId,
+//            // 可能需要额外参数,如 taskId
+//            'taskId' => $taskId,
+//        ];
+//        $response = $this->sendApiRequest($upscaleUrl, $postData, $config['api_key'], 'POST');
+//        echo "<pre>";
+//        print_r($response);
+//        echo "<pre>";
+//        $responseData = json_decode($response, true);
+//        echo "<pre>";
+//        print_r($responseData);
+//        echo "<pre>";
+//
+//
+//        echo "<pre>";
+//        print_r(21312312321321321);
+//        echo "<pre>";
+//        // 3. 调用API获取单个变体图片
+//        $upscaleUrl = $config['fetch_url'].$customId.'/image-seed';
+//        $upscaleResponse = $this->sendApiRequest($upscaleUrl, [], $config['api_key'], 'GET');
+//        echo "<pre>";
+//        print_r($upscaleResponse);
+//        echo "<pre>";
+//        $upscaleData = json_decode($upscaleResponse, true);
+//        echo "<pre>";
+//        print_r($upscaleData);
+//        echo "<pre>";
+//        die;
+//        if (empty($upscaleData['imageUrl'])) {
+//            throw new Exception('获取变体图片失败: '.($upscaleData['message'] ?? '未知错误'));
+//        }
+//
+//        // 4. 处理返回的图片URL
+//        $imageUrl = is_array($upscaleData['imageUrl']) ? $upscaleData['imageUrl'][0] : $upscaleData['imageUrl'];
+//        echo "<pre>";
+//        print_r($imageUrl.'3333');
+//        echo "<pre>";
+//        // 保存文件路径定义
+//        $img_name = mb_substr(preg_replace('/[^\x{4e00}-\x{9fa5}A-Za-z0-9_\- ]/u', '', $img_name), 0, 30);
+//        $filename = $img_name . '.png';
+//        $path512 = $fullBaseDir . '2048x2048/' . $filename;
+//
+//        // 下载并保存图片
+//        $imageContent = file_get_contents($imageUrl);
+//        if ($imageContent === false) {
+//            throw new Exception('下载图片失败');
+//        }
+//
+//        $saveResult = file_put_contents($path512, $imageContent);
+//        if ($saveResult === false) {
+//            throw new Exception('保存图片失败');
+//        }
+//
+//        // 数据库更新
+//        Db::name('text_to_image')->where('id', '552')->update([
+//            'new_image_url' => str_replace($rootPath . 'public/', '', $path512),
+//            'img_name' => $img_name,
+//            'model' => 'MID_JOURNEY',
+//            'status' => trim($img_name) === '' ? 0 : 1,
+//            'status_name' => "文生图",
+//            'size' => "2048",
+//            'quality' => 'standard',
+//            'style' => 'vivid',
+//            'error_msg' => '',
+//            'update_time' => date('Y-m-d H:i:s')
+//        ]);
+//
+//        return "成功";
+//    }
+
+    private function sendPostRequest($url, $data, $apiKey)
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+            'Authorization: Bearer ' . $apiKey,
+            'Accept: application/json',
+            'Content-Type: application/json'
+        ]);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 延长超时时间
+
+        $response = curl_exec($ch);
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        $error = curl_error($ch);
+        curl_close($ch);
+
+        return [
+            'response' => $response,
+            'http_code' => $httpCode,
+            'error' => $error
+        ];
+    }
+
+    /**
+     * 文本生成图片并保存第一张结果
+     * @param array $params 请求参数
+     * @return array 返回结果
+     */
+    public function txttowimg()
+    {
+        // API配置
+        $config = [
+            'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine',
+            'fetch_url' => 'https://chatapi.onechats.ai/mj/task/',
+            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+            'default_prompt' => '一个猫',
+            'wait_time' => 3 // 等待生成完成的秒数
+        ];
+
+        try {
+            // 1. 准备请求数据
+            $prompt =  $config['default_prompt'];
+            $postData = [
+                'botType' => 'MID_JOURNEY',
+                'prompt' => $prompt,
+                'base64Array' => [],
+                'accountFilter' => [
+                    'channelId' => "",
+                    'instanceId' => "",
+                    'modes' => [],
+                    'remark' => "",
+                    'remix' => true,
+                    'remixAutoConsidered' => true
+                ],
+                'notifyHook' => "",
+                'state' => ""
+            ];
+
+            // 2. 提交生成请求
+            $generateResponse = $this->sendApiRequest($config['api_url'], $postData, $config['api_key']);
+            $generateData = json_decode($generateResponse, true);
+
+            if (empty($generateData['result'])) {
+                throw new Exception('生成失败: '.($generateData['message'] ?? '未知错误'));
+            }
+
+            $taskId = $generateData['result'];
+
+            // 3. 等待图片生成完成
+            sleep($config['wait_time']);
+
+            // 4. 获取生成结果
+            $fetchUrl = $config['fetch_url'].$taskId.'/fetch';
+            $fetchResponse = $this->sendApiRequest($fetchUrl, [], $config['api_key'], 'GET');
+            $fetchData = json_decode($fetchResponse, true);
+
+            if (empty($fetchData['imageUrl'])) {
+                throw new Exception('获取图片失败: '.($fetchData['message'] ?? '未知错误'));
+            }
+
+            // 5. 处理返回的图片数组(取第一张)
+            $imageUrls = is_array($fetchData['imageUrl']) ? $fetchData['imageUrl'] : [$fetchData['imageUrl']];
+            $firstImageUrl = $imageUrls[0];
+
+            // 6. 保存图片到本地
+            $savePath = $this->saveImage($firstImageUrl);
+
+            // 7. 返回结果
+            return [
+                'code' => 200,
+                'msg' => '图片生成并保存成功',
+                'data' => [
+                    'local_path' => $savePath,
+                    'web_url' => request()->domain().$savePath,
+                    'task_id' => $taskId
+                ]
+            ];
+
+        } catch (Exception $e) {
+            // 错误处理
+            return [
+                'code' => 500,
+                'msg' => '处理失败: '.$e->getMessage(),
+                'data' => null
+            ];
+        }
+    }
+
+    /**
+     * 发送API请求
+     * @param string $url 请求地址
+     * @param array $data 请求数据
+     * @param string $apiKey API密钥
+     * @param string $method 请求方法
+     * @return string 响应内容
+     * @throws Exception
+     */
+    private function sendApiRequest($url, $data, $apiKey, $method = 'POST')
+    {
+        $ch = curl_init();
+
+        curl_setopt_array($ch, [
+            CURLOPT_URL => $url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_CUSTOMREQUEST => $method,
+            CURLOPT_HTTPHEADER => [
+                'Authorization: Bearer '.$apiKey,
+                'Accept: application/json',
+                'Content-Type: application/json'
+            ],
+            CURLOPT_POSTFIELDS => $method === 'POST' ? json_encode($data) : null,
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_SSL_VERIFYHOST => false,
+            CURLOPT_TIMEOUT => 60,
+            CURLOPT_FAILONERROR => true
+        ]);
+
+        $response = curl_exec($ch);
+        $error = curl_error($ch);
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        curl_close($ch);
+
+        if ($error) {
+            throw new Exception('API请求失败: '.$error);
+        }
+
+        if ($httpCode < 200 || $httpCode >= 300) {
+            throw new Exception('API返回错误状态码: '.$httpCode);
+        }
+
+        return $response;
+    }
+
+    /**
+     * 保存图片到本地
+     * @param string $imageUrl 图片URL
+     * @return string 本地保存路径
+     * @throws Exception
+     */
+    private function saveImage($imageUrl)
+    {
+        // 1. 创建存储目录
+        $saveDir = ROOT_PATH.'public'.DS.'uploads'.DS.'midjourney'.DS.date('Ymd');
+        if (!is_dir($saveDir)) {
+            mkdir($saveDir, 0755, true);
+        }
+
+        // 2. 生成唯一文件名
+        $filename = uniqid().'.png';
+        $localPath = DS.'uploads'.DS.'midjourney'.DS.date('Ymd').DS.$filename;
+        $fullPath = $saveDir.DS.$filename;
+
+        // 3. 下载图片
+        $ch = curl_init($imageUrl);
+        curl_setopt_array($ch, [
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_CONNECTTIMEOUT => 15
+        ]);
+
+        $imageData = curl_exec($ch);
+        $error = curl_error($ch);
+        curl_close($ch);
+
+        if (!$imageData) {
+            throw new Exception('图片下载失败: '.$error);
+        }
+
+        // 4. 验证图片类型
+        $imageInfo = getimagesizefromstring($imageData);
+        if (!in_array($imageInfo['mime'] ?? '', ['image/png', 'image/jpeg'])) {
+            throw new Exception('下载内容不是有效图片');
+        }
+
+        // 5. 保存文件
+        if (!file_put_contents($fullPath, $imageData)) {
+            throw new Exception('图片保存失败');
+        }
+
+        return $localPath;
+    }
+
+//    public function txttowimg($params = [])
+//    {
+//        $config = [
+//            'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine',
+//            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+//            'default_prompt' => '一个猫',
+//        ];
+//
+//        // 使用传入的prompt或默认值
+//        $prompt = $params['prompt'] ?? $config['default_prompt'];
+//
+//        // 构建请求数据
+//        $postData = [
+//            'botType' => 'MID_JOURNEY',
+//            'prompt' => $prompt,
+//            'base64Array' => [],
+//            'accountFilter' => [
+//                'channelId' => $params['channelId'] ?? "",
+//                'instanceId' => $params['instanceId'] ?? "",
+//                'modes' => $params['modes'] ?? [],
+//                'remark' => $params['remark'] ?? "",
+//                'remix' => $params['remix'] ?? true,
+//                'remixAutoConsidered' => $params['remixAutoConsidered'] ?? true
+//            ],
+//            'notifyHook' => $params['notifyHook'] ?? "",
+//            'state' => $params['state'] ?? ""
+//        ];
+//
+//        $arr =  $this->sendPostRequest($config['api_url'], $postData, $config['api_key']);
+//        $response = json_decode($arr['response'], true);
+//        $imageid = $response['result'];
+//        if (!$imageid) {
+//            throw new Exception('未找到图像id');
+//        }
+//        $imageUrl = $this->getImageSeed('1755151823075229');
+//        // 保存到本地
+//        $savePath = $this->saveImageToLocal($imageUrl['data']['imageUrl']);
+//
+//        return json([
+//            'code' => 200,
+//            'msg' => '图像生成并保存成功',
+//            'data' => [
+//                'local_path' => $savePath,
+//                'web_url' => request()->domain() . $savePath
+//            ]
+//        ]);
+//    }
+//
+//    private function sendPostRequest($url, $data, $apiKey)
+//    {
+//        $ch = curl_init();
+//        curl_setopt($ch, CURLOPT_URL, $url);
+//        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+//        curl_setopt($ch, CURLOPT_POST, true);
+//        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+//            'Authorization: Bearer ' . $apiKey,
+//            'Accept: application/json',
+//            'Content-Type: application/json'
+//        ]);
+//        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+//        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+//        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+//        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+//
+//        $response = curl_exec($ch);
+//        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+//        $error = curl_error($ch);
+//        curl_close($ch);
+//
+//        return [
+//            'response' => $response,
+//            'http_code' => $httpCode,
+//            'error' => $error
+//        ];
+//    }
+//
+//    /**
+//     * 获取任务图片地址
+//     * @param $taskId
+//     * @return array
+//     */
+//    public function getImageSeed($taskId)
+//    {
+//        // 配置参数
+//        $apiUrl = 'https://chatapi.onechats.ai/mj/task/' . $taskId . '/fetch';
+//        $apiKey = 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK';
+//
+//        try {
+//            // 初始化cURL
+//            $ch = curl_init();
+//
+//            // 设置cURL选项
+//            curl_setopt_array($ch, [
+//                CURLOPT_URL => $apiUrl,
+//                CURLOPT_RETURNTRANSFER => true,
+//                CURLOPT_CUSTOMREQUEST => 'GET',  // 明确指定GET方法
+//                CURLOPT_HTTPHEADER => [
+//                    'Authorization: Bearer ' . $apiKey,
+//                    'Accept: application/json',
+//                    'Content-Type: application/json'
+//                ],
+//                CURLOPT_SSL_VERIFYPEER => false,
+//                CURLOPT_SSL_VERIFYHOST => false,
+//                CURLOPT_TIMEOUT => 60,
+//                CURLOPT_FAILONERROR => true     // 添加失败时返回错误
+//            ]);
+//
+//            // 执行请求
+//            $response = curl_exec($ch);
+//            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+//
+//            // 错误处理
+//            if (curl_errno($ch)) {
+//                throw new Exception('cURL请求失败: ' . curl_error($ch));
+//            }
+//
+//            // 关闭连接
+//            curl_close($ch);
+//
+//            // 验证HTTP状态码
+//            if ($httpCode < 200 || $httpCode >= 300) {
+//                throw new Exception('API返回错误状态码: ' . $httpCode);
+//            }
+//
+//            // 解析JSON响应
+//            $responseData = json_decode($response, true);
+//            if (json_last_error() !== JSON_ERROR_NONE) {
+//                throw new Exception('JSON解析失败: ' . json_last_error_msg());
+//            }
+//
+//            // 返回结构化数据
+//            return [
+//                'success' => true,
+//                'http_code' => $httpCode,
+//                'data' => $responseData
+//            ];
+//
+//        } catch (Exception $e) {
+//            // 确保关闭cURL连接
+//            if (isset($ch) && is_resource($ch)) {
+//                curl_close($ch);
+//            }
+//
+//            return [
+//                'success' => false,
+//                'error' => $e->getMessage(),
+//                'http_code' => $httpCode ?? 0
+//            ];
+//        }
+//    }
+//
+//    private function saveImageToLocal($imageUrl)
+//    {
+//        // 创建存储目录
+//        $saveDir = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'midjourney' . DS . date('Ymd');
+//        if (!is_dir($saveDir)) {
+//            mkdir($saveDir, 0755, true);
+//        }
+//
+//        // 生成唯一文件名
+//        $filename = uniqid() . '.png';
+//        $localPath = DS . 'uploads' . DS . 'midjourney' . DS . date('Ymd') . DS . $filename;
+//        $fullPath = $saveDir . DS . $filename;
+//
+//        // 下载图像
+//        $imageData = $this->downloadImage($imageUrl);
+//
+//        // 保存到文件
+//        if (!file_put_contents($fullPath, $imageData)) {
+//            throw new Exception('图像保存失败');
+//        }
+//
+//        return $localPath;
+//    }
+//
+//    private function downloadImage($url)
+//    {
+//        $ch = curl_init($url);
+//        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+//        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+//        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+//        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+//
+//        $imageData = curl_exec($ch);
+//        $error = curl_error($ch);
+//        curl_close($ch);
+//
+//        if (!$imageData) {
+//            throw new Exception('图像下载失败: ' . $error);
+//        }
+//
+//        // 基本图像类型验证
+//        if (!in_array(getimagesizefromstring($imageData)['mime'] ?? '', ['image/png', 'image/jpeg'])) {
+//            throw new Exception('下载内容不是有效图像');
+//        }
+//
+//        return $imageData;
+//    }
+
+//    public function txttowimg()
+//    {
+//        $config = [
+//            'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine',
+//            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+//            'prompt' => '一个猫',
+//        ];
+//
+//        $postData = [
+//            'botType' => 'MID_JOURNEY',
+//            'prompt' => $config['prompt'],
+//            'base64Array' => [],
+//            'accountFilter' => [
+//                'channelId' => "",
+//                'instanceId' => "",
+//                'modes' => [],
+//                'remark' => "",
+//                'remix' => true,
+//                'remixAutoConsidered' => true
+//            ],
+//            'notifyHook' => "",
+//            'state' => ""
+//        ];
+//
+//        $headers = [
+//            'Authorization: Bearer ' . $config['api_key'],
+//            'Accept: application/json',
+//            'Content-Type: application/json'
+//        ];
+//
+//        $ch = curl_init();
+//        curl_setopt($ch, CURLOPT_URL, $config['api_url']);
+//        curl_setopt($ch, CURLOPT_POST, true);
+//        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+//        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
+//        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+//
+//        $response = curl_exec($ch);
+//        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+//
+//        if (curl_errno($ch)) {
+//            $error = curl_error($ch);
+//            curl_close($ch);
+//            throw new Exception("cURL Error: " . $error);
+//        }
+//
+//        curl_close($ch);
+//
+//        if ($httpCode >= 400) {
+//            throw new Exception("API Error: HTTP " . $httpCode . " - " . $response);
+//        }
+//
+//        return json_decode($response, true);
+//    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//    public function txttowimg()
+//    {
+//        $prompt = 'Cat'; // 或使用 '生成一个猫' 如果要中文
+//        $apiUrl = 'https://chatapi.onechats.ai/mj/submit/imagine';
+//        $apiKey = "sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK";
+//
+//    }
+
+
+
+
+
+    /**
+     * 图生图本地测试
+     */
     public function imgtowimg()
     {
         $prompt = $this->request->param('prompt', '');
@@ -122,96 +910,8 @@ class WorkOrder extends Api
         ]);
     }
 
-//    /**
-//     * 图生图功能-单张图片本地测试使用
-//     * 接口地址: /sdapi/v1/img2img
-//     */
-//    public function imgtowimg()
-//    {
-//        $prompt = $this->request->param('prompt', '将图片不完整部分补充完整');
-//        $imgRelPath = 'uploads/operate/ai/Preview/arr/一朵盛开的白色牡丹花为主体采用厚涂技法花心和背景点缀金箔灰银.png';
-//        $imgPath = ROOT_PATH . 'public/' . $imgRelPath;
-//        //原图是否存在
-//        if (!file_exists($imgPath)) {
-//            return json(['code' => 1, 'msg' => '原图不存在:' . $imgRelPath]);
-//        }
-//
-//        // -------- 图像编码 -------- //
-//        $imgData = file_get_contents($imgPath);
-//        $base64Img = base64_encode($imgData);
-//        $initImage = 'data:image/png;base64,' . $base64Img;
-//
-//        // -------- 请求体构建 -------- //
-//        $postData = json_encode([
-//            'prompt' => $prompt,
-//            'steps' => 30,                       // 步数
-//            'cfg_scale' => 7,                    // CFG 强度
-//            'denoising_strength' => 0.2,        // 重绘强度
-//            'width' => 679,                      // 图像宽度
-//            'height' => 862,                     // 图像高度
-//            'resize_mode' => 1,                 // 保留原图比例并裁剪
-//            'inpaint_full_res' => true,         // 使用原图分辨率
-//            'inpaint_full_res_padding' => 64,   // 边缘补全像素
-//            'mask_blur' => 4,                   // 蒙版柔化
-//            'inpainting_fill' => 3,             // 自动填充内容(不是黑色)
-//            'sampler_name' => 'DPM++ 2M SDE',   // 采样器
-//            'scheduler' => 'Exponential',       // ✅ 调度类型(补充字段)
-//            'seed' => 3689437019,               // 固定种子(确保结果可复现)
-//            'init_images' => [$initImage],      // 原图 base64
-//            'override_settings' => [
-//                'sd_model_checkpoint' => 'AbyssOrangeMix2_sfw', // 模型名
-//                'sd_vae' => "Automatic",
-//                'CLIP_stop_at_last_layers' => 2
-//            ],
-//            'override_settings_restore_afterwards' => true
-//        ]);
-//
-//        // -------- 发送请求到 SD API -------- //
-//        $apiUrl = "http://20.0.17.188:45001/sdapi/v1/img2img";
-//        $headers = ['Content-Type: application/json'];
-//
-//        $ch = curl_init();
-//        curl_setopt($ch, CURLOPT_URL, $apiUrl);
-//        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-//        curl_setopt($ch, CURLOPT_POST, true);
-//        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
-//        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
-//        curl_setopt($ch, CURLOPT_TIMEOUT, 90);
-//        $response = curl_exec($ch);
-//        $error = curl_error($ch);
-//        curl_close($ch);
-//
-//        if ($error) {return json(['code' => 1, 'msg' => '请求失败:' . $error]);}
-//        $data = json_decode($response, true);
-//        if (!isset($data['images'][0])) {
-//            return json(['code' => 1, 'msg' => '接口未返回图像数据']);
-//        }
-//
-//        // -------- 保存生成图像 -------- //
-//        $resultImg = base64_decode($data['images'][0]);
-//        $saveDir = ROOT_PATH . 'public/uploads/img2img/';
-//        if (!is_dir($saveDir)) {
-//            mkdir($saveDir, 0755, true);
-//        }
-//
-//        $originalBaseName = pathinfo($imgRelPath, PATHINFO_FILENAME);
-//        $fileName = $originalBaseName . '-' . time() . '-1.png';
-//        $savePath = $saveDir . $fileName;
-//        file_put_contents($savePath, $resultImg);
-//
-//        return json([
-//            'code' => 0,
-//            'msg' => '图像生成成功',
-//            'data' => [
-//                'origin_url' => '/uploads/img2img/' . $fileName
-//            ]
-//        ]);
-//    }
-
-
     /**
      * 后期图像处理-单张图片高清放大处理
-     * 接口地址: /sdapi/v1/extra-single-image
      */
     public function extra_image()
     {
@@ -334,9 +1034,6 @@ class WorkOrder extends Api
     }
 
 
-
-
-
     /**
      * 获取 SD 模型列表
      * 接口地址: /sdapi/v1/sd-models

+ 1 - 1
application/config.php

@@ -18,7 +18,7 @@ return [
     // 应用命名空间
     'app_namespace'          => 'app',
     // 应用调试模式
-    'app_debug'              => Env::get('app.debug', true),
+    'app_debug'              => Env::get('app.debug', false),
     // 应用Trace
     'app_trace'              => Env::get('app.trace', false),
     // 应用模式状态

+ 14 - 28
application/database.php

@@ -80,49 +80,35 @@ return [
         'debug'          => true,  // 开启调试
     ],
 
-    /**
-     * 配置中间表数据库
-     **/
-    'db3'             => [
-        // 数据库类型
-        'type'            => Env::get('database3.type', 'sqlsrv'),
-        // 服务器地址
-        'hostname'        => Env::get('database.hostname', '20.0.51.77'),
-        // 数据库名
+    'db3' => [
+        // ✅ 数据库类型明确设为 mysql
+        'type'            => 'mysql',
+
+        // 服务器地址(你写的没问题)
+        'hostname'        => Env::get('database.hostname', '20.0.16.87'),
+
+        // 数据库名、用户名、密码也 OK
         'database'        => Env::get('database.database', 'mesdb'),
-        // 用户名
         'username'        => Env::get('database.username', 'mesdb'),
-        // 密码
-        'password'        => Env::get('database.password', 'nY72kLdaXtpKdLNf'),
-        // 端口
+        'password'        => Env::get('database.password', 'NL484DiLH5EBxaAd'),
+
+        // ✅ 注意:MySQL 默认端口是 3306,不是 SQL Server 的
         'hostport'        => Env::get('database.hostport', '3306'),
-        // 连接dsn
+
+        // 其他配置项可以保留不变
         'dsn'             => '',
-        // 数据库连接参数
         'params'          => [],
-        // 数据库编码默认采用 utf8mb4
         'charset'         => Env::get('database3.charset', 'utf8mb4'),
-        // 数据库表前缀
         'prefix'          => Env::get('database3.prefix', ''),
-        // 数据库调试模式
         'debug'           => Env::get('database3.debug', false),
-        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
         'deploy'          => 0,
-        // 数据库读写是否分离 主从式有效
         'rw_separate'     => false,
-        // 读写分离后 主服务器数量
         'master_num'      => 1,
-        // 指定从服务器序号
         'slave_no'        => '',
-        // 是否严格检查字段是否存在
         'fields_strict'   => true,
-        // 数据集返回类型
         'resultset_type'  => 'array',
-        // 自动写入时间戳字段
         'auto_timestamp'  => false,
-        // 时间字段取出后的默认时间格式,默认为Y-m-d H:i:s
         'datetime_format' => false,
-        // 是否需要进行SQL性能分析
         'sql_explain'     => false,
-    ]
+    ],
 ];

+ 2 - 2
application/job/ImageJob.php

@@ -165,8 +165,8 @@ class ImageJob{
             return preg_replace('/^第[一二三四五六七八九十]+段[::]?\s*/u', '', $text);
         };
         // 防止越界,逐个安全提取
-        $englishDesc = isset($parts[0]) ? $cleanPrefix(trim($parts[0])) : '';
-        $chineseDesc = isset($parts[1]) ? $cleanPrefix(trim($parts[1])) : '';
+        $chineseDesc = isset($parts[0]) ? $cleanPrefix(trim($parts[0])) : '';
+        $englishDesc = isset($parts[1]) ? $cleanPrefix(trim($parts[1])) : '';
         $part2 = isset($parts[2]) ? $cleanPrefix(trim($parts[2])) : '';
 
         // 只保留中英文、数字、下划线、短横线、空格

+ 215 - 80
application/job/TextToImageJob.php

@@ -2,6 +2,7 @@
 namespace app\job;
 use app\service\AIGatewayService;
 use think\Db;
+use think\Exception;
 use think\Queue;
 use think\queue\Job;
 
@@ -64,9 +65,10 @@ class TextToImageJob
                         $data["outputDir"],
                         $data["width"],
                         $data["height"],
-                        $row["english_description"],
+                        $row["chinese_description"],
                         $row["img_name"],
-                        $data["selectedOption"]
+                        $data["selectedOption"],
+                        $data["executeKeywords"]
                     );
 
                     // 标准化结果文本
@@ -145,7 +147,7 @@ class TextToImageJob
      * 文生图处理函数
      * 描述:根据提示词调用图像生成接口,保存图像文件,并更新数据库
      */
-    public function textToImage($fileName, $outputDirRaw, $width, $height, $prompt, $img_name, $selectedOption)
+    public function textToImage($fileName, $outputDirRaw, $width, $height, $prompt, $img_name, $selectedOption,$executeKeywords)
     {
         $rootPath = str_replace('\\', '/', ROOT_PATH);
         $outputDir = rtrim($rootPath . 'public/' . $outputDirRaw, '/') . '/';
@@ -156,6 +158,10 @@ class TextToImageJob
         foreach ([$fullBaseDir, $fullBaseDir . '1024x1024/', $fullBaseDir . "{$width}x{$height}/"] as $dir) {
             if (!is_dir($dir)) mkdir($dir, 0755, true);
         }
+        // 确保目录存在
+        if (!is_dir($fullBaseDir . '2048x2048/')) {
+            mkdir($fullBaseDir . '2048x2048/', 0755, true);
+        }
 
         // 获取图像记录
         $record = Db::name('text_to_image')
@@ -163,101 +169,230 @@ class TextToImageJob
             ->order('id desc')
             ->find();
 
+
         Db::name('text_to_image')->where('id', $record['id'])->update([
             'new_image_url' => '',
         ]);
 
         if (!$record) return '没有找到匹配的图像记录';
 
-        // 过滤关键词
-        $prompt = preg_replace('/[\r\n\t]+/', ' ', $prompt);
-        foreach (['几何', 'geometry', 'geometric'] as $keyword) {
-            if (stripos($prompt, $keyword) !== false) {
-                Db::name('text_to_image')->where('id', $record['id'])->update([
-                    'status' => 3,
-                    'error_msg' => "包含关键词".$keyword,
-                    'update_time' => date('Y-m-d H:i:s')
-                ]);
-                return "包含关键词 - {$keyword}";
+        //判断是否执行几何图
+        if($executeKeywords == false){
+            // 过滤关键词
+            $prompt = preg_replace('/[\r\n\t]+/', ' ', $prompt);
+            foreach (['几何', 'geometry', 'geometric'] as $keyword) {
+                if (stripos($prompt, $keyword) !== false) {
+                    Db::name('text_to_image')->where('id', $record['id'])->update([
+                        'status' => 3,
+                        'error_msg' => "包含关键词".$keyword,
+                        'update_time' => date('Y-m-d H:i:s')
+                    ]);
+                    return "包含关键词 - {$keyword}";
+                }
             }
         }
 
         // AI 图像生成调用
         $ai = new AIGatewayService();
         $response = $ai->callDalleApi($prompt, $selectedOption);
-        if (isset($response['error'])) {
-            throw new \Exception("❌ 图像生成失败:" . $response['error']['message']);
+
+        if($response['result']){
+// echo "<pre>";
+// print_r($response);
+// echo "<pre>";
+//             sleep(180);
+
+//             $imageUrl = $this->getImageSeed($response['result']);
+//             // echo "<pre>";
+//             // print_r($imageUrl);
+//             // echo "<pre>";
+//             if (!$imageUrl['data']['imageUrl']) {
+//                 throw new Exception('未找到图像');
+//             }
+
+//             $img_name = mb_substr(preg_replace('/[^\x{4e00}-\x{9fa5}A-Za-z0-9_\- ]/u', '', $img_name), 0, 30);
+//             $filename = $img_name . '.png';
+//             $path512 = $fullBaseDir . '2048x2048/' . $filename;
+// // echo "<pre>";
+// // print_r($imageUrl['data']['imageUrl']);
+// // echo "<pre>";
+//             // 下载并保存图片
+//             file_get_contents($imageUrl['data']['imageUrl']);
+
+            // 数据库更新
+            Db::name('text_to_image')->where('id', $record['id'])->update([
+                // 'new_image_url' => str_replace($rootPath . 'public/', '', $path512),
+                'new_image_url' => $response['result'],
+                'taskId' => $response['result'],
+                'img_name' => $img_name,
+                'model' => $selectedOption,
+                'status' => trim($img_name) === '' ? 0 : 1,
+                'status_name' => "文生图",
+                'size' => "2028x2048",
+                'quality' => 'standard',
+                'style' => 'vivid',
+                'error_msg' => '',
+                'update_time' => date('Y-m-d H:i:s')
+            ]);
+            return "成功";
+
+
+
+        }else{
+
+
+            if (isset($response['error'])) {
+                throw new \Exception("❌ 图像生成失败:" . $response['error']['message']);
+            }
+            // 支持 URL 格式(为主)和 base64
+            $imgData = null;
+            if (isset($response['data'][0]['url'])) {
+                $imgData = @file_get_contents($response['data'][0]['url']);
+            } elseif (isset($response['data'][0]['b64_json'])) {
+                $imgData = base64_decode($response['data'][0]['b64_json']);
+            }
+            if (!$imgData || strlen($imgData) < 1000) {
+                throw new \Exception("❌ 图像内容为空或异常!");
+            }
+            // 保存文件路径定义
+            $img_name = mb_substr(preg_replace('/[^\x{4e00}-\x{9fa5}A-Za-z0-9_\- ]/u', '', $img_name), 0, 30);
+            $filename = $img_name . '.png';
+            $path512 = $fullBaseDir . '1024x1024/' . $filename;
+            $pathCustom = $fullBaseDir . "{$width}x{$height}/" . $filename;
+            // 保存原图
+            file_put_contents($path512, $imgData);
+            // 数据库更新
+            Db::name('text_to_image')->where('id', $record['id'])->update([
+                'new_image_url' => str_replace($rootPath . 'public/', '', $path512),
+                // 注释以下一行则不保存裁剪路径(适配你的配置)
+                // 'custom_image_url' => str_replace($rootPath . 'public/', '', $pathCustom),
+                'img_name' => $img_name,
+                'model' => $selectedOption,
+                'status' => trim($img_name) === '' ? 0 : 1,
+                'status_name' => "文生图",
+                'size' => "{$width}x{$height}",
+                'quality' => 'standard',
+                'style' => 'vivid',
+                'error_msg' => '',
+                'update_time' => date('Y-m-d H:i:s')
+            ]);
+            return "成功";
         }
 
-        // 支持 URL 格式(为主)和 base64
-        $imgData = null;
-        if (isset($response['data'][0]['url'])) {
-            $imgData = @file_get_contents($response['data'][0]['url']);
-        } elseif (isset($response['data'][0]['b64_json'])) {
-            $imgData = base64_decode($response['data'][0]['b64_json']);
+    }
+
+
+    public function getImageSeed($taskId)
+    {
+        // 配置参数
+        $apiUrl = 'https://chatapi.onechats.ai/mj/task/' . $taskId . '/fetch';
+        $apiKey = 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK';
+
+        try {
+            // 初始化cURL
+            $ch = curl_init();
+
+            // 设置cURL选项
+            curl_setopt_array($ch, [
+                CURLOPT_URL => $apiUrl,
+                CURLOPT_RETURNTRANSFER => true,
+                CURLOPT_CUSTOMREQUEST => 'GET',  // 明确指定GET方法
+                CURLOPT_HTTPHEADER => [
+                    'Authorization: Bearer ' . $apiKey,
+                    'Accept: application/json',
+                    'Content-Type: application/json'
+                ],
+                CURLOPT_SSL_VERIFYPEER => false,
+                CURLOPT_SSL_VERIFYHOST => false,
+                CURLOPT_TIMEOUT => 60,
+                CURLOPT_FAILONERROR => true     // 添加失败时返回错误
+            ]);
+
+            // 执行请求
+            $response = curl_exec($ch);
+            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+            // 错误处理
+            if (curl_errno($ch)) {
+                throw new Exception('cURL请求失败: ' . curl_error($ch));
+            }
+
+            // 关闭连接
+            curl_close($ch);
+
+            // 验证HTTP状态码
+            if ($httpCode < 200 || $httpCode >= 300) {
+                throw new Exception('API返回错误状态码: ' . $httpCode);
+            }
+
+            // 解析JSON响应
+            $responseData = json_decode($response, true);
+            if (json_last_error() !== JSON_ERROR_NONE) {
+                throw new Exception('JSON解析失败: ' . json_last_error_msg());
+            }
+
+            // 返回结构化数据
+            return [
+                'success' => true,
+                'http_code' => $httpCode,
+                'data' => $responseData
+            ];
+
+        } catch (Exception $e) {
+            // 确保关闭cURL连接
+            if (isset($ch) && is_resource($ch)) {
+                curl_close($ch);
+            }
+
+            return [
+                'success' => false,
+                'error' => $e->getMessage(),
+                'http_code' => $httpCode ?? 0
+            ];
         }
+    }
+    /**
+     * 发送API请求
+     * @param string $url 请求地址
+     * @param array $data 请求数据
+     * @param string $apiKey API密钥
+     * @param string $method 请求方法
+     * @return string 响应内容
+     * @throws Exception
+     */
+    private function sendApiRequest($url, $data, $apiKey, $method = 'POST')
+    {
+        $ch = curl_init();
+
+        curl_setopt_array($ch, [
+            CURLOPT_URL => $url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_CUSTOMREQUEST => $method,
+            CURLOPT_HTTPHEADER => [
+                'Authorization: Bearer '.$apiKey,
+                'Accept: application/json',
+                'Content-Type: application/json'
+            ],
+            CURLOPT_POSTFIELDS => $method === 'POST' ? json_encode($data) : null,
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_SSL_VERIFYHOST => false,
+            CURLOPT_TIMEOUT => 60,
+            CURLOPT_FAILONERROR => true
+        ]);
 
-        if (!$imgData || strlen($imgData) < 1000) {
-            throw new \Exception("❌ 图像内容为空或异常!");
+        $response = curl_exec($ch);
+        $error = curl_error($ch);
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        curl_close($ch);
+
+        if ($error) {
+            throw new Exception('API请求失败: '.$error);
         }
 
-        // 保存文件路径定义
-        $img_name = mb_substr(preg_replace('/[^\x{4e00}-\x{9fa5}A-Za-z0-9_\- ]/u', '', $img_name), 0, 30);
-        $filename = $img_name . '.png';
-        $path512 = $fullBaseDir . '1024x1024/' . $filename;
-        $pathCustom = $fullBaseDir . "{$width}x{$height}/" . $filename;
-
-        // 保存原图
-        file_put_contents($path512, $imgData);
-
-        // ➤ 是否执行裁剪(如不想裁剪,可注释以下 try-catch 整块)
-        // try {
-        //     $im = imagecreatefromstring($imgData);
-        //     if (!$im) throw new \Exception("图像无法解析");
-
-        //     $srcW = imagesx($im);
-        //     $srcH = imagesy($im);
-        //     $srcRatio = $srcW / $srcH;
-        //     $dstRatio = $width / $height;
-
-        //     if ($srcRatio > $dstRatio) {
-        //         $cropW = intval($srcH * $dstRatio);
-        //         $cropH = $srcH;
-        //         $srcX = intval(($srcW - $cropW) / 2);
-        //         $srcY = 0;
-        //     } else {
-        //         $cropW = $srcW;
-        //         $cropH = intval($srcW / $dstRatio);
-        //         $srcX = 0;
-        //         $srcY = intval(($srcH - $cropH) / 2);
-        //     }
-
-        //     $dstImg = imagecreatetruecolor($width, $height);
-        //     imagecopyresampled($dstImg, $im, 0, 0, $srcX, $srcY, $width, $height, $cropW, $cropH);
-        //     imagepng($dstImg, $pathCustom);
-        //     imagedestroy($im);
-        //     imagedestroy($dstImg);
-        // } catch (\Throwable $e) {
-        //     file_put_contents('/tmp/crop_error.png', $imgData);
-        //     throw new \Exception("图像裁剪失败:" . $e->getMessage());
-        // }
-
-        // 数据库更新
-        Db::name('text_to_image')->where('id', $record['id'])->update([
-            'new_image_url' => str_replace($rootPath . 'public/', '', $path512),
-            // 注释以下一行则不保存裁剪路径(适配你的配置)
-            // 'custom_image_url' => str_replace($rootPath . 'public/', '', $pathCustom),
-            'img_name' => $img_name,
-            'model' => $selectedOption,
-            'status' => trim($img_name) === '' ? 0 : 1,
-            'status_name' => "文生图",
-            'size' => "{$width}x{$height}",
-            'quality' => 'standard',
-            'style' => 'vivid',
-            'error_msg' => '',
-            'update_time' => date('Y-m-d H:i:s')
-        ]);
+        if ($httpCode < 200 || $httpCode >= 300) {
+            throw new Exception('API返回错误状态码: '.$httpCode);
+        }
 
-        return "成功";
+        return $response;
     }
 }

+ 27 - 8
application/service/AIGatewayService.php

@@ -30,10 +30,11 @@ class AIGatewayService{
         'txttoimg' => [
             // 'api_key' => 'sk-MB6SR8qNaTjO80U7HJl4ztivX3zQKPgKVka9oyfVSXIkHSYZ',
             'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
-
-
             'api_url' => 'https://chatapi.onechats.ai/v1/images/generations'
-
+        ],
+        'submitimage' => [
+            'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+            'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine'
         ]
     ];
 
@@ -152,36 +153,54 @@ class AIGatewayService{
                 'prompt'  => $prompt,
                 'model'   => $selectedOption,
                 'n'       => 1,
-                // 'size'    => '512x512',
                 'size'    => '1024x1024',
                 'quality' => 'hd',
                 'style'   => 'vivid',
                 'response_format' => 'url',
             ];
+            return $this->callApi($this->config['txttoimg']['api_url'],$this->config['txttoimg']['api_key'],$data);
         } else if ($selectedOption === 'black-forest-labs/FLUX.1-kontext-pro') {
             $data = [
                 'prompt'  => $prompt,
                 'model'   => $selectedOption,
                 'n'       => 1,
-                // 'size'    => '512x512',
                 'size'    => '1024x1024',
                 'quality' => 'hd',
                 'style'   => 'vivid',
                 'response_format' => 'url',
             ];
-        }else{
+            return $this->callApi($this->config['txttoimg']['api_url'],$this->config['txttoimg']['api_key'],$data);
+        } else if ($selectedOption === 'gpt-image-1') {
             $data = [
                 'prompt'  => $prompt,
                 'model'   => $selectedOption,
                 'n'       => 1,
-                // 'size'    => '512x512',
                 'size'    => '1024x1024',
                 'quality' => 'hd',
                 'style'   => 'vivid',
                 'response_format' => 'url',
             ];
+            return $this->callApi($this->config['txttoimg']['api_url'],$this->config['txttoimg']['api_key'],$data);
+        } else if ($selectedOption === 'MID_JOURNEY') {
+            $data = [
+                'botType' => $selectedOption,
+                'prompt' => $prompt,
+                'base64Array' => [],
+                'accountFilter' => [
+                    'channelId' => "",
+                    'instanceId' =>  "",
+                    'modes' => [],
+                    'remark' => "",
+                    'remix' => true,
+                    'remixAutoConsidered' => true
+                ],
+                'notifyHook' => "",
+                'state' => ""
+            ];
+            return $this->callApi($this->config['submitimage']['api_url'],$this->config['submitimage']['api_key'],$data);
+        }else{
+            echo '其他文生图模型参数配置';
         }
-        return $this->callApi($this->config['txttoimg']['api_url'],$this->config['txttoimg']['api_key'],$data);
     }
 
 

+ 2 - 1
application/service/ImageService.php

@@ -40,7 +40,8 @@ class ImageService{
                 "txttotxt_selectedOption" => $params['txttotxt_selectedOption'],
                 "prompt" => $template['content'],
                 "width" => $params['width'],
-                "height" => $params['height']
+                "height" => $params['height'],
+                "executeKeywords" => $params['executeKeywords']
             ];
             // 创建$num个相同的项目并合并到$arr
             $arr = array_merge($arr, array_fill(0, $num, $baseItem));