Commit 24763b3f authored by 刘小敏's avatar 刘小敏

3D试戴 图片生成 替换 obs

parent 7425af1c
......@@ -34,16 +34,18 @@ class User extends Common
*/
public function getObsToken()
{
// 获取华为云 OBS 配置(在 config.php 的 shopro 数组中)
$accessKey = config('shopro.obs_access_key');
$secretKey = config('shopro.obs_secret_key');
$endpoint = config('shopro.obs_endpoint');
$bucket = config('shopro.obs_bucket');
// 获取华为云 OBS 配置(从 hwobs 插件配置中获取)
$config = get_addon_config('hwobs');
// 检查配置是否完整
if (empty($accessKey) || empty($secretKey) || empty($endpoint) || empty($bucket)) {
if (empty($config) || empty($config['accessKey']) || empty($config['secretKey']) || empty($config['endpoint']) || empty($config['bucket'])) {
$this->error('OBS 配置未完成');
}
$accessKey = $config['accessKey'];
$secretKey = $config['secretKey'];
$endpoint = $config['endpoint'];
$bucket = $config['bucket'];
// 1. 生成上传目录(按日期分目录)
$dir = 'uploads/' . date('Ymd') . '/';
......
......@@ -80,8 +80,8 @@ class AiImgGen extends BaseJob
return false;
} else {
// 保存图片到本地
$attachment = $aiService->saveFileLoc(isset($res['data']) ? $res['data'] : '', '.png', 'gen_ai', $user_id);
// 保存图片到OBS存储
$attachment = $aiService->saveFileObs(isset($res['data']) ? $res['data'] : '', '.png', 'gen_ai', $user_id);
// 记录入参日志
$this->debug_log('['.$id.'][AI生成图片接口] user_id:' . $user_id . ' 保存到本地接口接口出参:' . json_encode($attachment), $user_id);
......@@ -93,7 +93,7 @@ class AiImgGen extends BaseJob
return false;
}
AiTryOnModel::where('id', $id)->where('user_id', $user_id)->update(['ai_status' => 1, 'ai_err_msg' => '图片已成功', 'ai_url' => config('shopro.api_host') . $attachment, 'user_id' => $user_id]);
AiTryOnModel::where('id', $id)->where('user_id', $user_id)->update(['ai_status' => 1, 'ai_err_msg' => '图片已成功', 'ai_url' => $attachment, 'user_id' => $user_id]);
// 发送消息通知
$aiService->sendNotification($user_id, $id);
......
......@@ -8,6 +8,7 @@ use addons\shopro\service\commission\Goods;
use addons\shopro\service\goods\GoodsService;
use app\admin\model\shopro\AiTryon as AiTryOnModel;
use app\admin\model\shopro\user\User;
use Obs\ObsClient;
use think\Config;
use think\exception\HttpResponseException;
use think\Log;
......@@ -121,6 +122,97 @@ class Ai
return 0;
}
}
/**
* 使用 OBS SDK 保存远程文件到华为云 OBS
* 直接下载远程文件并流式上传到 OBS,无需创建临时文件
* 主要用于3D试戴 2026.06.11
*
* @param string $file_url 远程文件URL
* @param string $file_suffix 文件后缀
* @param string $log_name 日志名称
* @param int $user_id 用户ID
* @return string|int 文件路径(成功)或 0(失败)
*/
public function saveFileObs($file_url, $file_suffix = '.png', $log_name = 'gen_ai', $user_id = 0)
{
if (empty($file_url)) {
return 0;
}
try {
custom_log('fileUrl: ' . $file_url, $user_id, $log_name);
// 1 获取 OBS 配置
$config = get_addon_config('hwobs');
custom_log('OBS 配置:' . json_encode($config), $user_id, $log_name);
if (empty($config) || empty($config['accessKey']) || empty($config['secretKey']) || empty($config['bucket']) || empty($config['endpoint'])) {
custom_log('OBS 配置未正确设置', $user_id, $log_name);
return 0;
}
// 2 生成存储路径(fastadmin标准uploads目录结构)
$upload_dir = '/uploads/gen_ai/' . date('Ymd') . '/';
$filename = md5(time() . uniqid()) . $file_suffix;
$object_key = ltrim($upload_dir . $filename, '/');
// 3 使用 curl 直接下载文件内容到内存
$ch = curl_init($file_url);
// 设置 curl 选项,将内容写入变量而不是文件
$file_content = '';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
// 执行下载
$file_content = curl_exec($ch);
$error = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 4 检查下载是否成功
if ($error || $http_code >= 400 || empty($file_content)) {
custom_log('文件下载失败:' . $error . " HTTP状态码:{$http_code} 内容为空", $user_id, $log_name);
return 0;
}
// 5 创建 OBS 客户端
$obs = new ObsClient([
'key' => $config['accessKey'],
'secret' => $config['secretKey'],
'endpoint' => $config['endpoint'],
'region' => $config['region'] ?? 'cn-east-3',
]);
// 6 直接上传文件内容到 OBS(使用 Body 参数)
$ret = $obs->putObject([
'Bucket' => $config['bucket'],
'Key' => $object_key,
'Body' => $file_content, // 直接使用文件内容
'ACL' => 'public-read', // 设置公共读权限
]);
// 7 检查上传结果
if (!isset($ret['ObjectURL'])) {
custom_log('OBS 上传失败', $user_id, $log_name);
return 0;
}
custom_log('OBS 上传成功:' . $ret['ObjectURL'], $user_id, $log_name);
// 返回相对路径(与 saveFileLoc 返回格式一致)
// return $upload_dir . $filename;
return $ret['ObjectURL'];
} catch (\Exception $e) {
format_log_error_custom_name($e, 'OBS 文件上传失败', '', $log_name);
return 0;
}
}
/**
* 根据商品分类判断AI耳饰类型
......@@ -298,8 +390,8 @@ class Ai
return $resGenImg;
}
// 保存图片到本地做备份
$attachment = $this->saveFileLoc(isset($resGenImg['data']) ? $resGenImg['data'] : '', '.png', 'gen_ai', $userId);
// 保存图片到 OBS
$attachment = $this->saveFileObs(isset($resGenImg['data']) ? $resGenImg['data'] : '', '.png', 'gen_ai', $userId);
custom_log('['.$id.'][AI视频生成异步队列]用户ID:'. $userId .' id:'. $id .'图片保存到本地接口接口出参:'. json_encode($attachment), $userId, 'gen_ai');
// 调试的时候用,一张AI佩戴饰品的照片
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment