AnimeCheckImgUrlCommand.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace App\Console\Anime;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Support\Facades\DB;
  5. class AnimeCheckImgUrlCommand extends Command
  6. {
  7. /**
  8. * The name and signature of the console command.
  9. *
  10. * @var string
  11. */
  12. protected $signature = 'Anime:checkImgUrl';
  13. /**
  14. * The console command description.
  15. *
  16. * @var string
  17. */
  18. protected $description = '检查动漫对话角色和场景图片生成状态';
  19. /**
  20. * Execute the console command.
  21. *
  22. * @return int
  23. */
  24. public function handle()
  25. {
  26. dLog('generate')->info('====================开始检查动漫对话角色和场景图片生成状态====================');
  27. $time_expire_datetime = date('Y-m-d H:i:s', strtotime('-12 hours'));
  28. DB::table('mp_animes')->where('generate_status', '执行中')->where('generate_at', '<', $time_expire_datetime)->update([
  29. 'generate_status' => '失败',
  30. 'updated_at'=>date('Y-m-d H:i:s'),
  31. ]);
  32. $time_start = microtime(true);
  33. // 获取待执行的动漫对话数据
  34. $data = DB::table('mp_animes')->where('generate_status', '执行中')->select('id', 'roles', 'scenes')->get();
  35. foreach ($data as $item) {
  36. $id = getProp($item, 'id');
  37. $roles = json_decode(getProp($item, 'roles'), true);
  38. $scenes = json_decode(getProp($item, 'scenes'), true);
  39. $role_count = count($roles);
  40. $scene_count = count($scenes);
  41. // 处理角色图片状态
  42. $role_result = $this->checkRoles($id, $roles);
  43. // 处理场景图片状态
  44. $scene_result = $this->checkScenes($id, $scenes);
  45. $scene_result['success_count'] = 6;
  46. if ($role_result['success_count'] == $role_count && $scene_result['success_count'] == $scene_count) {
  47. // 更新状态为已完成
  48. // DB::table('mp_animes')->where('id', $id)->update(['generate_status' => '已完成', 'updated_at'=>date('Y-m-d H:i:s')]);
  49. dLog('generate')->info('动漫对话图片已全部生成完毕');
  50. // 同步更新该动漫对话剧集的所有角色或场景
  51. $this->syncRolesAndScenes($id, $role_result['roles'], $scene_result['scenes']);
  52. }
  53. }
  54. $time_end = microtime(true);
  55. dLog('generate')->info('脚本执行时间: '.round($time_end-$time_start, 2).'秒');
  56. dLog('generate')->info('====================结束检查动漫对话角色和场景图片生成状态====================');
  57. }
  58. private function checkRoles($id, $roles) {
  59. $role_success_count = 0;
  60. foreach ($roles as &$role) {
  61. $task_id = getProp($role, 'task_id');
  62. $task_status = getProp($role, 'task_status');
  63. if (!$task_id || $task_status == 'success') {
  64. $role_success_count++;
  65. continue;
  66. }
  67. $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
  68. if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
  69. $role['task_status'] = 'success';
  70. $role['url'] = '';
  71. $result_url = getProp($task, 'result_url');
  72. if ($result_url && is_json($result_url)) {
  73. $role['url'] = json_decode($result_url, true)[0];
  74. }
  75. $role_success_count++;
  76. }
  77. }
  78. if ($role_success_count > 0) {
  79. DB::table('mp_animes')->where('id', $id)->update(['roles' => json_encode($roles, 256)]);
  80. }
  81. return [
  82. 'roles' => $roles,
  83. 'success_count' => $role_success_count,
  84. ];
  85. }
  86. private function checkScenes($id, $scenes) {
  87. $scene_success_count = 0;
  88. foreach ($scenes as &$scene) {
  89. $task_id = getProp($scene, 'task_id');
  90. $task_status = getProp($scene, 'task_status');
  91. if (!$task_id || $task_status == 'success') {
  92. $scene_success_count++;
  93. continue;
  94. }
  95. $task = DB::table('mp_generate_pic_tasks')->where('id', $task_id)->select('result_url', 'status')->first();
  96. if (in_array(getProp($task, 'status'), ['success', 'failed'])) {
  97. $scene['task_status'] = 'success';
  98. $scene['url'] = '';
  99. $result_url = getProp($task, 'result_url');
  100. if ($result_url && is_json($result_url)) {
  101. $scene['url'] = json_decode($result_url, true)[0];
  102. }
  103. $scene_success_count++;
  104. }
  105. }
  106. if ($scene_success_count > 0) {
  107. DB::table('mp_animes')->where('id', $id)->update(['scenes' => json_encode($scenes, 256)]);
  108. }
  109. return [
  110. 'scenes' => $scenes,
  111. 'success_count' => $scene_success_count,
  112. ];
  113. }
  114. private function syncRolesAndScenes($id, $roles, $scenes) {
  115. // 获取该动漫对话对应的所有剧集
  116. $episodes = DB::table('mp_anime_episodes')->where('anime_id', $id)->get();
  117. if ($episodes->isEmpty()) {
  118. dLog('generate')->info("动漫对话ID:{$id} 没有关联的剧集");
  119. return;
  120. }
  121. foreach ($episodes as $episode) {
  122. $episode_id = getProp($episode, 'id');
  123. $episode_roles = json_decode(getProp($episode, 'roles'), true) ?: [];
  124. $episode_scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
  125. $roles_updated = false;
  126. $scenes_updated = false;
  127. // 更新剧集中的角色URL
  128. foreach ($episode_roles as &$episode_role) {
  129. $episode_role_name = getProp($episode_role, 'role');
  130. $episode_description = getProp($episode_role, 'description');
  131. $episode_url = getProp($episode_role, 'url');
  132. // 遍历方法中的角色数据
  133. foreach ($roles as $role) {
  134. $role_name = getProp($role, 'role');
  135. $role_description = getProp($role, 'description');
  136. $role_url = getProp($role, 'url');
  137. // 满足三个条件:1.角色名相同 2.描述相同 3.剧集中URL为空且方法中URL不为空
  138. if ($episode_role_name == $role_name
  139. && $episode_description == $role_description
  140. && empty($episode_url)
  141. && !empty($role_url)) {
  142. $episode_role['url'] = $role_url;
  143. $roles_updated = true;
  144. dLog('generate')->info("剧集ID:{$episode_id} 角色:{$role_name} URL已更新");
  145. break;
  146. }
  147. }
  148. }
  149. // 更新剧集中的场景URL
  150. foreach ($episode_scenes as &$episode_scene) {
  151. $episode_scene_name = getProp($episode_scene, 'scene');
  152. $episode_description = getProp($episode_scene, 'description');
  153. $episode_url = getProp($episode_scene, 'url');
  154. // 遍历方法中的场景数据
  155. foreach ($scenes as $scene) {
  156. $scene_name = getProp($scene, 'scene');
  157. $scene_description = getProp($scene, 'description');
  158. $scene_url = getProp($scene, 'url');
  159. // 满足三个条件:1.场景名相同 2.描述相同 3.剧集中URL为空且方法中URL不为空
  160. if ($episode_scene_name == $scene_name
  161. && $episode_description == $scene_description
  162. && empty($episode_url)
  163. && !empty($scene_url)) {
  164. $episode_scene['url'] = $scene_url;
  165. $scenes_updated = true;
  166. dLog('generate')->info("剧集ID:{$episode_id} 场景:{$scene_name} URL已更新");
  167. break;
  168. }
  169. }
  170. }
  171. // 如果有更新,则保存到数据库
  172. if ($roles_updated || $scenes_updated) {
  173. $update_data = ['updated_at' => date('Y-m-d H:i:s')];
  174. if ($roles_updated) {
  175. $update_data['roles'] = json_encode($episode_roles, 256);
  176. }
  177. if ($scenes_updated) {
  178. $update_data['scenes'] = json_encode($episode_scenes, 256);
  179. }
  180. DB::table('mp_anime_episodes')->where('id', $episode_id)->update($update_data);
  181. dLog('generate')->info("剧集ID:{$episode_id} 数据已同步更新");
  182. }
  183. }
  184. }
  185. }