ProcessWMSDataJob.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace App\Jobs;
  3. use App\Model\SyncTempRecord;
  4. use Illuminate\Bus\Queueable;
  5. use Illuminate\Contracts\Queue\ShouldQueue;
  6. use Illuminate\Foundation\Bus\Dispatchable;
  7. use Illuminate\Queue\InteractsWithQueue;
  8. use Illuminate\Queue\SerializesModels;
  9. use Illuminate\Support\Facades\DB;
  10. use Illuminate\Support\Facades\Log;
  11. use Symfony\Component\Console\Output\ConsoleOutput;
  12. use Symfony\Component\Console\Output\OutputInterface;
  13. class ProcessWMSDataJob implements ShouldQueue
  14. {
  15. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  16. protected $data;
  17. public $timeout = 30;
  18. public function __construct($data)
  19. {
  20. //record表
  21. $this->data = $data;
  22. }
  23. public function handle()
  24. {
  25. try {
  26. list($bool, $msg) = $this->settle();
  27. if(! $bool) $this->finalDo($msg);
  28. } catch (\Throwable $e) {
  29. $this->finalDo("异常:" . $e->getMessage());
  30. $this->delete();
  31. }
  32. }
  33. private function finalDo($msg){
  34. SyncTempRecord::where('id', $this->data['id'])
  35. ->update(['error_msg' => $msg, 'status' => SyncTempRecord::status_one]);
  36. }
  37. private function settle()
  38. {
  39. $id = $this->data['id'];
  40. $record = SyncTempRecord::where('id', $id)->first();
  41. // 1. 安全检查:如果记录不存在,或者已经是成功状态(status_one),则退出
  42. if (!$record || $record->status != SyncTempRecord::status_zero) {
  43. return [true, '已处理或记录不存在'];
  44. }
  45. // 2. 解析 U8 原始数据
  46. $u8Data = is_array($record->payload) ? $record->payload : json_decode($record->payload, true);
  47. $type = $record->type;
  48. if($type == SyncTempRecord::type_eight){
  49. //检验单
  50. list($status, $msg) = $this->bjOrder($record, $u8Data);
  51. }else{
  52. //同步到音飞
  53. list($status, $msg) = $this->orderInsert($record, $u8Data);
  54. }
  55. return [$status, $msg];
  56. }
  57. public function orderInsert($record, $u8Data){
  58. $orderType = SyncTempRecord::$map[$record->type];
  59. if(is_array($orderType)) $orderType = $orderType[$record->type_2];
  60. // 3. 组装报文
  61. $jsonBody = [
  62. 'orderType' => $orderType,
  63. 'orderNo' => $record->u8_no,
  64. 'orderId' => $record->u8_id,
  65. 'operationType' => SyncTempRecord::$opMapping[$record->op_type],
  66. 'lottar1' => '',
  67. 'lottar2' => '',
  68. 'lottar3' => '',
  69. 'lottar4' => '',
  70. 'lottar5' => '',
  71. 'lottar6' => '',
  72. 'lottar7' => '',
  73. 'lottar8' => '',
  74. 'lottar9' => '',
  75. 'details' => []
  76. ];
  77. if (isset($u8Data['details']) && is_array($u8Data['details'])) {
  78. foreach ($u8Data['details'] as $item) {
  79. $jsonBody['details'][] = [
  80. 'lineNum' => $item['lineNum'] ?? 0,
  81. 'materialCode' => $item['materialCode'] ?? '',
  82. 'planQty' => (float)($item['planQty'] ?? 0),
  83. 'lottar1' => $item['lottar1'] ?? "",
  84. 'lottar2' => '',
  85. 'lottar3' => '',
  86. 'lottar4' => '',
  87. 'lottar5' => '',
  88. 'lottar6' => '',
  89. 'lottar7' => '',
  90. 'lottar8' => '',
  91. 'lottar9' => '',
  92. ];
  93. }
  94. }
  95. // 4. 接口路由
  96. $inboundTypes = [SyncTempRecord::type_one, SyncTempRecord::type_three];
  97. $path = in_array($record->type, $inboundTypes) ? '/erp/inbound' : '/erp/outbound';
  98. $apiUrl = config('wms.api_url') . $path;
  99. // 5. 调用 post_helper
  100. list($status, $result) = $this->post_helper($apiUrl, $jsonBody, ['Content-Type: application/json']);
  101. if (!$status) {
  102. // 接口返回失败或网络失败
  103. $record->update(['status' => SyncTempRecord::status_two, 'error_msg' => $result]);
  104. return [false, $result];
  105. }
  106. // 6. 接口返回成功 (200) 的后续操作
  107. DB::transaction(function () use ($record, $u8Data) {
  108. // 更新本地流水状态为成功
  109. $record->update([
  110. 'status' => SyncTempRecord::status_one,
  111. ]);
  112. // 同步维护快照表,保证下次 Command 比对正确
  113. if ($record->op_type == SyncTempRecord::opt_two) {
  114. DB::table('sync_snapshot')
  115. ->where('type', $record->type)
  116. ->where('u8_no', $record->u8_no)
  117. ->where('u8_id', $record->u8_id)
  118. ->delete();
  119. } else {
  120. DB::table('sync_snapshot')->updateOrInsert(
  121. ['type' => $record->type, 'u8_no' => $record->u8_no],
  122. ['u8_id' => $record->u8_id,'last_upd_time' => $record->u8_upd, 'order_date' => $u8Data['order_date'], 'payload' => json_encode($u8Data)]
  123. );
  124. }
  125. });
  126. return [true, ''];
  127. }
  128. //代码是有bug的 因为业务
  129. public function bjOrder($record, $u8Data){
  130. $hg_quantity = $u8Data['hg_quantity'] ?? 0;
  131. $rb_quantity = $u8Data['rb_quantity'] ?? 0;
  132. $hg_not_quantity = $u8Data['hg_not_quantity'] ?? 0;
  133. if($hg_quantity > 0){
  134. list($status, $msg) = $this->zj($record, $u8Data, 1);
  135. }elseif ($rb_quantity > 0) {
  136. list($status, $msg) = $this->zj($record, $u8Data,3);
  137. }elseif($hg_not_quantity > 0){
  138. list($status, $msg) = $this->zj($record, $u8Data,2);
  139. }
  140. return [$status ?? true, $msg ?? ""];
  141. }
  142. //todo
  143. public function zj($record, $u8Data, $type){
  144. // 3. 组装报文
  145. $jsonBody = [
  146. 'orderNo' => $record->u8_no,
  147. 'materialCode' => $u8Data['materialCode'],
  148. 'lot' => $u8Data['lot'] ?? "",
  149. 'inspectionStatus' => $type,
  150. ];
  151. // 4. 接口路由
  152. $apiUrl = config('wms.api_url') . '/erp/inspection';
  153. // 5. 调用 post_helper
  154. list($status, $result) = $this->post_helper($apiUrl, $jsonBody, ['Content-Type: application/json']);
  155. if (!$status) {
  156. // 接口返回失败或网络失败
  157. $record->update(['status' => SyncTempRecord::status_two, 'error_msg' => $result]);
  158. return [false, $result];
  159. }
  160. // 6. 接口返回成功 (200) 的后续操作
  161. DB::transaction(function () use ($record, $u8Data) {
  162. // 更新本地流水状态为成功
  163. $record->update([
  164. 'status' => SyncTempRecord::status_one,
  165. ]);
  166. // 同步维护快照表,保证下次 Command 比对正确
  167. if ($record->op_type == SyncTempRecord::opt_two) {
  168. DB::table('sync_snapshot')
  169. ->where('type', $record->type)
  170. ->where('u8_no', $record->u8_no)
  171. ->where('u8_id', $record->u8_id)
  172. ->delete();
  173. } else {
  174. DB::table('sync_snapshot')->updateOrInsert(
  175. ['type' => $record->type, 'u8_no' => $record->u8_no],
  176. ['u8_id' => $record->u8_id,'last_upd_time' => $record->u8_upd, 'order_date' => $u8Data['order_date'], 'payload' => json_encode($u8Data)]
  177. );
  178. }
  179. });
  180. return [true, ''];
  181. }
  182. public function post_helper($url, $data, $header = [], $timeout = 30)
  183. {
  184. Log::channel('apiLog')->info('WMS_POST_START', ["api" => $url, "param" => $data]);
  185. $ch = curl_init();
  186. curl_setopt($ch, CURLOPT_URL, $url);
  187. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  188. curl_setopt($ch, CURLOPT_POST, 1);
  189. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  190. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  191. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  192. if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  193. $r = curl_exec($ch);
  194. if ($r === false) {
  195. $errorMessage = curl_error($ch);
  196. curl_close($ch);
  197. Log::channel('apiLog')->error('WMS_CURL_ERROR', ["msg" => $errorMessage]);
  198. return [false, "网络错误: " . $errorMessage];
  199. }
  200. curl_close($ch);
  201. $return = json_decode($r, true);
  202. Log::channel('apiLog')->info('WMS_POST_RETURN', ["res" => $return]);
  203. // 判断逻辑:code 存在且为 200 才算 true
  204. if (isset($return['code']) && $return['code'] == 200) {
  205. return [true, $return];
  206. }
  207. $msg = $return['message'] ?? '未知接口错误';
  208. return [false, $msg];
  209. }
  210. protected function echoMessage(OutputInterface $output)
  211. {
  212. //输出消息
  213. $output->writeln(json_encode($this->data));
  214. }
  215. }