ShuanghongS 1 місяць тому
батько
коміт
deb05e905e
3 змінених файлів з 381 додано та 13 видалено
  1. 17 0
      include.ini.php
  2. 284 9
      service/ocean_order.class.php
  3. 80 4
      utils/common.class.php

+ 17 - 0
include.ini.php

@@ -173,6 +173,15 @@ function _customerFilerSearchHandNew($user, $schemas = "public", $p = 'place_of_
             $sqlWhere1 .= " or lower($n) " . common::getInNotInSql($_contact_id);
         }
     }
+
+    //controlling_customer_code
+    if (utils::checkExist($tt, 't')) {
+        if (empty($sqlWhere1)) {
+            $sqlWhere1 = " exists(select 1 from $schemas.ocean_extend ex where ex.serial_no = serial_no and lower(ex.customer_code) " . common::getInNotInSql($_contact_id)."  limit 1)";
+        } else {
+            $sqlWhere1 .= " or exists(select 1 from $schemas.ocean_extend ex where ex.serial_no = serial_no and lower(ex.customer_code) " . common::getInNotInSql($_contact_id)." limit 1)";
+        }
+    }
     if (empty($sqlWhere1))
         return "1<>1";
     $sqlWhere1 = "(" . $sqlWhere1 . ")";
@@ -394,6 +403,14 @@ function _customerAirFilerSearch($schemas = "public", $s = 'shipper_id', $c = 'c
             $sqlWhere1 .= " or lower($n) " . common::getInNotInSql($_contact_id);
         }
     }
+    //controlling_customer_code
+    if (utils::checkExist($tt, 't')) {
+        if (empty($sqlWhere1)) {
+            $sqlWhere1 = " exists(select 1 from $schemas.air_extend ex where ex.serial_no = serial_no and lower(ex.customer_code) " . common::getInNotInSql($_contact_id)."  limit 1)";
+        } else {
+            $sqlWhere1 .= " or exists(select 1 from $schemas.air_extend ex where ex.serial_no = serial_no and lower(ex.customer_code) " . common::getInNotInSql($_contact_id)." limit 1)";
+        }
+    }
     if (empty($sqlWhere1))
         return "1<>1";
     $sqlWhere1 = "(" . $sqlWhere1 . ")";

+ 284 - 9
service/ocean_order.class.php

@@ -80,6 +80,75 @@ class ocean_order {
             column::getInstance()->settingDisplay('Ocean_Search', 'main_new_version.php?action=ocean_order');
         }
 
+        /*
+        * download  batch document 
+        */
+        if ($operate == "batch_download_load") {
+            $this->_batch_download_load();
+        }
+
+
+        /*
+        * download  batch document 
+        */
+        if ($operate == "batch_download") {
+            $url_param = $_POST['url_param'];
+            $url = $_POST['url'];
+            $h_bol = $_POST['h_bol'];
+            $label = $_POST['label'];
+            $is_topocean = $_POST['is_topocean'];
+
+            $fileMap = array();
+            foreach($url_param as $key => $_url_param){
+                if($is_topocean[$key] == 't'){
+                    continue;
+                    //远程获取文件,并保存到服务器
+                    // $opts = array(
+                    //     'http'=>array(
+                    //         'method'=>"GET",
+                    //         'timeout'=>300,
+                    //     )
+                    // );
+                    // $context = stream_context_create($opts);
+                    // $jd = file_get_contents($url, false, $context);
+                    // //测试数据
+                    // $jd = json_decode(trim($jd,"\xEF\xBB\xBF"),true);
+                    // $data = base64_decode($jd['data']);
+                    
+                    // $old_filename = $jd['filename'];
+                   
+                    // $file_path = FILE_UPLOAD_PAHT . date("Ymd") . DS. date('His') . DS;
+                    // if (!is_dir($file_path)) {
+                    //     common::mkdirs($file_path);
+                    // }
+                    // if (file_exists($file_path . $old_filename)) {
+                    //     $old_filename = common::uuid() . $old_filename;
+                    // }
+                    // $path = $file_path . $old_filename;
+                    // $myfile = fopen($path, "w") or die("Unable to open file!");
+                    // fwrite($myfile, $data);
+                    // fclose($myfile);
+                   
+                    // //真实路径 => 压缩包内新名字
+                    // $customName = $label."_".$h_bol."_".basename($path);
+                    // $fileMap[] = array($path =>$customName);
+                }else{
+                    $filename = common::deCode($_url_param, 'D');
+                    $filename = str_replace("/", DIRECTORY_SEPARATOR, $filename);
+                    $filename = str_replace("\\", DIRECTORY_SEPARATOR, $filename);
+                    if (!file_exists($filename))
+                        exit('File Not Exist');
+
+                    $fileMap[] = [
+                            'file_path' => $filename,
+                            'h_bol' => $h_bol[$key],
+                            'format_name' => $label[$key]
+                        ];
+                }
+            }
+            common::downloadFilesAsZip($fileMap);
+        }
+
         /*
         * download document
         */
