Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
loveisland
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘小敏
loveisland
Commits
285b276b
Commit
285b276b
authored
May 14, 2026
by
刘小敏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AI视频队列程序日志优化;
parent
ab7732df
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
37 deletions
+120
-37
AiTryon.php
addons/shopro/controller/user/AiTryon.php
+1
-0
helper.php
addons/shopro/helper/helper.php
+1
-2
AiVideoGen.php
addons/shopro/job/AiVideoGen.php
+98
-35
common.php
application/common.php
+20
-0
No files found.
addons/shopro/controller/user/AiTryon.php
View file @
285b276b
...
@@ -226,6 +226,7 @@ class AiTryon extends Common
...
@@ -226,6 +226,7 @@ class AiTryon extends Common
$user
=
auth_user
();
$user
=
auth_user
();
// \think\Queue::push('\addons\shopro\job\AiVideoGen@save', ['taskid' => 'cgt-20260506113558-x6wtq', 'user' => $user], 'shopro-high');
// \think\Queue::push('\addons\shopro\job\AiVideoGen@save', ['taskid' => 'cgt-20260506113558-x6wtq', 'user' => $user], 'shopro-high');
// $this->success('推送队列成功');
// $this->success('推送队列成功');
// exit;
// exit;
...
...
addons/shopro/helper/helper.php
View file @
285b276b
...
@@ -926,9 +926,8 @@ if (!function_exists('operate_disabled')) {
...
@@ -926,9 +926,8 @@ if (!function_exists('operate_disabled')) {
// 调试输出
// 调试输出
if
(
!
function_exists
(
'debug_echo'
))
{
if
(
!
function_exists
(
'debug_echo'
))
{
function
debug_echo
(
$text
=
''
)
function
debug_echo
(
$text
=
''
,
$name
=
'gen_ai'
)
{
{
echo
PHP_EOL
.
'------'
.
$text
.
'------'
.
PHP_EOL
;
echo
PHP_EOL
.
'------'
.
$text
.
'------'
.
PHP_EOL
;
\think\Log
::
info
(
$text
);
}
}
}
}
addons/shopro/job/AiVideoGen.php
View file @
285b276b
...
@@ -7,6 +7,9 @@ use addons\shopro\library\HttpClient as Http;
...
@@ -7,6 +7,9 @@ use addons\shopro\library\HttpClient as Http;
use
app\admin\model\shopro\AiTryon
as
AiTryOnModel
;
use
app\admin\model\shopro\AiTryon
as
AiTryOnModel
;
use
think\Log
;
use
think\Log
;
use
think\queue\Job
;
use
think\queue\Job
;
use
app\admin\model\shopro\user\User
;
use
think\facade\Notification
as
NotificationFacade
;
use
addons\shopro\notification\ai\AiVideoSuccess
;
/**
/**
* AI生成的视频保存到本地并更新数据表
* AI生成的视频保存到本地并更新数据表
...
@@ -18,12 +21,27 @@ class AiVideoGen extends BaseJob
...
@@ -18,12 +21,27 @@ class AiVideoGen extends BaseJob
private
$ark_host
=
'https://ark.cn-beijing.volces.com'
;
private
$ark_host
=
'https://ark.cn-beijing.volces.com'
;
private
$public_dir
=
ROOT_PATH
.
'public'
;
private
$public_dir
=
ROOT_PATH
.
'public'
;
// 是否输出调试日志
private
$is_debug
=
true
;
// 是否记录日志
private
$is_log
=
true
;
// 调试日志 && 自定义日志
private
function
debug_log
(
$text
=
''
){
if
(
$this
->
is_debug
){
debug_echo
(
$text
);
}
if
(
$this
->
is_log
){
custom_log
(
$text
,
'gen_ai_video'
);
}
}
/**
/**
* 保存远端视频文件到本地
* 保存远端视频文件到本地
*/
*/
private
function
saveVideoLoc
(
$videoUrl
){
private
function
saveVideoLoc
(
$videoUrl
){
debug_echo
(
'videoUrl: '
.
$videoUrl
);
$this
->
debug_log
(
'videoUrl: '
.
$videoUrl
);
// 1 生成存储目录(fastadmin标准uploads目录)
// 1 生成存储目录(fastadmin标准uploads目录)
$upload_dir
=
'/uploads/ai_video/'
.
date
(
'Ymd'
)
.
'/'
;
$upload_dir
=
'/uploads/ai_video/'
.
date
(
'Ymd'
)
.
'/'
;
...
@@ -60,7 +78,7 @@ class AiVideoGen extends BaseJob
...
@@ -60,7 +78,7 @@ class AiVideoGen extends BaseJob
if
(
file_exists
(
$full_path
))
{
if
(
file_exists
(
$full_path
))
{
unlink
(
$full_path
);
unlink
(
$full_path
);
}
}
debug_echo
(
'视频下载失败:'
.
$error
.
"HTTP状态码:
{
$http_code
}
,文件为空"
);
$this
->
debug_log
(
'视频下载失败:'
.
$error
.
"HTTP状态码:
{
$http_code
}
,文件为空"
);
return
0
;
// 统一失败返回值
return
0
;
// 统一失败返回值
}
}
...
@@ -102,30 +120,28 @@ class AiVideoGen extends BaseJob
...
@@ -102,30 +120,28 @@ class AiVideoGen extends BaseJob
}
}
/**
/**
* AI视频结果
存
* AI视频结果
处理
*/
*/
public
function
save
(
Job
$job
,
$data
)
public
function
save
(
Job
$job
,
$data
)
{
{
try
{
try
{
$taskid
=
$data
[
'taskid'
];
$taskid
=
$data
[
'taskid'
];
// $taskid = 'cgt-20260430190444-vmb4q';
$user
=
$data
[
'user'
];
$user
=
$data
[
'user'
];
$user_id
=
isset
(
$user
[
'id'
])
?
$user
[
'id'
]
:
0
;
$user_id
=
isset
(
$user
[
'id'
])
?
$user
[
'id'
]
:
0
;
$this
->
debug_log
(
'***************************** 保存AI视频脚本开始 userid '
.
$user_id
.
' taskid:'
.
$taskid
.
' ***********************************'
.
PHP_EOL
);
if
(
!
isset
(
$taskid
)
||
empty
(
$taskid
)
||
!
isset
(
$user_id
)
||
empty
(
$user_id
))
{
if
(
!
isset
(
$taskid
)
||
empty
(
$taskid
)
||
!
isset
(
$user_id
)
||
empty
(
$user_id
))
{
debug_echo
(
'[AI视频]入参有空值 taskid:'
.
$taskid
.
' user_id:'
.
$user_id
);
$this
->
debug_log
(
'[AI视频]入参有空值 taskid:'
.
$taskid
.
' user_id:'
.
$user_id
);
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
return
false
;
return
false
;
}
}
$url
=
$this
->
ark_host
.
'/api/v3/contents/generations/tasks/'
.
$taskid
;
$url
=
$this
->
ark_host
.
'/api/v3/contents/generations/tasks/'
.
$taskid
;
debug_echo
(
'[AI视频]脚本开始执行 AI接口url:'
.
$url
);
$params
=
[
$params
=
[
'headers'
=>
[
'headers'
=>
[
'Authorization'
=>
'Bearer '
.
config
(
'shopro.ai_api_key'
),
'Authorization'
=>
'Bearer '
.
config
(
'shopro.ai_api_key'
),
...
@@ -135,6 +151,8 @@ class AiVideoGen extends BaseJob
...
@@ -135,6 +151,8 @@ class AiVideoGen extends BaseJob
'allow_redirects'
=>
true
'allow_redirects'
=>
true
];
];
$this
->
debug_log
(
'[AI视频]请求AI接口入参 user_id:'
.
$user_id
.
' AI接口url:'
.
$url
.
' params:'
.
json_encode
(
$params
));
// 向AI接口 发送请求
// 向AI接口 发送请求
$client
=
new
Http
();
$client
=
new
Http
();
$response
=
$client
->
get
(
$url
,
$params
);
$response
=
$client
->
get
(
$url
,
$params
);
...
@@ -143,77 +161,77 @@ class AiVideoGen extends BaseJob
...
@@ -143,77 +161,77 @@ class AiVideoGen extends BaseJob
$content
=
preg_replace
(
'/[^\x20-\x7E]/'
,
''
,
$content
);
$content
=
preg_replace
(
'/[^\x20-\x7E]/'
,
''
,
$content
);
$result
=
json_decode
(
$content
,
true
);
$result
=
json_decode
(
$content
,
true
);
$this
->
debug_log
(
'[AI视频]请求AI接口出参 response:'
.
json_encode
(
$result
));
// AI接口 返回失败
// AI接口 返回失败
if
(
isset
(
$result
[
'error'
])){
if
(
isset
(
$result
[
'error'
])){
$code
=
$result
[
'error'
][
'code'
]
??
''
;
$message
=
$result
[
'error'
][
'message'
]
??
'未知错误'
;
$message
=
$result
[
'error'
][
'message'
]
??
'未知错误'
;
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
$message
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
$message
]);
// 记录错误日志
Log
::
error
(
'AI生成视频队列返回:taskId: '
.
$taskid
.
'code '
.
$code
.
'message: '
.
$message
.
' result:'
.
$content
.
PHP_EOL
);
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
return
false
;
return
false
;
}
}
// AI接口 返回成功
// AI接口 返回成功
if
(
isset
(
$result
[
'status'
])){
if
(
isset
(
$result
[
'status'
])){
debug_echo
(
'[AI视频]AI接口 返回成功 status有值:'
.
$result
[
'status'
]);
switch
(
$result
[
'status'
])
{
switch
(
$result
[
'status'
])
{
// 成功返回视频链接
// 成功返回视频链接
case
'succeeded'
:
case
'succeeded'
:
// 保存远程视频到本地
// 保存远程视频到本地
$video_url
=
$this
->
saveVideoLoc
(
isset
(
$result
[
'content'
][
'video_url'
])
?
$result
[
'content'
][
'video_url'
]
:
''
);
$video_url
=
$this
->
saveVideoLoc
(
isset
(
$result
[
'content'
][
'video_url'
])
?
$result
[
'content'
][
'video_url'
]
:
''
);
debug_echo
(
'[AI视频]保存本地接口返回值 video_url:'
.
$video_url
);
$this
->
debug_log
(
'[AI视频]保存本地接口返回值 video_url:'
.
$video_url
);
if
(
$video_url
===
0
){
if
(
$video_url
===
0
){
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'视频保存到本地失败'
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'视频保存到本地失败'
]);
debug_echo
(
'[AI视频]保存本地视频失败sql:'
.
db
()
->
getLastSql
());
$this
->
debug_log
(
'[AI视频]保存本地视频失败 sql: '
.
db
()
->
getLastSql
());
break
;
}
}
// 更新我的试戴
// 更新我的试戴
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
1
,
'ai_url'
=>
config
(
'shopro.api_host'
)
.
$video_url
,
'ai_err_msg'
=>
'视频生成成功'
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
1
,
'ai_url'
=>
config
(
'shopro.api_host'
)
.
$video_url
,
'ai_err_msg'
=>
'视频生成成功'
]);
debug_echo
(
'[AI视频]保存本地视频成功sql:'
.
db
()
->
getLastSql
());
$this
->
debug_log
(
'[AI视频]保存本地视频成功 sql: '
.
db
()
->
getLastSql
());
// ========== 新增:发送消息通知 ==========
// $this->sendNotification($user_id, config('shopro.api_host').$video_url);
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
break
;
break
;
case
'cancelled'
:
case
'cancelled'
:
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'任务已取消'
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'任务已取消'
]);
debug_echo
(
'[AI视频]AI生成视频任务 取消: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
$this
->
debug_log
(
'[AI视频]AI生成视频任务 取消: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
debug_echo
(
'[AI视频]AI生成视频任务 取消: result:'
.
json_encode
(
$result
));
$this
->
debug_log
(
'[AI视频]AI生成视频任务 取消: result:'
.
json_encode
(
$result
));
debug_echo
(
'[AI视频]AI生成视频任务 取消: sql:'
.
db
()
->
getLastSql
());
$this
->
debug_log
(
'[AI视频]AI生成视频任务 取消: sql:'
.
db
()
->
getLastSql
());
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
break
;
break
;
case
'failed'
:
case
'failed'
:
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'视频生成失败'
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'视频生成失败'
]);
debug_echo
(
'[AI视频]AI生成视频任务 失败: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
$this
->
debug_log
(
'[AI视频]AI生成视频任务 失败: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
debug_echo
(
'[AI视频]AI生成视频任务 失败: result:'
.
json_encode
(
$result
));
$this
->
debug_log
(
'[AI视频]AI生成视频任务 失败: result:'
.
json_encode
(
$result
));
debug_echo
(
'[AI视频]AI生成视频任务 失败: sql:'
.
db
()
->
getLastSql
());
$this
->
debug_log
(
'[AI视频]AI生成视频任务 失败: sql:'
.
db
()
->
getLastSql
());
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
break
;
break
;
case
'expired'
:
case
'expired'
:
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'任务已过期'
]);
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_task_id'
,
$taskid
)
->
update
([
'ai_status'
=>
2
,
'ai_err_msg'
=>
'任务已过期'
]);
debug_echo
(
'[AI视频]AI生成视频任务 过期: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
$this
->
debug_log
(
'[AI视频]AI生成视频任务 过期: taskId: '
.
$taskid
.
'userId '
.
$user_id
);
debug_echo
(
'[AI视频]AI生成视频任务 过期: result:'
.
json_encode
(
$result
));
$this
->
debug_log
(
'[AI视频]AI生成视频任务 过期: result:'
.
json_encode
(
$result
));
debug_echo
(
'[AI视频]AI生成视频任务 过期: sql:'
.
db
()
->
getLastSql
());
$this
->
debug_log
(
'[AI视频]AI生成视频任务 过期: sql:'
.
db
()
->
getLastSql
());
// 删除队列job
// 删除队列job
debug_echo
(
'[AI视频]删除Job'
);
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
$job
->
delete
();
break
;
break
;
...
@@ -228,11 +246,56 @@ class AiVideoGen extends BaseJob
...
@@ -228,11 +246,56 @@ class AiVideoGen extends BaseJob
}
catch
(
\Exception
$e
)
{
}
catch
(
\Exception
$e
)
{
// 队列执行失败
// 队列执行失败
debug_echo
(
'[AI视频]异常:'
.
$e
->
getMessage
());
$logInfo
=
[
format_log_error
(
$e
,
'AiVideoGen.save.'
.
isset
(
$user
[
'id'
])
??
'user_id'
.
isset
(
$video_url
)
??
'video_url'
);
" [AI视频] Exception LOG INFO BEGIN "
,
'[ Message ] '
.
var_export
(
'['
.
$e
->
getCode
()
.
']'
.
$e
->
getMessage
()
.
' '
.
'AiVideoGen.save.'
.
$user
[
'id'
]
??
'user_id'
.
$video_url
??
'video_url'
,
true
),
'[ File ] '
.
var_export
(
$e
->
getFile
()
.
':'
.
$e
->
getLine
(),
true
),
'[ Trace ] '
.
var_export
(
$e
->
getTraceAsString
(),
true
),
"[AI视频] Exception LOG INFO ENDED "
,
];
$logInfo
=
implode
(
PHP_EOL
,
$logInfo
)
.
PHP_EOL
;
$this
->
debug_log
(
$logInfo
);
// $this->deleteLocalVideo($video_url); // 删除保存到本地的视频,如果已经保存了的话,暂时不处理保存到视频,获取不到video_url
// 删除队列job
$this
->
debug_log
(
'[AI视频]删除Job'
);
$job
->
delete
();
}
}
debug_echo
(
'[AI视频]异常删除视频:'
.
$video_url
);
/**
$this
->
deleteLocalVideo
(
$video_url
);
// 删除保存到本地的视频,如果已经保存了的话
* 发送AI视频生成成功通知
*/
private
function
sendNotification
(
$user_id
,
$video_url
)
{
try
{
// 获取用户信息
$user
=
User
::
find
(
$user_id
);
if
(
!
$user
)
{
// Log::error('[AI视频通知]用户不存在: ' . $user_id);
$this
->
debug_log
(
'[AI视频通知]用户不存在: '
.
$user_id
,
'gen_ai'
);
return
false
;
}
// 获取AI试戴记录
$aiTryon
=
AiTryOnModel
::
where
(
'user_id'
,
$user_id
)
->
where
(
'ai_url'
,
$video_url
)
->
find
();
// 发送通知
NotificationFacade
::
send
(
$user
,
new
AiVideoSuccess
([
'ai_tryon'
=>
$aiTryon
?
$aiTryon
->
toArray
()
:
[],
'user'
=>
$user
->
toArray
()
]));
// Log::info('[AI视频通知]通知发送成功: user_id=' . $user_id);
$this
->
debug_log
(
'[AI视频通知]通知发送成功: user_id='
.
$user_id
,
'gen_ai'
);
return
true
;
}
catch
(
\Exception
$e
)
{
// Log::error('[AI视频通知]发送失败: ' . $e->getMessage());
$this
->
debug_log
(
'[AI视频通知]发送失败: user_id='
.
$user_id
.
' '
.
$e
->
getMessage
(),
'gen_ai'
);
return
false
;
}
}
}
}
...
...
application/common.php
View file @
285b276b
...
@@ -507,3 +507,23 @@ EOT;
...
@@ -507,3 +507,23 @@ EOT;
return
$icon
;
return
$icon
;
}
}
}
}
if
(
!
function_exists
(
'custom_log'
))
{
/**
* 自定义日志文件名
* @param string $content 日志内容
* @param string $name 文件名(不需要 .log)
* @param string $level 级别 info/error/debug
*/
function
custom_log
(
$content
,
$name
=
'custom'
,
$level
=
'info'
)
{
\think\Log
::
init
([
'type'
=>
'File'
,
'path'
=>
RUNTIME_PATH
.
'log/'
.
date
(
'Ym'
)
.
'/'
,
'single'
=>
$name
.
'_'
.
date
(
'Ymd'
)
.
'_'
,
'max_files'
=>
0
,
]);
\think\Log
::
record
(
$content
,
$level
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment