ShuanghongS 2 săptămâni în urmă
părinte
comite
99832d1a1f

+ 10 - 10
main_new_version.php

@@ -100,17 +100,17 @@ switch ($action) {
                         }
                         //特殊处理book,需要加二级菜
                         if($v['s_column'] =="Ocean Booking"){
-                            $urlData = $menuSetting[$v['s_column']];
-                            $menuList[] = array("index"=>"$index","label"=>$urlData['label'],"icon"=>$urlData['icon'],"path"=>$urlData['path']);
-                            // $bookingManagement = array("index"=>"$index","label"=>"Booking","icon"=>"icon_booking__fill_b","type"=>"list");
-                            // $children  = array(); 
+                            //$urlData = $menuSetting[$v['s_column']];
+                            //$menuList[] = array("index"=>"$index","label"=>$urlData['label'],"icon"=>$urlData['icon'],"path"=>$urlData['path']);
+                            $bookingManagement = array("index"=>"$index","label"=>"Booking","icon"=>"icon_booking__fill_b","type"=>"list");
+                            $children  = array(); 
 
-                            // $urlData = $menuSetting[$v['s_column']];
-                            // $children[] = array("index"=>$index.'-1',"label"=>"Booking Management","path"=>$urlData['path']);
-                            // $children[] = array("index"=>$index.'-2',"label"=>"Destination Delivery","path"=>"/destination-delivery");
-                            // $bookingManagement["children"] = $children;
-                            // $menuList[] = $bookingManagement;
-                            // $index = $index + 1;
+                            $urlData = $menuSetting[$v['s_column']];
+                            $children[] = array("index"=>$index.'-1',"label"=>"Booking Management","path"=>$urlData['path']);
+                            $children[] = array("index"=>$index.'-2',"label"=>"Destination Delivery","path"=>"/destination-delivery");
+                            $bookingManagement["children"] = $children;
+                            $menuList[] = $bookingManagement;
+                            $index = $index + 1;
                         }
                     }
                 }

+ 21 - 15
service/destination_delivery.class.php