@@ -136,10 +205,15 @@ class ocean_order {
             $_schemas = $_REQUEST["_schemas"];
             $transport_mode = $_POST['transport_mode'];
             $bol = $_POST['h_bol'];
+            $_bol = "";
             if ($transport_mode == "sea") {
+                //m_bol,h_bol,job_no
                 $count = common::excuteObjectSql("select * from ocean where lower(h_bol) = '" . strtolower($bol) . "'");
+                $_bol = $count['m_bol'];
             } elseif ($transport_mode == "air") {
+                //mawb,mawb_name,hawb
                 $count = common::excuteObjectSql("select * from air where lower(hawb) = '" . strtolower($bol) . "'");
+                $_bol = $count['mawb'] . '-' . $count['mawb_name'];
             }
             if (empty($count) || utils::count($count) <= 0){
                 $data = array(
@@ -153,9 +227,32 @@ class ocean_order {
             $_table =  $transport_mode == "sea" ? "ra_online_doc_upload" : "air_doc_upload";
             $_table_format =  $transport_mode == "sea" ? "ra_online_file_format" : "air_file_format";
             //格式配置只查询public
-            $format = common::excuteObjectSql("select serial_no,standard,client_upload,notify_station,auto_sync_to_station from public.$_table_format where format_name = '$file_type'");       
+            $format = common::excuteObjectSql("select serial_no,m_h,standard,client_upload,notify_station,auto_sync_to_station from public.$_table_format where format_name = '$file_type'");       
             //查询存在的文件类型最大序号
-            $num = common::excuteOneSql("select count(*) from $_table where lower(bol) = '" . strtolower($bol) . "' and  format_serailno = '".$format['serial_no']."'");
+            //$num = common::excuteOneSql("select count(*) from $_table where lower(bol) = '" . strtolower($bol) . "' and  format_serailno = '".$format['serial_no']."'");
+            $num = 0;
+            if ($transport_mode == "sea") {
+                if (strtolower($format["m_h"]) == 'm'){
+                    $num = common::excuteOneSql("select count(*) from $_schemas.$_table where (lower(bol) = '" . strtolower($count['m_bol']) . "' or lower(bol) = '" . strtolower($count['job_no']) . "') and  format_serailno = '".$format['serial_no']."'");
+                }
+                if (strtolower($format["m_h"]) == 'h'){
+                   $num = common::excuteOneSql("select count(*) from $_schemas.$_table where lower(bol) = '" . strtolower($count['h_bol']) . "' and  format_serailno = '".$format['serial_no']."'");
+                }
+                if (strtolower($format["m_h"]) == 'a'){
+                    $num = common::excuteOneSql("select count(*) from $_schemas.$_table where(lower(bol) = '" . strtolower($count['m_bol']) . "' or lower(bol) = '" . strtolower($count['h_bol']) . "' or lower(bol) = '" . strtolower($count['job_no']) . "') and  format_serailno = '".$format['serial_no']."'");
+                }
+            } elseif ($transport_mode == "air") {
+                if (strtolower($format["m_h"]) == 'm'){
+                    $num = common::excuteOneSql("select count(*) from $_schemas.$_table where lower(bol) = '" . strtolower($count['mawb'] . '-' . $count['mawb_name']) . "' and  format_serailno = '".$format['serial_no']."'");
+                }
+                if (strtolower($format["m_h"]) == 'h'){
+                    $num = common::excuteOneSql("select count(*) from $_schemas.$_table where lower(bol) = '" . strtolower($count['hawb']) . "' and  format_serailno = '".$format['serial_no']."'");
+                }
+                if (strtolower($format["m_h"]) == 'a'){
+                    $num = common::excuteOneSql("select count(*) from $_schemas.$_table where ( lower(bol) = '" . strtolower($count['hawb']) . "'  OR  lower(bol) = '" . strtolower($count['mawb'] . '-' . $count['mawb_name']) . "') and  format_serailno = '".$format['serial_no']."'");
+                }
+            }
+
             try {
                 //$allow_extend = "|.pdf|.xlsx|.docx|";
                 $allow_extend = "|.pdf|";
@@ -212,17 +309,19 @@ class ocean_order {
                         continue;
                     }
                     //pdf文件不需要处理宏,直接保存
+                    $_bol_filed =  (strtolower($format["m_h"]) == 'm') ? $_bol : $bol;
                     if($exten == "pdf"){
                         if (move_uploaded_file($_FILES['file']['tmp_name'][$i], $save_path . $filename)) {
                             $sql .= "insert into $_schemas.$_table (file_name, file_path, upload_date, upload_ip, upload_by, bol, file_type, file_size, online_upload, 
                                 origin, destination, from_station, serial_no, 
                                 online_format,format_serailno,source_filename) 
                             values ('" . common::check_input($filename) . "','" . common::check_input($save_path) . "', now(), '" . common::ip() . "', 
-                                    '" . common::check_input(_getLoginName()) . "','" . common::check_input(strtoupper($bol)) . "', '$order_type', '" . common::check_input($file_size) . "',
+                                    '" . common::check_input(_getLoginName()) . "','" . common::check_input(strtoupper($_bol_filed)) . "', '$order_type', '" . common::check_input($file_size) . "',
                                     't', '" . common::check_input($origin_station) . "', '" .common::check_input($destination_station) . "',
                                     '" . common::check_input($from_station) . "', '" . $serial_no . "',
                                     '" . common::check_input($file_type) . "','" . common::check_input($format_serialno) . "','" . common::check_input($filename) . "');";        
                         } else {
+                            error_log("Upload Filed Failed: move_uploaded_file error");
                             $errorMsg = "Upload Filed Failed.";
                             continue;
                         }
@@ -239,7 +338,7 @@ class ocean_order {
                                     origin, destination, from_station, serial_no, 
                                     online_format,format_serailno,source_filename) 
                                 values ('" . common::check_input($filename) . "','" . common::check_input($save_path) . "', now(), '" . common::ip() . "', 
-                                        '" . common::check_input(_getLoginName()) . "','" . common::check_input(strtoupper($bol)) . "', '$order_type', '" . common::check_input($file_size) . "',
+                                        '" . common::check_input(_getLoginName()) . "','" . common::check_input(strtoupper($_bol_filed)) . "', '$order_type', '" . common::check_input($file_size) . "',
                                         't', '" . common::check_input($origin_station) . "', '" .common::check_input($destination_station) . "',
                                         '" . common::check_input($from_station) . "', '" . $serial_no . "',
                                         '" . common::check_input($file_type) . "','" . common::check_input($format_serialno) . "','" . common::check_input($filename) . "');";
@@ -450,7 +549,7 @@ class ocean_order {
                 common::echo_json_encode(200,$data);
                 exit();
             } catch (Exception $e) {
-                error_log($e->getTraceAsString());
+                error_log("Upload Filed Failed:".$e->getTraceAsString());
                 $data = array(
                     'msg' => "Upload Filed Failed."
                 );
@@ -1191,7 +1290,11 @@ class ocean_order {
 
         //处理ocean_reference
         $ref_no = array();
-        $ref_arr = common::excuteListSql("select * from ocean_reference where  ref_code <> 'PO' and lower(serial_no) = '" . strtolower($serial_no) . "'");
+        $ref_arr = common::excuteListSql("select * from ocean_reference where  ref_code <> 'PO' 
+            and COALESCE(ref_value,'')<>''
+            AND ref_value IS NOT NULL  
+            AND LENGTH(TRIM(BOTH FROM ref_value)) > 0  
+            and lower(serial_no) = '" . strtolower($serial_no) . "'");
         if(!empty($ref_arr)){
             foreach($ref_arr as  $ref) {
                 $ref_no[] = array("label"=>$ref["ref_code"],"value"=>$ref["ref_value"]);
@@ -1783,13 +1886,13 @@ class ocean_order {
             $m_b = $m_bs[$k];
             if (strtolower($m_b) == 'm')
                 $sql = "SELECT (SELECT format_name  from $_schemas.ra_online_file_format where serial_no = ra_online_doc_upload.format_serailno) as format_name,
-                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from ra_online_doc_upload where (lower(bol) = '" . strtolower($m_bol) . "' or lower(bol) ='".strtolower($job_no)."' ) and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
+                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from $_schemas.ra_online_doc_upload where (lower(bol) = '" . strtolower($m_bol) . "' or lower(bol) ='".strtolower($job_no)."' ) and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
             if (strtolower($m_b) == 'h')
                 $sql = "SELECT (SELECT format_name  from $_schemas.ra_online_file_format where serial_no = ra_online_doc_upload.format_serailno) as format_name,
-                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from ra_online_doc_upload where lower(bol) =  '" . strtolower($h_bol) . "' and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
+                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from $_schemas.ra_online_doc_upload where lower(bol) =  '" . strtolower($h_bol) . "' and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
             if (strtolower($m_b) == 'a')
                 $sql = "SELECT (SELECT format_name  from $_schemas.ra_online_file_format where serial_no = ra_online_doc_upload.format_serailno) as format_name,
-                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from ra_online_doc_upload where (lower(bol) = '" . strtolower($m_bol) . "' or lower(bol) = '" . strtolower($h_bol) . "' or lower(bol) ='".strtolower($job_no)."') and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
+                    from_system,serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date from $_schemas.ra_online_doc_upload where (lower(bol) = '" . strtolower($m_bol) . "' or lower(bol) = '" . strtolower($h_bol) . "' or lower(bol) ='".strtolower($job_no)."') and lower(format_serailno) = '$type' and upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter." order by id desc";
             if (!empty($sql)) {
                 $rss = common::excuteListSql($sql);
                 foreach ($rss as $rs) {
@@ -1854,6 +1957,138 @@ class ocean_order {
         return $file;
     }
 
+    /**
+     * 批量选着文件下载
+     */
+    private function _batch_download_load(){
+        //ocean的相关配置参数    
+        $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 user_login='".$_SESSION['ONLINE_USER']['user_login']."'");
+        $tar = json_decode($ocean_can_view_file,true);
+        $sqlFiterWhere = "1<>1 ";
+        foreach($tar as $_tar){
+            foreach($_tar as $dkey => $dvalue){
+                $sqlFiterWhere.= " or (lower(format_serailno) in ('".strtolower(str_replace(";","','",$dvalue['value']))."')  
+                    and upper((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2]) = '".$dvalue['type']."')";
+            }
+        }
+
+        //air的相关配置参数  
+        $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'])."'");
+        $air_tar = json_decode($air_can_view_file,true);
+        $air_sqlFiterWhere = "1<>1 ";
+        foreach($air_tar as $_air_tar){
+            foreach($_air_tar as $air_dkey => $air_dvalue){
+                $air_sqlFiterWhere.= " or (lower(format_serailno) in ('".strtolower(str_replace(";","','",$air_dvalue['value']))."')  
+                    and upper((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2]) = '".$air_dvalue['type']."')";
+            }
+        }
+
+        $vueData = array();
+        $serial_no_arr = $_POST['serial_no_arr'];
+        $_schemas_arr = $_POST['schemas_arr'];
+
+        foreach($serial_no_arr as $key =>$serial_no){
+            $_schemas = $_schemas_arr[$key];
+            
+            $ocean = common::excuteObjectSql("select m_bol as _m_bol,
+                h_bol as _h_bol,
+                transport_mode,
+                order_from,
+                case when transport_mode = 'sea' and order_from = 'public' then (select job_no from public.ocean o  where  o.serial_no = oo.serial_no)
+                    when transport_mode = 'sea' and order_from = 'sfs' then (select job_no from sfs.ocean o  where  o.serial_no = oo.serial_no)
+                else ''::text end as _job_bol
+            from public.kln_ocean oo where oo.serial_no = '$serial_no' and order_from = '$_schemas'");
+
+            $i = $key +1;
+            if ($ocean["transport_mode"] == 'sea'){
+                //ocean 能看的文件类型
+                $document = _getViewDocType($_schemas);
+                $file_serial_nos = array();
+                foreach ($document as $v) {
+                    $types = $v['serial_no'];
+                    $types = strtolower($types);
+                    $types = explode(";", $types);
+                    foreach ($types as $k => $type) {
+                        $file_serial_nos[] = $type;
+                    }
+                }
+                $file_serial_nos = utils::implode(';',$file_serial_nos);
+
+                $filefilter = " ('TELEX') ";
+                $fileSql = "SELECT ff.format_name,
+                            from_system,doc.serial_no,file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date
+                        from $_schemas.ra_online_doc_upload doc
+                            left join $_schemas.ra_online_file_format ff on ff.serial_no = doc.format_serailno
+                    where (lower(bol) = '" . strtolower($ocean['_m_bol']) . "' or lower(bol) = '" . strtolower($ocean['_h_bol']) . "' or lower(bol) = '".strtolower($ocean['_job_bol'])."' )
+                        and (
+                            (upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter.") 
+                            or  ".$sqlFiterWhere."
+                        ) and lower(format_serailno) " . common::getInNotInSql($file_serial_nos) . "  order by ff.format_name ASC,doc.id desc"; 
+
+                $rss = common::excuteListSql($fileSql);
+                $file_arr = array();
+                foreach ($rss as $rs) {
+                    if ($rs['from_system']=="TOPOCEAN"||$rs['from_system']=="KSMART") {
+                        $file_arr[] = array("url"=>$OutFileURL.'/download.php?_schemas=&a='.base64_encode(base64_encode($rs['serial_no'])),
+                                    "url_param" =>$OutFileURL.'/download.php?_schemas=&a='.base64_encode(base64_encode($rs['serial_no'])),
+                                    "file_name" => $rs['file_name'],
+                                    "format_name" => $rs['format_name'],
+                                    "detail"=>$rs['upload_date'],
+                                    "is_topocean" =>true);
+                    }else {
+                        $file_arr[] = array("url"=>"main_new_version.php?action=ocean_order&operate=download&url=". (common::deCode($rs['file_path'] . DS . $rs['file_name'], 'E')),
+                                "url_param" => common::deCode($rs['file_path'] . DS . $rs['file_name'], 'E'),
+                                "file_name" => $rs['file_name'],
+                                "format_name" => $rs['format_name'],
+                                "detail"=>$rs['upload_date'],
+                                "is_topocean" =>false);
+                    }
+                } 
+                $vueData[] = $this->batch_document_upload_Vue_Data($file_arr,$ocean['_h_bol'],$i);   
+            }
+            if ($ocean["transport_mode"] == 'air'){
+                //air能看的文件类型
+                $document = _getAirViewDocType($_schemas);
+                $file_serial_nos = array();
+                foreach ($document as $v) {
+                    $types = $v['serial_no'];
+                    $types = strtolower($types);
+                    $types = explode(";", $types);
+                    foreach ($types as $k => $type) {
+                        $file_serial_nos[] = $type;
+                    }
+                }
+                $file_serial_nos = utils::implode(';',$file_serial_nos);
+
+                $filefilter = " ('TELEX') ";
+                $fileSql = "SELECT ff.format_name,
+                            file_path, file_name, upload_by, to_char(upload_date, 'MM/DD/YYYY') as upload_date
+                        from $_schemas.air_doc_upload 
+                            left join $_schemas.air_file_format ff on ff.serial_no = air_doc_upload.format_serailno
+                    where (lower(bol) = '" . strtolower($ocean['_m_bol']) . "' or lower(bol) = '" . strtolower($ocean['_h_bol']) . "')
+                        and (
+                            (upper(coalesce((string_to_array((string_to_array(file_name,'.'))[1], '_'))[2],'')) not in ".$filefilter.") 
+                            or  ".$sqlFiterWhere."
+                        ) and lower(format_serailno) " . common::getInNotInSql($file_serial_nos) . "  order by ff.format_name ASC,air_doc_upload.id desc"; 
+
+                $rss = common::excuteListSql($fileSql);
+                $file_arr = array();
+                foreach ($rss as $rs) {
+                    $file_arr[] = array("url"=>"main_new_version.php?action=ocean_order&operate=download&url=". (common::deCode($rs['file_path'] . DS . $rs['file_name'], 'E')),
+                                "url_param"=>common::deCode($rs['file_path'] . DS . $rs['file_name'], 'E'),
+                                "file_name" => $rs['file_name'],
+                                "format_name" => $rs['format_name'],
+                                "detail"=>$rs['upload_date'],
+                                "is_topocean" =>false);
+                } 
+                $vueData[] = $this->batch_document_upload_Vue_Data($file_arr,$ocean['_h_bol'],$i);   
+            }
+        }
+        common::echo_json_encode(200, $vueData);
+        exit();
+    }
+
     /*
      * download file
     */
@@ -2467,5 +2702,45 @@ class ocean_order {
         $sql = "SELECT ra_value from ra_online_config where lower(ra_name) = 'upload_document'";
         return common::excuteOneSql($sql);
     }
+
+    private function batch_document_upload_Vue_Data($file_arr,$h_bol,$i){
+        // ==================== 开始转换为目标结构 ====================
+        $result = [
+            'id'         => $i,
+            'isSelect'   => false,
+            'no'         => 'Shipment No. '.$h_bol, // 可动态传入
+            'typeList'   => []
+        ];
+        // 按 format_name 分组
+        $grouped = [];
+        foreach ($file_arr as $file) {
+            $formatName = $file['format_name'] ?: 'Other'; // 防止 null
+
+            if (!isset($grouped[$formatName])) {
+                $grouped[$formatName] = [
+                    'label' => $formatName,
+                    'attachmentList' => []
+                ];
+            }
+
+            $grouped[$formatName]['attachmentList'][] = [
+                'name'       => $file['file_name'],
+                'isSelect'   => false,
+                'url'        => $file['url'],
+                'url_param'  => $file['url_param'],
+                'detail'     => $file['detail'],
+                'h_bol'      => $h_bol,
+                'label'      => $formatName,
+                'is_topocean'=> $file['is_topocean']
+            ];
+        }
+
+        // 添加 number 字段,并保持自然顺序(PHP 数组顺序)
+        foreach ($grouped as $key => $group) {
+            $group['number'] = count($group['attachmentList']);
+            $result['typeList'][] = $group;
+        }
+        return $result;
+    }
 }
 ?>

+ 80 - 4
utils/common.class.php

@@ -1018,6 +1018,70 @@ class common {
         return $filetype[$extend];
     }
 
+    /**
+     * 生成嵌套 ZIP 文件(按 format_name 分组)
+     *
+     * @param array $files 文件列表
+     */
+    public static  function downloadFilesAsZip($files)
+    {
+        // 清除缓冲区,防止输出干扰 ZIP 文件
+        if (ob_get_level()) {
+            ob_end_clean();
+        }
+
+        $f = ONLINE_ROOT . DS . "tmp" . DS . "Attachment Summary_" . date('Y-m-dH\hi\ms\s', time()) . ".zip";
+        $zip = new ZipArchive();
+
+        if ($zip->open($f, ZipArchive::OVERWRITE) === TRUE ||
+            $zip->open($f, ZipArchive::CREATE) === TRUE) {
+            die("create ZIP faild。");
+        }
+
+        // 按 format_name 分组
+        $grouped = [];
+        foreach ($files as $file) {
+            $format = $file['format_name'] ?: 'Other';
+            if (!isset($grouped[$format])) {
+                $grouped[$format] = [];
+            }
+            $grouped[$format][] = $file;
+        }
+
+        // 遍历每个分组(类型),创建子目录
+        foreach ($grouped as $formatName => $fileList) {
+            // 生成子文件夹名:FormatName_YYYYMMDD_HHMMSS
+            $subFolderName = $formatName . '_' . date('Ymd') . '_' . date('His');
+
+            // 添加子文件夹(空目录)
+            $zip->addEmptyDir($subFolderName);
+
+            // 添加每个文件到对应子文件夹
+            $h_bol_num = array();
+            foreach ($fileList as $file) {
+                if(array_key_exists($file['h_bol'], $h_bol_num)){
+                    $h_bol_num[$file['h_bol']] += 1; 
+                }else{
+                    $h_bol_num[$file['h_bol']] = 1;
+                }
+
+                $realPath = $file['file_path'];
+                $extend = self::getExtendFilename($realPath);
+
+                $fileName = $file['h_bol']."_".$file['format_name']."_V".$h_bol_num[$file['h_bol']].".".$extend;
+
+                if (file_exists($realPath) && is_file($realPath)) {
+                    $targetPath = $subFolderName . '/' . $fileName;
+                    $zip->addFile($realPath, $targetPath);
+                }
+            }
+        }
+        $zip->close();
+        // 输出下载 headers
+        common::download_file($f, null, TRUE, null);
+    }
+
+
     /*
      * Get the file extension
     */
@@ -4068,6 +4132,14 @@ class common {
             $consignee_name = common::excuteOneSql("select company from $_schema_contacts.contacts where contact_id = '$consignee' limit 1");
             $consignee_exp = common::combineContactInfoString($delivery_address);
             $consignee_sync_key = $delivery_address['sync_key'];
+            $consignee_country_code = $delivery_address['country'];
+            $consignee_city_code = $delivery_address['city'];
+            $consignee_pic = $delivery_address['contact_person'];
+            $consignee_tel = $delivery_address['contact_number'];
+            $consignee_address1 = $delivery_address['address_1'];
+            $consignee_address2 = $delivery_address['address_2'];
+            $consignee_address3 = $delivery_address['address_3'];
+            $consignee_address4 = $delivery_address['address_4'];
 
             $ctnrs = common::excuteListSql("select * FROM $_schema.oc_container oc where oc.serial_no::text = '".$serial_no."' 
                     and oc.ctnr in (select regexp_split_to_table('".$ctnr_db."', ','))" );
@@ -4101,15 +4173,19 @@ class common {
                 total_volume, total_volume_unit,
                 est_delivery_date, est_delivery_time,instructions,
                 create_user, create_time,delivery_vehicle_type,delivery_fuel_type,
-                consignee, consignee_name, consignee_exp,delivery_to_address_sync_key,
-                refno)
+                consignee, consignee_name, consignee_exp,
+                consignee_address1,consignee_address2,consignee_address3,consignee_address4,
+                consignee_country_code,consignee_city_code,consignee_pic,consignee_tel,consignee_addr_type_id,
+                delivery_to_address_sync_key,refno)
             VALUES ('".$do_serial_no."','".$detail_row_count."','Ocean', '".$oceanInfo['agent']."','".$biztype."','Awaiting Confirmation','".$mode_type."',
                 '".$serial_no."','".$oceanInfo['m_bol']."','".$oceanInfo['h_bol']."','".$oceanInfo['job_no']."',now(),
                 ".$total_pcs.",'".$total_pcs_unit."',".$total_weight.",'".$total_weight_unit."',".$total_volume.",'".$total_volume_unit."',
                 '".$delivery_booking['_delivery_date']."','".$delivery_booking['_delivery_time']."',
                 '".$delivery_booking['special_requirements']."',
-                'KLN_Online',now(),'Subcontractor','Diesel','".$consignee."','".$consignee_name."','".$consignee_exp."','".$consignee_sync_key."',
-                '".$oceanInfo['delivery_reference']."');"; 
+                'KLN_Online',now(),'Subcontractor','Diesel','".$consignee."','".$consignee_name."','".$consignee_exp."',
+                '".$consignee_address1."','".$consignee_address2."','".$consignee_address3."','".$consignee_address4."',
+                '".$consignee_country_code."','".$consignee_city_code."','".$consignee_pic."','".$consignee_tel."',0,
+                '".$consignee_sync_key."','".$oceanInfo['delivery_reference']."');"; 
             
             foreach($ctnrs as $ctnr){
                 $qty = empty($ctnr['qty']) ? "null" : "'".$ctnr['qty']."'";