|
|
@@ -3,6 +3,7 @@ namespace app\api\controller;
|
|
|
|
|
|
use app\common\controller\Api;
|
|
|
use app\job\ImageJob;
|
|
|
+use app\service\AIGatewayService;
|
|
|
use app\service\ImageService;
|
|
|
use think\App;
|
|
|
use think\Db;
|
|
|
@@ -10,11 +11,18 @@ use think\Exception;
|
|
|
use think\Log;
|
|
|
use think\Queue;
|
|
|
use think\queue\job\Redis;
|
|
|
+use think\Request;
|
|
|
+
|
|
|
class WorkOrder extends Api
|
|
|
{
|
|
|
protected $noNeedLogin = ['*'];
|
|
|
protected $noNeedRight = ['*'];
|
|
|
|
|
|
+ public function indexx()
|
|
|
+ {
|
|
|
+ echo 123;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 出图接口
|
|
|
* 此方法处理图像转换为文本的请求,将图像信息存入队列以供后续处理。
|
|
|
@@ -22,9 +30,338 @@ class WorkOrder extends Api
|
|
|
public function imageToText()
|
|
|
{
|
|
|
$params = $this->request->param();
|
|
|
- $service = new ImageService();
|
|
|
- $service->handleImage($params);
|
|
|
- $this->success('任务成功提交至队列');
|
|
|
+ $service = new ImageService();
|
|
|
+ $service->handleImage($params);
|
|
|
+ $this->success('任务成功提交至队列');
|
|
|
+ }
|
|
|
+
|
|
|
+ //扩写文本内容提示词
|
|
|
+ public function GetTxtToTxt(){
|
|
|
+ // 确保所有必要的变量都已初始化
|
|
|
+ $params = $this->request->param();
|
|
|
+ $prompt = $params['prompt'];
|
|
|
+
|
|
|
+ $ai = new AIGatewayService();
|
|
|
+ $gptRes = $ai->txtGptApi($prompt,'gemini-2.0-flash');
|
|
|
+ echo "<pre>";
|
|
|
+ print_r($gptRes);
|
|
|
+ echo "<pre>";
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取URL地址与端口
|
|
|
+ public function GetHttpUrl(){
|
|
|
+ $data = Db::name('http_url')->find();
|
|
|
+ // 拼接完整的HTTP URL
|
|
|
+ $fullUrl = "http://" . $data['baseUrl'] . ":" . $data['port'];
|
|
|
+ $res = [
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '成功',
|
|
|
+ 'data' => [
|
|
|
+ 'full_url' => $fullUrl,
|
|
|
+ 'id' => $data['id'],
|
|
|
+ 'baseUrl' => $data['baseUrl'],
|
|
|
+ 'port' => $data['port']
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ return json($res);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public function Getvideolist(){
|
|
|
+ if (!$this->request->isGet()) {
|
|
|
+ $this->error('请求方式错误');
|
|
|
+ }
|
|
|
+ $params = $this->request->param();
|
|
|
+ $search = input('search', '');
|
|
|
+ $page = isset($params['page']) ? (int)$params['page'] : 1;
|
|
|
+ $limit = isset($params['limit']) ? (int)$params['limit'] : 50;
|
|
|
+ $where = [];
|
|
|
+ if (!empty($search)) {
|
|
|
+ $where['prompt'] = ['like', '%' . $search . '%'];
|
|
|
+ }
|
|
|
+ $list = Db::name('video')->where('mod_rq', null)
|
|
|
+ ->where($where)
|
|
|
+ ->order('id desc')
|
|
|
+ ->limit(($page - 1) * $limit, $limit)
|
|
|
+ ->select();
|
|
|
+ $total = Db::name('video')->where('mod_rq', null)
|
|
|
+ ->where($where)
|
|
|
+ ->count();
|
|
|
+ $res['code'] = 0;
|
|
|
+ $res['msg'] = '成功';
|
|
|
+ $res['count'] = $total;
|
|
|
+ $res['data'] = $list;
|
|
|
+ return json($res);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //video_691c078dbb648190a17625bbef815ce50cbc1621ce1702d7
|
|
|
+ public function video()
|
|
|
+ {
|
|
|
+ $params = $this->request->param();
|
|
|
+
|
|
|
+ $apiUrl = 'https://chatapi.onechats.ai/v1/videos';
|
|
|
+ $apiKey = 'sk-sWW1GFlnjbrDRb1DkMEzePIxgdvLK6cZt0Qg93yDMVP2z1yN';
|
|
|
+ $postData = [
|
|
|
+ 'prompt' => $params['prompt'],
|
|
|
+ 'model' => $params['model'],
|
|
|
+ 'seconds' => $params['seconds'],
|
|
|
+ 'size' => $params['size'],
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 初始化CURL
|
|
|
+ $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_POSTFIELDS, $postData);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
+ 'Authorization: Bearer ' . $apiKey
|
|
|
+ ]);
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, 300);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
|
|
+ curl_setopt($ch, CURLOPT_HEADER, true); // 获取响应头
|
|
|
+ curl_setopt($ch, CURLOPT_VERBOSE, true); // 启用详细输出以进行调试
|
|
|
+ // 创建临时文件来捕获详细的cURL输出
|
|
|
+ $verbose = fopen('php://temp', 'w+');
|
|
|
+ curl_setopt($ch, CURLOPT_STDERR, $verbose);
|
|
|
+ // 执行请求
|
|
|
+ $response = curl_exec($ch);
|
|
|
+ //HTTP状态码
|
|
|
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
+ // 获取详细的cURL调试信息
|
|
|
+ rewind($verbose);
|
|
|
+ //CURL调试信息
|
|
|
+ $verboseLog = stream_get_contents($verbose);
|
|
|
+ fclose($verbose);
|
|
|
+ // 分离头部和主体
|
|
|
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
|
|
+ //响应头部
|
|
|
+ $header = substr($response, 0, $header_size);
|
|
|
+ //响应主体
|
|
|
+ $body = substr($response, $header_size);
|
|
|
+ // 检查CURL错误
|
|
|
+ $curlError = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ $responseData = json_decode($body, true);
|
|
|
+
|
|
|
+ // 检查API是否返回了错误信息
|
|
|
+ if (isset($responseData['error'])) {
|
|
|
+ $errorMessage = isset($responseData['error']['message']) ? $responseData['error']['message'] : 'API请求失败';
|
|
|
+ return json([
|
|
|
+ 'code' => 1,
|
|
|
+ 'msg' => '视频生成请求失败',
|
|
|
+ 'data' => [
|
|
|
+ 'error_type' => isset($responseData['error']['type']) ? $responseData['error']['type'] : 'unknown',
|
|
|
+ 'error_code' => isset($responseData['error']['code']) ? $responseData['error']['code'] : 'unknown',
|
|
|
+ 'error_message' => $errorMessage
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否有自定义错误格式
|
|
|
+ if (isset($responseData['code']) && $responseData['code'] === 'fail_to_fetch_task' && isset($responseData['message'])) {
|
|
|
+ return json([
|
|
|
+ 'code' => 1,
|
|
|
+ 'msg' => '视频生成请求失败',
|
|
|
+ 'data' => [
|
|
|
+ 'error_code' => $responseData['code'],
|
|
|
+ 'error_message' => $responseData['message']
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否存在id字段
|
|
|
+ if (!isset($responseData['id'])) {
|
|
|
+ return json([
|
|
|
+ 'code' => 1,
|
|
|
+ 'msg' => '无法获取视频ID',
|
|
|
+ 'data' => [
|
|
|
+ 'response_data' => $responseData,
|
|
|
+ 'http_code' => $httpCode
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $videoData = [
|
|
|
+ 'video_id' => $responseData['id'],
|
|
|
+ 'prompt' => $postData['prompt'],
|
|
|
+ 'model' => $postData['model'],
|
|
|
+ 'seconds' => $postData['seconds'],
|
|
|
+ 'size' => $postData['size'],
|
|
|
+ 'sys_rq' => date("Y-m-d H:i:s")
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 尝试插入数据
|
|
|
+ try {
|
|
|
+ $res = Db::name('video')->insert($videoData);
|
|
|
+ return json([
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '视频正在生成中',
|
|
|
+ 'data ' => [
|
|
|
+ 'video_id' => $responseData['id'],
|
|
|
+ 'insert_result' => $res
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ } catch (Exception $e) {
|
|
|
+ return json([
|
|
|
+ 'code' => 1,
|
|
|
+ 'msg' => '数据库操作失败',
|
|
|
+ 'data' => [
|
|
|
+ 'error_message' => $e->getMessage()
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取视频内容
|
|
|
+ * 下载已完成的视频内容
|
|
|
+ */
|
|
|
+ public function videoContent(){
|
|
|
+ // 从请求参数获取video_id,如果没有则使用默认值
|
|
|
+ $video_id = input('get.video_id');
|
|
|
+
|
|
|
+ $apiKey = 'sk-sWW1GFlnjbrDRb1DkMEzePIxgdvLK6cZt0Qg93yDMVP2z1yN';
|
|
|
+ // 1. 先检查视频状态
|
|
|
+ $statusUrl = 'https://chatapi.onechats.ai/v1/videos/' . $video_id;
|
|
|
+ $statusData = $this->fetchVideoStatus($statusUrl, $apiKey);
|
|
|
+
|
|
|
+ // 检查视频状态
|
|
|
+ if ($statusData['status'] !== 'completed') {
|
|
|
+ return json([
|
|
|
+ 'code' => 202,
|
|
|
+ 'msg' => '视频尚未生成完成',
|
|
|
+ 'data' => [
|
|
|
+ 'video_id' => $video_id,
|
|
|
+ 'status' => $statusData['status'],
|
|
|
+ 'progress' => $statusData['progress'],
|
|
|
+ 'created_at' => $statusData['created_at'],
|
|
|
+ 'message' => '请稍后再试,视频仍在' . ($statusData['status'] === 'queued' ? '排队中' : '处理中')
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 视频生成完成,准备下载
|
|
|
+ $apiUrl = 'https://chatapi.onechats.ai/v1/videos/' . $video_id . '/content';
|
|
|
+
|
|
|
+ // 获取可选的variant参数
|
|
|
+ $variant = input('get.variant', '');
|
|
|
+ if (!empty($variant)) {
|
|
|
+ $apiUrl .= '?variant=' . urlencode($variant);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建保存目录
|
|
|
+ $saveDir = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'videos' . DS . date('Ymd');
|
|
|
+ if (!is_dir($saveDir)) {
|
|
|
+ mkdir($saveDir, 0755, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成唯一文件名
|
|
|
+ $filename = $video_id . '.mp4';
|
|
|
+ $localPath = DS . 'uploads' . DS . 'videos' . DS . date('Ymd') . DS . $filename;
|
|
|
+ $fullPath = $saveDir . DS . $filename;
|
|
|
+
|
|
|
+ // 3. 下载视频
|
|
|
+ $videoData = $this->downloadVideo($apiUrl, $apiKey);
|
|
|
+
|
|
|
+ // 4. 保存视频文件
|
|
|
+ if (file_put_contents($fullPath, $videoData) === false) {
|
|
|
+ throw new Exception('视频保存失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保路径使用正斜杠,并只保存相对路径部分
|
|
|
+ $localPath = str_replace('\\', '/', $localPath);
|
|
|
+ // 移除开头的斜杠,确保路径格式为uploads/videos/...
|
|
|
+ $savePath = ltrim($localPath, '/');
|
|
|
+
|
|
|
+ // 将正确格式的文件路径存入数据库
|
|
|
+ Db::name('video')->where('video_id', $video_id)->update([
|
|
|
+ 'web_url' => $savePath
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 返回成功响应
|
|
|
+ return json([
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => '视频下载成功',
|
|
|
+ 'data' => [
|
|
|
+ 'video_id' => $video_id,
|
|
|
+ 'local_path' => $localPath,
|
|
|
+ 'web_url' => $savePath,
|
|
|
+ 'file_size' => filesize($fullPath)
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取视频状态
|
|
|
+ */
|
|
|
+ private function fetchVideoStatus($url, $apiKey) {
|
|
|
+ $ch = curl_init();
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPGET, true);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
+ 'Authorization: Bearer ' . $apiKey,
|
|
|
+ 'Accept: application/json'
|
|
|
+ ]);
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
|
|
+
|
|
|
+ $response = curl_exec($ch);
|
|
|
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ if ($error) {
|
|
|
+ throw new Exception('获取视频状态失败: ' . $error);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($httpCode < 200 || $httpCode >= 300) {
|
|
|
+ throw new Exception('获取视频状态失败,HTTP状态码: ' . $httpCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = json_decode($response, true);
|
|
|
+ if (!is_array($data)) {
|
|
|
+ throw new Exception('视频状态数据格式错误');
|
|
|
+ }
|
|
|
+
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 下载视频文件
|
|
|
+ */
|
|
|
+ private function downloadVideo($url, $apiKey) {
|
|
|
+ $ch = curl_init();
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPGET, true);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
+ 'Authorization: Bearer ' . $apiKey
|
|
|
+ ]);
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, 300);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
|
|
+
|
|
|
+ $response = curl_exec($ch);
|
|
|
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ if ($error) {
|
|
|
+ throw new Exception('视频下载失败: ' . $error);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($httpCode < 200 || $httpCode >= 300) {
|
|
|
+ throw new Exception('视频下载失败,HTTP状态码: ' . $httpCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $response;
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -390,7 +727,7 @@ class WorkOrder extends Api
|
|
|
public function imgtowimg()
|
|
|
{
|
|
|
$prompt = $this->request->param('prompt', '');
|
|
|
- $imgRelPath = 'uploads/operate/ai/Preview/arr/两只手碰拳的黑白线条插画下有Daddy Me字样风格简约质.png';
|
|
|
+ $imgRelPath = 'uploads/operate/ai/Preview/arr/0835006071623.png';
|
|
|
|
|
|
$imgPath = ROOT_PATH . 'public/' . $imgRelPath;
|
|
|
|
|
|
@@ -487,7 +824,7 @@ class WorkOrder extends Api
|
|
|
{
|
|
|
// 配置参数
|
|
|
$config = [
|
|
|
- 'input_dir' => 'uploads/operate/ai/Preview/arr/',
|
|
|
+ 'input_dir' => 'uploads/img2img/',
|
|
|
'output_dir' => 'uploads/extra_image/',
|
|
|
'api_url' => 'http://20.0.17.188:45001/sdapi/v1/extra-single-image',
|
|
|
'timeout' => 120, // 增加超时时间,高清处理可能耗时较长
|
|
|
@@ -507,7 +844,7 @@ class WorkOrder extends Api
|
|
|
];
|
|
|
|
|
|
// 输入文件处理
|
|
|
- $imgRelPath = '图案的整体色调是柔和的蓝色和灰色形成温馨而宁静的视觉效果花卉.png';
|
|
|
+ $imgRelPath = '0835006071623-1757406184-1024x1248.png';
|
|
|
$imgPath = ROOT_PATH . 'public/' . $config['input_dir'] . $imgRelPath;
|
|
|
|
|
|
if (!file_exists($imgPath)) {
|
|
|
@@ -740,6 +1077,7 @@ class WorkOrder extends Api
|
|
|
->group('status')
|
|
|
->select();
|
|
|
|
|
|
+
|
|
|
$statusCount = [];
|
|
|
foreach ($statusList as $item) {
|
|
|
$statusCount[$item['status']] = $item['total'];
|
|
|
@@ -920,4 +1258,6 @@ class WorkOrder extends Api
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
}
|