'采购入库', self::two => '采购退货', self::three => '材料出库', self::four => '采购入库', self::five => '采购入库', self::six => '采购入库', self::seven => '采购入库', self::eight => '采购入库', ]; public function settleU8Data($data){ if(empty($data['type'])) return [false, 'type类型不能为空']; if(! isset(self::type_all[$data['type']])) return [false, 'type类型错误']; $type = $data['type']; list($status, $msg) = $this->getToken(); // if(! $status) return [false, $msg]; $data['u8_data'] = $msg; if($type == self::one){ list($status, $msg) = $this->purchaseIn($data); }elseif ($type == self::two){ list($status, $msg) = $this->purchaseReturn($data); }elseif ($type == self::three){ list($status, $msg) = $this->materialOut($data); }elseif ($type == self::four){ list($status, $msg) = $this->purchaseIn($data); }elseif ($type == self::five){ list($status, $msg) = $this->purchaseIn($data); }elseif ($type == self::six){ list($status, $msg) = $this->purchaseIn($data); }elseif ($type == self::seven){ list($status, $msg) = $this->purchaseIn($data); }elseif ($type == self::eight){ list($status, $msg) = $this->purchaseIn($data); } } public function getToken(){ $key = "drb_u8_api"; $config = config('wms.drb'); // 1. 自检网络通畅 list($bool, $msg) = $this->checkNetworkStatus($config['api_host'], $config['api_port']); if (!$bool) return [false, "网络连接失败: " . $msg]; $host = $config['api_host'] . ":" . $config['api_port']; // 2. 尝试从缓存获取 $token = Cache::get($key); if (! $token) { // 3. 缓存失效,请求新 Token $url = $host . "/api/System/GetToken"; $date = date("Y-m-d"); $json = [ "U8DbName" => $config['database'], "sUserId" => $config['user_id'], "sPassword" => $config['user_password'], "LoginDateTime" => $date, "bPersist" => true ]; $header = ['Content-Type:application/json']; // 调用你的 POST 辅助函数 list($status, $result) = $this->post_helper1($url, json_encode($json), $header); if (!$status) return [false, "用友token获取失败: " . $result]; if (!isset($result['code'])) return [false, '获取用友登录信息失败: 响应格式异常']; if ($result['code'] != 0) return [false, "U8错误: " . ($result['msg'] ?? '未知错误')]; $token = $result['data']['Token'] ?? ""; if (empty($token)) return [false, "接口返回的 Token 为空"]; // 30分钟 = 1800秒 Cache::put($key, $token, now()->addMinutes(30)); } return [true, ['host' => $host, 'token' => $token]]; } public function purchaseIn($data){ if(empty($data['orderId'])) return [false, '采购到货单ID不能为空']; if(empty($data['orderNo'])) return [false, '采购到货单单号不能为空']; if(empty($data['detail'])) return [false, '表体信息detail不能为空']; $body = []; foreach ($data['detail'] as $key => $value){ if(empty($value['lineNum'])) return [false, '行号不能为空']; if(! is_numeric($value['lineNum'])) return [false, '行号错误']; if(empty($value['materialCode'])) return [false, '存货编码不能为空']; if(empty($value['productDate']) || ! $this->validateProductDate($value['productDate'])) return [false, '生产日期为空或格式错误']; if(empty($value['failureDate']) || ! $this->validateProductDate($value['failureDate'])) return [false, '失效日期为空或格式错误']; if(empty($value['lot'])) return [false, '批号不能为空']; $body[] = [ 'ivouchrowno' => $value['lineNum'], 'dPDate' => $value['productDate'], 'dVDate' => $value['failureDate'], 'cBatch' => $value['lot'], 'editprop' => 'M', ]; } //调用所需 $host = $data['u8_data']['host']; $token = $data['u8_data']['token']; //采购到货单弃审 $header = ["Authorization: {$token}",'Content-Type:application/json']; $url = $host . "/api/PuArrVouch/UnVerify"; $json = [ "VouchId" => $data['orderId'], ]; $json = json_encode($json); list($status, $result) = $this->post_helper1($url,$json, $header, 30); if(! $status) return [false, $result]; if(! isset($result['code'])) return [false, '采购到货单弃审失败']; if($result['code'] != 0) return [false, $result['msg']]; //采购到货单编辑并审核 $url = $host . "/api/PuArrVouch/Update"; $json_final[] = [ "Inum" => "PuArrVouch", "data" =>[ "iHead" => [ "cCode" => $data['orderNo'], "IsVerify" => true, "debug" => true, ], "iBody" => $body, ], ]; $json = json_encode($json_final); list($status, $result) = $this->post_helper1($url,$json, $header, 30); if(! $status) return [false, $result]; if(! isset($result['code'])) return [false, '采购到货单编辑并审核失败']; if($result['code'] != 0) return [false, $result['msg']]; return [true, '']; } public function materialOut($data){ if(empty($data['orderId'])) return [false, '领料申请单ID不能为空']; if(empty($data['orderNo'])) return [false, '领料申请单单号不能为空']; if(empty($data['detail'])) return [false, '表体信息detail不能为空']; $body = []; foreach ($data['detail'] as $key => $value){ if(empty($value['lineNum'])) return [false, '行号不能为空']; if(! is_numeric($value['lineNum'])) return [false, '行号错误']; if(empty($value['materialCode'])) return [false, '存货编码不能为空']; if(empty($value['productDate']) || ! $this->validateProductDate($value['productDate'])) return [false, '生产日期为空或格式错误']; if(empty($value['failureDate']) || ! $this->validateProductDate($value['failureDate'])) return [false, '失效日期为空或格式错误']; if(empty($value['lot'])) return [false, '批号不能为空']; $body[] = [ 'ivouchrowno' => $value['lineNum'], 'dPDate' => $value['productDate'], 'dVDate' => $value['failureDate'], 'cBatch' => $value['lot'], 'editprop' => 'M', ]; } //调用所需 $host = $data['u8_data']['host']; $token = $data['u8_data']['token']; //采购到货单弃审 $header = ["Authorization: {$token}",'Content-Type:application/json']; $url = $host . "/api/PuArrVouch/UnVerify"; $json = [ "VouchId" => $data['orderId'], ]; $json = json_encode($json); list($status, $result) = $this->post_helper1($url,$json, $header, 30); if(! $status) return [false, $result]; if(! isset($result['code'])) return [false, '采购到货单弃审失败']; if($result['code'] != 0) return [false, $result['msg']]; //采购到货单编辑并审核 $url = $host . "/api/PuArrVouch/Update"; $json_final[] = [ "Inum" => "PuArrVouch", "data" =>[ "iHead" => [ "cCode" => $data['orderNo'], "IsVerify" => true, "debug" => true, ], "iBody" => $body, ], ]; $json = json_encode($json_final); list($status, $result) = $this->post_helper1($url,$json, $header, 30); if(! $status) return [false, $result]; if(! isset($result['code'])) return [false, '采购到货单编辑并审核失败']; if($result['code'] != 0) return [false, $result['msg']]; return [true, '']; } public function purchaseReturn($data){ if(empty($data['orderId'])) return [false, '采购退货单ID不能为空']; if(empty($data['orderNo'])) return [false, '采购退货单单号不能为空']; //获取单据 $service = new U8ThirtyPartyDatabaseServerService(); list($status, $order) = $service->getArrivalVouchById($data['orderId']); if(! $status) return [false, $order]; dd($order); $final_data = []; foreach ($order['details'] as $value){ if(empty($value['cWhCode'])) continue; if(isset($final_data[$value['cWhCode']])){ }else{ $tmp = [ "Inum" => "PurchaseIn", "data" =>[ "iHead" => [ "bIsRedVouch" => true, // 表体必须负数 "bCalPrice" => true, // 是否由接口计算金额 "cWhCode" => $value['cWhCode'], "cRdCode" => $order['rd_code'], // 入库类别 "cDepCode" => $order['depart_code'], "cARVCode" => $order['no'], "cSource" => "采购到货单", "cBusType" => "普通采购", "cMemo" => "", "dDate" => date("Y-m-d"), "IsVerify" => true, ], "iBody" => $order['details'], ], ]; } } //调用所需 $host = $data['u8_data']['host'] ?? ""; $token = $data['u8_data']['token'] ?? ""; //采购退货单生成 $header = ["Authorization: {$token}",'Content-Type:application/json']; //生成红字采购入库单 $url = $host . "/api/PurchaseIn/Add"; $json_final[] = [ "Inum" => "PurchaseIn", "data" =>[ "iHead" => [ "bIsRedVouch" => true, // 表体必须负数 "bCalPrice" => true, // 是否由接口计算金额 "cWhCode" => $data['warehouseCode'], "cRdCode" => $order['rd_code'], // 入库类别 "cDepCode" => $order['depart_code'], "cARVCode" => $order['no'], "cSource" => "采购到货单", "cBusType" => "普通采购", "cMemo" => "", "dDate" => date("Y-m-d"), "IsVerify" => true, ], "iBody" => $order['details'], ], ]; $json = json_encode($json_final); list($status, $result) = $this->post_helper1($url,$json, $header, 30); if(! $status) return [false, $result]; if(! isset($result['code'])) return [false, '红字采购入库单生成并审核失败']; if($result['code'] != 0) return [false, $result['msg']]; return [true, '']; } public function post_helper1($url, $data, $header = [], $timeout = 20){ Log::channel('apiLog')->info('POST', ["api" => $url , "param" => json_decode($data,true) ,"header" => $header]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $r = curl_exec($ch); if ($r === false) { // 获取错误号 $errorNumber = curl_errno($ch); // 获取错误信息 $errorMessage = curl_error($ch); $message = "cURL Error #{$errorNumber}: {$errorMessage}"; Log::channel('apiLog')->info('POST结果', ["message" => $message ]); return [false, $message]; } curl_close($ch); $return = json_decode($r, true); unset($r); Log::channel('apiLog')->info('POST结果', ["message" => $return ]); return [true, $return]; } function validateProductDate($dateStr) { // SQL Server 常用的 datetime 格式包含 .v (毫秒) // 注意:这里的格式必须严格对应 " 2025-12-13 00:00:00.000" // 如果字符串开头有空格,格式字符串里也要留空格 $format = ' Y-m-d H:i:s.v'; $d = \DateTime::createFromFormat($format, $dateStr); // 检查是否转换成功,并且转换后的格式与原字符串完全一致 return $d && $d->format($format) === $dateStr; } }