'PKL', 'QO' => 'QOF', 'Z' => '', 'S' => 'ISF', 'H' => 'HBL', 'CON' => 'CON', 'M' => 'MBL', 'O' => 'DOR', 'PU' => '', 'C' => 'CRD', 'F' => 'FRL', 'D' => 'OTH', 'RUT' => 'INS', 'CNEEA' => '', 'MF1' => 'CMS', 'CNEEV' => '', 'A' => 'ARN', 'COO' => 'COO', 'I' => 'CIV', 'V' => '', 'B' => 'OTH', 'CRD' => 'CUD', 'BC' => 'BCF', 'DCIV' => 'CIV', 'DPKGLIST' => 'PKL', 'TIV' => 'DBN', 'MIV' => '', 'DA' => 'DLA', 'CPV' => '', 'BE' => 'BOE', 'Q' => 'QOF', 'SO' => 'SSO', 'WCR' => 'WCR', 'DG' => 'DGC', 'PL-LEN' => '', 'CCO' => 'CCO', 'DN' => 'DBN', 'NPRS' => 'NPS', 'SOP' => 'SOP', 'TD' => 'TAX', 'BI' => 'BIS', 'CRL' => 'CUR', 'PRF' => 'PRF', 'SCIV' => 'SCV', 'JC' => 'PNL', 'TELEX' => 'TLX', 'CN' => 'CRN', 'DGD' => 'DGC', 'CPS' => 'CPS', 'SPIV' => 'SIV', 'CSI' => 'CSI', 'MSTY' => 'DGC', 'CLP' => 'CLP', 'DD' => 'DND', 'PA' => 'PAL', 'JS' => 'IBI', 'TCR' => 'TCR', 'T' => '', 'OFT' => 'OFT', 'CM' => 'PCD', 'DUT' => 'DUT', 'EIR' => 'EIR', 'MS' => 'BMS', 'ECLR' => 'ECL', 'CPA' => 'CPA', 'SOC' => 'SOC', 'CP' => 'CPG', 'PSJS' => 'FRL', 'CI' => 'SIV', 'CPC' => 'CPC', 'DBL' => 'DBL', 'PNL' => 'PNL', 'POD' => 'POD', 'MD' => 'DES', 'SWB' => 'HBL', 'SC' => 'SCC', 'TO' => 'TSO', 'WO' => 'TSO', 'DR' => 'DKR', 'RM' => '', 'FCR' => 'FCR', 'BS' => 'BSL', 'TM' => '', 'FCLP' => 'CLP', 'SRD' => 'SRD', 'SLI' => 'SLI', 'SSI' => 'SSI', 'VGM' => 'VGM', 'SLG' => 'SLG', 'ICLR' => 'ICL', ]; private static $airMapping = [ 'M' => 'MBL', 'H' => 'HBL', 'S' => 'ISF', 'DG' => 'DGC', 'CRL' => 'CUR', 'O' => 'DOR', 'D' => 'OTH', 'TD' => 'TAX', 'T' => 'CRD', 'C' => '', 'SOP' => 'SOP', 'CCO' => 'CCO', 'A' => 'ARN', 'MF' => '', 'F' => 'FRL', 'BE' => 'BOE', 'NPRS' => 'NPS', 'FCR' => 'FCR', 'VGM' => 'VGM', 'CON' => 'CON', 'JS' => 'IBI', 'HB' => 'HBL', 'SPIV' => 'SIV', 'WCR' => 'WCR', 'APRHB' => 'HBL', 'B' => 'OTH', 'TCR' => 'TCR', 'CLP' => 'CLP', 'MAB' => 'MBL', 'DAB' => 'DBL', 'TELEX' => 'TLX', 'I' => 'o', 'P' => 'PKL', 'SLG' => 'SLG', 'QO' => 'QOF', 'SC' => 'SCC', 'CPV' => 'PRF', 'SO' => 'SSO', 'FCLP' => 'CLP', 'PNL' => 'dg', 'TM' => '', 'MSTY' => 'DGC', 'POD' => 'POD', 'DR' => 'DKR', 'RM' => '', 'DBL' => 'DBL', 'CSI' => 'CSI', 'ICLR' => 'ICL', 'ECLR' => 'ECL', 'MD' => 'DES', 'CP' => 'CPG', 'CPS' => 'CPS', 'CPA' => 'CPA', 'CPC' => 'CPC', 'TO' => 'TSO', 'SCIV' => 'SCV', 'PR' => 'PRF', 'DA' => 'DLA', 'MS' => 'BMS', 'DGD' => 'DGC', 'PLLEN' => '', 'SLI' => 'SLI', 'MIV' => '', 'PSJS' => 'FRL', 'TIV' => 'DBN', 'DPKGLIST' => 'PKL', 'DCIV' => 'CIV', 'BC' => 'BCF', 'SWB' => 'HBL', 'SSI' => 'SSI', 'BI' => 'BIS', 'JC' => 'PNL', 'AL' => 'ALL', 'BS' => 'BSL', 'WO' => 'TSO', 'PA' => 'PAL', ]; /** * 获取文件List */ public static function getEdocFile($hbol,$docTypes,$oceanAir){ try { $result = null; //old code => Doc_Code $mapping = $oceanAir == "ocean" ? self::$oceanMapping : self::$airMapping; $resultDocTypes = array_values(array_filter( array_map( fn($type) => $mapping[$type] ?? null, $docTypes ), fn($mapped) => !empty($mapped) // 过滤 null 和空字符串 )); $data = [ 'fromStation' => '', 'hbol' => $hbol, 'docTypes' => $resultDocTypes ]; // $data = [ // 'fromStation' => '', // 'hbol' => 'ABCNA1008776', // 'docTypes' => ["WO"] // ]; $accessTokenUrl = 'http://dms.kln.com/keycloak/realms/dsms-realm/protocol/openid-connect/token'; //prod 账号 $grant_type = 'client_credentials'; $client_id = 'online'; $client_secret = 'ouuRZ8QbIrcqKZi0NBJLt7PUEiRr5uXd'; $accessToken = dms_edoc::getAccessToken($accessTokenUrl,$grant_type,$client_id,$client_secret); if ($accessToken === null) { throw new Exception("Failed to obtain access token"); } $New_Dms_Url = 'http://dms.kln.com/edoc/documents/fileList'; $result = dms_edoc::CURLClient($New_Dms_Url,$accessToken,$data); } catch (Exception $e) { error_log("Error getEdocFile: " . $e->getMessage()); } return $result; } /** * 下载文件byoutId */ public static function downloadEdocFile($outId,$display_name){ try { $result = null; $data = ['outId' => $outId]; $accessTokenUrl = 'http://dms.kln.com/keycloak/realms/dsms-realm/protocol/openid-connect/token'; //prod 账号 $grant_type = 'client_credentials'; $client_id = 'online'; $client_secret = 'ouuRZ8QbIrcqKZi0NBJLt7PUEiRr5uXd'; $accessToken = dms_edoc::getAccessToken($accessTokenUrl,$grant_type,$client_id,$client_secret); if ($accessToken === null) { throw new Exception("Failed to obtain access token"); } $New_Dms_Url = 'http://dms.kln.com/storagesrv/files/download/edoc/downloadByOutId'; dms_edoc::CURLClientDownload($New_Dms_Url,$accessToken,$data,$display_name); } catch (Exception $e) { error_log("Error getEdocFile: " . $e->getMessage()); } } public static function getAccessToken($accessTokenUrl,$grant_type,$client_id,$client_secret){ //还是需要这个,如果在一个请求里多次调用这个方法的话,就可以用缓存的 if (self::$cachedToken !== null && time() * 1000 < self::$tokenExpiryTime) { return self::$cachedToken; } $postData = http_build_query([ 'grant_type' => $grant_type, 'client_id' => $client_id, 'client_secret' => $client_secret ]); $headers = [ 'Content-Type: application/x-www-form-urlencoded', 'Accept: application/json' ]; $curlInit = curl_init(); curl_setopt_array($curlInit, [ CURLOPT_URL => $accessTokenUrl, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postData, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, // 关键!返回字符串而不是输出 CURLOPT_SSL_VERIFYPEER => false, // 生产环境建议开启 CURLOPT_TIMEOUT => 30, CURLOPT_HEADER => false, // 不返回 header ]); $response = curl_exec($curlInit); $httpCode = curl_getinfo($curlInit, CURLINFO_HTTP_CODE); // 关闭 cURL curl_close($curlInit); // 解析响应 if ($httpCode === 200) { $jsonResponse = json_decode($response, true); if (isset($jsonResponse['access_token'])) { self::$cachedToken = $jsonResponse['access_token']; $expiresIn = isset($jsonResponse['expires_in']) ? $jsonResponse['expires_in'] * 1000 : 600 * 1000; self::$tokenExpiryTime = (time() * 1000) + $expiresIn - 300000; return self::$cachedToken; } } //如果是这里返回,说明Token请求失败 self::$cachedToken = null; self::$tokenExpiryTime = 0; return null; } /** * 使用 cURL 获取文件list */ public static function CURLClient($url,$accessToken,$data){ $headers = [ 'Authorization: Bearer ' . $accessToken, 'Content-Type: application/json', 'Accept: ' . 'application/json' ]; //$url = 'http://dsms-alb-internet-facing-449737170.ap-southeast-1.elb.amazonaws.com/edoc/documents/fileList'; //$url = 'http://dms.kln.com/edoc/documents/fileList'; // 将数据编码为 JSON $jsonData = json_encode($data); try { $curlInit = curl_init(); curl_setopt_array($curlInit, [ CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $jsonData, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, // 关键!返回字符串而不是输出 CURLOPT_SSL_VERIFYPEER => false, // 生产环境建议开启 CURLOPT_TIMEOUT => 30, CURLOPT_HEADER => false, // 不返回 header ]); $response = curl_exec($curlInit); // 检查是否有错误 if ($response === false) { $error = curl_error($curlInit); error_log("cURL 请求失败: " . $error); throw new Exception("cURL 请求失败: " . $error); } // 获取 HTTP 状态码 $httpCode = curl_getinfo($curlInit, CURLINFO_HTTP_CODE); // 关闭 cURL curl_close($curlInit); // 解析响应 $result = json_decode($response, true); if ($httpCode == 200 && isset($result['data'])) { return json_encode($result['data'], JSON_UNESCAPED_UNICODE); } } catch (Exception $e) { error_log($e->getMessage()); } return null; } /** * 使用 cURL 下载文件 */ public static function CURLClientDownload($url,$accessToken,$data,$filename){ $headers = [ 'Authorization: Bearer ' . $accessToken, 'Content-Type: application/json' ]; // 将数据编码为 JSON $jsonData = json_encode($data); try { $curlInit = curl_init(); curl_setopt_array($curlInit, [ CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $jsonData, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, // 关键!返回字符串而不是输出 CURLOPT_SSL_VERIFYPEER => false, // 生产环境建议开启 CURLOPT_TIMEOUT => 30, CURLOPT_HEADER => false, // 不返回 header ]); $response = curl_exec($curlInit); // 检查是否有错误 if ($response === false) { $error = curl_error($curlInit); error_log("cURL 请求失败: " . $error); throw new Exception("cURL 请求失败: " . $error); } // 获取 HTTP 状态码 $httpCode = curl_getinfo($curlInit, CURLINFO_HTTP_CODE); // 关闭 cURL curl_close($curlInit); // 判断响应是否是 JSON(通常是错误信息) $isJson = false; $jsonResponse = json_decode($response, true); if (json_last_error() === JSON_ERROR_NONE && isset($jsonResponse['status'])) { $isJson = true; } if ($isJson) { // 是错误响应 if ($jsonResponse['status'] === 'FAILED') { // 是 DMS 返回的错误 http_response_code(404); header('Content-Type: application/json; charset=utf-8'); echo json_encode([ 'error' => $jsonResponse['message'] ?? 'Document not found', 'code' => $jsonResponse['code'] ?? 'download_error' ], JSON_UNESCAPED_UNICODE); return; } } else { // 直接当作 ZIP 下载 while (ob_get_level()) ob_end_clean(); //header("Content-Type: application/pdf"); header("Content-type:" . common::getContentType($filename)); header("Content-Length: " . strlen($response)); header("Content-Disposition: attachment; filename=\"" . rawurlencode($filename) . "\"; filename*=UTF-8''" . rawurlencode($filename)); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: public"); echo $response; exit; } } catch (Exception $e) { error_log($e->getMessage()); } } } ?>