@@ -730,7 +730,12 @@ class destination_delivery {
                 foreach($rs as $key => $val){
                     $rs[$key]["_serial_no"] = common::deCode($val['serial_no'], 'E');
                     $rs[$key]["status"] = common::deliveryStatusConvert($val['status']);
-                    $rs[$key]["h_bol"] = json_decode($val['h_bol_multiple_link']);
+                    //转换一下
+                    $h_bol_multiple_link = json_decode($val['h_bol_multiple_link'],true);
+                    foreach($h_bol_multiple_link as $linkkey => $link){
+                        $h_bol_multiple_link[ $linkkey]['value'] = common::deCode($link['value'], 'E');
+                    }
+                    $rs[$key]["h_bol"] = $h_bol_multiple_link;
                     $rs[$key]["kln_pic"] = empty($val['kln_pic']) ? array() : explode(";", $val['kln_pic']);
                 }
                 $arrTmp = array('searchData' => $rs,
@@ -1198,13 +1203,13 @@ class destination_delivery {
 
             $data = common::excuteObjectSql("select * from public.kln_destination_delivery where serial_no = '$serial_no'");
 
-            $_shipmentsData = array();
+            //$_shipmentsData = array();
             $shipmentsData = $this->search_shipment_with_booking($data['serial_no'],$data['h_serial_no'],$data['ctnr']);
-            foreach($shipmentsData["data"] as $shipment){
-                $_shipmentsData[] = array("HBOL No." => $shipment['h_bol'],"Container No." => $shipment['ctnr'],
-                    "Service Type" => $shipment['service'],"ETA" => $shipment['eta'],
-                    "Recommended Delivery Date" => $shipment['date_range']);
-            }
+            // foreach($shipmentsData["data"] as $shipment){
+            //     $_shipmentsData[] = array("HBOL No." => $shipment['h_bol'],"Container No." => $shipment['ctnr'],
+            //         "Service Type" => $shipment['service'],"ETA" => $shipment['eta'],
+            //         "Recommended Delivery Date" => $shipment['date_range']);
+            // }
 
             $_operation_log = array();
             $operation_log = common::excuteListSql("select * from public.kln_destination_delivery_operation_log where serial_no = '$serial_no' order by id desc");
@@ -1217,7 +1222,7 @@ class destination_delivery {
 
             $retData = $data;
             $retData["status"] = common::deliveryStatusConvert($retData["status"]);
-            $retData['shipmentsData'] = $_shipmentsData;
+            $retData['shipmentsData'] = $shipmentsData["data"];
             $retData['operation_log'] = $_operation_log;
 
             $data = array("msg" =>"success","data"=>$retData);
@@ -1689,15 +1694,15 @@ class destination_delivery {
             select md.*,
                 CASE 
                     WHEN kd.recommended_delivery_window_date_from IS NOT NULL AND kd.recommended_delivery_window_date_to IS NOT NULL THEN
-                        to_char((recommended_delivery_window_date_from)::date, 'YYYY-MM-DD') 
-                        || ';' ||
-                        to_char((recommended_delivery_window_date_to)::date, 'YYYY-MM-DD')
+                        to_char((recommended_delivery_window_date_from)::date, 'YYYY.MM.DD') 
+                        || '-' ||
+                        to_char((recommended_delivery_window_date_to)::date, 'YYYY.MM.DD')
                     WHEN kd.recommended_delivery_window_date_from IS NULL AND kd.recommended_delivery_window_date_to IS NOT NULL THEN
-                        ';' || 
-                        to_char((recommended_delivery_window_date_to)::date, 'YYYY-MM-DD')
+                        '-' || 
+                        to_char((recommended_delivery_window_date_to)::date, 'YYYY.MM.DD')
                     WHEN kd.recommended_delivery_window_date_from IS NOT NULL AND kd.recommended_delivery_window_date_to IS NULL THEN
-                        to_char((recommended_delivery_window_date_from)::date, 'YYYY-MM-DD') 
-                        || ';'
+                        to_char((recommended_delivery_window_date_from)::date, 'YYYY.MM.DD') 
+                        || '-'
                     ELSE  '' 
                 END AS date_range,
                 kd.recommended_delivery_from, 
@@ -1786,6 +1791,7 @@ class destination_delivery {
                     $item['consignee_id'] = array($item['consignee_id']);
                     $item['h_serial_no'] = array($item['h_serial_no']);
                     $item['h_bol'] = array($item['h_bol']);
+                    $item['pakages'] = 0;
                     $item['h_bol_multiple_link'] = array(array("key"=>$h_bol,"value" =>$h_serial_no,"order_from"=>$order_from));
                     $groupedByShipmentId[$h_serial_no] = $item;
                 }

+ 16 - 16
service/login.class.php

@@ -388,9 +388,9 @@ class login {
                     }
 
                     if (!empty($online_user['docdownload']))
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where lower(serial_no) " . common::getInNotInSql($online_user['docdownload']) . " and active = true group by display_name order by min(id)";
+                        $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where lower(serial_no) " . common::getInNotInSql($online_user['docdownload']) . " and active = true group by display_name order by min(id)";
                     else {
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where active = true";
+                        $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where active = true";
                         if (strtolower($online_user['user_type']) == "customer")
                             $sql .= " and client_display = true";
                         $sql .= " group by display_name order by min(id)";
@@ -398,9 +398,9 @@ class login {
                     $online_user['view_doc_type'] = common::excuteListSql($sql);
 
                     if (!empty($online_user['view_air_file_format']))
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where lower(serial_no) " . common::getInNotInSql($online_user['view_air_file_format']) . " and active = true group by display_name order by min(id)";
+                        $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where lower(serial_no) " . common::getInNotInSql($online_user['view_air_file_format']) . " and active = true group by display_name order by min(id)";
                     else {
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where active = true";
+                        $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where active = true";
                         if (strtolower($online_user['user_type']) == "customer")
                             $sql .= " and client_display = true";
                         $sql .= " group by display_name order by min(id)";
@@ -450,9 +450,9 @@ class login {
                         }
 
                         if (!empty($ttdd['docdownload'])) {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['docdownload']) . " and active = true group by display_name order by min(id)";
+                            $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['docdownload']) . " and active = true group by display_name order by min(id)";
                         } else {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where active = true";
+                            $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where active = true";
                             if (strtolower($ttdd['user_type']) == "customer")
                                 $sql .= " and client_display = true";
                             $sql .= " group by display_name order by min(id)";
@@ -460,9 +460,9 @@ class login {
                         $ttdd['view_doc_type'] = common::excuteListSql($sql);
 
                         if (!empty($ttdd['view_air_file_format'])) {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['view_air_file_format']) . " and active = true group by display_name order by min(id)";
+                            $sql = "select  string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['view_air_file_format']) . " and active = true group by display_name order by min(id)";
                         } else {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where active = true";
+                            $sql = "select  string_agg(standard, ';') as standard, string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where active = true";
                             if (strtolower($ttdd['user_type']) == "customer")
                                 $sql .= " and client_display = true";
                             $sql .= " group by display_name order by min(id)";
@@ -948,9 +948,9 @@ class login {
                     }
 
                     if (!empty($online_user['docdownload']))
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where lower(serial_no) " . common::getInNotInSql($online_user['docdownload']) . " and active = true group by display_name order by min(id)";
+                        $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where lower(serial_no) " . common::getInNotInSql($online_user['docdownload']) . " and active = true group by display_name order by min(id)";
                     else {
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where active = true";
+                        $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from ra_online_file_format where active = true";
                         if (strtolower($online_user['user_type']) == "customer")
                             $sql .= " and client_display = true";
                         $sql .= " group by display_name order by min(id)";
@@ -958,9 +958,9 @@ class login {
                     $online_user['view_doc_type'] = common::excuteListSql($sql);
 
                     if (!empty($online_user['view_air_file_format']))
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where lower(serial_no) " . common::getInNotInSql($online_user['view_air_file_format']) . " and active = true group by display_name order by min(id)";
+                        $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where lower(serial_no) " . common::getInNotInSql($online_user['view_air_file_format']) . " and active = true group by display_name order by min(id)";
                     else {
-                        $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where active = true";
+                        $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from air_file_format where active = true";
                         if (strtolower($online_user['user_type']) == "customer")
                             $sql .= " and client_display = true";
                         $sql .= " group by display_name order by min(id)";
@@ -1010,9 +1010,9 @@ class login {
                         }
 
                         if (!empty($ttdd['docdownload'])) {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['docdownload']) . " and active = true group by display_name order by min(id)";
+                            $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['docdownload']) . " and active = true group by display_name order by min(id)";
                         } else {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where active = true";
+                            $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".ra_online_file_format where active = true";
                             if (strtolower($ttdd['user_type']) == "customer")
                                 $sql .= " and client_display = true";
                             $sql .= " group by display_name order by min(id)";
@@ -1020,9 +1020,9 @@ class login {
                         $ttdd['view_doc_type'] = common::excuteListSql($sql);
 
                         if (!empty($ttdd['view_air_file_format'])) {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['view_air_file_format']) . " and active = true group by display_name order by min(id)";
+                            $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where lower(serial_no) " . common::getInNotInSql($ttdd['view_air_file_format']) . " and active = true group by display_name order by min(id)";
                         } else {
-                            $sql = "select string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where active = true";
+                            $sql = "select string_agg(standard, ';') as standard,string_agg(serial_no, ';') as serial_no, string_agg(m_h, ';') as m_h, display_name from " . $sv['schemas_name'] . ".air_file_format where active = true";
                             if (strtolower($ttdd['user_type']) == "customer")
                                 $sql .= " and client_display = true";
                             $sql .= " group by display_name order by min(id)";

+ 59 - 4
service/ocean_order.class.php

@@ -1263,7 +1263,8 @@ class ocean_order {
         //$ocean["m_eta"] = $ocean["oo_eta"];
         //$ocean["atd"] = $ocean["oo_atd"];
         //$ocean["ata"] = $ocean["oo_ata"];
-        
+
+        $_schemas = $_REQUEST["_schemas"];
         if (!empty($ocean)) {
             $ocean['_isf_bol'] = $ocean['isf_bol'];
             if (empty($ocean['_isf_bol'])) {
@@ -1273,7 +1274,6 @@ class ocean_order {
             $isf_ss = substr($isf_ss, 7) . substr($isf_ss, 0, 7);
             //ETA Dest的计算逻辑移除
             // most update status
-            $_schemas = $_REQUEST["_schemas"];
             $mostStatusSql = "select last_status_loc, last_status_city, to_char(last_status_315_date, 'MM/DD/YYYY') as last_status_315_date,last_status_315_code "
                     . ", fport_of_loading_un, mport_of_discharge_un, place_of_receipt_un, place_of_delivery_un FROM public.kln_ocean "
                     . "where serial_no= '" . $ocean["serial_no"] . "'";
@@ -1421,6 +1421,30 @@ class ocean_order {
 
         $document_data = array();
         $document = _getViewDocType($_REQUEST["_schemas"]);
+        if($ocean['source_user'] == 'K5' || $ocean['source_user'] == 'KSMART_AIR2'){
+            //DMS的接口 K5和KSMART AIR的文檔數
+            if (!empty($document)) {
+                $docTypes = array();
+                foreach ($document as $v) {
+                    $_docTypes = $v['standard'];
+                    $_docTypes = explode(";", $_docTypes);
+                    foreach ($_docTypes as $k => $_type) {
+                        $docTypes[] = $_type;
+                    }
+                }
+                $jsonResponse = dms_edoc::getEdocFile($ocean['h_bol'],$docTypes,'ocean');
+                $file_arr = json_decode($jsonResponse, true);
+                foreach($file_arr as $f){
+                    $temp_f = array("url"=>"main_new_version.php?action=ocean_order&operate=download&url=".common::deCode("dms", 'E')."&filename=".common::deCode($f['fileName'], 'E')."&outId=".$f['outId'],
+                            "file_name" => $f['fileName'],
+                            "format_name" => $f['docName'],
+                            "detail"=>$f['uploadDate'],
+                            "can_delete"=>false,
+                            "from_system" =>'dms');
+                    $document_data[] = array("file_type"=>$temp_f["format_name"],"file"=>$temp_f);
+                }
+            }
+        }else{
         $OutFileURL = common::excuteOneSql("select item_value from config where item='OutFileURL'");
 
         $ocean_can_view_file = common::excuteOneSql("select ocean_can_view_file from ra_online_user where lower(user_login)='".strtolower($_SESSION['ONLINE_USER']['user_login'])."'");
@@ -1490,6 +1514,7 @@ class ocean_order {
                 }
             }
         }
+        }
         $document_info = array("document_column"=>$document_column,"document_data" =>$document_data);
 
         $emailRecords = $this->getCommunicationNew($ocean["serial_no"]);
@@ -1594,6 +1619,29 @@ class ocean_order {
         $document_data = array();
 
         $document = _getAirViewDocType($_REQUEST["_schemas"]);
+        if($air['source_user'] == 'K5' || $air['source_user'] == 'KSMART_AIR2'){
+            //DMS的接口 K5和KSMART AIR的文檔數
+            if (!empty($document)) {
+                $docTypes = array();
+                foreach ($document as $v) {
+                    $_docTypes = $v['standard'];
+                    $_docTypes = explode(";", $_docTypes);
+                    foreach ($_docTypes as $k => $_type) {
+                        $docTypes[] = $_type;
+                    }
+                }
+                $file_arr = dms_edoc::getEdocFile($air['_h_bol'],$docTypes,'air');
+                foreach($file_arr as $f){
+                    $temp_f = array("url"=>"main_new_version.php?action=ocean_order&operate=download&url=".common::deCode("dms", 'E')."&filename = ".common::deCode($f['fileName'], 'E')."&outId=".$f['outId'],
+                            "file_name" => $f['fileName'],
+                            "format_name" => $f['docName'],
+                            "detail"=>$f['uploadDate'],
+                            "can_delete"=>false,
+                            "from_system" =>'dms');
+                    $document_data[] = array("file_type"=>$temp_f["format_name"],"file"=>$temp_f);
+                }
+            }                        
+        }else{
         $air_can_view_file = common::excuteOneSql("select air_can_view_file from ra_online_user where lower(user_login)='".strtolower($_SESSION['ONLINE_USER']['user_login'])."'");
         if (!empty($document)) {
             foreach ($document as $v) {
@@ -1649,6 +1697,7 @@ class ocean_order {
                 }
             }
         }
+        }
         $document_info = array("document_column"=>$document_column,"document_data" =>$document_data);
 
         $emailRecords = $this->getCommunicationNew($air["serial_no"]);
@@ -2136,7 +2185,13 @@ class ocean_order {
     */
     private function _download() {
         $url = common::deCode($_GET['url'], 'D');
-        common::download_file($url);
+        if ($url == "dms"){
+            $filename  = common::deCode($_GET['filename'], 'D');
+            $outId  = $_GET['outId'];
+            dms_edoc::downloadEdocFile($outId,$filename);
+        } else {
+            common::download_file($url);
+        }
     }
     
     private function save_vgm() {
@@ -2352,7 +2407,7 @@ class ocean_order {
         from o 
             LEFT JOIN LATERAL ( SELECT  departure_airport_name as fport_of_loading_exp,
                 destination_airport_name as mport_of_discharge_exp,
-                mawb as _mawb, mawb_name as _mawb_name, hawb as _hawb
+                mawb as _mawb, mawb_name as _mawb_name, hawb as _hawb,source_user
             FROM $order_from.air a WHERE a.serial_no = o.serial_no) air ON true
             LEFT JOIN LATERAL ( SELECT company as cn_company,
                 address_1 as cn_address_1,

+ 305 - 6
utils/dms_edoc.class.php

@@ -10,17 +10,206 @@ if (!defined('IN_ONLINE')) {
  * @author Administrator
  */
 class dms_edoc {
+    private static $cachedToken = null;
+    private static $tokenExpiryTime = 0;
+    private static $oceanMapping = [
+                'P'      => '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){
+    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'    => $docTypes
+                'docTypes'    => $resultDocTypes
             ];
+            // $data = [
+            //     'fromStation' => '',
+            //     'hbol'        => 'ABCNA1008776',
+            //     'docTypes'    => ["WO"]
+            // ];
 
             $accessTokenUrl = 'http://dms.kln.com/keycloak/realms/dsms-realm/protocol/openid-connect/token';
             //prod 账号
@@ -41,7 +230,37 @@ class dms_edoc {
         
     }
 
+    /**
+     * 下载文件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,
@@ -76,14 +295,21 @@ class dms_edoc {
         if ($httpCode === 200) {
             $jsonResponse = json_decode($response, true);
             if (isset($jsonResponse['access_token'])) {
-                return $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
+     * 使用 cURL 获取文件list
     */
     public static function CURLClient($url,$accessToken,$data){
         $headers = [
@@ -131,5 +357,78 @@ class dms_edoc {
         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());
+        }
+    }
 }
 ?>