WorkOrder.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use app\job\ImageJob;
  5. use app\service\ImageService;
  6. use think\App;
  7. use think\Db;
  8. use think\Log;
  9. use think\Queue;
  10. use think\queue\job\Redis;
  11. class WorkOrder extends Api
  12. {
  13. protected $noNeedLogin = ['*'];
  14. protected $noNeedRight = ['*'];
  15. /**
  16. * 出图接口
  17. * 此方法处理图像转换为文本的请求,将图像信息存入队列以供后续处理。
  18. */
  19. public function imageToText()
  20. {
  21. $params = $this->request->param();
  22. $service = new ImageService();
  23. $service->handleImage($params);
  24. $this->success('任务成功提交至队列');
  25. }
  26. /**
  27. * 查询队列列表
  28. * 统计文件对应的队列情况
  29. */
  30. public function get_queue_logs()
  31. {
  32. $params = $this->request->param('old_image_file', '');
  33. $queue_logs = Db::name('queue_logs')
  34. ->where('old_image_file', $params)
  35. ->order('id desc')
  36. ->select();
  37. foreach ($queue_logs as &$log) {
  38. $taskId = $log['id'];
  39. // 从 image_task_log 表统计状态
  40. $statusCount = Db::name('image_task_log')
  41. ->field('status, COUNT(*) as count')
  42. ->where('task_id', $taskId)
  43. ->group('status')
  44. ->select();
  45. $log['已完成数量'] = 0;
  46. $log['处理中数量'] = 0;
  47. $log['排队中的数量'] = 0;
  48. $log['失败数量'] = 0;
  49. foreach ($statusCount as $item) {
  50. switch ($item['status']) {
  51. case 0:
  52. $log['排队中的数量'] = $item['count'];
  53. break;
  54. case 1:
  55. $log['处理中数量'] = $item['count'];
  56. break;
  57. case 2:
  58. $log['已完成数量'] = $item['count'];
  59. break;
  60. case -1:
  61. $log['失败数量'] = $item['count'];
  62. break;
  63. }
  64. }
  65. // ✅ 只保留排队中的数量大于 0 的记录
  66. if ($log['排队中的数量'] > 0) {
  67. $result[] = $log;
  68. }
  69. }
  70. return json([
  71. 'code' => 0,
  72. 'msg' => '查询成功',
  73. 'data' => $result,
  74. 'count' => count($result)
  75. ]);
  76. }
  77. /**
  78. * 查询总队列状态(统计当前处理的数据量)
  79. */
  80. public function queueStats()
  81. {
  82. $statusList = Db::name('image_task_log')
  83. ->field('status, COUNT(*) as total')
  84. ->where('create_time', '>=', date('Y-m-d 00:00:00'))
  85. ->group('status')
  86. ->select();
  87. $statusCount = [];
  88. foreach ($statusList as $item) {
  89. $statusCount[$item['status']] = $item['total'];
  90. }
  91. // 总数为所有状态和
  92. $total = array_sum($statusCount);
  93. //获取队列当前状态
  94. $statusText = Db::name('queue_logs')->order('id desc')->value('status');
  95. return json([
  96. 'code' => 0,
  97. 'msg' => '获取成功',
  98. 'data' => [
  99. '总任务数' => $total,
  100. '待处理' => $statusCount[0] ?? 0,
  101. '处理中' => $statusCount[1] ?? 0,
  102. '成功' => $statusCount[2] ?? 0,
  103. '失败' => $statusCount[-1] ?? 0,
  104. '当前状态' => $statusText
  105. ]
  106. ]);
  107. }
  108. /**
  109. * 显示当前运行中的队列监听进程
  110. */
  111. public function viewQueueStatus()
  112. {
  113. $redis = new \Redis();
  114. $redis->connect('127.0.0.1', 6379);
  115. $redis->auth('123456');
  116. $redis->select(15);
  117. $key = 'queues:imgtotxt';
  118. // 判断 key 是否存在,避免报错
  119. if (!$redis->exists($key)) {
  120. return json([
  121. 'code' => 0,
  122. 'msg' => '查询成功,队列为空',
  123. 'count' => 0,
  124. 'tasks_preview' => []
  125. ]);
  126. }
  127. $count = $redis->lLen($key);
  128. $list = $redis->lRange($key, 0, 9);
  129. // 解码 JSON 内容,确保每一项都有效
  130. $parsed = array_filter(array_map(function ($item) {
  131. return json_decode($item, true);
  132. }, $list), function ($item) {
  133. return !is_null($item);
  134. });
  135. return json([
  136. 'code' => 0,
  137. 'msg' => '查询成功',
  138. 'count' => $count,
  139. 'tasks_preview' => $parsed
  140. ]);
  141. }
  142. /**
  143. * 清空队列并删除队列日志记录
  144. */
  145. public function stopQueueProcesses()
  146. {
  147. $redis = new \Redis();
  148. $redis->connect('127.0.0.1', 6379);
  149. $redis->auth('123456');
  150. $redis->select(15);
  151. $key_txttoimg = 'queues:txttoimg';
  152. $key_txttotxt = 'queues:txttotxt';
  153. $key_imgtotxt = 'queues:imgtotxt';
  154. $count = $redis->lLen($key_txttoimg) + $redis->lLen($key_txttotxt) + $redis->lLen($key_imgtotxt);
  155. if ($count === 0) {
  156. return json([
  157. 'code' => 1,
  158. 'msg' => '暂无队列需要停止'
  159. ]);
  160. }
  161. // 清空 Redis 队列
  162. $redis->del($key_txttoimg);
  163. $redis->del($key_txttotxt);
  164. $redis->del($key_imgtotxt);
  165. // 删除数据库中 log = '队列中' 的记录
  166. Db::name('image_task_log')
  167. ->where('log', '队列中')
  168. ->delete();
  169. return json([
  170. 'code' => 0,
  171. 'msg' => '已成功停止队列任务并清除队列日志'
  172. ]);
  173. }
  174. /**
  175. * 开启队列任务
  176. * 暂时用不到、服务器已开启自动开启队列模式
  177. */
  178. // public function kaiStats()
  179. // {
  180. // // 判断是否已有监听进程在运行
  181. // $check = shell_exec("ps aux | grep 'queue:listen' | grep -v grep");
  182. // if ($check) {
  183. // return json([
  184. // 'code' => 1,
  185. // 'msg' => '监听进程已存在,请勿重复启动'
  186. // ]);
  187. // }
  188. // // 启动监听
  189. // $command = 'nohup php think queue:listen --queue --timeout=300 --sleep=3 --memory=256 > /var/log/job_queue.log 2>&1 &';
  190. // exec($command, $output, $status);
  191. // if ($status === 0) {
  192. // return json([
  193. // 'code' => 0,
  194. // 'msg' => '队列监听已启动'
  195. // ]);
  196. // } else {
  197. // return json([
  198. // 'code' => 1,
  199. // 'msg' => '队列启动失败',
  200. // 'output' => $output
  201. // ]);
  202. // }
  203. // }
  204. }