|
|
@@ -9906,6 +9906,9 @@ class AnimeService
|
|
|
$scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
|
|
|
$props = json_decode(getProp($episode, 'props'), true) ?: [];
|
|
|
|
|
|
+ // 确认前校验并等待角色、场景、道具图片全部生成(参照 episodePicsInfo 更新与监控逻辑),未全部生成不得继续后续逻辑
|
|
|
+ $this->waitForEpisodeAssetsImagesReady($episode_id, $roles, $scenes, $props);
|
|
|
+
|
|
|
// 获取所有片段数据
|
|
|
$acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
|
|
|
|
|
|
@@ -10116,6 +10119,112 @@ class AnimeService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 参照 episodePicsInfo 的更新与监控逻辑:
|
|
|
+ * 每5秒查询一次角色/场景/道具的图片任务状态,任务成功后将图片URL回填到对应资产并写回分集表。
|
|
|
+ * 所有需要图片的资产均已生成(url 非空)才返回;最多等待1分钟,仍有图片未生成则直接报错。
|
|
|
+ */
|
|
|
+ private function waitForEpisodeAssetsImagesReady($episode_id, &$roles, &$scenes, &$props) {
|
|
|
+ $pollInterval = 5; // 每5秒查询一次
|
|
|
+ $maxWaitSeconds = 60; // 最多持续1分钟
|
|
|
+ $startTime = time();
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ // 从数据库读取最新数据,兼容后台 Anime:checkImgUrl 等任务对角色/场景/道具图片URL的更新
|
|
|
+ $episode = DB::table('mp_anime_episodes')->where('id', $episode_id)->first();
|
|
|
+ if (!$episode) {
|
|
|
+ Utils::throwError('20003:分集不存在');
|
|
|
+ }
|
|
|
+ $roles = json_decode(getProp($episode, 'roles'), true) ?: [];
|
|
|
+ $scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
|
|
|
+ $props = json_decode(getProp($episode, 'props'), true) ?: [];
|
|
|
+
|
|
|
+ $updated = false;
|
|
|
+ $pendingAssets = [];
|
|
|
+
|
|
|
+ $this->refreshEpisodeAssetsImageTasks($roles, 'role', '旁白', $pendingAssets, $updated);
|
|
|
+ $this->refreshEpisodeAssetsImageTasks($scenes, 'scene', '', $pendingAssets, $updated);
|
|
|
+ $this->refreshEpisodeAssetsImageTasks($props, 'prop', '', $pendingAssets, $updated);
|
|
|
+
|
|
|
+ // 有图片任务结果更新时写回分集表
|
|
|
+ if ($updated) {
|
|
|
+ DB::table('mp_anime_episodes')->where('id', $episode_id)->update([
|
|
|
+ 'roles' => json_encode($roles, JSON_UNESCAPED_UNICODE),
|
|
|
+ 'scenes' => json_encode($scenes, JSON_UNESCAPED_UNICODE),
|
|
|
+ 'props' => json_encode($props, JSON_UNESCAPED_UNICODE),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 所有需要图片的资产都已生成,允许继续 confirmActs 后续逻辑
|
|
|
+ if (empty($pendingAssets)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 超过1分钟仍未生成完毕,阻止 confirmActs 后续逻辑
|
|
|
+ if (time() - $startTime >= $maxWaitSeconds) {
|
|
|
+ Utils::throwError('20003:还有主体、场景或道具图片未生成,请等待图片生成后重试');
|
|
|
+ }
|
|
|
+
|
|
|
+ sleep($pollInterval);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 参照 episodePicsInfo:遍历单个资产列表,对有图片任务但还没有图片URL的资产查询图片任务结果并回填。
|
|
|
+ * 任务成功但没有可用的结果URL、或任务不存在/生成失败时,直接阻止继续(抛出图片未生成的错误)。
|
|
|
+ */
|
|
|
+ private function refreshEpisodeAssetsImageTasks(&$assets, $nameKey, $skipName, &$pendingAssets, &$updated) {
|
|
|
+ foreach ($assets as &$asset) {
|
|
|
+ $assetName = getProp($asset, $nameKey);
|
|
|
+ if ($assetName === '' || ($skipName !== '' && $assetName === $skipName)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已有图片URL的资产视为已生成
|
|
|
+ if (getProp($asset, 'url')) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $task_id = getProp($asset, 'task_id');
|
|
|
+ // 没有图片任务且没有图片URL,说明图片尚未生成
|
|
|
+ if (!$task_id) {
|
|
|
+ $pendingAssets[] = $assetName;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $task = DB::table('mp_generate_pic_tasks')
|
|
|
+ ->where('id', $task_id)
|
|
|
+ ->select('status', 'result_url')
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$task) {
|
|
|
+ Utils::throwError('20003:还有主体、场景或道具图片未生成,请等待图片生成后重试');
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($task->status === 'success') {
|
|
|
+ $result_url = getProp($task, 'result_url');
|
|
|
+ if ($result_url) {
|
|
|
+ $result_urls = is_json($result_url) ? json_decode($result_url, true) : [$result_url];
|
|
|
+ if (is_array($result_urls) && !empty($result_urls[0])) {
|
|
|
+ $asset['url'] = $result_urls[0];
|
|
|
+ $asset['task_status'] = 'success';
|
|
|
+ $updated = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 任务成功但没有可用的结果URL,仍视为未生成
|
|
|
+ $pendingAssets[] = $assetName;
|
|
|
+ } elseif ($task->status === 'failed') {
|
|
|
+ Utils::throwError('20003:还有主体、场景或道具图片未生成,请等待图片生成后重试');
|
|
|
+ } else {
|
|
|
+ // 任务仍在生成中,等待下一次轮询
|
|
|
+ $pendingAssets[] = $assetName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ unset($asset);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 导出动漫剧本为PDF(参照示例PDF版式)
|
|
|
* @param int $animeId 动漫ID
|
|
|
* @param int $episodeCount 导出集数,默认8,传-1表示全部
|